Files
Starseed/docs/specs/M5-tickets-pesee/prompts/ERP-182-migration.md
T
Matthieu 312c119c06 feat(logistique) : entité WeighingTicket + dette site.code (ERP-183)
Entité WeighingTicket
- Entité métier complète (#[Auditable], TimestampableBlamableTrait, relations
  ORM Client/Supplier/Site) + contrat de sérialisation à 3 maillons
  (weighing_ticket:read / :item:read + contextes par opération).
- Getters calculés displayDate et plateFreeFormat (#[SerializedName]),
  sécurité view/manage, pas de Delete/archive.
- Validation #[Assert\*] messages FR + #[Assert\Callback] RG-5.03 (->atPath()),
  libellé i18n audit.entity.logistique_weighingticket.
- Repository : interface Domain + DoctrineWeighingTicketRepository
  (recherche + tri number DESC, deletedAt IS NULL).

Dette site.code
- Site.code mappé VARCHAR(8) (groupes read/write), dérivation auto au
  PrePersist (2 premiers chiffres du CP), UniqueConstraint uq_site_code.
- Migration Version20260617160000 : ALTER COLUMN code SET NOT NULL + COMMENT.
- Fixtures (codes 86/17/82) et SiteApiTest ajustés.

Câblage
- doctrine.yaml : mapping ORM du module Logistique (absent du scaffold ERP-181).
- ColumnCommentsCatalog : site.code + table weighing_ticket.

Specs M5 versionnées (spec-back / spec-front / prompts).
2026-06-18 14:37:16 +02:00

2.9 KiB

Prompt d'implémentation — M5 · ERP-182 (1.2) — Migrer le schéma M5

Projet Starseed. Tâche back / migration. Lis CLAUDE.md (règles n°11 et n°12), .claude/rules/backend.md (§ Migrations) et la spec : docs/specs/M5-tickets-pesee/spec-back.md (§ 3.2, § 3.2.bis, § 2.5, § 2.7).

Mission

Écrire une migration Doctrine au namespace racine DoctrineMigrations (migrations/VersionYYYYMMDDHHMMSS.php, postérieure aux existantes) qui crée tout le schéma M5.

Étapes

  1. site.code : ALTER TABLE site ADD COLUMN code VARCHAR(8) NULLABLE → backfill UPDATE site SET code = LEFT(postal_code, 2) WHERE code IS NULL → index unique uq_site_code (tolère les NULL multiples Postgres).
    • NE PAS poser SET NOT NULL ici. Sur make db-reset, les fixtures SitesFixtures insèrent des sites via l'ORM, qui ne connaît code que si la propriété est mappée sur l'entité Site.php (fait en ERP-183) → sinon INSERT sans code → violation NOT NULL → db-reset plante. Le NOT NULL est posé en ERP-183 (2ᵉ migration) une fois Site::code mappé + peuplé. Cf. spec § 2.5.
  2. Table weighing_ticket_counter (site_id PK → site, last_value INT NOT NULL DEFAULT 0) (séquence numéro par site, RG-5.02).
  3. Table weighbridge_dsd_counter (site_id PK → site, last_value INT NOT NULL DEFAULT 0) (compteur DSD par site, RG-5.04).
  4. Table weighing_ticket : copier le DDL de la spec § 3.2 (colonnes site_id, number, contrepartie counterparty_type/client_id/supplier_id/other_label, immatriculation/plate_free_format, empty_*, full_*, net_weight, deleted_at + 4 colonnes Timestampable/Blamable).
    • Convention INT GENERATED BY DEFAULT AS IDENTITY, TIMESTAMP(0) WITHOUT TIME ZONE (§ 2.2).
    • CHECK : counterparty_type, empty_mode/full_mode, et les 3 branches contrepartie (RG-5.03).
    • Index unique (site_id, number) + index FK (site, client, supplier, deleted_at, created_by, updated_by).
  5. Règle ABSOLUE n°12 : COMMENT ON COLUMN (FR, ≤ 200 car., sémantique + RG) sur chaque colonne créée — cf. échantillon § 3.2.bis. Les 4 colonnes Timestampable/Blamable via addStandardTimestampableBlamableComments($schema, 'weighing_ticket'). Bonus COMMENT ON TABLE.
  6. Écrire down() symétrique (drop tables + drop colonne site.code).

Garde-fous

  • Noms de colonnes en minuscules (Postgres).
  • FK cross-module (user, client, supplier, site) → la migration doit vivre au namespace racine (règle n°11), sinon make db-reset casse l'ordre.
  • ON DELETE : site = RESTRICT, client/supplier = RESTRICT, created_by/updated_by = SET NULL, compteurs = CASCADE.

Vérification

  • make db-reset puis make migration-migrate (BDD fraîche) → OK.
  • make test : ColumnsHaveSqlCommentTest vert (aucune colonne public sans col_description).
  • make php-cs-fixer-allow-risky.