Add name change functionality to user settings. Update SettingsPasswordForm to handle name updates, including validation and error handling. Fetch current user name for display in settings page.
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m44s

This commit is contained in:
Julien Froidefond
2026-02-20 14:47:32 +01:00
parent 8073321b0f
commit 160e90fbde
5 changed files with 170 additions and 6 deletions

69
CLAUDE.md Normal file
View File

@@ -0,0 +1,69 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
pnpm dev # Start dev server
pnpm build # Production build
pnpm lint # ESLint
pnpm typecheck # tsc --noEmit
pnpm test # Vitest unit tests (run once)
pnpm test:e2e # Playwright E2E (requires dev server running)
pnpm db:generate # Regenerate Prisma client after schema changes
pnpm db:push # Sync schema to DB (dev, no migration files)
pnpm db:migrate # Apply migrations (production)
pnpm db:seed # Seed with sample data
pnpm db:studio # Open Prisma Studio
```
Package manager: **pnpm**.
## Coding conventions
### Server-first by default
This codebase maximises server-side rendering and minimises client-side JavaScript:
- **All pages are server components** by default. Never add `"use client"` to a page file.
- **Data fetching always happens server-side** in `src/lib/server-data.ts` — never `fetch()` from the client, never call Prisma from a client component.
- **All mutations use server actions** (`src/actions/`) — never create new API routes for mutations. The only remaining API routes are the export endpoints and auth (see below).
- **`"use client"` is only added** to components that genuinely need browser APIs or React state (forms, interactive widgets). Keep the surface area small.
- **Auth checks happen in every server action** via `const session = await auth()` before touching the DB.
### Data flow pattern
- **Server page** calls `src/lib/server-data.ts` functions (which call `auth()` + Prisma internally)
- Page passes serialized data as props to **client components** in `src/components/`
- Client components call **server actions** (`src/actions/`) for mutations
- Server actions call `revalidatePath()` to trigger cache invalidation
### Auth
`src/auth.ts` — NextAuth v5 with Credentials provider (email + bcrypt password). JWT strategy with `id` and `role` added to the token. Two roles: `evaluator` (default) and `admin`.
`src/middleware.ts` — Protects all routes. Admin routes redirect non-admins. Auth routes redirect logged-in users to `/dashboard`.
### Access control
`src/lib/evaluation-access.ts``canAccessEvaluation()` is the single source of truth. An evaluation is accessible if: user is admin, user is the evaluator, evaluation is shared with the user (`EvaluationShare`), or `isPublic` is true (read-only).
### Database
SQLite in dev (`DATABASE_URL=file:./dev.db`), swap to Postgres for production. Schema lives in `prisma/schema.prisma`. Key relations:
- `Evaluation``Template``TemplateDimension[]`
- `Evaluation``DimensionScore[]` (one per dimension, `@@unique([evaluationId, dimensionId])`)
- `Evaluation``EvaluationShare[]` (many users)
- `Evaluation``AuditLog[]`
`TemplateDimension.suggestedQuestions` is stored as a JSON string (array). `TemplateDimension.rubric` is stored as a `"1:X;2:Y;..."` string. Both are parsed client-side.
### API routes (remaining)
Only exports and auth use API routes:
- `GET /api/export/csv?id=` and `GET /api/export/pdf?id=` — use `src/lib/export-utils.ts`
- `POST /api/ai/suggest-followups`**stub**, returns deterministic suggestions; replace with real LLM call if needed
- `POST /api/auth/signup` — user registration
### Key types
`src/types/next-auth.d.ts` extends `Session.user` with `id` and `role`. Always use `session.user.id` (never `session.user.email`) as the user identifier in server actions.
### JWT staleness
`session.user.name` comes from the JWT token frozen at login time. If a page needs the user's current `name` (or any other mutable profile field), query Prisma directly using `session.user.id` — do not rely on the session object for those values.