Contexte
Issue de suivi globale : #1889 — [NestJS] Modularisation de server
Ce ticket couvre spécifiquement le portage de la route POST /api/v1/auth depuis apps/server (Fastify) vers apps/server-nestjs. Cette route est la seule partie du module user (Vague 2 — Sprint 5) qui nécessite une synchronisation de session Keycloak.
Périmètre
Portage de la route :
POST /api/v1/auth — Authentification / synchronisation session (OIDC callback, signin ou signup)
Comportement actuel (server Fastify)
Le handler actuel (apps/server/src/resources/user/router.ts) :
- Récupère l'utilisateur depuis la session Keycloak (
req.session.user)
- Appelle
logViaSession(user) qui :
- Recherche ou crée l'utilisateur en base (Prisma
user)
- Calcule les rôles admin via groupes OIDC Keycloak + rôles persistés en BDD (table
adminRole)
- Calcule le bitmask de permissions admin (
adminPerms)
- Met à jour
lastLogin
- Retourne
{ user, adminPerms } avec un JWT signé
- Si pas de session → 401
Méthode cible (server-nestjs)
Module NestJS
Créer le module UserModule dans apps/server-nestjs/src/modules/user/ :
user/
├── user.module.ts
├── user.controller.ts
├── user.service.ts
├── user-datastore.service.ts
└── *.spec.ts
UserController / UserService
La route POST /api/v1/auth doit être gérée par un UserController qui :
- Utilise le décorateur
@Session() (session Fastify via fastify-session) pour récupérer l'utilisateur Keycloak
- Délègue la synchronisation à
UserService.syncSession(user: UserTrial)
UserService réplique la logique de logViaSession :
UserDatastoreService : findUnique/upsert sur user, findMany sur adminRole
- Calcul du bitmask via
PermissionService (existant dans infrastructure/permission)
- Émet l'événement
user.synchronisé via @nestjs/event-emitter
- Retourne
UserSchema (contrat partagé via @cpn-console/shared)
- Si pas de session →
UnauthorizedException (401)
Contrat API
Le contrat est déjà défini dans packages/shared/src/contracts/user.ts :
auth: {
method: 'POST',
path: ${apiPrefix}/auth`,
summary: 'Login',
description: 'OIDC callback to signin or signup',
responses: { 200: UserSchema, 307: null, 500: ErrorSchema },
}
Utiliser les décorateurs NestJS natifs (@Post(), @Session()) — ne pas réutiliser ts-rest côté serveur.
Dépendances
- AuthService (Couche 0,
infrastructure/auth/) : existe déjà, gère l'auth par token (x-dso-token et bearer JWT). Cette route utilise un troisième chemin (session Keycloak via cookie), donc une extension de AuthService ou un guard dédié est nécessaire pour la session.
- UserDatastoreService : n'existe pas encore. Doit être créé dans le module.
- Événement
adminRole.upsert : EventEmitterModule (Couche 0d) doit être fonctionnel (pré-requis : ticket à créer/assigner si non fait).
- Nginx strangler : après validation, mettre à jour
nginx-strangler/conf.d/routing.conf pour router POST /api/v1/auth vers server-nestjs.
Critères de fini
Estimation
~2 jours (complexité moyenne : logique métier dense, 3 chemins d'auth à harmoniser, événement Ember).
Références
- Code legacy :
apps/server/src/resources/user/router.ts (handler auth)
- Business logic :
apps/server/src/resources/user/business.ts (logViaSession)
- Contrat :
packages/shared/src/contracts/user.ts
- Auth existante :
apps/server-nestjs/src/modules/infrastructure/auth/
- Documentation modularisation :
apps/server-nestjs/documentation/Modularisation-de-console-server/
Contexte
Issue de suivi globale : #1889 — [NestJS] Modularisation de server
Ce ticket couvre spécifiquement le portage de la route
POST /api/v1/authdepuisapps/server(Fastify) versapps/server-nestjs. Cette route est la seule partie du moduleuser(Vague 2 — Sprint 5) qui nécessite une synchronisation de session Keycloak.Périmètre
Portage de la route :
POST /api/v1/auth— Authentification / synchronisation session (OIDC callback, signin ou signup)Comportement actuel (server Fastify)
Le handler actuel (
apps/server/src/resources/user/router.ts) :req.session.user)logViaSession(user)qui :user)adminRole)adminPerms)lastLogin{ user, adminPerms }avec un JWT signéMéthode cible (server-nestjs)
Module NestJS
Créer le module
UserModuledansapps/server-nestjs/src/modules/user/:UserController / UserService
La route
POST /api/v1/authdoit être gérée par unUserControllerqui :@Session()(session Fastify viafastify-session) pour récupérer l'utilisateur KeycloakUserService.syncSession(user: UserTrial)UserServiceréplique la logique delogViaSession:UserDatastoreService: findUnique/upsert suruser, findMany suradminRolePermissionService(existant dansinfrastructure/permission)user.synchronisévia@nestjs/event-emitterUserSchema(contrat partagé via@cpn-console/shared)UnauthorizedException(401)Contrat API
Le contrat est déjà défini dans
packages/shared/src/contracts/user.ts:Utiliser les décorateurs NestJS natifs (
@Post(),@Session()) — ne pas réutiliser ts-rest côté serveur.Dépendances
infrastructure/auth/) : existe déjà, gère l'auth par token (x-dso-token et bearer JWT). Cette route utilise un troisième chemin (session Keycloak via cookie), donc une extension deAuthServiceou un guard dédié est nécessaire pour la session.adminRole.upsert:EventEmitterModule(Couche 0d) doit être fonctionnel (pré-requis : ticket à créer/assigner si non fait).nginx-strangler/conf.d/routing.confpour routerPOST /api/v1/authversserver-nestjs.Critères de fini
UserModulecréé dansapps/server-nestjs/src/modules/user/POST /api/v1/authimplémenté avec synchronisation session KeycloakUserDatastoreServiceavec queries Prisma (pas de queries-index partagées)@nestjs/event-emitterpouradminRole.upsertMigré (Code-Ready))MODULARISATION-STATUT.mdEstimation
~2 jours (complexité moyenne : logique métier dense, 3 chemins d'auth à harmoniser, événement Ember).
Références
apps/server/src/resources/user/router.ts(handlerauth)apps/server/src/resources/user/business.ts(logViaSession)packages/shared/src/contracts/user.tsapps/server-nestjs/src/modules/infrastructure/auth/apps/server-nestjs/documentation/Modularisation-de-console-server/