# Notes de réalisation

Écarts par rapport au `reference/BRIEF.md`, et décisions prises en cours de route.
Chaque point porte sa raison. Rien n'a été écarté en silence.

---

## 1. Écarts assumés

### Trois fichiers partagés au lieu d'un

Le brief prévoyait `merlin-tokens.css` comme **seul** fichier partagé. La livraison en compte trois :

| Fichier | Contenu | Pourquoi |
|---|---|---|
| `merlin-tokens.css` | **Intact, au caractère près.** Aucune ligne modifiée. | Contrat de charte |
| `merlin-ui.css` | La couche de composants : une classe par composant React attendu en production | Dupliquer 270 lignes de CSS dans 19 fichiers rendait toute correction de style impossible à propager, et privait l'équipe de développement de l'inventaire des composants — qui est justement ce qu'elle doit reprendre |
| `merlin-data.js` | Le jeu de données et les règles de calcul | Les quatre fonctions `controles()`, `journees()`, `cible()` et `reel()` sont **la spécification exécutable** du module. Les recopier écran par écran aurait produit dix-neuf variantes divergentes — exactement ce que la maquette cherche à éviter |

Les contraintes réelles du brief sont respectées : **aucun build, aucune dépendance externe, aucun CDN**. Un écran s'ouvre par double-clic.

### Dix-neuf écrans, pas seize

Le brief annonce « seize écrans » puis en liste dix-neuf (A : 3, B : 4, C : 3, D : 4, E : 2, F : 3). La liste fait foi ; les dix-neuf sont livrés.

### Codes chantier à huit caractères

La maquette de référence affiche `AUB-51` et `CLV-12` ; le brief impose `CEDR0051` et `BELV0012`. Les **codes à huit caractères ont été retenus partout**, y compris dans les pastilles : ce sont eux qui sortent dans les deux exports (`chantier` est un champ de 8 caractères exactement, complété par des zéros). Afficher un code court à l'écran et un code long à l'export aurait introduit une traduction invisible.

### Le lot Tempo passe de cinq à sept lignes (F1)

Le brief demande que F1 montre **quatre motifs de rejet**. Le lot d'origine n'en produit que deux (matricule inconnu, code non mappé). Deux lignes ont été ajoutées, construites à partir des mêmes personnes et des mêmes codes :

- ligne 6 — chantier `CEDR0099` : **chantier inconnu** ;
- ligne 7 — `FERR-02` sur `BELV0012` : le code est mappé vers « Ferraillage », mais **cette activité n'existe pas dans le budget de BELV0012**. C'est le motif le plus subtil des quatre, et le seul qui démontre que la proposition se résout budget par budget.

### Tout est anonymisé

Les maquettes ne portent plus aucune donnée attribuable. Renommés le 07/09/2026 :

| Catégorie | Avant | Après |
|---|---|---|
| Client | le donneur d'ordre réel | **Constructa Luxembourg** (`CONSTRUCTA` dans l'export) |
| Chantiers | deux chantiers réels | **Les Cèdres 51** (`CEDR0051`), **Résidence Belvédère** (`BELV0012`) |
| Personnes | sept ouvriers, deux intérimaires, trois rôles | Renard C., Dubois M., Ferreira L., Rossi A., Nguyen T., Haddad Y., Blanc P., Novak D., Costa F., Adamec R., Perrin C., Lambert N. |
| Systèmes tiers | collecte, analytique, paie, intérim, ERP | **Tempo**, **Kostor**, **Salaris**, **Staffis**, **ERP Groupe** |
| GUID de qualification | identifiants de production réels | GUID fictifs, format canonique respecté |

Les **volumétries** (9 055 lignes, 79 matricules, 11 201 lignes, 122 triplets) sont conservées :
ce sont des statistiques anonymes, et ce sont elles qui donnent au dossier sa crédibilité.

Les documents de `docs/` — le brief et les deux spécifications — **n'ont pas été touchés** :
ce sont les pièces d'origine, et les falsifier reviendrait à perdre la trace de ce qui a
réellement été dit. Ils ne sont pas servis publiquement.

### Deux valeurs de démonstration explicitement signalées

- **Localités** — `Bertrange` pour CEDR0051, `Mamer` pour BELV0012. La colonne `localite chantier` de l'export Salaris les exige ; la maquette de référence n'en portait aucune. À remplacer par les vraies avant toute démonstration client.
- **Taux horaires** — ceux de la maquette de référence (34 à 52 €/h). Chaque écran qui les affiche **le dit à l'écran**.

### Les GUID d'activité ne sont pas inventés

Les 122 triplets `activitysheet / activity / sub-activity` de Kostor ne sont pas connus. Deux choix étaient possibles : remplir les colonnes 11 à 13 de valeurs plausibles, ou montrer l'état réel. **La seconde a été retenue** : l'export Kostor sort ses trois colonnes à `00000000-0000-0000-0000-000000000000`, un bandeau le marque incomplet, et F2 affiche seize activités non mappées.

C'est aussi le cas limite le plus instructif de D4 : **Salaris est complet alors que Kostor est bloqué**, précisément parce que Salaris ne porte aucun axe analytique.

