Files

52 lines
2.3 KiB
Markdown

# seiche-server
Backend Fastify 5 (TypeScript strict, Node 22 via `tsx`). Sert l'API `/api/*` et, en production, le front prébuildé (`SEICHE_PUBLIC_DIR`) sur le même port — zéro CORS, 1 conteneur.
## Scripts
| Script | Rôle |
|---|---|
| `pnpm dev` | Serveur en watch sur `http://localhost:8787` (défauts config) |
| `pnpm start` | Serveur en mode prod (idem, sans watch) |
| `pnpm setup` | Crée le compte admin initial (idempotent ; `SEICHE_ADMIN_USERNAME` / `SEICHE_ADMIN_PASSWORD`, mdp ≥ 12 car.) |
| `pnpm db:generate` | `drizzle-kit generate` — génère les migrations dans `drizzle/` |
| `pnpm test` | Vitest (API injectée, SQLite `:memory:`) — 30 tests |
| `pnpm typecheck` | `tsc --noEmit` |
Les migrations sont **appliquées automatiquement au boot** (`migrate()` de Drizzle, dossier `drizzle/`).
## Structure
```
src/
├── main.ts # boot : dataDir, DB + migrations, listen, shutdown propre
├── app.ts # buildApp (trustProxy, logger, plugins, routes)
├── config.ts # toutes les variables d'env (voir .env.example racine)
├── validation.ts # schémas Zod partagés
├── setup.ts # création idempotente du compte admin
├── auth/ # password (argon2id), session + CSRF, rate-limit
├── routes/ # auth, external, health
├── db/ # client libsql (WAL) + schema Drizzle
├── external/ # client du service REST externe (adaptateurs example/http)
└── drizzle/ # migrations versionnées (drizzle/)
```
## API
| Route | Accès | Rôle |
|---|---|---|
| `GET /api/health` | public | healthcheck |
| `POST /api/auth/login` | rate-limit | session httpOnly + cookie CSRF (double-submit) |
| `POST /api/auth/logout` · `GET /api/auth/session` | session | révocation / état de la session |
| `GET /api/external/health` · `GET /api/external/items` · `POST /api/external/items` | session | pont vers le service externe (adaptateurs `example` / `http`) |
Erreurs : corps JSON `{ statusCode, error, message, code, ... }` (le code machine est stable, le message ne fuit jamais les détails internes).
## Tests
```bash
pnpm test
```
Les tests injectent Fastify (`app.inject`) avec une base `:memory:` par worker (`tests/helpers.ts` : `makeConfig`, `openTestDb`, cookies) — pas de dépendance au réseau.