From 024af5887e1a7b685b7b26712df99993bd0eba7d Mon Sep 17 00:00:00 2001 From: tristan Date: Tue, 17 Mar 2026 16:36:19 +0100 Subject: [PATCH] feat : ajout de supplier dans la feed et fixtures --- .idea/dataSources.xml | 19 ---- .idea/db-forest-config.xml | 2 +- .idea/workspace.xml | 92 ++++++++++-------- AGENTS.md | 73 -------------- CLAUDE.md | 127 +++++++++++++++++++++++++ src/Command/SeedCommand.php | 30 ++++++ src/DataFixtures/ReferenceFixtures.php | 30 ++++++ 7 files changed, 241 insertions(+), 132 deletions(-) delete mode 100644 .idea/dataSources.xml delete mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index 4fee92a..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - postgresql - true - org.postgresql.Driver - jdbc:postgresql://localhost:5432/ferme - $ProjectFileDir$ - - - postgresql - true - org.postgresql.Driver - jdbc:postgresql://localhost:5432/postgres - $ProjectFileDir$ - - - diff --git a/.idea/db-forest-config.xml b/.idea/db-forest-config.xml index 0620fdb..235c8ff 100644 --- a/.idea/db-forest-config.xml +++ b/.idea/db-forest-config.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 88f52e0..8974e33 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,10 +4,13 @@ - @@ -778,7 +791,8 @@ - diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index b1aac43..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,73 +0,0 @@ -# AGENTS.md - -Project overview -- Symfony 8 + API Platform 4 backend, Nuxt 3 frontend in `frontend/`. -- Apache vhost serves API under `/api` and frontend from `frontend/dist`. -- API base URL on frontend uses `NUXT_PUBLIC_API_BASE` (see `frontend/.env`). - -Backend conventions -- Use English for code identifiers/messages; keep “pont-bascule” as domain term. -- API Platform operations are defined on Doctrine entities. -- No custom repository classes are used (`src/Repository` removed); use default Doctrine repositories via `EntityManagerInterface`. -- Reception entity is in `src/Entity/Reception.php`, with custom weigh endpoint `/receptions/weigh`. -- Reception fields: `date_reception`, `license_plate`, `current_step` (default 0), `is_valid` (default false). -- Reception also has `identification_number` (auto `N-BR-####`), `merchandise_type`, `merchandise_detail`, `buildings` (M2M), and `pellet_buildings` (via `reception_pellet_building`). -- `date_reception` is set by the UI, stored as `DateTimeImmutable`, serialized as `Y-m-d`. -- Weight entity (`src/Entity/Weight.php`) is 1–N with Reception, each row stores `type` (`gross` or `tare`), `dsd`, `weight`, `weighed_at` (all nullable except `type`). -- Weigh endpoint `/receptions/weigh` returns `PontBasculeReading` with `dsd`, `weight`, `weighedAt` (formatted `Y-m-d`). -- Custom exception: `App\Exception\PontBasculeException` with French messages, mapped to 500 in provider. -- Parsing of pont-bascule payload is in `src/Service/PontBasculePayloadDecoder.php`. -- `config/reference.php` is auto-generated; keep it. -- Bovine storage: - - `src/Entity/Bovine.php` with fields `nationalNumber` (unique), `receivedWeight`, `arrivalDate`, and `buildingCase` (ManyToOne). - - `src/Entity/BuildingCase.php` has `bovines` (OneToMany). -- Case PDF report: - - Endpoint: `GET /building_cases/{id}/weights-report` (provider: `App\State\BuildingCaseWeightsReportProvider`). - - Template: `templates/case_weights_report.html.twig`. - - Projection logic is done in backend from `arrivalDate`; daily gain is currently fixed at `1.3 kg/day` for all races. - -Frontend conventions -- Nuxt SSR disabled; Tailwind used. -- Layout in `frontend/layouts/default.vue`: max width `1050px`, header full width. -- Tailwind custom color palette is `primary` (e.g. `bg-primary-500`). -- Global font stack uses Helvetica via Tailwind (`font-sans`) and `frontend/assets/css/main.css`. -- API composable in `frontend/composables/useApi.ts` with `get/post/put/patch/delete` and default JSON/PATCH content types. -- API errors/success toasts can be customized via `toastErrorMessage`/`toastSuccessMessage` or i18n keys `toastErrorKey`/`toastSuccessKey`. Global method fallbacks use `errors.http.*` keys. -- `useApi` uses `useNuxtApp().$i18n` (not `useI18n`) to avoid setup-only constraint in service calls. -- Pinia store: `frontend/stores/reception.ts` is the source of truth for the current reception. -- Zod is used for form validation (e.g. `frontend/components/reception/reception-form.vue`); shared helpers live in `frontend/utils/zod-errors.ts`. -- Weighing logic is shared via `frontend/composables/useWeighing.ts`. -- Reception step UI uses store state (`currentStep`) in `frontend/pages/reception/[[id]].vue`. -- Step 2 uses `frontend/components/reception/reception-product-received.vue` for merchandise selection; type codes in `frontend/utils/constants.ts`. -- Active nav styles in header use `NuxtLink` with `custom` slot. -- Reusable UI components live under `frontend/components/ui/` and are auto-imported with `Ui` prefix (e.g. `UiLoadingDots`). -- Service layer lives in `frontend/services/` with typed DTOs in `frontend/services/dto/`. -- Reception service uses `receptions`, `receptions/{id}`, `receptions/weigh` and supports success/error toast keys. -- Reception receipt endpoint is `receptions/{id}/receipt` (PDF) via `frontend/composables/usePdfPrinter.ts`. -- Infrastructure case page prints the case weight report PDF from `frontend/pages/infrastructure/case.vue` using `usePdfPrinter('/building_cases/{id}/weights-report')`. - -Environment & routing -- Frontend dev server: `npm run dev` in `frontend/`. -- API base for local dev: `http://localhost:8080/api` (set in `frontend/.env` via `NUXT_PUBLIC_API_BASE`). -- CORS handled by Nelmio; `.env` includes `CORS_ALLOW_ORIGIN` regex for localhost. -- Nuxt i18n locales live in `frontend/i18n/locales` (configured via `langDir: 'locales'`). -- Default locale is `fr`; translations in `frontend/i18n/locales/fr.json`. - -Notes -- Do not add a GET that creates resources; use POST + PATCH. -- Keep endpoints in plural (API Platform convention). -- Seed and fixtures conventions: - - `app:seed` now seeds infrastructure (`statut`, `building_layout`, `building_case`, `building_case_position`) and bovines. - - `app:seed` uses intermediate flushes (after buildings and after infrastructure) so find queries can resolve just-created records. - - Bovine seed rows use a legacy case token mapping to building-case code (`B{building}-C{case}`) before fallback to direct id lookup. - - Fixtures include `BuildingInfrastructureFixtures` + `BovineFixtures` (via `AppFixtures` dependencies). -- New reference data added: - - Reception types (`reception_type`, fields: `label`, `code`), selectable on reception form. - - Merchandise types (`merchandise_type`, fields: `label`, `code`) and pellet types (`pellet_type`, fields: `label`, `code`). - - Buildings (`building`, fields: `label`, `code`) and reception allocations (`reception_building` M2M, `reception_pellet_building` unique on reception/pellet/building). - - Suppliers (`supplier`) with addresses (`address`, fields: `label`, `street`, `postal_code`, `city`, `country_code` ISO2), via `supplier_address` join table. - - Trucks (`truck`, field: `name`), linked to receptions. - - Carriers (`carrier`, fields: `name`, nullable `code`), Drivers (`driver`, fields: `name`, `carrier_id`), Vehicles (`vehicle`, fields: `plate`, `carrier_id`, `truck_id`) used for LIOT logic. - - Reception links: `reception_type_id`, `supplier_id`, `address_id`, `truck_id`, `carrier_id`, `driver_id`, `user_id`. - - Address exposes `fullAddress` via getter for display. - - LIOT behavior in reception form: if carrier code = `LIOT`, show driver + vehicle selects and hide manual license plate input; vehicle list filters by truck type and carrier; selected vehicle sets `license_plate`. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..fbb6785 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,127 @@ +# 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 +├── composables/ # useApi, useWeighing, usePdfPrinter, useAppVersion +├── services/ # Couche service avec DTOs typés dans services/dto/ +├── stores/ # Pinia stores (reception, shipment, auth) +├── 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. + +## 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). + +## Domaine métier clé + +### Réception (pesée pont-bascule) +- Entité principale `Reception` : `date_reception` (DateTimeImmutable, format `Y-m-d`), `identification_number` (auto `N-BR-####`), `current_step` (défaut 0), `is_valid` (défaut false). +- `Weight` (1-N avec Reception) : `type` (`gross`/`tare`), `dsd`, `weight`, `weighed_at`. +- Endpoint pesée : `/receptions/weigh` → `PontBasculeReading` (dsd, weight, weighedAt). +- Parsing payload pont-bascule : `Service/PontBasculePayloadDecoder.php`. +- Exception : `PontBasculeException` (messages en français, mappée 500). +- Store Pinia `reception.ts` = source de vérité pour la réception en cours. +- UI multi-étapes dans `pages/reception/[[id]].vue` basée sur `currentStep`. + +### LIOT (transport) +- Si carrier code = `LIOT` : afficher sélecteurs driver + vehicle, masquer saisie plaque manuelle. +- Liste véhicules filtrée par type de camion et transporteur. +- Le véhicule sélectionné alimente `license_plate`. + +### Bovins & infrastructure +- `Bovine` : `nationalNumber` (unique), `receivedWeight`, `arrivalDate`, `buildingCase` (ManyToOne). +- `BuildingCase` a `bovines` (OneToMany). +- Rapport PDF cases : `GET /building_cases/{id}/weights-report` → template Twig, projection depuis `arrivalDate`, gain journalier fixe `1.3 kg/jour`. + +### Données de référence +- `ReceptionType`, `MerchandiseType`, `PelletType`, `Building`, `Supplier` (avec `Address` via join table), `Truck`, `Carrier`, `Driver`, `Vehicle`. +- `Address` expose `fullAddress` via getter. + +### Seed & fixtures +- Commande `app:seed` : seed infrastructure (statut, building_layout, building_case, building_case_position) puis bovins. +- Utilise des flush intermédiaires pour que les queries find fonctionnent sur les records fraîchement créés. +- Fixtures : `BuildingInfrastructureFixtures` + `BovineFixtures` (via dépendances `AppFixtures`). + +## Environnement + +- API base dev : `http://localhost:8080/api` (via `NUXT_PUBLIC_API_BASE` dans `frontend/.env`) +- CORS : Nelmio, configurable via `CORS_ALLOW_ORIGIN` dans `.env` +- Locale par défaut : `fr` — traductions dans `frontend/i18n/locales/fr.json` +- Docker env : `docker/.env.docker` (défaut) avec override possible via `docker/.env.docker.local` diff --git a/src/Command/SeedCommand.php b/src/Command/SeedCommand.php index bd69db1..c83c6eb 100644 --- a/src/Command/SeedCommand.php +++ b/src/Command/SeedCommand.php @@ -748,6 +748,36 @@ class SeedCommand extends Command ], ], ], + [ + 'name' => 'EARL DE LA MENAUDIERE', + 'email' => 'frederic.doussineau@orange.fr', + 'phone' => '0675446004', + 'addresses' => [ + [ + 'label' => 'EARL DE LA MENAUDIERE', + 'street' => '1 la menaudière', + 'street2' => null, + 'postalCode' => '86450', + 'city' => 'LEIGNE LES BOIS ', + 'countryCode' => 'FR', + ], + ], + ], + [ + 'name' => 'SARL ERBS', + 'email' => 'touillet.jacques@yahoo.fr', + 'phone' => '0675030304', + 'addresses' => [ + [ + 'label' => 'SARL ERBS', + 'street' => 'les rodières ', + 'street2' => null, + 'postalCode' => '86230', + 'city' => 'Sérigny', + 'countryCode' => 'FR', + ], + ], + ], ]; foreach ($suppliers as $supplierData) { diff --git a/src/DataFixtures/ReferenceFixtures.php b/src/DataFixtures/ReferenceFixtures.php index b8751e1..556cacb 100644 --- a/src/DataFixtures/ReferenceFixtures.php +++ b/src/DataFixtures/ReferenceFixtures.php @@ -311,6 +311,36 @@ class ReferenceFixtures extends Fixture ], ], ], + [ + 'name' => 'EARL DE LA MENAUDIERE', + 'email' => 'frederic.doussineau@orange.fr', + 'phone' => '0675446004', + 'addresses' => [ + [ + 'label' => 'EARL DE LA MENAUDIERE', + 'street' => '1 la menaudière', + 'street2' => null, + 'postalCode' => '86450', + 'city' => 'LEIGNE LES BOIS ', + 'countryCode' => 'FR', + ], + ], + ], + [ + 'name' => 'SARL ERBS', + 'email' => 'touillet.jacques@yahoo.fr', + 'phone' => '0675030304', + 'addresses' => [ + [ + 'label' => 'SARL ERBS', + 'street' => 'les rodières ', + 'street2' => null, + 'postalCode' => '86230', + 'city' => 'Sérigny', + 'countryCode' => 'FR', + ], + ], + ], ]; foreach ($suppliers as $supplierData) {