Note:
CLAUDE.mdis a symlink to this file for backward compatibility with Claude Code.
Yarn v4 monorepo with Nx for build orchestration and task running. French government application to track and reduce vacant housing.
Stack: TypeScript, React (frontend), Express (backend), PostgreSQL
├── frontend/ # React app (@zerologementvacant/front)
│ # See frontend/AGENTS.md for frontend-specific patterns
├── server/ # Express API (@zerologementvacant/server)
│ # See server/AGENTS.md for backend-specific patterns
├── e2e/ # End-to-end Cypress tests
├── queue/ # Background job processor
└── packages/
├── api-sdk/ # API client
├── models/ # Shared data models (DTOs)
├── schemas/ # Validation schemas
├── utils/ # Shared utilities
├── healthcheck/ # Health check utilities
└── draft/ # Draft models/utilities
When to work in each workspace:
- Frontend work (React components, UI, state management) → Work in
frontend/, read frontend/AGENTS.md - Backend work (API endpoints, database, validation) → Work in
server/, read server/AGENTS.md - Shared types/models → Work in
packages/models/(DTOs used by both frontend and server) - Validation schemas → Work in
packages/schemas/(shared Yup schemas) - E2E tests → Work in
e2e/
AI agents automatically read the nearest AGENTS.md file in the directory tree. Work in the appropriate workspace and follow its specific conventions.
Run commands from root using Nx via Yarn:
yarn nx <target> <project> # Run specific task for project
yarn nx run-many -t <target> # Run task for all projects
yarn nx run-many -t <target> --exclude=zero-logement-vacantAvailable targets: build, test, typecheck, lint, dev
Examples:
yarn nx test server # Test server only
yarn nx test server -- <file-pattern> # Test specific files (vitest)
yarn nx build frontend # Build frontend
yarn test # Test all (via nx run-many)Copy .env.example files in each workspace and configure.
export DEV_DB=postgres://postgres:postgres@localhost/dev
export TEST_DB=postgres://postgres:postgres@localhost/test
bash .docker/setup.sh # Setup DB + servicesOr manually:
docker compose -f .docker/docker-compose.yml up -d
yarn workspace @zerologementvacant/server migrate
yarn workspace @zerologementvacant/server seedyarn workspace @zerologementvacant/front dev # localhost:3000
yarn workspace @zerologementvacant/server dev # localhost:3001/apiWhen to create shared code:
- Models/DTOs →
packages/models/when types are used by both frontend and server- Naming:
ExampleDTO,ExamplePayload(no DTO suffix for payloads) - Example:
HousingDTO,HousingUpdatePayload
- Naming:
- Validation schemas →
packages/schemas/when validation is shared- Used by both server (API validation) and frontend (form validation)
- Utilities →
packages/utils/for pure functions used across workspaces - Types → Co-locate with implementation unless shared across workspaces
Don't duplicate types! Always check packages/models/ first before creating new types.
// Correct - importing shared DTOs
import { HousingDTO, OwnerDTO } from '@zerologementvacant/models';
import { housingUpdatePayload } from '@zerologementvacant/schemas';
// Frontend extends DTOs with parsed values
interface Housing extends HousingDTO {
lastContact?: Date; // Parsed from ISO string
}
// Backend uses DTOs directly or creates API models
interface HousingApi extends HousingDTO {
// Additional backend-specific fields
}All test fixtures must extend shared DTOs:
- Backend:
genHousingApi()must call/extendgenHousingDTO()from@zerologementvacant/models - Frontend:
genHousing()must call/extendgenHousingDTO()from@zerologementvacant/models - Anything not following this pattern is legacy and should be refactored
Example:
// In @zerologementvacant/models
export function genHousingDTO(): HousingDTO { ... }
// In server tests
export function genHousingApi(): HousingApi {
return {
...genHousingDTO(), // Extend shared DTO
// Add backend-specific fields
};
}
// In frontend tests
export function genHousing(): Housing {
return {
...genHousingDTO(), // Extend shared DTO
// Add parsed/frontend-specific fields
};
}Test-Driven Development (TDD) is mandatory:
- Tests MUST be written BEFORE implementation
- Write failing tests first, then implement to make them pass
Framework:
- All apps and packages use Vitest (not Jest!)
- Any workspace still using Jest is legacy or forced to do so for compatibility reasons
- E2E tests use Cypress
Property-based testing:
- Must use
@fast-check/vitestfor:- API input validation tests
- Schema validation tests
- Any test validating data structures
Test file locations:
- API endpoint tests:
src/controllers/test/<name>-api.test.ts - Repository tests:
src/repositories/test/<name>Repository.test.ts - Component tests: Co-located with components
Running tests:
yarn nx test <project> # Test specific workspace
yarn nx test <project> -- <pattern> # Filter by file pattern
yarn test # Test all workspacesPackage manager: Yarn v4 (requires Node v24)
Adding dependencies:
yarn workspace @zerologementvacant/<workspace> add <package>Security: Use npq for dependency auditing:
npx npq install <package-name> # Checks vulnerabilities before installGitHub Actions runs E2E tests on PRs. See badge in README.
Environments:
- Staging: https://zerologementvacant-staging.incubateur.net
- Production: https://zerologementvacant.beta.gouv.fr
- Wrong command → Always use
yarn nx, never runnxdirectly - Wrong test runner → All workspaces use Vitest (not Jest) unless forced by compatibility
- Duplicating types → Always check
packages/models/before creating new types - Missing env vars → Each workspace needs its own
.envfile - DB not migrated → Run migrations after pulling:
yarn workspace @zerologementvacant/server migrate - Using
yarn testin workspace → Useyarn nx test <project>from root instead - Not following TDD → Write tests BEFORE implementation
- Legacy test fixtures → Ensure all fixtures extend
gen*DTO()from@zerologementvacant/models
Husky configured for pre-commit linting. Configured via .husky/.
- Commit messages: Always in English
- PR titles and descriptions: Always in English
- Branch naming: Use prefixes like
feat/,fix/,chore/,refactor/
- Frontend development → frontend/AGENTS.md
- Backend/API development → server/AGENTS.md
- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through
nx(i.e.nx run,nx run-many,nx affected) instead of using the underlying tooling directly - You have access to the Nx MCP server and its tools, use them to help the user
- When answering questions about the repository, use the
nx_workspacetool first to gain an understanding of the workspace architecture where applicable. - When working in individual projects, use the
nx_project_detailsmcp tool to analyze and understand the specific project structure and dependencies - For questions around nx configuration, best practices or if you're unsure, use the
nx_docstool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration - If the user needs help with an Nx configuration or project graph error, use the
nx_workspacetool to get any errors - For Nx plugin best practices, check
node_modules/@nx/<plugin>/PLUGIN.md. Not all plugins have this file - proceed without it if unavailable.