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>
This commit is contained in:
pr-daaif
2026-07-16 12:27:48 +01:00
parent 6d9aafdab4
commit 266ffaaf1b
36 changed files with 6016 additions and 13 deletions

View File

@@ -40,5 +40,7 @@ pnpm + Turborepo. `apps/api` : NestJS, Prisma, PostgreSQL (pgvector + PostGIS),
- **R0.12 — tests + CI** (5 jobs verts) : `lint` (ESLint 10 flat config racine, règle ADR-001 anti-import MinIO codée et vérifiée), `ci-contract` (régénération spec+client, diff bloquant), `api` (PostgreSQL 18 + Redis, migrate deploy, Jest couverture 70 % bloquante mesurée 97,5 %), `web` (typecheck + vitest + build), `e2e` (Playwright : parcours démo, bascule < 3 s chronométrée, déconnexion). Badge au README.
- **R0.13 — Dockerfiles + runbook Dokploy** : image api (multi-stage pnpm deploy, `prisma migrate deploy` au boot, seed optionnel `SEED_ON_START`, non-root, healthcheck ; `binaryTargets` explicites) ; image web (nginx, proxy `/api` résolu à la requête, fallback SPA, cache assets) ; `infra/docker-compose.dokploy.yml` (5 services `siop2-`, seul le web sur `dokploy-network`) ; runbook `docs/06-production/runbook-dokploy.md`. **Répétition locale complète validée** (migrate+seed au boot, parcours via nginx conteneurisé, double verrou ADR-002 observé). Le déploiement réel attend les accès au serveur du partenaire.
- **R0 CLOSE** (tag `release/r0`) en production : `https://siop2.apps.enset.top` (Dokploy ENSET, profil démo, vérifiée en ligne). Restes non bloquants : secret `DOKPLOY_WEBHOOK_URL` (CD), sauvegardes PostgreSQL Dokploy. Production client SPELEV : attend les accès au serveur du partenaire.
- 🔄 **R1 Référentiel — ouverte, design d'abord** : `docs/02-design/maquettes/maquette-r1.html` (7 écrans : sites+carte, fiche site, ascenseurs, création, étiquette QR, personnes & équipes, catégories) ** en attente de validation du référent avant tout code R1**. Ensuite : modèle de données R1 (Location PostGIS, Asset+organes, Category, Team, invitation/activation) API web tests/e2e déploiement.
- **R1 — maquettes validées** (16/07) : `maquette-r1.html`, 7 écrans + 4 décisions (statuts d'équipement statuts OT ; organe sans emplacement par construction ; invitation par lien 7 j ; catégories jamais supprimées si utilisées).
- **R1.1 — socle backend** : migration `r1_referentiel` (Category, Location sitezone + PostGIS générée, Asset, AssetComponent, Team, invitation User), 21 nouvelles opérations au contrat (26 total), 4 modules API + invitations/activation sous `@RequirePermission`, seed parc maquette (5 sites, 8 appareils, organes, 2 équipes), 36 tests (96 %/85 %), CI sur `postgis/postgis:18-3.6`.
- 🔄 **R1.2 — reprise ici** : `apps/web` écrans Sites (+ carte Leaflet/OSM à intégrer), Fiche site, Ascenseurs, Nouvel ascenseur, Étiquette QR imprimable, Personnes & équipes (invitation + lien à copier), Catégories fidèles à maquette-r1.html ; puis e2e Playwright du parcours de recette R1 et déploiement.
- Détail quotidien : `docs/journal/journal.md`. Dépôt : `siop-spelev/siop2` (privé), jalons R0R5.