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

View File

@@ -0,0 +1,27 @@
import { Body, Controller, Get, HttpCode, Post } from '@nestjs/common';
import { DemoLoginRequestSchema, type DemoLoginRequest } from '@siop/shared';
import { ZodValidationPipe } from '../../common/zod-validation.pipe';
import { AuthService } from '../auth.service';
import { Public } from '../public.decorator';
/** ADR-002 — ces routes n'existent que si DemoAuthModule est enregistré
* (DEMO_MODE=true) ; sinon : 404, vérifié par test e2e. */
@Controller('auth')
export class DemoAuthController {
constructor(private readonly authService: AuthService) {}
@Public()
@Get('demo-accounts')
listDemoAccounts() {
return this.authService.listDemoAccounts();
}
@Public()
@Post('demo-login')
@HttpCode(200)
demoLogin(
@Body(new ZodValidationPipe(DemoLoginRequestSchema)) body: DemoLoginRequest,
) {
return this.authService.demoLogin(body.userId);
}
}

View File

@@ -0,0 +1,27 @@
import { Logger, Module, OnModuleInit } from '@nestjs/common';
import { assertDemoModeAllowed } from '../../config/env';
import { AuthModule } from '../auth.module';
import { DemoAuthController } from './demo-auth.controller';
/**
* ADR-002 : module enregistré UNIQUEMENT quand DEMO_MODE=true
* (voir AppModule.forRoot). Double verrou : refuse de démarrer en production
* sans DEMO_MODE_I_KNOW=true.
*/
@Module({
imports: [AuthModule],
controllers: [DemoAuthController],
})
export class DemoAuthModule implements OnModuleInit {
private readonly logger = new Logger(DemoAuthModule.name);
constructor() {
assertDemoModeAllowed();
}
onModuleInit() {
this.logger.warn(
'DEMO_MODE actif — /auth/demo-accounts et /auth/demo-login sont exposées.',
);
}
}