|
| 1 | +# Agent Guidelines |
| 2 | + |
| 3 | +## Project Structure |
| 4 | + |
| 5 | +- **Backend**: `apps/api/` - NestJS with Drizzle ORM |
| 6 | +- **Frontend**: `apps/web/` - TanStack Start |
| 7 | +- **Shared**: `packages/typescript-config/` - Shared TypeScript configs |
| 8 | + |
| 9 | +## Frontend |
| 10 | + |
| 11 | +### Routing (TanStack Start) |
| 12 | + |
| 13 | +- Use Tanstack Start best practices |
| 14 | + |
| 15 | +### Data Fetching (TanStack Query) |
| 16 | + |
| 17 | +- Query keys: `['resource', id, 'sub-resource']` |
| 18 | +- Use `invalidateQueries()` without parameters |
| 19 | + |
| 20 | +### Forms (TanStack Forms) |
| 21 | + |
| 22 | +- Use `useForm()`, ShadCN Field components (`Field`, `FieldLabel`, `FieldError`), `form.useField()` for fields |
| 23 | + |
| 24 | +### UI Components (ShadCN + BaseUI) |
| 25 | + |
| 26 | +- Components: `apps/web/src/components/ui/` - ShadCN |
| 27 | +- Prefer BaseUI primitives over raw html (`@base-ui/react`) |
| 28 | +- Utils: `apps/web/src/lib/utils.ts` - `cn()` helper |
| 29 | +- Tailwind CSS with ShadCN design tokens |
| 30 | + |
| 31 | +### Type Safety |
| 32 | + |
| 33 | +- E2E types: `apps/api/generated/openapi.d.ts` (auto-generated) |
| 34 | + |
| 35 | +### Creating Routes/Components |
| 36 | + |
| 37 | +- Routes: `apps/web/src/routes/{path}.tsx` with `createFileRoute()` |
| 38 | +- Components: `apps/web/src/components/` using ShadCN UI + `cn()` |
| 39 | + |
| 40 | +## Backend |
| 41 | + |
| 42 | +### Database |
| 43 | + |
| 44 | +- Schema: `apps/api/src/databases/drizzle.schema.ts` |
| 45 | +- Tables: `apps/api/src/databases/tables/*.table.ts` |
| 46 | +- Utils: `apps/api/src/databases/drizzle.utils.ts` |
| 47 | +- Provider: `apps/api/src/databases/drizzle.provider.ts` |
| 48 | + |
| 49 | +### Authentication |
| 50 | + |
| 51 | +- Provider: `apps/api/src/auth/better-auth.provider.ts` |
| 52 | +- Guard: `apps/api/src/auth/guards/auth.guard.ts` |
| 53 | +- Decorators: `@Auth()`, `@ActiveUser()`, `@ActiveSession()` |
| 54 | + |
| 55 | +### Transactions |
| 56 | + |
| 57 | +- Use `@Transactional()` decorator |
| 58 | +- Inject `TransactionHost<DrizzleTransactionClient>` |
| 59 | +- Don't manually wrap with `tx.transaction()` |
| 60 | + |
| 61 | +### Services |
| 62 | + |
| 63 | +- Providers for external clients (Better Auth, Drizzle) |
| 64 | +- Services handle business logic |
| 65 | +- Export providers with `Inject*()` helpers |
| 66 | + |
| 67 | +### Error Handling |
| 68 | + |
| 69 | +- Use NestJS exceptions (`NotFoundException`, `UnauthorizedException`, etc.) |
| 70 | + |
| 71 | +### Type Safety |
| 72 | + |
| 73 | +- E2E types: `apps/api/generated/openapi.d.ts` (auto-generated) |
| 74 | +- Use `Serialize` decorator for DTO transformation |
| 75 | + |
| 76 | +### Creating Tables |
| 77 | + |
| 78 | +1. Create `apps/api/src/databases/tables/{name}.table.ts` |
| 79 | +2. Export from `drizzle.schema.ts` |
| 80 | +3. Add relations in `drizzle.relations.ts` |
| 81 | + |
| 82 | +## Important Notes |
| 83 | + |
| 84 | +- Don't nest transactions - use `@Transactional()` decorator |
| 85 | +- Avoid `as any` - use proper types or `as` with specific types |
0 commit comments