Schéma BDD du répertoire transporteurs (M4) + entités + contrat de lecture (liste + détail), socle du front. - Migration Version20260615150000 : tables carrier / carrier_address / carrier_contact / carrier_price (FK cross-module, CHECK enum, index partiel uq_carrier_name_active, COMMENT ON COLUMN). uploaded_document et qualimat_carrier réutilisées (non recréées). - Entités Carrier* (#[Auditable], Timestampable/Blamable) + ApiResource LECTURE seule (GetCollection + Get via CarrierProvider, anti-N+1, exclusion archivés + ?includeArchived). Écriture (POST/PATCH + Processor) reportée WT4+. - QualimatCarrier : mapping ORM lecture seule sur la table référentielle existante (sortie du schema_filter, mapping aligné DDL ERP-39, schema:update no-op) + endpoint de recherche read-only (§ 4.7). - Relations cross-module des prix (Client/Supplier/adresses) via contrats Shared (ClientInterface, SupplierInterface, ClientAddressInterface, SupplierAddressInterface) + resolve_target_entities — sans import inter-module (règle n°1). Ajout du groupe supplier_address:read aux champs de SupplierAddress pour l'embed. - Garde-fous : ColumnCommentsCatalog (carrier* + qualimat_carrier), makefile test-db-setup (index partiel carrier), i18n audit (transport_carrier*), EntitiesAreTimestampableBlamableTest (QualimatCarrier whitelisté). - CarrierSerializationContractTest : contrat JSON liste + détail vérifié (embeds objet, booléens, enveloppe Hydra) ; JSON réel capturé dans spec-back § 4.0.bis. make db-reset OK, make test vert (731), make nuxt-test vert (480), php-cs-fixer OK.
5.6 KiB
WT3 ⭐ — Migration + entités Carrier* + ApiResource + Provider (tickets 1.3 + 1.5 / ERP-155 + ERP-157)
Worktree pivot : il livre le CONTRAT JSON qui débloque tout le front. Mode STACK, sans worktree (repo principal) — base = branche de WT2 :
cd /home/matthieu/dev_malio/Starseed && git fetch origin git checkout -b feat/erp-155-carrier-schema-entities origin/feat/erp-153-rbacBase :
feat/erp-153-rbac(contient ERP-150 + WT1 + RBAC WT2). Quand #111 sera mergé dans develop, la PR de WT3 se recible automatiquement sur develop.
Prompt à coller
Projet Starseed (modular monolith DDD, Symfony 8 / API Platform 4). Lis CLAUDE.md, .claude/rules/backend.md, .claude/rules/architecture.md. Charge le skill backend-entity-conventions (patterns entités/migrations complets).
Mission : créer le schéma BDD du répertoire transporteurs + les entités + le contrat de lecture (liste + détail). Tu poses le contrat JSON sur lequel le front s'appuiera — c'est le livrable critique.
Spec : spec-back.md § 3.2 / 3.3 / 3.4 / 4.0 / 4.1 / 4.2. Miroir = le module Supplier : src/Module/Commercial/Domain/Entity/Supplier*.php, …/Infrastructure/ApiPlatform/State/Provider/SupplierProvider.php, …/Serializer/SupplierReadGroupContextBuilder.php. Carrier vit dans src/Module/Transport/.
Étape A — Migration (migrations/, namespace racine DoctrineMigrations)
- PAS de migration modulaire : même si la spec dit « modulaire », toute migration va dans
migrations/namespace racine (tri FQCN cassant sinon). Postérieure à la dernière présente — vérifiels migrations/(à ce jourVersion20260615120000). - Tables
carrier,carrier_address,carrier_contact,carrier_price+ FK :qualimat_carrier,uploaded_document,client,client_address,supplier,supplier_address,site,user. certification_typenullable (null en cas LIOT) + CHECK enum ; CHECK surcontainer_type,direction,pricing_unit,price_state, branches Prix client/fournisseur.- Index partiel
uq_carrier_name_active:LOWER(name)WHERE non archivé ET non supprimé. COMMENT ON COLUMNsur TOUTES les colonnes (FR, ≤200 car.) + helper standard pour les 4 colonnes Timestampable/Blamable. BonusCOMMENT ON TABLE.
Étape B — Entités + repos
Carrier,CarrierAddress,CarrierContact,CarrierPrice:#[Auditable],implements TimestampableInterface, BlamableInterface+use TimestampableBlamableTrait. Repos*RepositoryInterface(Domain) +Doctrine*Repository(Infrastructure).ApiResourceCarrier (attribut sur l'entité, comme Supplier) :GetCollection+Get+Post+Patchavecsecurity(§ 3.3). PAS de Delete.- Groupes :
carrier:read,carrier:item:read,qualimat:read. Embed au détail (pas IRI) :client:read/client_address:read/supplier:read/supplier_address:read/site:read+qualimatCarrier. ⚠ les adresses de l'onglet Prix sont desClientAddress/SupplierAddressdistinctes. CarrierProviderpaginé (ApiPlatform\Doctrine\Orm\Paginator), liste sans cloisonnement site (§ 2.3), anti-N+1 (fetch joins, § 2.11), exclut les archivés par défaut +?includeArchived=true.- Piège booléen :
#[SerializedName('isArchived')]sur le getter.
Gardes-fous qui CASSENT make test (à traiter dans CE worktree)
ColumnsHaveSqlCommentTest→ COMMENT partout + ajouter les blocscarrier,carrier_address,carrier_contact,carrier_pricedanssrc/Shared/Infrastructure/Database/ColumnCommentsCatalog.php(sinontest-db-setupdrope les COMMENT).makefile test-db-setup: l'index partieluq_carrier_name_activen'est PAS exprimé parschema:update→ ajoute-le à la lignedbal:run-sqldu targettest-db-setupdumakefile, sinonmake testcasse.AuditableEntitiesHaveI18nLabelTest→ ajoute dansfrontend/i18n/locales/fr.jsonles clésaudit.entity.transport_carrier,transport_carrieraddress,transport_carriercontact,transport_carrierprice(clé = strtolower(module)+'_'+strtolower(Entity)).EntitiesAreTimestampableBlamableTest,EntityConstraintsHaveFrenchMessageTest(messages FR +Length.max= longueur colonne),CollectionsArePaginatedTest.
Scope STRICT : schéma + entités + ApiResource lecture + Provider + i18n audit. PAS le Processor d'écriture (→ WT4), PAS les sous-ressources POST/PATCH adresses/contacts/prix (→ WT6/7/8), PAS l'export (→ WT9). Mets un CarrierFixtures minimal (1-2 lignes) juste pour faire tourner tes tests de lecture ; les fixtures complètes sont faites par WT10 — n'y investis pas.
Tests à écrire : liste exclut archivés / ?includeArchived=true ; enveloppe Hydra (member/totalItems) ; isArchived présent dans le JSON ; embeds détail présents (pas IRI).
LIVRABLE GATE : une fois vert, capture le JSON réel liste + détail (curl ou test) et colle-le dans spec-back.md § 4.0.bis. C'est le signal pour démarrer le front. Préviens la conv maître.
Fini quand : make db-reset OK + make test vert + make php-cs-fixer-allow-risky. Commit (--no-verify si test vert), puis ouvre la PR :
git push -u origin feat/erp-155-carrier-schema-entities
tea pr create --base feat/erp-153-rbac --head feat/erp-155-carrier-schema-entities \
--title "feat(transport) : schéma + entités Carrier + contrat lecture (ERP-155/157)" \
--description "Migration + entités Carrier* + ApiResource lecture + Provider + i18n audit + contrat JSON. Tickets ERP-155, ERP-157."
Puis labellise via l'API Gitea. Cible develop. Aucune mention IA.