Files
Inventory/docs/superpowers/specs/2026-03-31-supplier-references-design.md
Matthieu 476060cf7d WIP
2026-03-31 17:57:59 +02:00

83 lines
4.4 KiB
Markdown

# Références Fournisseur par Item — Design Spec
**Date :** 2026-03-31
**Statut :** Validé
## Contexte
Chaque entité (Machine, Pièce, Composant, Produit) a un champ `reference` générique et une relation ManyToMany avec `Constructeur`. Il n'existe aucun moyen de stocker une référence spécifique par fournisseur — si un item est vendu par 3 fournisseurs avec 3 références différentes, on ne peut en stocker qu'une seule.
## Objectif
Permettre de stocker une référence fournisseur (`supplierReference`) par couple (item, constructeur). Le champ `reference` existant reste inchangé comme référence interne. Le champ `supplierPrice` sur Product reste inchangé.
## Design
### Approche retenue : conversion ManyToMany → entités pivot
Remplacer les 4 tables de jointure simples (`_MachineConstructeurs`, `_PieceConstructeurs`, `_ComposantConstructeurs`, `_ProductConstructeurs`) par de vraies entités Doctrine Link, suivant le pattern existant (`MachinePieceLink`, `MachineComponentLink`, etc.).
### Nouvelles entités
| Entité | Table | FK item | FK constructeur | Champs extra |
|--------|-------|---------|-----------------|--------------|
| `MachineConstructeurLink` | `machine_constructeur_links` | `machineId``Machine` | `constructeurId``Constructeur` | `supplierReference` (string 255, nullable) |
| `PieceConstructeurLink` | `piece_constructeur_links` | `pieceId``Piece` | `constructeurId``Constructeur` | `supplierReference` (string 255, nullable) |
| `ComposantConstructeurLink` | `composant_constructeur_links` | `composantId``Composant` | `constructeurId``Constructeur` | `supplierReference` (string 255, nullable) |
| `ProductConstructeurLink` | `product_constructeur_links` | `productId``Product` | `constructeurId``Constructeur` | `supplierReference` (string 255, nullable) |
### Structure de chaque entité
Chaque entité suit le pattern `MachinePieceLink` :
- `CuidEntityTrait` pour l'ID (string, 36 chars)
- `#[ORM\HasLifecycleCallbacks]` avec `createdAt` / `updatedAt`
- Contrainte unique sur `(item_id, constructeur_id)` via `#[ORM\UniqueConstraint]`
- `#[ApiResource]` avec opérations CRUD complètes
- Sécurité : `ROLE_VIEWER` pour lecture, `ROLE_GESTIONNAIRE` pour écriture
- `ManyToOne` vers l'item (onDelete CASCADE)
- `ManyToOne` vers `Constructeur` (onDelete CASCADE)
- Champ `supplierReference` (string 255, nullable)
### Modifications sur les entités existantes
#### Machine, Pièce, Composant, Produit
- Supprimer la propriété `ManyToMany` `constructeurs` et ses getters/setters/add/remove
- Ajouter une propriété `OneToMany` `constructeurLinks` vers le Link correspondant
- Getter `getConstructeurLinks(): Collection`
#### Constructeur
- Supprimer les 4 propriétés `ManyToMany` (`machines`, `composants`, `pieces`, `products`) et leurs getters/setters
- Ajouter 4 propriétés `OneToMany` vers les Links correspondants
### Migration SQL
1. Créer les 4 nouvelles tables avec colonnes `id`, `machineId`/`pieceId`/etc., `constructeurId`, `supplierReference`, `createdAt`, `updatedAt`
2. Ajouter les contraintes uniques
3. Migrer les données des anciennes tables de jointure vers les nouvelles (génération CUID pour chaque ligne, `supplierReference` = NULL)
4. Supprimer les anciennes tables de jointure (`_MachineConstructeurs`, `_PieceConstructeurs`, `_ComposantConstructeurs`, `_ProductConstructeurs`)
### API
Endpoints API Platform auto-générés pour chaque Link :
- `GET /api/machine_constructeur_links` — liste (filtrable par machine, constructeur)
- `GET /api/machine_constructeur_links/{id}` — détail
- `POST /api/machine_constructeur_links` — créer un lien avec référence
- `PATCH /api/machine_constructeur_links/{id}` — modifier la référence
- `DELETE /api/machine_constructeur_links/{id}` — supprimer le lien
Idem pour les 3 autres types.
### Frontend
Les pages détail/édition qui affichent les constructeurs devront être adaptées pour :
- Afficher la `supplierReference` à côté de chaque constructeur
- Permettre l'édition de la référence fournisseur lors de l'ajout/modification d'un constructeur
- Utiliser les endpoints `*ConstructeurLink` au lieu de la collection `constructeurs`
### Hors périmètre
- Migration de `supplierPrice` de Product vers le Link (explicitement exclu)
- Modification du champ `reference` existant sur les entités
- Référence auto (`referenceAuto`) sur Pièce/Composant — non impactée