# CLAUDE.md ## Stack - **Backend:** Symfony 8 + API Platform 4 (PHP 8.4) - **Frontend:** Nuxt 4 (Vue 3, Pinia, Tailwind, Zod) in `frontend/` - **Infra:** Docker (PHP-FPM + Nginx), Apache vhost serves API sous `/api` et frontend depuis `frontend/dist` ## Commands ```bash # Docker make start # Démarrer les containers make stop # Arrêter les containers make restart # Redémarrer les containers make shell # Shell dans le container PHP # Install complet make install # composer install + migrations + build frontend # Backend make composer-install # Installer dépendances PHP make migration-migrate # Lancer les migrations make fixtures # Charger les fixtures make cache-clear # Vider le cache Symfony make test # Lancer les tests PHPUnit make test FILES=tests/path/to/TestFile.php # Test spécifique make php-cs-fixer-allow-risky FILES=src/... # Fixer le style # Frontend make build-nuxtJS # npm install + build:dist (dans le container) make dev-nuxt # Serveur dev Nuxt (dans le container) # Ou directement dans frontend/ : cd frontend && npm run dev # Dev server (port 3000) cd frontend && npm run build:dist # Build production # Base de données make db-reset # ⚠️ Supprime et recrée la BDD + migrations + fixtures ``` ## Architecture backend ``` src/ ├── ApiResource/ # Ressources API Platform custom ├── Command/ # Commandes Symfony (dont app:seed) ├── DataFixtures/ # Fixtures Doctrine ├── Dto/ # DTOs (ex: PontBasculeReading) ├── Entity/ # Entités Doctrine (= ressources API Platform) ├── Exception/ # Exceptions custom (PontBasculeException) ├── Kernel.php ├── Service/ # Services métier (PontBasculePayloadDecoder…) └── State/ # State providers/processors API Platform ``` ## Architecture frontend ``` frontend/ ├── components/ │ ├── ui/ # Composants réutilisables, auto-importés avec préfixe Ui (ex: UiLoadingDots) │ ├── reception/ # Composants métier réception │ ├── shipment/ # Composants métier expédition │ ├── workflow/ # Composants partagés réception/expédition (workflow-weight, workflow-waiting-list, workflow-liot-fields) │ └── commun/ # Composants communs (update-weight) ├── composables/ # useApi, useWeighing, usePdfPrinter, useAppVersion, useLiotHandling, useFormDataLoading, useAddressSync, useWorkflowSteps │ └── steps/ # useWeighingStep (logique étape pesée) ├── config/ # reception.config.ts, shipment.config.ts (WorkflowConfig) ├── types/ # workflow.ts (interfaces partagées WorkflowEntity, WorkflowConfig, StepDefinition) ├── services/ # Couche service avec DTOs typés dans services/dto/ │ └── workflow-service.ts # Factory service API (createWorkflowService) ├── stores/ # Pinia stores (reception, shipment, auth) │ └── workflow-store.ts # Factory store (useWorkflowStoreLogic) ├── pages/ # Pages Nuxt (file-based routing) ├── layouts/ # Layout default : max-width 1050px ├── i18n/locales/ # Traductions (défaut: fr) ├── utils/ # Constants, zod-errors helpers └── assets/css/ # Tailwind config, main.css (font Helvetica) ``` ## Conventions backend - Code en anglais ; "pont-bascule" est un terme métier conservé tel quel. - Les opérations API Platform sont définies directement sur les entités Doctrine. - Pas de classes Repository custom : utiliser `EntityManagerInterface` avec les repos par défaut. - `config/reference.php` est auto-généré — ne pas modifier à la main. - Endpoints toujours au pluriel (convention API Platform). - Ne jamais créer de GET qui crée des ressources : utiliser POST + PATCH. - Les noms de `Supplier`, `Customer` et `Carrier` sont automatiquement mis en majuscule via `mb_strtoupper` dans `setName()`. ## Conventions frontend - SSR désactivé. Tailwind avec palette custom `primary` (ex: `bg-primary-500`). - `useApi` (`composables/useApi.ts`) : méthodes `get/post/put/patch/delete` avec content-types par défaut. - Toasts personnalisables via `toastErrorMessage`/`toastSuccessMessage` ou clés i18n `toastErrorKey`/`toastSuccessKey`. - Utilise `useNuxtApp().$i18n` (pas `useI18n`) pour fonctionner hors setup. - Validation formulaires avec Zod ; helpers dans `utils/zod-errors.ts`. - Nav active : `NuxtLink` avec slot `custom`. - PDFs : `usePdfPrinter` (receipt réception, rapport poids cases). ### Validation required & erreurs visuelles - Les champs `required` utilisent l'attribut HTML natif forwardé via `v-bind="attrs"` dans les composants UI. - La bordure rouge n'apparaît qu'après soumission grâce à la classe CSS `submitted` ajoutée sur le `