Même logique pour :

- les qualifications **Ferrailleur** et **Cloisonneur**, sans GUID parce qu'elles n'apparaissent dans aucun pointage chantier de janvier à juin 2026 ;
- le `ref` de flux Kostor, affiché comme paramètre d'environnement à obtenir (question E1) ;
- le **NISS**, masqué à l'écran (question E8 — donnée personnelle sensible, à éviter si elle n'est pas nécessaire).

Les GUID de qualification étaient repris de `specification-exports.md` §2.5 ; ils ont été remplacés par des GUID fictifs à l'anonymisation. Le raisonnement tient toujours : ce qui n'est pas connu sort à zéro et l'export est marqué incomplet.

### E2 reconduit le planning sur le mois

La matrice ouvriers × jours a besoin de trente colonnes. Seules les journées du **samedi 12** et du **mardi 15 septembre** sont celles de la maquette de référence ; les autres jours ouvrés reconduisent le planning nominal, congé de Blanc P. compris. C'est écrit sous le tableau, à l'écran.

### Playwright n'a pas été utilisé

La vérification s'est faite avec le navigateur intégré, plus un harnais maison : `audit.html` charge les dix-neuf écrans dans un cadre à **1440 px puis à 1024 px** et mesure, pour chacun, le rendu effectif et le débordement horizontal. `verifier.sh` contrôle la syntaxe des scripts sans navigateur. Les deux sont livrés — ils resserviront.

**Résultat du dernier passage : 38 contrôles, aucun débordement, aucun écran vide.**

### B2 et C1 n'ont pas été soumis à validation avant les autres

Le brief prévoyait un point d'arrêt ; la demande était de livrer la maquette complète. B2 et C1 ont bien été **construits et vérifiés en premier**, comme le brief le recommandait, mais les dix-sept autres ont suivi sans attendre.

---

## 2. Décisions de conception non dictées par le brief

**Le rail de navigation est présent sur tous les écrans.** Le brief ne demandait qu'un `index.html`. Passer d'un écran à l'autre sans repasser par le sommaire change complètement une session de revue à trois personnes.

**Chaque écran porte le fil du flux en haut**, avec sa position marquée. C'est ce qui évite la question « on est où, là ? » toutes les deux minutes.

**Le bouton « Notes développeur » est actif par défaut** et masque ou affiche les règles à coder. Actif par défaut parce que le premier public est l'équipe de développement ; masquable en un clic pour une démonstration client.

**Les écarts entre écrans sont volontairement cohérents.** Ferreira L. est le manquant de C3, de E1 et de E2. Haddad Y. porte 6 h + 4 h — dix heures — dans C1, C2, D1, D2 et D3. Dubois M. porte deux activités dans B3, D1 et D2. Une incohérence entre deux écrans se paierait en réunion.

**Les écrans sont réellement interactifs.** Compteurs, glisser-déposer, filtres, sélecteurs d'imputation, scission, validations : tout fonctionne. L'état vit en mémoire et repart de zéro au rechargement — **aucun `localStorage`**, conformément au brief.

---

## 3. Contrôle des interdits

| Interdit | État |
|---|---|
| Dégradés | Aucun |
| Ombres portées hors du cadre téléphone | Aucune. `--shadow` n'est appliqué qu'à `.device` et au toast |
| Icônes décoratives, emoji | Aucun |
| Barres de couleur collées aux bords | Aucune |
| Majuscules pour les titres | Aucune. Les majuscules sont réservées aux étiquettes de rail et de section, en 10 px, `letter-spacing: .06em` |
| `localStorage` | Aucun |
| Texte de remplissage, noms inventés | Aucun — voir §1 pour les deux valeurs de démonstration signalées |
| Couleur absente de `merlin-tokens.css` | Aucune. Les nuances dérivées passent par `color-mix()` sur un jeton, jamais par une valeur littérale |

---

## 4. Ce qui reste ouvert

Ces points sont visibles **dans** les écrans, pas seulement dans cette note.

| Réf. | Question | Écran concerné |
|---|---|---|
| A8 | Les alertes bloquent-elles, ou se contentent-elles d'alerter ? | F3 — le réglage existe et la simulation en montre l'effet |
| A11 | Le conducteur est-il notifié quand le bureau modifie ses chiffres ? | C2 et D2 — la modification est tracée, la notification ne l'est pas |
| E1 | D'où vient le GUID `ref` de Kostor ? | D4, F2 |
| E2 | Le triplet d'activité est-il choisi, ou déduit d'une règle ? | F2 — la table est vide et le dit |
| E3 | Merlin produit-il les lignes d'absence, ou la paie les génère-t-elle ? | D4 — elles sont produites ici, à confirmer |
| E7 | Le libellé de chantier doit-il reproduire la concaténation actuelle ? | F2 |
| E8 | Le NISS transite-t-il par Merlin ? | D4 — masqué en attendant |
| — | Le motif « Formation » n'a pas d'équivalent parmi les 14 types Salaris | F2, onglet Motifs d'absence |
