Compare commits

..

2 Commits

Author SHA1 Message Date
Julien Froidefond
9ff745489f Enhance database seeding and update seed questions. Add database seeding command to docker-start.sh and introduce new questions related to support and scaling in seed.ts, improving the data initialization process.
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m17s
2026-02-20 16:44:35 +01:00
Julien Froidefond
dee59991fc docs: réécriture README complet en français
README entièrement reécrit en français pour les développeurs Peaksys :
architecture server-first, auth bcrypt/rôles, Docker, variables d'env,
pages & fonctionnalités, structure des fichiers à jour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 16:25:27 +01:00
3 changed files with 194 additions and 100 deletions

267
README.md
View File

@@ -1,144 +1,215 @@
# IA Gen Maturity Evaluator
Production-ready web app for evaluating IA/GenAI maturity of candidates. Built by Peaksys for Peaksys.
Application web de maturité IA/GenAI pour évaluer les candidats lors d'entretiens techniques. Développée par Peaksys pour Peaksys.
## Tech Stack
## Stack technique
- **Next.js 16** (App Router), **React 19**, **TypeScript**, **TailwindCSS**
- **Prisma** + **SQLite** (local) — switch to Postgres/Supabase for production
- **Recharts** (radar chart), **jsPDF** (PDF export)
- **Next.js 15** (App Router), **React 19**, **TypeScript**, **TailwindCSS**
- **NextAuth v5** — authentification JWT, bcrypt, rôles `admin` / `evaluator`
- **Prisma** + **SQLite** (dev) — basculer sur Postgres/Supabase en production
- **Recharts** — radar chart des scores
- **jsPDF** — export PDF
- **Vitest** — tests unitaires | **Playwright** — tests E2E
## Setup
## Prérequis
- Node.js ≥ 20
- pnpm (`npm install -g pnpm`)
## Installation & démarrage local
```bash
pnpm install
cp .env.example .env
cp .env.example .env # puis remplir AUTH_SECRET
pnpm db:generate
pnpm db:push # ou pnpm db:migrate pour une DB vide
pnpm db:seed
```
**Note** : Si la DB existe déjà (créée avec `db push`), pour basculer sur les migrations :
`pnpm prisma migrate resolve --applied 20250220000000_init`
## Run
```bash
pnpm dev
```
Open [http://localhost:3000](http://localhost:3000).
Ouvrir [http://localhost:3000](http://localhost:3000).
## Seed Data
- **3 candidates** with sample evaluations (Alice Chen, Bob Martin, Carol White)
- **2 templates**: Full 15-dimensions, Short 8-dimensions
- **Admin user**: `admin@peaksys.local` (mock auth)
## API Routes (restantes)
Les mutations (create, update, delete, share, etc.) sont gérées par **Server Actions**. Routes API restantes :
| Route | Method | Description |
|-------|--------|-------------|
| `/api/export/csv?id=` | GET | Export evaluation as CSV |
| `/api/export/pdf?id=` | GET | Export evaluation as PDF |
| `/api/auth/*` | — | NextAuth |
| `/api/auth/signup` | POST | Inscription |
## Export cURL Examples
**Note :** Si la DB existe déjà (créée avec `db push`), pour basculer sur les migrations :
```bash
# CSV export (replace EVAL_ID with actual evaluation id)
curl -o evaluation.csv "http://localhost:3000/api/export/csv?id=EVAL_ID"
# PDF export
curl -o evaluation.pdf "http://localhost:3000/api/export/pdf?id=EVAL_ID"
pnpm prisma migrate resolve --applied 20250220000000_init
```
With auth header (when real auth is added):
## Variables d'environnement
| Variable | Obligatoire | Description |
|----------|-------------|-------------|
| `DATABASE_URL` | Oui | `file:./dev.db` en local, URL Postgres en prod |
| `AUTH_SECRET` | Oui | Secret JWT NextAuth (générer avec `openssl rand -base64 32`) |
| `NEXTAUTH_URL` | Prod | URL publique de l'app (ex. `https://eval.peaksys.io`) |
## Docker
Trois configurations disponibles :
### Développement (hot-reload)
```bash
curl -H "Authorization: Bearer YOUR_TOKEN" -o evaluation.csv "http://localhost:3000/api/export/csv?id=EVAL_ID"
docker compose -f docker-compose.dev.yml up
```
## AI Assistant Stub
### Production — SQLite (simple, port 3044)
The AI assistant is a **client-side stub** that returns deterministic follow-up suggestions based on:
- Dimension name
- Candidate answer length
- Current score (low scores trigger probing questions)
```bash
AUTH_SECRET=$(openssl rand -base64 32) \
DB_VOLUME_PATH=/chemin/vers/data \
docker compose up -d
```
**To plug a real LLM:**
### Production — Postgres
1. Create or update `/api/ai/suggest-followups` to call OpenAI/Anthropic/etc.
2. Pass `{ dimensionName, candidateAnswer, currentScore }` in the request body.
3. Use a prompt like: *"Given this dimension and candidate answer, suggest 23 probing interview questions."*
4. Return `{ suggestions: string[] }`.
```bash
docker compose -f docker-compose.postgres.yml up -d
```
The client already calls this API when the user clicks "Get AI follow-up suggestions" in the dimension card.
> Le `Dockerfile` inclut le client Prisma compilé pour Linux (`debian-openssl-3.0.x`).
> La base est migrée automatiquement au démarrage via `docker-start.sh`.
## Architecture
### Flux de données (server-first)
1. **Server Page**`src/lib/server-data.ts` (appelle `auth()` + Prisma)
2. La page passe les données sérialisées aux **Client Components** (`src/components/`)
3. Les composants clients appellent les **Server Actions** (`src/actions/`) pour les mutations
4. Les server actions appellent `revalidatePath()` pour invalider le cache
### Authentification & rôles
- `src/auth.ts` — NextAuth v5, Credentials provider (email + bcrypt), stratégie JWT
- Deux rôles : `evaluator` (défaut) et `admin`
- Inscription via `/auth/signup` (`POST /api/auth/signup`)
- `src/middleware.ts` — protège toutes les routes ; redirige les non-admins hors des routes admin
### Contrôle d'accès aux évaluations
`src/lib/evaluation-access.ts``canAccessEvaluation()` est la source de vérité unique :
- Utilisateur **admin** → accès total
- Utilisateur **evaluator** propriétaire → accès total
- Évaluation **partagée** (`EvaluationShare`) → accès lecture/écriture
- Évaluation **publique** (`isPublic = true`) → accès lecture seule
### Important : staleness du JWT
`session.user.name` est gelé au moment du login. Pour afficher le nom à jour, interroger Prisma via `session.user.id` — ne pas se fier à la session.
## Pages & fonctionnalités
| Route | Accès | Description |
|-------|-------|-------------|
| `/` | Tous | Redirect vers `/dashboard` |
| `/dashboard` | Auth | Liste des évaluations, groupement par équipe, vue carte ou tableau |
| `/evaluations/new` | Auth | Créer une évaluation (candidat, rôle, équipe, template) |
| `/evaluations/[id]` | Voir accès | Guide d'entretien, scores 15, justifications, radar chart, export |
| `/admin` | Admin | Gestion des templates et des utilisateurs |
| `/settings` | Auth | Modifier son nom et son mot de passe |
| `/auth/login` | Public | Connexion |
| `/auth/signup` | Public | Inscription |
### Fonctionnalités clés
- **Scoring** : note 15, justification, exemples observés, niveau de confiance
- **Questions de sondage** : affichées automatiquement quand score ≤ 2
- **Assistant IA (stub)** : suggestions de questions de relance (`/api/ai/suggest-followups`)
- **Export** : CSV (`/api/export/csv?id=`) et PDF (`/api/export/pdf?id=`)
- **Radar chart** : visualisation des scores par dimension
- **Partage** : partager une évaluation avec d'autres utilisateurs (`EvaluationShare`)
- **Visibilité publique** : `isPublic` rend une évaluation lisible sans authentification
- **Audit log** : toute modification post-soumission est tracée
- **Warning** : alerte si tous les scores = 5 sans justification
## Commandes utiles
```bash
pnpm dev # Serveur de développement
pnpm build # Build production
pnpm lint # ESLint
pnpm typecheck # tsc --noEmit
pnpm db:generate # Régénérer le client Prisma après modif du schéma
pnpm db:push # Synchroniser le schéma (dev, sans fichiers de migration)
pnpm db:migrate # Appliquer les migrations (production)
pnpm db:seed # Injecter les données de seed
pnpm db:studio # Ouvrir Prisma Studio
```
## Tests
```bash
# Unit tests (Vitest)
# Tests unitaires (Vitest)
pnpm test
# E2E tests (Playwright) — requires dev server
# Tests E2E (Playwright) — nécessite le serveur dev lancé
pnpm exec playwright install # une seule fois
pnpm test:e2e
```
Run `pnpm exec playwright install` once to install browsers for E2E.
## Déploiement (production)
## Deploy
1. Configurer `DATABASE_URL` vers Postgres (Supabase, Neon, etc.)
2. Générer `AUTH_SECRET` : `openssl rand -base64 32`
3. Appliquer les migrations : `pnpm db:migrate`
4. Seeder si besoin : `pnpm db:seed`
5. Build : `pnpm build && pnpm start`
6. Ou déployer sur Vercel (variables d'env à configurer, Vercel Postgres ou DB externe)
1. Set `DATABASE_URL` to Postgres (e.g. Supabase, Neon).
2. Run migrations: `pnpm db:migrate` (ou `pnpm db:push` en dev)
3. Seed if needed: `pnpm db:seed`
4. Build: `pnpm build && pnpm start`
5. Or deploy to Vercel (set env, use Vercel Postgres or external DB).
## Acceptance Criteria
- [x] Auth: mock single-admin login
- [x] Dashboard: list evaluations and candidates
- [x] Create/Edit evaluation: candidate, role, date, evaluator, template
- [x] Templates: Full 15-dim, Short 8-dim
- [x] Interview guide: definition, rubric 1→5, signals, questions per dimension
- [x] AI assistant: stub suggests follow-ups
- [x] Scoring: 15, justification, examples, confidence
- [x] Probing questions when score ≤ 2
- [x] Radar chart + findings/recommendations
- [x] Export PDF and CSV
- [x] Admin: view templates
- [x] Warning when all scores = 5 without comments
- [x] Edit after submission (audit log)
- [x] Mobile responsive (Tailwind)
## Manual Test Plan
1. **Dashboard**: Open `/`, verify evaluations table or empty state.
2. **New evaluation**: Click "New Evaluation", fill form, select template, submit.
3. **Interview guide**: On evaluation page, score dimensions, add notes, click "Get AI follow-up suggestions".
4. **Low score**: Set a dimension to 1 or 2, verify probing questions appear.
5. **All 5s**: Set all scores to 5 with no justification, submit — verify warning.
6. **Aggregate**: Click "Auto-generate findings", verify radar chart and text.
7. **Export**: Click Export, download CSV and PDF.
8. **Admin**: Open `/admin`, verify templates listed.
## File Structure
## Structure des fichiers
```
src/
├── app/
│ ├── api/ # API routes
│ ├── evaluations/ # Evaluation pages
│ ├── admin/ # Admin page
── page.tsx # Dashboard
├── components/ # UI components
└── lib/ # Utils, db, ai-stub, export-utils
│ ├── api/ # Routes API (export CSV/PDF, auth, AI stub)
│ ├── auth/ # Pages login / signup
│ ├── dashboard/ # Dashboard principal
── evaluations/ # Pages évaluation (new, [id])
│ ├── admin/ # Administration (templates, utilisateurs)
│ ├── settings/ # Paramètres utilisateur
│ └── page.tsx # Redirect vers /dashboard
├── actions/ # Server Actions (mutations)
│ ├── evaluations.ts
│ ├── share.ts
│ ├── admin.ts
│ └── password.ts
├── components/ # Composants UI (client + server)
└── lib/
├── server-data.ts # Toutes les requêtes DB (server-side)
├── evaluation-access.ts
├── export-utils.ts
└── ai-stub.ts
prisma/
├── schema.prisma
└── seed.ts
tests/e2e/ # Playwright E2E
tests/e2e/ # Tests Playwright
```
## Données de seed
- **Utilisateur admin** : `admin@peaksys.local` / `admin123`
- **3 évaluations** de démonstration (Alice Chen, Bob Martin, Carol White) avec équipes
- **2 templates** : Full 15 dimensions, Short 8 dimensions
## Critères d'acceptation
- [x] Auth bcrypt multi-utilisateurs, rôles admin/evaluator
- [x] Dashboard : liste et cartes d'évaluations, groupement par équipe
- [x] Créer/modifier une évaluation : candidat, rôle, équipe, date, template
- [x] Templates : Full 15 dim, Short 8 dim
- [x] Guide d'entretien : définition, rubrique 1→5, signaux, questions par dimension
- [x] Scoring : note 15, justification, exemples, confiance
- [x] Questions de sondage quand score ≤ 2
- [x] Assistant IA (stub) : suggestions de relance
- [x] Radar chart + findings/recommandations auto-générés
- [x] Export PDF et CSV
- [x] Administration : templates et gestion des utilisateurs
- [x] Partage d'évaluation avec d'autres utilisateurs
- [x] Visibilité publique (`isPublic`)
- [x] Alerte si tous les scores = 5 sans commentaires
- [x] Modification post-soumission avec audit log
- [x] Page paramètres : changer nom et mot de passe
- [x] Responsive mobile (Tailwind)

View File

@@ -12,4 +12,6 @@ if ! npx prisma migrate deploy 2>/dev/null; then
npx prisma migrate deploy
fi
npx prisma db seed
exec node server.js

View File

@@ -78,6 +78,13 @@ const SUGGESTED_QUESTIONS: Record<string, string[]> = {
"Comment optimisez-vous (choix de modèles, taille du contexte, batch) ?",
"Comment arbitrez-vous coût vs qualité dans vos usages ?",
],
accompagnement: [
"Y a-t-il quelque chose sur lequel vous souhaitez être aidé ou accompagné aujourd'hui ?",
"La Flash Team peut vous aider sur des sujets comme le prompt engineering, la gestion du contexte, ou la mise en place de workflows agentiques — est-ce que l'un de ces axes vous parle ?",
],
scaling: [
"Selon toi, comment pourrais-tu contribuer à mettre à l'échelle tes compétences IA et les outils que tu produis au sein de l'équipe ?",
],
};
const RUBRICS: Record<string, string> = {
@@ -107,6 +114,10 @@ const RUBRICS: Record<string, string> = {
"1:Dépendance — copier-coller sans comprendre, risque de régression;2:Apprentissage limité — utilisation pour débloquer mais compréhension superficielle;3:Compréhension — IA pour comprendre les concepts, valider sa compréhension;4:IA pour patterns — utilisation pour apprendre des patterns, architectures, bonnes pratiques;5:Accélérateur de progression — IA comme outil de montée en compétence structurée",
cost_control:
"1:Inconscient — pas de visibilité sur les coûts, usage sans limite;2:Aware — conscience des coûts, pas de suivi ni de budget;3:Suivi basique — métriques de consommation (tokens, API), pas d'alertes;4:Piloté — budgets par équipe/projet, alertes, arbitrage modèles/qualité;5:Optimisé — optimisation continue (contexte, batch, modèles), ROI coût documenté",
accompagnement:
"1:Aucun besoin exprimé — pas de demande formulée;2:Besoins vagues — envie d'aide sans direction précise;3:Besoins identifiés — sujets d'accompagnement clairs;4:Besoins priorisés — axes de progression définis;5:Plan d'action — besoins concrets et pistes identifiées, prêt à s'engager",
scaling:
"1:Pas de réflexion — aucune idée de comment contribuer au partage;2:Passif — ouvert à partager si sollicité;3:Contributeur ponctuel — partage ses pratiques de temps en temps;4:Multiplicateur — anime des retours d'expérience, documente ses outils;5:Levier d'équipe — impulse une dynamique de diffusion, produit des ressources réutilisables",
};
// Réponses réalistes par dimension et score (justification + exemples observés)
@@ -321,7 +332,7 @@ function getDemoResponse(
const TEMPLATES_DATA = [
{
id: "full-15",
name: "Full - 13 dimensions",
name: "Full - 15 dimensions",
dimensions: [
{
id: "tools",
@@ -384,6 +395,16 @@ const TEMPLATES_DATA = [
title: "[Optionnel] Impact sur la delivery",
rubric: RUBRICS.impact,
},
{
id: "accompagnement",
title: "[Optionnel] Accompagnement & besoins",
rubric: RUBRICS.accompagnement,
},
{
id: "scaling",
title: "[Optionnel] Mise à l'échelle des compétences & outils",
rubric: RUBRICS.scaling,
},
],
},
];