# SIRH ## Mandatory Rules - Any functional change MUST update `doc/` in the same intervention - At the end of every feature addition or functional modification, update this CLAUDE.md to reflect new patterns, rules, or conventions introduced ## Commands - `make start` — start Docker stack - `make test` — run backend tests (PHPUnit) - `make dev-nuxt` — dev frontend - `cd frontend && npm run build` — build frontend - `php bin/console cache:clear && php bin/console cache:warmup` — clear cache after deploy ## Stack - Backend: Symfony + API Platform + Doctrine ORM - Frontend: Nuxt 4 + Vue 3 + TypeScript + Tailwind CSS ## Project Structure - `src/` — Symfony domain, API resources, state providers/processors, services - `frontend/` — Nuxt app (pages, components, composables, services) - `migrations/` — Doctrine migrations (always include working `down()`) - `doc/` — functional rules and business documentation ## Functional Rules - Reference: `doc/functional-rules.md` (mandatory reading before any business logic change) - Complementary: `doc/leave-rollover.md`, `doc/rtt-rollover.md` ## Domain Model - Contracts: `trackingMode` (TIME=hours, PRESENCE=half-days), `weeklyHours` - Contract types: FORFAIT, THIRTY_FIVE_HOURS, THIRTY_NINE_HOURS, INTERIM, CUSTOM - Contract nature (per period): CDI, CDD, INTERIM - Employee contract history: `employee_contract_periods`, resolved by `EmployeeContractResolver` - Absences: stored per day (auto-split), AM/PM/full day, clear corresponding hour slots - Absences with `countAsWorkedHours=true`: credit minutes (TIME) or nothing (PRESENCE) ## Validation Rules - `isValid` (RH): locks line for everyone (admin can only untoggle validation) - `isSiteValid` (site manager): locks for non-admin, admin can still edit - Any real modification resets both `isSiteValid=false` and `isValid=false` - No-op saves preserve existing validations ## Overtime Rules - Contracts <= 35h: +25% from 35h to 43h, +50% beyond - Contracts >= 39h: +25% from 39h to 43h, +50% beyond - INTERIM: no overtime bonuses, no recovery time ## Frontend Patterns ### Table styling (standard across all pages) - Header: `grid border border-black bg-tertiary-500 px-6 py-3 text-[20px] font-semibold text-black rounded-t-md sticky top-0 z-10` - Body wrapper: `border-x border-b border-primary-500 rounded-b-md` - Rows: `grid items-center gap-4 border-b border-primary-500 px-6 py-3 text-md font-bold text-primary-500 last:border-b-0 cursor-pointer hover:bg-tertiary-500` - Page wrapper for scroll: `h-full flex flex-col overflow-hidden`, table container: `min-h-0 overflow-auto rounded-md bg-white` ### Drawer buttons (AppDrawer) - Edit mode: `grid grid-cols-2 gap-3` → Supprimer (red, left) + Modifier (primary, right) - Create mode: centered `+ Ajouter` button, w-[200px] - Exception: Users drawer has NO delete button - All "Ajouter" buttons across the app use "+" prefix ### API Platform (backend) - Custom operations use Processor (write) / Provider (read) - File uploads: `deserialize: false` on Post, access file via RequestStack - Upload dir: `%kernel.project_dir%/var/uploads` ## Backend Conventions - Prefer explicit DTOs over associative arrays - Business rules in backend (providers/processors/services), frontend is display/interaction only - Keep backend PHP DTOs aligned with frontend TS DTOs (`frontend/services/dto/*`) - Update unit tests when constructor/service signatures change ## Language - UI is in French - User communicates in French - Code (variables, comments) in English