Feature #1263
openFeature #1262: Onboarding premier utilisateur : wizard d'amorçage + profilage progressif + visite guidée
Backend — Persistance OnboardingState + endpoints GET/PATCH /onboarding/:workspaceId + couture AppClient
0%
Description
Fondation de l'epic (bloque toutes les autres sous-tâches). Persister l'état d'onboarding côté serveur, par utilisateur ET par espace de travail (multi-appareils), et l'exposer au frontend via la couture AppClient.
Contrat de données (§8) :
`OnboardingState { userId; workspaceId; completed; skipped; currentStep 1..3; role?; firstName?; lastName?; structureName?; structureType?; eventsPerYear? lt10|10_30|30_80|gt80; invitesSent?[{email, role admin|member|volunteer}]; tour{completed,lastStep}; checklist Record<string,boolean> (7 items §3); progressiveDone Record<string,boolean> (§4); updatedAt }`.
Enums : `OnboardingRole = direction|booking|admin_compta|regie_technique|communication|restauration|coordination_benevoles|autre` ; `StructureType = salle_smac|festival|theatre|centre_culturel|cafe_concert|association|autre`.
Contraintes Scobby :
- Ne PAS éditer `server/prisma/schema.prisma` à la main : ajouter/ajuster l'entité dans `base44/entities/*.jsonc` (avec bloc `rls`) puis `npm run schema:generate`.
- Architecture hexagonale : use case `application/`, port + adapter repo `infrastructure/persistence/`, controller `interface/http/`. `server/test/architecture.test.ts` ne doit pas casser.
- `GET /onboarding/:workspaceId` (retourne l'état, crée un état vide `completed:false, currentStep:1` si absent) et `PATCH /onboarding/:workspaceId` (merge partiel : `completed, skipped, currentStep, role`, champs structure, `invitesSent`, `checklist`, `tour`, `progressiveDone` ; met à jour `updatedAt`).
- Exposer via la couture (`src/api/client/types.ts` + `base44-adapter.ts` / `local-adapter.ts` / `in-memory-adapter.ts`), sans élargir la surface hors AppClient.
- Idempotence : ne jamais ré-initialiser un état `completed === true` (sauf nouvel espace).
- Note PO : `role` doit faire partie du contrat #1 pour que la checklist (#3) et la visite (#4) n'aient pas de dépendance runtime cachée vers le wizard (#2). Prévoir aussi un emplacement/stub pour un wrapper de télémétrie léger landé tôt.
Dépend de : —
## Critères d'acceptation
- L'entité OnboardingState est définie dans `base44/entities/*.jsonc` (avec `rls`) et `schema.prisma` est régénéré via `npm run schema:generate` (pas d'édition manuelle).
- `GET /onboarding/:workspaceId` renvoie l'état de l'espace pour l'utilisateur courant ; si absent, état initial `completed:false, currentStep:1`, checklist/tour/progressiveDone vides.
- `PATCH /onboarding/:workspaceId` applique un merge partiel (incl. completed, skipped, currentStep, role, champs structure, invitesSent, checklist, tour, progressiveDone) et met à jour `updatedAt`.
- État isolé par (userId, workspaceId) ; deux espaces indépendants ; aucun re-déclenchement d'un onboarding `completed:true`.
- Joignable depuis le frontend via la couture AppClient (interface + 3 adaptateurs, incl. in-memory) sans élargir la surface hors AppClient.
- Tests e2e backend (GET/PATCH, isolation par espace, idempotence) verts ; `test:unit` + `typecheck` verts ; `architecture.test.ts` passe.
- Les enums OnboardingRole et StructureType respectent exactement les valeurs du §8.
RA Updated by Redmine Admin about 1 month ago
- Status changed from Submitted to Preprod