pr-daaif
2ffdd13cf4
feat(r3.2): bibliothèque de documents (FileStorage réel) + analytics
...
- FileStorage : putObject/getObjectStream/removeObject, bucket créé au
démarrage — MinIO confiné à son implémentation (règle ESLint intacte)
- documents : upload multipart (PDF/JPG/PNG, 20 Mo max, rattachement
appareil OU OT requis, permission d'édition sur la CIBLE), liste
filtrable, téléchargement STREAMÉ par l'API (MinIO jamais exposé),
suppression ; e2e : octets téléchargés identiques aux octets envoyés
- analytics : GET /analytics/summary dérivé du réel — coûts/mois
(mouvements + main-d'œuvre figés), pannes par organe (bilans codés),
taux de préventif, durée moyenne de résolution, top équipements
- générateur OpenAPI : query params, multipart, réponse binaire (71 ops)
- CI : service MinIO (bitnami) sur les jobs api et e2e
- test de régression du tri « Interventions récentes » rendu déterministe
(positions absolues instables sous 12 suites parallèles) ; 58 tests,
6 runs complets consécutifs verts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-16 21:24:04 +01:00
pr-daaif
50254daea4
feat(r2.4): portail public QR — signalement sans compte, suivi par jeton
...
- 3 routes publiques /portal (les seules @Public métier), throttlées
(@nestjs/throttler : 10 signalements/min, 60 lectures/min) : résolution
du QR, signalement (retourne un jeton de suivi opaque), suivi par
référence + jeton — pas de jeton, pas de lecture, jamais de liste
- migration r2_portail : Request.publicToken (unique)
- page /q/{réf} fidèle à l'écran 6 validé R0 (mobile d'abord) : équipement
prérempli « détecté par le QR », interrupteur personne bloquée,
suivi sans jargon Reçu → Intervention → Résolu (dérivé de l'OT lié),
rejet affiché « Sans suite : {motif} », photo annoncée (upload R3) ;
signalements gardés sur le téléphone (localStorage, 10 max)
- e2e : LA boucle produit — gardien sans compte → traitement → ✓ Résolu ;
11 tests Playwright verts, 50 tests API, 52 opérations au contrat
- générateur OpenAPI : paramètres non-« id » plus typés uuid
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-16 17:33:10 +01:00
pr-daaif
ce24d9c32b
build(r0.13): Dockerfiles api/web + compose Dokploy + runbook — R0 prêt à déployer
...
- image api : multi-stage (pnpm deploy --legacy --prod), client Prisma
régénéré dans l'arborescence déployée, binaryTargets explicites
(debian/arm64 openssl-3), entrypoint migrate deploy → seed optionnel
(SEED_ON_START, compilé dist/seed) → API ; non-root, healthcheck /health
- image web : nginx alpine, statique Vite, proxy /api résolu À LA REQUÊTE
(resolver Docker + variable — nginx démarre sans l'API), fallback SPA,
cache immuable /assets, healthcheck IPv4 (127.0.0.1)
- infra/docker-compose.dokploy.yml : 5 services préfixés siop2-, secrets
exigés, seul siop2-web rejoint dokploy-network (API jamais exposée)
- runbook docs/06-production/runbook-dokploy.md : topologie, profils
d'environnement, checklist première prod, rollback, répétition locale
- répétition locale validée de bout en bout : migrate+seed au boot,
parcours demo-login → /users/me à travers nginx conteneurisé, conteneurs
healthy ; le double verrou ADR-002 (DEMO_MODE sans I_KNOW en production)
a refusé de démarrer — observé en situation réelle
- prisma passe en dépendance de production (migrations au boot)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-15 22:58:42 +01:00
pr-daaif
36de93bb7e
test(r0.12): ESLint monorepo + parcours démo Playwright — R0.12 clos
...
- ESLint 10 flat config racine (typescript-eslint, react-hooks) ; règle
ADR-001 codée : no-restricted-imports interdit « minio » partout sauf
minio-storage.service.ts (violation vérifiée) ; jobs lint par paquet
- Playwright apps/web/e2e : redirection sans jeton, connexion démo 1 clic,
coquille (rail actif, chip DÉMO), bascule de rôle chronométrée < 3 s
(ADR-002), /design, déconnexion avec purge ; webServer api dist + vite,
seed idempotent en globalSetup, PW_CHANNEL=chrome en local
- CI : jobs lint + e2e (services PostgreSQL/Redis, artefact
playwright-report sur échec) ; vitest restreint à src/
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-15 22:36:17 +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