pr-daaif
dfdf8f7c18
feat(r3.1): socle backend gestion — stock dérivé, BC, coûts figés sur OT
...
- migration r3_gestion (7 tables) : Partner, Part (SANS colonne de
quantité), StockMovement (signé, tracé, PU figé), PurchaseOrder/Line,
LaborTime (taux figé), Document (R3.2) ; User.hourlyRate administrable
- API (66 opérations) : tiers ; pièces (stock = Σ mouvements, alerte sous
seuil) ; entrée/ajustement (motif requis, stock jamais négatif, en
transaction) ; BC Brouillon→Envoyé→Reçu (la réception crée les RECEIPT
et met à jour lastUnitPrice) ; consommation sur OT (stock suffisant,
PRIX FIGÉ) ; main-d'œuvre (TAUX FIGÉ, refus si taux non défini) ;
WorkOrderDetail.costs ; coûts verrouillés après clôture (409)
- seed : tiers/pièces/BC/taux de la maquette — OT-0341 = 505 MAD (testé)
- durcissement : références OT/DEM/BC/P par SÉQUENCES Postgres (nextval)
— fin des courses « max+1 » (500 sporadiques sous charge parallèle) ;
3 runs Jest complets consécutifs verts
- 55 tests (92 % stmts / 74,9 % branches) dont la recette officielle :
consommer sous seuil → BC → réception → réappro, prix/taux figés prouvés
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-16 20:42:03 +01:00
pr-daaif
f7702e4252
feat(r2.1): socle backend exploitation — machine à états, bilan codé, demandes 1-1
...
- migration r2_exploitation (10 tables) : WorkOrder (référence séquentielle,
horodatages), WorkOrderEvent, Request (1-1, motif de rejet), ReferenceValue,
InterventionReport (6 FK), TaskTemplate/ChecklistItem, Meter/MeterReading
- contrat : 15 opérations (41 total) ; la table des transitions et les champs
requis du bilan vivent dans @siop/shared ; la fiche OT expose
allowedTransitions + closureBlockers (messages métier)
- API : machine à états stricte ; garde de clôture (bilan 3 champs requis +
checklist sans tâche en attente) ; approbation → OT lié 1-1 (409 si déjà
traitée) ; rejet à motif obligatoire ; scoping « voir autre » sur listes et
accès directs (404 sans fuite) ; validation des valeurs de bilan par champ ;
« personne bloquée » triée en tête côté API
- seed : 31 valeurs de référentiels, 8 gabarits (parachute réglementaire),
OT/demandes/compteurs de la maquette — idempotent
- 45 tests verts (95 % stmts / 79 % branches) dont la recette officielle
rejouée de bout en bout ; smoke test sur build de prod
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-16 13:56:07 +01:00
pr-daaif
266ffaaf1b
feat(r1.1): socle backend du référentiel — modèle, contrat, API, seed, tests
...
- migration r1_referentiel : Category (EQUIPMENT/COMPONENT_TYPE), Location
(site → zone, lat/lng + colonne PostGIS générée geography(Point,4326)
+ index GIST), Asset (statut d'équipement), AssetComponent (organe sans
emplacement PAR CONSTRUCTION), Team, invitation sur User ; migration
autosuffisante (CREATE EXTENSION IF NOT EXISTS postgis)
- contrat : 21 nouvelles opérations (26 total), générateur OpenAPI étendu
aux paramètres de chemin ; spec + client web régénérés dans ce commit
- API : modules categories/locations/assets/teams + gestion des personnes
(liste, rôles, invitation lien 7 j à usage unique, activation publique
qui connecte directement, mise à jour rôle/équipes) — tout sous
@RequirePermission ; invariants en service (profondeur 2, kinds,
catégorie jamais supprimée)
- seed : parc de la maquette validée (5 sites + 8 zones, 8 appareils,
organes A1/B2, 9 catégories, 2 équipes) — idempotent
- 36 tests verts (couverture 96 % stmts / 85 % branches) : recette
site→zone→appareil→organes, matrice vivante, invitation→activation ;
smoke test sur build de prod
- CI : postgres → postgis/postgis:18-3.6 (la migration R1 l'exige)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-16 12:27:48 +01:00
pr-daaif
4f3af5af4f
feat(r0.11): apps/web — connexion + sélecteur démo, coquille, /design, client typé
...
- React 19 + Vite + Tailwind v4 : tokens.css copié tel quel (source de
vérité), classes composants extraites de la maquette validée, Manrope
auto-hébergée, primitives shadcn-style possédées (Button cva, menu Radix)
- connexion fidèle à la maquette ; liste démo affichée seulement si
/auth/demo-accounts répond (404 ⇒ rien — ADR-002, l'API seule source)
- coquille : sidebar 4 groupes avec rail safran actif (écrans futurs marqués
R1-R3), topbar recherche/thème/chip DÉMO + sélecteur de rôle (bascule 101 ms,
critère < 3 s) ; page /design = référence vivante des revues pixel
- règle d'or : schema.d.ts généré depuis docs/openapi.json et committé
(openapi-typescript + openapi-fetch)
- tokens.css : tokens --nav-* ajoutés (valeurs de la maquette validée) ;
seed réaligné sur les personas de la maquette
- vérifié en navigateur réel (Playwright + Chrome headless) : 7 captures,
parcours démo complet, bi-thème, zéro erreur console ; typecheck + vitest + build OK
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-15 22:09:40 +01:00
pr-daaif
8adb561b63
feat(r0.10): apps/api — auth fermée par défaut, matrice en base, démo-login ADR-002, seed
...
- packages/shared : rôles/catégories, schémas Zod, contrat d'API ;
pnpm contract → docs/openapi.json committée (règle d'or ADR-001)
- apps/api : NestJS 11 + Prisma 6, migration r0_identity (Role/Permission/User) ;
guard JWT global + @Public() ; PermissionsGuard (@RequirePermission,
matrice relue en base, cache 60 s) ; FileStorage (seul import MinIO) ; /health
- démo-login ADR-002 : module conditionnel DEMO_MODE (404 sinon, testé e2e),
double verrou production, refus des comptes isDemo=false
- seed idempotent : 7 rôles, matrice complète (70 lignes), 7 comptes démo
- 19 tests Jest (unit + e2e) ; smoke test sur build de prod
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-15 21:55:04 +01:00