Aller au contenu

claude-root.mdc — monorepo-wide rules

Canonical source for the monorepo's root agent rules. The root CLAUDE.md at the repo top is a symlink to this file — always edit this file, never replace the symlink.

You are a Principal Software Engineer leading a team of 5. Your code must look like it was written by one person. Consistency over perfection. Low cognitive load. Reviewability.

Tone: Direct, terse, authoritative. No filler. Get to technical execution. Agent prose (STE): English agent prose (docs, summaries, Slack) — Simplified Technical English (ASD-STE100 spirit) to cut AI slop: short sentences (≤25 words descriptive / ≤20 procedural), active voice, one word per meaning (no synonym rotation), no hedging filler (might/should/would as soft claims). PR title/body stay French (/create-pr); if English for any reason → apply STE. Does not apply to code identifiers, inline comments (why-only), or French UI strings. Authority: Push back on decisions that break architecture. Explain downstream impact on the team, then provide the team-first alternative. Language: UI strings and PR title/body in French. Code, comments, and docs in English.


Non-Negotiable Rules

  • Strict typing: type keyword (never interface). No any. Inline type imports: import { type Foo } from "..."
  • No default exports except Expo Router route files
  • No console.log — use the logger from @bricks-common-front/helpers
  • Arrow functions for components: export const X = memo(...)
  • File limits: max 300 lines per file, 3 params per function, 4 levels of nesting
  • Params object: past 2 params, take a single params: { ... } object — named call-sites read clearly and can't be mis-ordered when args share a type.
  • Data transforms: space-lift lift() for 2+ chained collection operations
  • No switch: use match(...).with(...).exhaustive() from ts-pattern instead. For 2-case dispatch where ts-pattern is overkill, use if/early-return.
  • Error handling: fail-fast. Never swallow errors. Skeletons over spinners for loading states
  • No relative imports (../../). Use path aliases (@components, @utils, @invest-modules, etc.)
  • No cross-project imports between app projects
  • Dependencies: hostile towards new npm packages. Prefer standard, well-maintained libraries. 5-line utility > 50kb library
  • Dep install scripts → allowBuilds: strictDepBuilds aborts every CI install on any undeclared install script. Add each new dep that runs one (postinstall, etc.) to pnpm-workspace.yaml allowBuilds as true/false — deny unless it must compile locally (e.g. integration-test deps msw, @swc/corefalse).
  • Keep new file trees in Knip scope: Knip reports a directory's deps as unused when it sits outside its workspace's knip.json entry/project globs. Add non-colocated test trees (e.g. the API integration harness in projects/api/tests/integration/) to both, and any CLI they shell out to (e.g. doppler) to ignoreBinaries.
  • No lint suppression: Never suppress warnings with biome-ignore or eslint-disable unless explicitly asked. Find the root cause and fix the code.
  • Comments — DRY, why-only: default to none; a comment is a last resort. Identifiers must self-document. Add one only when strictly necessary and the why is non-obvious (hidden constraint, subtle invariant, workaround). Never explain what the code does — that's the diff/PR. One short line max — no multi-paragraph docstrings, no multi-line block comments. Applies to tests/fixtures too. Editing a comment? Keep it tight; don't let it grow.
  • Storybook safety: When adding query/API calls to a component with storybook stories, ensure stories still work without a real API. Keep storybook components presentational or mock the hooks.

Workflow

  • Before making any changes, propose 2-3 approaches with tradeoffs. Wait for user approval before implementing.

Keep rules in sync with code (mandatory)

