| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 1 | 2 | 38 | 2% |
| Commands | 0 | 16 | 18 | 0% |
| Section tags | 2 | 1 | 9 | 17% |
What each file covers
Sections
1 shared · 2 only in A · 38 only in B- − APIs
- − Frontend
- + Before starting work
- + Post-task checklist (REQUIRED — do not skip)
- + What is lat.md?
- + Development Commands (wodsmith-start)
- + Build and Development
- + Code Quality
- + Database Operations
- + Cloudflare
- + Architecture Overview (wodsmith-start)
- + Tech Stack
- + Project Structure (wodsmith-start)
- + Multi-Tenancy
- + Database Schema
- + Development Guidelines
- + Code Style
- + Database
- + Authentication & Authorization
- + State Management
- + API Patterns
- + TanStack Start Server Functions (wodsmith-start)
- + Syntax primer
- + Test specs
- + Tests
- + User login
- + Rejects expired tokens
- + Handles missing password
- + @lat: [[tests#User login#Rejects expired tokens]]
- + @lat: [[tests#User login#Handles missing password]]
- + Section structure
- + Good Section
- + Child heading
- + Bad Section
- + Skill mappings - when working in these areas, load the linked skill file into context.
- + GitNexus — Code Intelligence
- + Always Do
- + Never Do
- + Resources
- + CLI
- Testing
Commands
0 shared · 16 only in A · 18 only in B- − bun <file>
- − node <file>
- − bun test
- − jest
- − vitest
- − bun build <file.html|file.ts|file.css>
- − bun install
- − npm install
- − yarn install
- − pnpm install
- − bun run <script>
- − npm run <script>
- − yarn run <script>
- − pnpm run <script>
- − bun:sqlite
- − node:fs
- + pnpm dev
- + pnpm build
- + pnpm preview
- + pnpm lint
- + pnpm format
- + pnpm check
- + pnpm type-check
- + pnpm db:push
- + pnpm db:generate --name=X
- + pnpm db:studio
- + pnpm db:migrate:local
- + pnpm test
- + pnpm cf-typegen
- + npx alchemy deploy
- + pnpm alchemy:dev
- + pnpm
- + pnpm db:generate --name=feature-name
- + npx gitnexus analyze
Section tags
2 shared · 1 only in A · 9 only in B- − setup
- + build
- + lint-format
- + architecture
- + types
- + git-pr
- + security
- + database
- + api
- + do-not
- test
- code-style
Line diff
wodsmith/thewodapp · .claude/hooks/CLAUDE.md
@@ −1 @@
1---
2description: Use Bun instead of Node.js, npm, pnpm, or vite.
3globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
4alwaysApply: false
5---
6
7Default to using Bun instead of Node.js.
8
9- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
10- Use `bun test` instead of `jest` or `vitest`
11- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
12- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
13- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
14- Bun automatically loads .env, so don't use dotenv.
15
16## APIs
17
18- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
19- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
20- `Bun.redis` for Redis. Don't use `ioredis`.
21- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
22- `WebSocket` is built-in. Don't use `ws`.
23- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
24- Bun.$`ls` instead of execa.
25
26## Testing
27
28Use `bun test` to run tests.
29
30```ts#index.test.ts
31import { test, expect } from "bun:test";
32
33test("hello world", () => {
34 expect(1).toBe(1);
35});
36```
37
38## Frontend
39
40Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
41
42Server:
43
44```ts#index.ts
45import index from "./index.html"
46
47Bun.serve({
48 routes: {
49 "/": index,
50 "/api/users/:id": {
51 GET: (req) => {
52 return new Response(JSON.stringify({ id: req.params.id }));
53 },
54 },
55 },
56 // optional websocket support
57 websocket: {
58 open: (ws) => {
59 ws.send("Hello, world!");
60 },
61 message: (ws, message) => {
62 ws.send(message);
63 },
64 close: (ws) => {
65 // handle close
66 }
67 },
68 development: {
69 hmr: true,
70 console: true,
71 }
72})
73```
74
75HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
76
77```html#index.html
78<html>
79 <body>
80 <h1>Hello, world!</h1>
81 <script type="module" src="./frontend.tsx"></script>
82 </body>
83</html>
84```
85
86With the following `frontend.tsx`:
87
88```tsx#frontend.tsx
89import React from "react";
90
91// import .css files directly and it works
92import './index.css';
93
94import { createRoot } from "react-dom/client";
95
96const root = createRoot(document.body);
97
98export default function Frontend() {
99 return <h1>Hello, world!</h1>;
100}
101
102root.render(<Frontend />);
103```
104
105Then, run index.ts
106
107```sh
108bun --hot ./index.ts
109```
110
111For more information, read the Bun API docs in `node_modules/bun-types/docs/**.md`.
112
wodsmith/thewodapp · CLAUDE.md
@@ +1 @@
1# Before starting work
2
3- Run `lat search` to find sections relevant to your task. Read them to understand the design intent before writing code.
4- Run `lat expand` on user prompts to expand any `[[refs]]` — this resolves section names to file locations and provides context.
5
6# Post-task checklist (REQUIRED — do not skip)
7
8After EVERY task, before responding to the user:
9
10- [ ] Update `lat.md/` if you added or changed any functionality, architecture, tests, or behavior
11- [ ] Run `lat check` — all wiki links and code refs must pass
12- [ ] Do not skip these steps. Do not consider your task done until both are complete.
13
14---
15
16# What is lat.md?
17
18This project uses [lat.md](https://www.npmjs.com/package/lat.md) to maintain a structured knowledge graph of its architecture, design decisions, and test specs in the `lat.md/` directory. It is a set of cross-linked markdown files that describe **what** this project does and **why** — the domain concepts, key design decisions, business logic, and test specifications. Use it to ground your work in the actual architecture rather than guessing.
19
20## Development Commands (wodsmith-start)
21
22Run these from `apps/wodsmith-start/`:
23
24### Build and Development
25
26- `pnpm dev` - Start development server
27- `pnpm build` - Build TanStack Start application
28- `pnpm preview` - Preview production build with Cloudflare
29
30### Code Quality
31
32- `pnpm lint` - Run Biome linter
33- `pnpm format` - Format code with Biome
34- `pnpm check` - Run Biome check (lint + format)
35- `pnpm type-check` - Run TypeScript type checking
36
37### Database Operations
38
39- `pnpm db:push` - Push schema changes to PlanetScale dev branch (use during development)
40- `pnpm db:generate --name=X` - Generate migration (only before merging to main)
41- `pnpm db:studio` - Open Drizzle Studio
42- `pnpm db:migrate:local` - Apply migrations locally
43
44### Testing
45
46- `pnpm test` - Run all tests with Vitest (single run mode)
47- Test files are located in `test/` directory
48
49### Cloudflare
50
51- `pnpm cf-typegen` - Generate Cloudflare types (run after wrangler.jsonc changes)
52- `npx alchemy deploy` - Deploy using Alchemy IaC
53- `pnpm alchemy:dev` - Deploy local dev environment with Alchemy (required after changing env vars in `.dev.vars`)
54
55## Architecture Overview (wodsmith-start)
56
57### Tech Stack
58
59- **Framework**: TanStack Start (React 19, TypeScript, Vinxi/Vite)
60- **Database**: PlanetScale (MySQL) with Drizzle ORM via Hyperdrive
61- **Authentication**: Custom auth with KV sessions
62- **Deployment**: Cloudflare Workers via Alchemy IaC
63- **UI**: Tailwind CSS, Shadcn UI, Radix primitives
64- **State**: Zustand (client), TanStack Router loaders (server)
65- **API**: TanStack Start server functions (`createServerFn`)
66
67### Project Structure (wodsmith-start)
68
69```
70apps/wodsmith-start/src/
71├── routes/ # TanStack Router file-based routes
72│ ├── api/ # API routes (server handlers)
73│ └── compete/ # Competition features
74├── components/ # React components
75├── db/ # Database schema and migrations
76│ ├── schema.ts # Main schema exports
77│ └── migrations/ # Auto-generated migrations
78├── server/ # Server-only business logic
79├── server-fns/ # Server functions (createServerFn)
80├── lib/ # Shared utilities
81│ ├── env.ts # Server-only env access (getAppUrl, etc.)
82│ └── stripe.ts # Server-only Stripe client
83├── utils/ # Shared utilities
84├── state/ # Client state (Zustand)
85└── schemas/ # Zod validation schemas
86```
87
88### Multi-Tenancy
89
90- Team-based data isolation with `teamId` filtering
91- Role-based permissions (admin, member roles)
92- Team switching via team-switcher component
93- All database operations must include team context
94
95### Database Schema
96
97Database is modularly structured in `src/db/schemas/`:
98
99- `users.ts` - User accounts and authentication
100- `teams.ts` - Team/organization management
101- `workouts.ts` - Workout management system
102- `programming.ts` - Programming tracks and scheduling
103- `billing.ts` - Credit billing system
104- `scaling.ts` - Workout scaling options
105- `scheduling.ts` - Schedule templates and scheduling
106- Main schema exports from `src/db/schema.ts`
107
108## Development Guidelines
109
110### Code Style
111
112- Use TypeScript everywhere, prefer interfaces over types
113- Functional components, avoid classes
114- Server Components by default, `use client` only when necessary
115- Add `import "server-only"` to server-only files (except page.tsx)
116- Use semantic commit messages: `feat:`, `fix:`, `chore:`
117- Use `pnpm` as package manager
118
119### Database
120
121- **Local development**: Use `pnpm db:push` to apply schema changes directly (no migration files)
122- **Before merging**: Generate migrations with `pnpm db:generate --name=feature-name`
123- **Never write SQL migrations manually** - always use drizzle-kit
124- Use `db.transaction()` when multiple writes need to be atomic (PlanetScale supports transactions)
125- Never pass `id` when inserting (auto-generated with CUID2)
126- Always filter by `teamId` for multi-tenant data
127- Use helper functions in `src/server/` for business logic
128- Use standard Drizzle queries with `inArray()` directly — PlanetScale has no restrictive parameter limits
129
130### Authentication & Authorization
131
132- Session handling: `getSessionFromCookie()` for server components
133- Client session: `useSession()` from `src/utils/auth-client.ts`
134- Team authorization utilities in `src/utils/team-auth.ts`
135- Protect routes with team context validation
136- When checking roles use available roles from `src/db/schemas/teams.ts`
137
138### State Management
139
140- Server state: React Server Components
141- Client state: Zustand stores in `src/state/`
142- URL state: NUQS for search parameters
143- Forms: React Hook Form with Zod validation
144
145### API Patterns
146
147- Server functions with TanStack Start: `createServerFn` (see below)
148- Named object parameters for functions with >1 parameter
149- Consistent error handling with proper HTTP status codes
150- Rate limiting on auth endpoints
151
152### TanStack Start Server Functions (wodsmith-start)
153
154#### Environment Variables
155
156**ALWAYS** use `env` from `cloudflare:workers` - never use `process.env`:
157
158```typescript
159import {env} from 'cloudflare:workers'
160
161env.HYPERDRIVE // PlanetScale via Hyperdrive
162env.KV_SESSION // KV namespace binding
163env.APP_URL // Environment variable
164env.STRIPE_SECRET_KEY // Secret
165```
166
167**TypeScript not recognizing env vars?** If you've added new bindings in `alchemy.run.ts` and deployed with `pnpm alchemy:dev`, but TypeScript doesn't see them, run:
168
169```bash
170lat locate "Section Name" # find a section by name (exact, fuzzy)
171lat refs "file#Section" # find what references a section
172lat search "natural language" # semantic search across all sections
173lat expand "user prompt text" # expand [[refs]] to resolved locations
174lat check # validate all links and code refs
175```
176
177Run `lat --help` when in doubt about available commands or options.
178
179If `lat search` fails because no API key is configured, explain to the user that semantic search requires a key provided via `LAT_LLM_KEY` (direct value), `LAT_LLM_KEY_FILE` (path to key file), or `LAT_LLM_KEY_HELPER` (command that prints the key). Supported key prefixes: `sk-...` (OpenAI) or `vck_...` (Vercel). If the user doesn't want to set it up, use `lat locate` for direct lookups instead.
180
181# Syntax primer
182
183- **Section ids**: `lat.md/path/to/file#Heading#SubHeading` — full form uses project-root-relative path (e.g. `lat.md/tests/search#RAG Replay Tests`). Short form uses bare file name when unique (e.g. `search#RAG Replay Tests`, `cli#search#Indexing`).
184- **Wiki links**: `[[target]]` or `[[target|alias]]` — cross-references between sections. Can also reference source code: `[[src/foo.ts#myFunction]]`.
185- **Source code links**: Wiki links in `lat.md/` files can reference functions, classes, constants, and methods in TypeScript/JavaScript/Python/Rust/Go/C files. Use the full path: `[[src/config.ts#getConfigDir]]`, `[[src/server.ts#App#listen]]` (class method), `[[lib/utils.py#parse_args]]`, `[[src/lib.rs#Greeter#greet]]` (Rust impl method), `[[src/app.go#Greeter#Greet]]` (Go method), `[[src/app.h#Greeter]]` (C struct). `lat check` validates these exist.
186- **Code refs**: `// @lat: [[section-id]]` (JS/TS/Rust/Go/C) or `# @lat: [[section-id]]` (Python) — ties source code to concepts
187
188# Test specs
189
190Key tests can be described as sections in `lat.md/` files (e.g. `tests.md`). Add frontmatter to require that every leaf section is referenced by a `// @lat:` or `# @lat:` comment in test code:
191
192```markdown
193---
194lat:
195 require-code-mention: true
196---
197# Tests
198
199Authentication and authorization test specifications.
200
201## User login
202
203Verify credential validation and error handling for the login endpoint.
204
205### Rejects expired tokens
206Tokens past their expiry timestamp are rejected with 401, even if otherwise valid.
207
208### Handles missing password
209Login request without a password field returns 400 with a descriptive error.
210```
211
212Every section MUST have a description — at least one sentence explaining what the test verifies and why. Empty sections with just a heading are not acceptable. (This is a specific case of the general leading paragraph rule below.)
213
214Each test in code should reference its spec with exactly one comment placed next to the relevant test — not at the top of the file:
215
216```python
217# @lat: [[tests#User login#Rejects expired tokens]]
218def test_rejects_expired_tokens():
219 ...
220
221# @lat: [[tests#User login#Handles missing password]]
222def test_handles_missing_password():
223 ...
224```
225
226Do not duplicate refs. One `@lat:` comment per spec section, placed at the test that covers it. `lat check` will flag any spec section not covered by a code reference, and any code reference pointing to a nonexistent section.
227
228# Section structure
229
230Every section in `lat.md/` **must** have a leading paragraph — at least one sentence immediately after the heading, before any child headings or other block content. The first paragraph must be ≤250 characters (excluding `[[wiki link]]` content). This paragraph serves as the section's overview and is used in search results, command output, and RAG context — keeping it concise guarantees the section's essence is always captured.
231
232```markdown
233# Good Section
234
235Brief overview of what this section documents and why it matters.
236
237More detail can go in subsequent paragraphs, code blocks, or lists.
238
239## Child heading
240
241Details about this child topic.
242```
243
244```markdown
245# Bad Section
246
247## Child heading
248
249Details about this child topic.
250```
251
252The second example is invalid because `Bad Section` has no leading paragraph. `lat check` validates this rule and reports errors for missing or overly long leading paragraphs.
253
254<!-- intent-skills:start -->
255# Skill mappings - when working in these areas, load the linked skill file into context.
256skills:
257 - task: "TanStack Router core concepts, route trees, createRouter, createRoute, file naming conventions"
258 load: "node_modules/@tanstack/router-core/skills/router-core/SKILL.md"
259 - task: "Route protection, auth guards, beforeLoad redirects, RBAC, authenticated layouts"
260 load: "node_modules/@tanstack/router-core/skills/router-core/auth-and-guards/SKILL.md"
261 - task: "Code splitting, lazy routes, .lazy.tsx, autoCodeSplitting, getRouteApi"
262 load: "node_modules/@tanstack/router-core/skills/router-core/code-splitting/SKILL.md"
263 - task: "Route data loading, loaders, loaderDeps, staleTime, pendingComponent, Await, deferred data"
264 load: "node_modules/@tanstack/router-core/skills/router-core/data-loading/SKILL.md"
265 - task: "Link component, useNavigate, preloading, navigation blocking, scroll restoration"
266 load: "node_modules/@tanstack/router-core/skills/router-core/navigation/SKILL.md"
267 - task: "notFound handling, errorComponent, CatchBoundary, route masking"
268 load: "node_modules/@tanstack/router-core/skills/router-core/not-found-and-errors/SKILL.md"
269 - task: "Dynamic path params, splat routes, optional params, useParams"
270 load: "node_modules/@tanstack/router-core/skills/router-core/path-params/SKILL.md"
271 - task: "Search params validation, Zod adapters, search middlewares, retainSearchParams"
272 load: "node_modules/@tanstack/router-core/skills/router-core/search-params/SKILL.md"
273 - task: "SSR, streaming, renderRouterToStream, HeadContent, Scripts, head route option, meta tags"
274 load: "node_modules/@tanstack/router-core/skills/router-core/ssr/SKILL.md"
275 - task: "Router type safety, Register declaration, from narrowing, strict mode, LinkProps"
276 load: "node_modules/@tanstack/router-core/skills/router-core/type-safety/SKILL.md"
277<!-- intent-skills:end -->
278
279<!-- gitnexus:start -->
280# GitNexus — Code Intelligence
281
282This project is indexed by GitNexus as **thewodapp** (53782 symbols, 88590 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
283
284> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
285
286## Always Do
287
288- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
289- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows.
290- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
291- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
292- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`.
293
294## Never Do
295
296- NEVER edit a function, class, or method without first running `gitnexus_impact` on it.
297- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
298- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph.
299- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope.
300
301## Resources
302
303| Resource | Use for |
304|----------|---------|
305| `gitnexus://repo/thewodapp/context` | Codebase overview, check index freshness |
306| `gitnexus://repo/thewodapp/clusters` | All functional areas |
307| `gitnexus://repo/thewodapp/processes` | All execution flows |
308| `gitnexus://repo/thewodapp/process/{name}` | Step-by-step execution trace |
309
310## CLI
311
312| Task | Read this skill file |
313|------|---------------------|
314| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
315| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
316| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
317| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
318| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
319| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |
320
321<!-- gitnexus:end -->
322
@@ −1 +1 @@
1+# Before starting work
2+
3+- Run `lat search` to find sections relevant to your task. Read them to understand the design intent before writing code.
4+- Run `lat expand` on user prompts to expand any `[[refs]]` — this resolves section names to file locations and provides context.
5+
6+# Post-task checklist (REQUIRED — do not skip)
7+
8+After EVERY task, before responding to the user:
9+
10+- [ ] Update `lat.md/` if you added or changed any functionality, architecture, tests, or behavior
11+- [ ] Run `lat check` — all wiki links and code refs must pass
12+- [ ] Do not skip these steps. Do not consider your task done until both are complete.
13+
114 ---
2−description: Use Bun instead of Node.js, npm, pnpm, or vite.
3−globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
4−alwaysApply: false
5−---
615
7−Default to using Bun instead of Node.js.
16+# What is lat.md?
817
9−- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
10−- Use `bun test` instead of `jest` or `vitest`
11−- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
12−- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
13−- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
14−- Bun automatically loads .env, so don't use dotenv.
18+This project uses [lat.md](https://www.npmjs.com/package/lat.md) to maintain a structured knowledge graph of its architecture, design decisions, and test specs in the `lat.md/` directory. It is a set of cross-linked markdown files that describe **what** this project does and **why** — the domain concepts, key design decisions, business logic, and test specifications. Use it to ground your work in the actual architecture rather than guessing.
1519
16−## APIs
20+## Development Commands (wodsmith-start)
1721
18−- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
19−- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
20−- `Bun.redis` for Redis. Don't use `ioredis`.
21−- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
22−- `WebSocket` is built-in. Don't use `ws`.
23−- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
24−- Bun.$`ls` instead of execa.
22+Run these from `apps/wodsmith-start/`:
2523
26−## Testing
24+### Build and Development
2725
28−Use `bun test` to run tests.
26+- `pnpm dev` - Start development server
27+- `pnpm build` - Build TanStack Start application
28+- `pnpm preview` - Preview production build with Cloudflare
2929
30−```ts#index.test.ts
31−import { test, expect } from "bun:test";
30+### Code Quality
3231
33−test("hello world", () => {
34− expect(1).toBe(1);
35−});
32+- `pnpm lint` - Run Biome linter
33+- `pnpm format` - Format code with Biome
34+- `pnpm check` - Run Biome check (lint + format)
35+- `pnpm type-check` - Run TypeScript type checking
36+
37+### Database Operations
38+
39+- `pnpm db:push` - Push schema changes to PlanetScale dev branch (use during development)
40+- `pnpm db:generate --name=X` - Generate migration (only before merging to main)
41+- `pnpm db:studio` - Open Drizzle Studio
42+- `pnpm db:migrate:local` - Apply migrations locally
43+
44+### Testing
45+
46+- `pnpm test` - Run all tests with Vitest (single run mode)
47+- Test files are located in `test/` directory
48+
49+### Cloudflare
50+
51+- `pnpm cf-typegen` - Generate Cloudflare types (run after wrangler.jsonc changes)
52+- `npx alchemy deploy` - Deploy using Alchemy IaC
53+- `pnpm alchemy:dev` - Deploy local dev environment with Alchemy (required after changing env vars in `.dev.vars`)
54+
55+## Architecture Overview (wodsmith-start)
56+
57+### Tech Stack
58+
59+- **Framework**: TanStack Start (React 19, TypeScript, Vinxi/Vite)
60+- **Database**: PlanetScale (MySQL) with Drizzle ORM via Hyperdrive
61+- **Authentication**: Custom auth with KV sessions
62+- **Deployment**: Cloudflare Workers via Alchemy IaC
63+- **UI**: Tailwind CSS, Shadcn UI, Radix primitives
64+- **State**: Zustand (client), TanStack Router loaders (server)
65+- **API**: TanStack Start server functions (`createServerFn`)
66+
67+### Project Structure (wodsmith-start)
68+
3669 ```
70+apps/wodsmith-start/src/
71+├── routes/ # TanStack Router file-based routes
72+│ ├── api/ # API routes (server handlers)
73+│ └── compete/ # Competition features
74+├── components/ # React components
75+├── db/ # Database schema and migrations
76+│ ├── schema.ts # Main schema exports
77+│ └── migrations/ # Auto-generated migrations
78+├── server/ # Server-only business logic
79+├── server-fns/ # Server functions (createServerFn)
80+├── lib/ # Shared utilities
81+│ ├── env.ts # Server-only env access (getAppUrl, etc.)
82+│ └── stripe.ts # Server-only Stripe client
83+├── utils/ # Shared utilities
84+├── state/ # Client state (Zustand)
85+└── schemas/ # Zod validation schemas
86+```
3787
38−## Frontend
88+### Multi-Tenancy
3989
40−Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
90+- Team-based data isolation with `teamId` filtering
91+- Role-based permissions (admin, member roles)
92+- Team switching via team-switcher component
93+- All database operations must include team context
4194
42−Server:
95+### Database Schema
4396
44−```ts#index.ts
45−import index from "./index.html"
97+Database is modularly structured in `src/db/schemas/`:
4698
47−Bun.serve({
48− routes: {
49− "/": index,
50− "/api/users/:id": {
51− GET: (req) => {
52− return new Response(JSON.stringify({ id: req.params.id }));
53− },
54− },
55− },
56− // optional websocket support
57− websocket: {
58− open: (ws) => {
59− ws.send("Hello, world!");
60− },
61− message: (ws, message) => {
62− ws.send(message);
63− },
64− close: (ws) => {
65− // handle close
66− }
67− },
68− development: {
69− hmr: true,
70− console: true,
71− }
72−})
99+- `users.ts` - User accounts and authentication
100+- `teams.ts` - Team/organization management
101+- `workouts.ts` - Workout management system
102+- `programming.ts` - Programming tracks and scheduling
103+- `billing.ts` - Credit billing system
104+- `scaling.ts` - Workout scaling options
105+- `scheduling.ts` - Schedule templates and scheduling
106+- Main schema exports from `src/db/schema.ts`
107+
108+## Development Guidelines
109+
110+### Code Style
111+
112+- Use TypeScript everywhere, prefer interfaces over types
113+- Functional components, avoid classes
114+- Server Components by default, `use client` only when necessary
115+- Add `import "server-only"` to server-only files (except page.tsx)
116+- Use semantic commit messages: `feat:`, `fix:`, `chore:`
117+- Use `pnpm` as package manager
118+
119+### Database
120+
121+- **Local development**: Use `pnpm db:push` to apply schema changes directly (no migration files)
122+- **Before merging**: Generate migrations with `pnpm db:generate --name=feature-name`
123+- **Never write SQL migrations manually** - always use drizzle-kit
124+- Use `db.transaction()` when multiple writes need to be atomic (PlanetScale supports transactions)
125+- Never pass `id` when inserting (auto-generated with CUID2)
126+- Always filter by `teamId` for multi-tenant data
127+- Use helper functions in `src/server/` for business logic
128+- Use standard Drizzle queries with `inArray()` directly — PlanetScale has no restrictive parameter limits
129+
130+### Authentication & Authorization
131+
132+- Session handling: `getSessionFromCookie()` for server components
133+- Client session: `useSession()` from `src/utils/auth-client.ts`
134+- Team authorization utilities in `src/utils/team-auth.ts`
135+- Protect routes with team context validation
136+- When checking roles use available roles from `src/db/schemas/teams.ts`
137+
138+### State Management
139+
140+- Server state: React Server Components
141+- Client state: Zustand stores in `src/state/`
142+- URL state: NUQS for search parameters
143+- Forms: React Hook Form with Zod validation
144+
145+### API Patterns
146+
147+- Server functions with TanStack Start: `createServerFn` (see below)
148+- Named object parameters for functions with >1 parameter
149+- Consistent error handling with proper HTTP status codes
150+- Rate limiting on auth endpoints
151+
152+### TanStack Start Server Functions (wodsmith-start)
153+
154+#### Environment Variables
155+
156+**ALWAYS** use `env` from `cloudflare:workers` - never use `process.env`:
157+
158+```typescript
159+import {env} from 'cloudflare:workers'
160+
161+env.HYPERDRIVE // PlanetScale via Hyperdrive
162+env.KV_SESSION // KV namespace binding
163+env.APP_URL // Environment variable
164+env.STRIPE_SECRET_KEY // Secret
73165 ```
74166
75−HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
167+**TypeScript not recognizing env vars?** If you've added new bindings in `alchemy.run.ts` and deployed with `pnpm alchemy:dev`, but TypeScript doesn't see them, run:
76168
77−```html#index.html
78−<html>
79− <body>
80− <h1>Hello, world!</h1>
81− <script type="module" src="./frontend.tsx"></script>
82− </body>
83−</html>
169+```bash
170+lat locate "Section Name" # find a section by name (exact, fuzzy)
171+lat refs "file#Section" # find what references a section
172+lat search "natural language" # semantic search across all sections
173+lat expand "user prompt text" # expand [[refs]] to resolved locations
174+lat check # validate all links and code refs
84175 ```
85176
86−With the following `frontend.tsx`:
177+Run `lat --help` when in doubt about available commands or options.
87178
88−```tsx#frontend.tsx
89−import React from "react";
179+If `lat search` fails because no API key is configured, explain to the user that semantic search requires a key provided via `LAT_LLM_KEY` (direct value), `LAT_LLM_KEY_FILE` (path to key file), or `LAT_LLM_KEY_HELPER` (command that prints the key). Supported key prefixes: `sk-...` (OpenAI) or `vck_...` (Vercel). If the user doesn't want to set it up, use `lat locate` for direct lookups instead.
90180
91−// import .css files directly and it works
92−import './index.css';
181+# Syntax primer
93182
94−import { createRoot } from "react-dom/client";
183+- **Section ids**: `lat.md/path/to/file#Heading#SubHeading` — full form uses project-root-relative path (e.g. `lat.md/tests/search#RAG Replay Tests`). Short form uses bare file name when unique (e.g. `search#RAG Replay Tests`, `cli#search#Indexing`).
184+- **Wiki links**: `[[target]]` or `[[target|alias]]` — cross-references between sections. Can also reference source code: `[[src/foo.ts#myFunction]]`.
185+- **Source code links**: Wiki links in `lat.md/` files can reference functions, classes, constants, and methods in TypeScript/JavaScript/Python/Rust/Go/C files. Use the full path: `[[src/config.ts#getConfigDir]]`, `[[src/server.ts#App#listen]]` (class method), `[[lib/utils.py#parse_args]]`, `[[src/lib.rs#Greeter#greet]]` (Rust impl method), `[[src/app.go#Greeter#Greet]]` (Go method), `[[src/app.h#Greeter]]` (C struct). `lat check` validates these exist.
186+- **Code refs**: `// @lat: [[section-id]]` (JS/TS/Rust/Go/C) or `# @lat: [[section-id]]` (Python) — ties source code to concepts
95187
96−const root = createRoot(document.body);
188+# Test specs
97189
98−export default function Frontend() {
99− return <h1>Hello, world!</h1>;
100−}
190+Key tests can be described as sections in `lat.md/` files (e.g. `tests.md`). Add frontmatter to require that every leaf section is referenced by a `// @lat:` or `# @lat:` comment in test code:
101191
102−root.render(<Frontend />);
192+```markdown
193+---
194+lat:
195+ require-code-mention: true
196+---
197+# Tests
198+
199+Authentication and authorization test specifications.
200+
201+## User login
202+
203+Verify credential validation and error handling for the login endpoint.
204+
205+### Rejects expired tokens
206+Tokens past their expiry timestamp are rejected with 401, even if otherwise valid.
207+
208+### Handles missing password
209+Login request without a password field returns 400 with a descriptive error.
103210 ```
104211
105−Then, run index.ts
212+Every section MUST have a description — at least one sentence explaining what the test verifies and why. Empty sections with just a heading are not acceptable. (This is a specific case of the general leading paragraph rule below.)
106213
107−```sh
108−bun --hot ./index.ts
214+Each test in code should reference its spec with exactly one comment placed next to the relevant test — not at the top of the file:
215+
216+```python
217+# @lat: [[tests#User login#Rejects expired tokens]]
218+def test_rejects_expired_tokens():
219+ ...
220+
221+# @lat: [[tests#User login#Handles missing password]]
222+def test_handles_missing_password():
223+ ...
109224 ```
110225
111−For more information, read the Bun API docs in `node_modules/bun-types/docs/**.md`.
226+Do not duplicate refs. One `@lat:` comment per spec section, placed at the test that covers it. `lat check` will flag any spec section not covered by a code reference, and any code reference pointing to a nonexistent section.
227+
228+# Section structure
229+
230+Every section in `lat.md/` **must** have a leading paragraph — at least one sentence immediately after the heading, before any child headings or other block content. The first paragraph must be ≤250 characters (excluding `[[wiki link]]` content). This paragraph serves as the section's overview and is used in search results, command output, and RAG context — keeping it concise guarantees the section's essence is always captured.
231+
232+```markdown
233+# Good Section
234+
235+Brief overview of what this section documents and why it matters.
236+
237+More detail can go in subsequent paragraphs, code blocks, or lists.
238+
239+## Child heading
240+
241+Details about this child topic.
242+```
243+
244+```markdown
245+# Bad Section
246+
247+## Child heading
248+
249+Details about this child topic.
250+```
251+
252+The second example is invalid because `Bad Section` has no leading paragraph. `lat check` validates this rule and reports errors for missing or overly long leading paragraphs.
253+
254+<!-- intent-skills:start -->
255+# Skill mappings - when working in these areas, load the linked skill file into context.
256+skills:
257+ - task: "TanStack Router core concepts, route trees, createRouter, createRoute, file naming conventions"
258+ load: "node_modules/@tanstack/router-core/skills/router-core/SKILL.md"
259+ - task: "Route protection, auth guards, beforeLoad redirects, RBAC, authenticated layouts"
260+ load: "node_modules/@tanstack/router-core/skills/router-core/auth-and-guards/SKILL.md"
261+ - task: "Code splitting, lazy routes, .lazy.tsx, autoCodeSplitting, getRouteApi"
262+ load: "node_modules/@tanstack/router-core/skills/router-core/code-splitting/SKILL.md"
263+ - task: "Route data loading, loaders, loaderDeps, staleTime, pendingComponent, Await, deferred data"
264+ load: "node_modules/@tanstack/router-core/skills/router-core/data-loading/SKILL.md"
265+ - task: "Link component, useNavigate, preloading, navigation blocking, scroll restoration"
266+ load: "node_modules/@tanstack/router-core/skills/router-core/navigation/SKILL.md"
267+ - task: "notFound handling, errorComponent, CatchBoundary, route masking"
268+ load: "node_modules/@tanstack/router-core/skills/router-core/not-found-and-errors/SKILL.md"
269+ - task: "Dynamic path params, splat routes, optional params, useParams"
270+ load: "node_modules/@tanstack/router-core/skills/router-core/path-params/SKILL.md"
271+ - task: "Search params validation, Zod adapters, search middlewares, retainSearchParams"
272+ load: "node_modules/@tanstack/router-core/skills/router-core/search-params/SKILL.md"
273+ - task: "SSR, streaming, renderRouterToStream, HeadContent, Scripts, head route option, meta tags"
274+ load: "node_modules/@tanstack/router-core/skills/router-core/ssr/SKILL.md"
275+ - task: "Router type safety, Register declaration, from narrowing, strict mode, LinkProps"
276+ load: "node_modules/@tanstack/router-core/skills/router-core/type-safety/SKILL.md"
277+<!-- intent-skills:end -->
278+
279+<!-- gitnexus:start -->
280+# GitNexus — Code Intelligence
281+
282+This project is indexed by GitNexus as **thewodapp** (53782 symbols, 88590 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
283+
284+> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
285+
286+## Always Do
287+
288+- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
289+- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows.
290+- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
291+- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
292+- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`.
293+
294+## Never Do
295+
296+- NEVER edit a function, class, or method without first running `gitnexus_impact` on it.
297+- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
298+- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph.
299+- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope.
300+
301+## Resources
302+
303+| Resource | Use for |
304+|----------|---------|
305+| `gitnexus://repo/thewodapp/context` | Codebase overview, check index freshness |
306+| `gitnexus://repo/thewodapp/clusters` | All functional areas |
307+| `gitnexus://repo/thewodapp/processes` | All execution flows |
308+| `gitnexus://repo/thewodapp/process/{name}` | Step-by-step execution trace |
309+
310+## CLI
311+
312+| Task | Read this skill file |
313+|------|---------------------|
314+| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
315+| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
316+| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
317+| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
318+| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
319+| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |
320+
321+<!-- gitnexus:end -->
112322
