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>
This commit is contained in:
pr-daaif
2026-07-15 21:55:04 +01:00
parent ddc9dc52b5
commit 8adb561b63
62 changed files with 8509 additions and 2 deletions

6
infra/.env.example Normal file
View File

@@ -0,0 +1,6 @@
# Infrastructure locale (valeurs de développement — jamais utilisées en production)
POSTGRES_USER=siop
POSTGRES_PASSWORD=siop
POSTGRES_DB=siop
MINIO_ROOT_USER=siop
MINIO_ROOT_PASSWORD=siop-minio

60
infra/docker-compose.yml Normal file
View File

@@ -0,0 +1,60 @@
# Infrastructure locale SIOP V2 : PostgreSQL (pgvector+PostGIS), Redis, MinIO.
# Usage : pnpm infra:up / infra:down / infra:reset
#
# CONVENTION (demande du référent, leçon v1) : tous les services et conteneurs
# sont préfixés « siop2- » — sur le réseau partagé de Dokploy, un service nommé
# « postgres » ou « api » entre en collision avec les autres projets.
name: siop2-infra
services:
siop2-postgres:
container_name: siop2-postgres
build: ./postgres
image: siop2/postgres:18-pgvector-postgis
environment:
POSTGRES_USER: ${POSTGRES_USER:-siop}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-siop}
POSTGRES_DB: ${POSTGRES_DB:-siop}
ports:
- "5432:5432"
volumes:
- pg-data:/var/lib/postgresql
- ./postgres/init.sql:/docker-entrypoint-initdb.d/10-extensions.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U siop -d siop"]
interval: 5s
timeout: 3s
retries: 10
siop2-redis:
container_name: siop2-redis
image: redis:7.4.9-alpine
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
siop2-minio:
container_name: siop2-minio
image: minio/minio:RELEASE.2025-09-07T16-13-09Z
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-siop}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-siop-minio}
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio-data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 5s
timeout: 3s
retries: 10
volumes:
pg-data:
minio-data:

View File

@@ -0,0 +1,6 @@
# PostgreSQL 18 + pgvector (RAG, R5) + PostGIS (carte, R1) — une seule base pour tout.
FROM pgvector/pgvector:0.8.4-pg18-trixie
RUN apt-get update \
&& apt-get install -y --no-install-recommends postgresql-18-postgis-3 \
&& rm -rf /var/lib/apt/lists/*

3
infra/postgres/init.sql Normal file
View File

@@ -0,0 +1,3 @@
-- Extensions activées à la création de la base (idempotent).
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS postgis;