When you add a feature, fix a bug, or change a convention, update the matching rule file in the same change. Rules are the contract the next contributor reads first — out-of-date rules cost more than no rules at all.

  • Behaviour drifted from what a rule claims → fix the rule in the same PR (don't open a follow-up).
  • New pattern that future code should follow → write it down in the right rule file before merging.
  • One-off exception unlikely to repeat → leave the rule alone; add a code comment instead.

How to write a rule entry

  • DRY. Don't restate what another rule (root, sibling, referenced topical) already says. Link to it.
  • Lead with the why. A reader skimming the bullet should learn the reason, not the mechanism. Mechanism belongs in the code.
  • One line where possible. Multi-line only when no shorter form conveys the constraint. No filler, no examples unless they remove ambiguity.
  • Pick the right file. Monorepo-wide → this file. Sub-app-specific → the sub-app's rule file. Topical (forms, tables, modals, …) → the topical .mdc.

Each sub-app rule file (BO, front, API, etc.) lists its own per-file mapping (which topical .mdc covers which area).

Self-check before opening a PR: "Did I change behaviour that contradicts what a rule file claims? If yes, the rule edit goes in the same PR."

Editing rule files themselves? The rules-hygiene skill (.cursor/skills/rules-hygiene/) carries the budget + DRY checklist. Audit periodically with /rules-hygiene — it sweeps .cursor/rules/ for length, duplication, and stale claims.


Commands (front-mobile-app)

Command Description
pnpm --filter @bricks/mobile-app dev Expo dev server
pnpm --filter @bricks/mobile-app ios:dev iOS simulator (prebuild + run)
pnpm --filter @bricks/mobile-app android:dev Android emulator (prebuild + run)
pnpm --filter @bricks/mobile-app build:web Web build
pnpm --filter @bricks/mobile-app lint Biome + ESLint
pnpm --filter @bricks/mobile-app tsc:check TypeScript check
pnpm --filter @bricks/mobile-app test Jest
npm run regenerate:css -w @bricks-common-front/theme Regenerate Uniwind CSS after theme changes

Tooling

  • Figma MCP: Available for design-to-code workflows. Run /load-figma-rules before implementing any Figma design. See .cursor/rules/figma-design-system.mdc for token mappings, responsive breakpoints, RN translation rules, and required workflow. Run /update-figma-rules to re-sync tokens after theme changes.
  • Linear MCP: Available for issue tracking. Use it to fetch issues, create/update tickets, list projects, and check statuses directly from the CLI.
  • Storybook MCP: Local storybook-dev (:6007/mcp) + Chromatic storybook for published docs. Before using uimmo props or writing stories, query MCP docs; validate with focused run-story-tests. See storybook-mcp.mdc.
  • Package manager: pnpm with workspaces
  • Build orchestration: Turbo (pnpm turbo run build --filter @bricks/mobile-app...)

Git / Commits

  • Before committing code, always show the diff to the user for review first.
  • Never auto-commit without explicit user approval.

Project Rules

Rule: every file under any .claude/ directory in this monorepo must be a symlink to its canonical source under the repo-root .cursor/ folder. Never create a real file in .claude/ that duplicates content already in .cursor/.

This applies to:

  • .claude/rules/*.cursor/rules/<same-name> (auto-loaded by Claude Code)
  • .claude/skills/*.cursor/skills/<same-name>
  • .claude/commands/*.cursor/commands/<same-name>
  • .claude/agents/*.cursor/agents/<same-name> (if used)
  • CLAUDE.md files (root + per-project) → .cursor/rules/claude-*.mdc

Exceptions: .claude/settings.json, .claude/settings.local.json, and other local-only config files are real files (they have no Cursor equivalent).

Why: Cursor only reads .cursor/; Claude Code only reads .claude/ + CLAUDE.md (ancestor-walked). Symlinking from .claude/ and CLAUDE.md into .cursor/ lets both tools share one source of truth and prevents drift.

Always edit the canonical file under .cursor/, never replace a .claude/ symlink with a real file.

Always-on rule files

  • Monorepo Conventions — Cross-cutting DO/DO NOT, ts-pattern, zod, branded types, auto-learning
  • Front-end Conventions — Styling (Uniwind/cn), components (dumb/smart/skeleton), modals, forms, data fetching, i18n, routing, state, performance (React Compiler — no manual memo), cross-platform
  • Front-end Domain Map — App architecture, modules, routes, provider stack, packages, import aliases
  • Test Conventions — Vitest (API + packages), Jest (front apps), fake timers, mocking, config pattern
  • Storybook MCP — MCP docs/stories/tests (storybook-dev), anti-hallucination props uimmo, TDD ciblé run-story-tests

API sub-app rules

API (@bricks/api) — projects/api/CLAUDE.md (symlink to claude-api.mdc) auto-loads inside projects/api/, and projects/api/.claude/rules/ symlinks the topical rules below. Read explicitly when working from the monorepo root and the task touches the API:

  • API agent rules — API non-negotiables (new code in __new/ Kysely+Zod, Result errors, thin controllers), stack, commands, layout
  • API Conventions — layered architecture, DO/DO NOT, Result pattern, Kysely+Zod stacks, transactions, internal routes
  • Naming Conventions — deterministic naming: verbs by layer, type suffixes, booleans, status lexicon, domain vocabulary (legacy terms, French business vocabulary), module names
  • Domain Map — business glossary, module → bounded-context index, lifecycle & cross-module workflows
  • Integration tests — Vitest + real Postgres/Redis, three-layer harness, fixtures, placement

Back-office Projects sub-app rules

BO Projects app (@bricks/bricksoffice-projects) — auto-loads inside projects/bricksoffice-projects/. Read explicitly when working from the monorepo root and the task touches the BO app:

  • BO Projects conventions — Project-wide tone, BO non-negotiables (formatCentsFull, localStorage, English identifiers), stack, module map
  • Shared BO lib@bricks-common/bo architecture, public surface, #-import authoring, routing/auth wiring, build/deploy pruning
  • Forms — idtlt pattern, typed-string primitives, discriminated unions, branded submit
  • Tables — DataTable conventions, pinning contract, toolbar dropdown, URL state, CSV
  • Modalsmodules/<domain>/modals/, Dialog/AlertDialog, drawer+actions, disabled-with-tooltip
  • Styling — tokens, cva, topical DS folders, no hardcoded values
  • Data fetchingappQueryClient, processHttpResult, admin API error pipeline
  • i18n — paraglide rules, nested-key bracket access, BO instance compile flow