Files
promo_rathaus/.claude/CLAUDE.md
T
lukas 09b883cc50
CI / deploy (push) Successful in 2s
CI / test (push) Successful in 5m11s
CI / build (push) Successful in 4m47s
✨ Update design
2026-09-02 08:51:30 +02:00

6.7 KiB

CLAUDE.md

Guidance for Claude Code when working in this repository.

Project overview

[1-2 sentences: what this app does, who it's for]

Stack:

  • TanStack Start (React, file-based routing via TanStack Router)
  • TypeScript (strict mode)
  • Vite
  • SCSS Modules
  • Drizzle ORM + PostgreSQL
  • [Auth: Better Auth / Clerk / custom / none yet]
  • [Package manager: pnpm / npm / bun]

Commands

pnpm dev          # start dev server (http://localhost:3000)
pnpm build        # production build
pnpm typecheck    # tsc --noEmit
pnpm lint         # eslint
pnpm test         # [test runner, e.g. vitest]

Always run typecheck and lint before considering a task done. If build fails with TypeScript errors, run typecheck first to isolate them.

Project structure

src/
├── routes/            # file-based routes (TanStack Router)
│   ├── __root.tsx      # root layout, wraps every page
│   └── index.tsx        # home page
├── routeTree.gen.ts    # AUTO-GENERATED — never edit by hand
├── router.tsx           # router instance/config
├── components/
│   ├── ui/               # base primitives (buttons, inputs, etc.)
│   └── <domain>/         # feature-specific components, e.g. posts/, auth/
├── lib/                  # shared utilities, API clients, helpers
├── db/
│   ├── schema.ts         # Drizzle schema definitions
│   ├── index.ts          # Drizzle client instance
│   └── migrations/       # generated SQL migrations — never hand-edit
├── styles/
│   ├── globals.scss      # global styles, resets
│   └── _variables.scss   # shared SCSS variables/mixins (partial)
public/                  # static assets
drizzle.config.ts         # Drizzle Kit config (schema path, out dir, dialect)

Routing conventions

  • Routes live under src/routes/ and map to URLs by file name/path.
  • __root.tsx is the root layout every route renders inside.
  • routeTree.gen.ts is generated by TanStack Router — never edit it directly; it regenerates on dev/build from the files in routes/.
  • Use route loaders for data fetching tied to a route, not useEffect.
  • Keep server-only code (secrets, DB access) out of files that ship to the client; be careful with verbatimModuleSyntax so server code doesn't leak into client bundles.

Styling (SCSS Modules)

  • Every component that needs styles gets a co-located Component.module.scss next to Component.tsx — not a shared stylesheet.
  • Import as import styles from './Component.module.scss' and apply classes via className={styles.foo}; never reference a module class by string outside that import.
  • Class names in .module.scss files are camelCase (e.g. .cardHeader, not .card-header) so they read naturally as styles.cardHeader.
  • Shared tokens (colors, spacing, breakpoints) live in src/styles/_variables.scss and are pulled in with @use '~/styles/variables' as *; — don't hardcode colors/spacing that already exist as a variable.
  • src/styles/globals.scss is for resets and truly global rules only (imported once in __root.tsx); component-specific styles always go in a module, never in globals.
  • Avoid deep nesting (max ~3 levels) and avoid !important.

Code style

  • TypeScript strict mode; avoid any. Prefer inferred types everywhere possible — let TypeScript infer return types and variable types rather than annotating them. Only add explicit types where inference can't reach: function parameters (always type these), exported values whose inferred type would be unclear to a caller, or when inference produces something wider than intended (e.g. use as const or a literal type instead of annotating).
  • Functional React components only, no class components.
  • Use arrow functions everywhere (components, handlers, utilities) instead of the function keyword — e.g. const getUser = async (id: string) => {...} and export const Button = (props: ButtonProps) => {...}.
  • [Naming conventions: PascalCase components, camelCase functions/vars, etc.]
  • [Import order / path aliases, e.g. ~/ or @/ for src/]
  • Co-locate a component's test file next to it unless it's a shared primitive in components/ui/ (see "Styling" for .module.scss placement).
  • No comments unless they're unavoidable for understanding — e.g. explaining why a non-obvious workaround exists, documenting a constraint imposed by an external system, or flagging a case that genuinely can't be made self-evident through naming/structure. Never comment what the code already says; prefer clearer names and smaller functions over a comment explaining an unclear one.

Data layer (Drizzle + Postgres)

  • Schema lives in src/db/schema.ts; the Drizzle client is created once in src/db/index.ts and imported from there — don't instantiate new clients elsewhere.
  • Only import db/* from server-only code (route loaders/actions, server functions) — never from client components, to avoid leaking DB credentials into the client bundle.
  • Query with Drizzle's query builder (db.select()..., db.query.table...) rather than raw SQL, unless a query genuinely needs it.
  • After changing schema.ts, generate a migration rather than editing the database by hand:
    pnpm drizzle-kit generate   # create a migration from schema changes
    pnpm drizzle-kit migrate    # apply pending migrations
    
  • Never hand-edit files under db/migrations/ — they're generated and should be treated as a history, not touched retroactively.
  • [Connection details: env var name for DATABASE_URL, whether using a connection pool like postgres.js or node-postgres, local dev DB setup e.g. Docker Compose]

Testing

  • [Test runner and conventions, e.g. Vitest + Testing Library]
  • [Where tests live: colocated *.test.ts(x) vs a __tests__ dir]
  • Run the relevant test file after changes, not just the full suite, unless asked to verify broadly.

Things to avoid

  • Don't hand-edit routeTree.gen.ts or files under db/migrations/.
  • Don't run destructive Drizzle commands (drizzle-kit push against a populated DB, or anything that drops columns/tables) without confirming first — prefer generate + migrate so changes are reviewable.
  • Don't introduce a new state-management library without asking — prefer route loaders / TanStack Query cache / local state first.
  • Don't add new dependencies without checking package.json for an existing one that already covers the need.
  • [Any other project-specific guardrails]

Git / PR conventions

  • [Commit message style, branch naming, whether Claude should commit automatically or leave changes staged for review]