# CLAUDE.md REST-API für das snakkimo-Projekt. Node/Express + PostgreSQL (`pg`, kein ORM), Bild-Assets auf Hetzner Object Storage (S3-kompatibel). Ausführliche API-Doku in [README.md](README.md). ## Befehle - `npm run dev` — lokaler Server mit nodemon (Hot-Reload) - `npm start` — Produktion (`node src/index.js`) - Keine Tests / kein Linter konfiguriert. ## Architektur - Einstieg: [src/index.js](src/index.js) — registriert alle Routen, jede `/api/*`-Route ist mit der `auth`-Middleware geschützt. - **Migrationen laufen automatisch beim Boot** ([src/db-migrate.js](src/db-migrate.js)), bevor der Server lauscht. Idempotent halten: `CREATE TABLE IF NOT EXISTS`, Spalten-Renames mit `.catch(() => {})`. Es gibt **kein** separates Migrations-Tool — Schema-Änderungen hier eintragen. - `src/db.js` exportiert `query(text, params)` und `pool`. Immer parametrisierte Queries (`$1, $2 …`), nie String-Interpolation von User-Input. - `src/routes/` — eine Datei pro Entität. `src/lib/`, `src/middleware/`, `src/s3.js`, `src/voices.js` für geteilte Logik. ## Konventionen - **Code-Kommentare auf Deutsch**, Code/Bezeichner auf Englisch (dem Bestand folgen). - Route-Handler-Muster: `async (req, res, next) => { try { … } catch (err) { next(err); } }`. Fehler an den zentralen Error-Handler in `index.js` durchreichen, nicht selbst 500en. - Listen-Endpoints: `limit`/`offset` aus Query, `limit` hart begrenzen (z. B. `Math.min(parseInt(limit), 500)`). - Status-Felder gegen eine `STATUSES`-Whitelist prüfen → bei Verstoß `400`. - **Sprachen-Suffixe: `_de`, `_en`, `_sv`.** `_se` ist veraltet (falscher ISO-639-1-Code) und wird beim Boot zu `_sv` umbenannt — niemals neue `_se`-Spalten anlegen. ## Auth (zwei Pfade, siehe [src/middleware/auth.js](src/middleware/auth.js)) 1. Statische Tokens aus `API_TOKENS` (komma-separiert) → Server-zu-Server / Admin, keine Rollenprüfung. 2. JWT aus `/auth/login` · `/auth/register`. Rolle `end-user` bekommt auf allen `/api/*` bewusst **403** (App-Gating). Öffentlich (ohne Auth): `GET /health`, `/auth/*`. Konfig über `.env` (siehe [.env.example](.env.example)). Deployment via Coolify/Docker.