docs : add piece quantity design spec

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-03-12 11:44:34 +01:00
parent 03e6c2432b
commit 7a7af58074

View File

@@ -0,0 +1,98 @@
# Piece Quantity — Design Spec
## Context
L'application gère des machines composées de composants et de pièces. Une même pièce (catalogue) peut apparaître dans plusieurs contextes avec des quantités différentes. La quantité doit être portée par la **relation**, pas par l'entité catalogue.
## Scope
- Quantité sur les **pièces directement liées à une machine** (`MachinePieceLink`)
- Quantité sur les **pièces d'un composant** (JSON `structure.pieces` du `Composant`)
- **Hors scope** : quantité sur `MachineComponentLink`, `MachineProductLink`, override de quantité composant au niveau machine
## Règles métier
| Contexte | Stockage | Éditable depuis | Visible sur machine |
|----------|----------|-----------------|---------------------|
| Pièce directement sur machine | `MachinePieceLink.quantity` | Page machine | Oui, éditable |
| Pièce d'un composant | `Composant.structure.pieces[].quantity` | Page composant (création + édition) | Oui, lecture seule |
- Type : entier, valeur par défaut = 1
- Affichage : "×N" après le nom de la pièce, masqué si N = 1
## Backend
### 1. MachinePieceLink — Nouvelle colonne
Ajout d'un champ `quantity` sur l'entité `MachinePieceLink` :
```php
#[ORM\Column(type: Types::INTEGER, options: ['default' => 1])]
#[Groups(['machine_piece_link:read', 'machine_piece_link:write'])]
private int $quantity = 1;
```
Getter/setter standard.
### 2. Migration SQL
```sql
ALTER TABLE machine_piece_link ADD COLUMN IF NOT EXISTS quantity INTEGER NOT NULL DEFAULT 1;
```
Idempotente avec `IF NOT EXISTS`.
### 3. Composant.structure JSON
Le tableau `pieces` dans le JSON `structure` du Composant accepte une nouvelle clé `quantity`. Pas de migration DB nécessaire — c'est un champ JSON libre.
Avant :
```json
{ "typePieceId": "...", "role": "Filtration" }
```
Après :
```json
{ "typePieceId": "...", "role": "Filtration", "quantity": 4 }
```
Les entrées existantes sans `quantity` sont traitées comme `quantity = 1` (défaut côté frontend et backend).
### 4. MachineStructureController
- `normalizePieceLinks()` : inclure `quantity` dans la réponse JSON
- Pièce machine directe (parentLink = null) : `quantity` depuis `MachinePieceLink.quantity`
- Pièce sous composant : `quantity` depuis le `structure.pieces` du composant source
- **PATCH** : accepter `quantity` pour les pièces directement sur la machine uniquement
## Frontend
### 1. Types TypeScript
Mise à jour de `ComponentModelPiece` :
```typescript
interface ComponentModelPiece {
typePieceId?: string
typePieceLabel?: string
reference?: string
familyCode?: string
role?: string
quantity?: number // défaut 1
}
```
### 2. Pages composant (création + édition)
Dans l'éditeur de structure, chaque pièce du tableau `structure.pieces` affiche un champ input :
- Type : `number`, min = 1, step = 1
- Valeur par défaut : 1
- Style : `input input-bordered input-sm md:input-md` (DaisyUI)
- Position : à côté des champs existants (reference, role)
### 3. Page machine (détail/structure)
- **Pièce directe** (parentLink = null) : affiche "×N" à côté du nom, quantité éditable (input entier)
- **Pièce de composant** : affiche "×N" à côté du nom, lecture seule (pas d'input)
- Si quantité = 1 : rien n'est affiché (pas de bruit visuel)
- Style du label : texte secondaire (`text-base-content/60` ou classe équivalente)