Files
flimmer/CLAUDE.md
T
Florian Wilde 39098cd201
CI / pruefen (pull_request) Canceled after 0s
chore: Update-Skript erkennt Container-Zustand, Merkposten ergaenzt
Das Update-Skript prüfte allein http://127.0.0.1:APP_PORT/api/health. Hinter
einem Reverse Proxy ist der App-Port oft gar nicht auf dem Host
veröffentlicht — dann meldete das Skript nach zwei Minuten einen Fehlschlag,
obwohl das Update sauber durchgelaufen war.

Schlägt die Abfrage vom Host fehl, zählt jetzt der HEALTHCHECK des Containers.
Den bringt das Image schon mit; er fragt /api/health von innen ab und ist
damit unabhängig von der Portveröffentlichung.

Im Fehlerfall nennt das Skript zusätzlich den Container-Zustand und ordnet ihn
ein: kein Container (Start fehlgeschlagen), startet noch (Migrationen dauern),
läuft aber ungesund (Fehler in der Anwendung), oder ein älteres Image ohne
Healthcheck. Ohne diese Auskunft sah ein nicht veröffentlichter Port genauso
aus wie eine abgestürzte Anwendung.

container_zustand() gibt bewusst immer 0 zurück — unter set -e dürfte die
Diagnose nicht selbst abbrechen, bevor der Weg zurück ausgegeben ist.

Dazu drei Merkposten in CLAUDE.md, die diese Sitzung Zeit gekostet haben:
Klickwege müssen gegen einen Produktionsbau geprüft werden (im
Entwicklungsmodus hydratisiert unter headless Chromium nichts, weil der
HMR-Socket scheitert — ohne jede Fehlermeldung), vor npm start den Port
prüfen, und dass scripts/shot.mjs sich nicht anmeldet.
2026-09-02 00:11:22 +02:00

147 lines
9.3 KiB
Markdown

# Flimmer — Arbeitsauftrag & Projektgedächtnis
> Diese Datei ist mein (Claude) Gedächtnis für dieses Projekt. Sie hält fest,
> **was gebaut werden soll**, **wie gearbeitet wird** und **wo ich gerade stehe**.
> Nach jeder Etappe wird der Abschnitt „Fortschritt" aktualisiert.
## Was ist Flimmer?
Selbst hostbarer Serien- & Film-Tracker (angelehnt an „Flimmerkiste"). Multi-User,
TMDB-Metadaten, Episodenfortschritt, eigene Universen mit mehreren Reihenfolgen,
Statistiken, Benachrichtigungen, REST-API, PWA. Oberflächensprache **Deutsch**.
## Verbindliche Entscheidungen (nicht ohne Rückfrage ändern)
| Bereich | Entscheidung | Begründung |
|---|---|---|
| Framework | **Next.js 15, App Router, TypeScript** | UI + REST-API + Cron in einem Deployment; Server Components halten Prisma serverseitig; `output: "standalone"` ergibt ein schlankes Docker-Image |
| DB | **PostgreSQL + Prisma** (Schema + Migrationen) | vorgegeben |
| Styling | **Tailwind CSS v4** (`@theme`, CSS-Variablen) | Design-Tokens sind in v4 nativ CSS-Variablen → Dark/Light/Themes bauen sauber darauf auf |
| Auth | **eigene Session-Schicht**: bcryptjs + opake Tokens in DB-Tabelle `Session`, httpOnly-Cookie; OIDC optional über `jose` + Discovery | DB-Sessions erlauben Sperren/Abmelden durch Admin; kein Beta-API-Risiko von next-auth v5; Credentials + OIDC parallel möglich |
| Passwort-Hash | **bcryptjs** (pure JS) | keine nativen Build-Abhängigkeiten im Docker-Image |
| Scheduler | in-process über `instrumentation.ts` (`ENABLE_SCHEDULER`) **plus** `/api/cron/*` mit `CRON_SECRET` | kein zweiter Container nötig, externe Scheduler trotzdem möglich |
| Bild-Cache | Dateien unter `DATA_DIR/images`, ausgeliefert über `/api/image` | kein TMDB-Abruf pro Seitenaufruf |
| Charts | handgeschriebene SVG-Komponenten | volle Kontrolle über Design-Tokens, keine Chart-Lib-Abhängigkeit |
| PWA | eigenes `sw.js` + `manifest.webmanifest` | keine zusätzliche Abhängigkeit |
| i18n | Dictionary `src/i18n/de.ts` + `t()`-Helper mit Punkt-Keys | weitere Sprachen ergänzbar |
| API | `/api/v1/**`, Bearer-API-Keys pro Nutzer, OpenAPI unter `/api/v1/openapi.json` | für spätere Mobile-App/Skripte |
## Branding (fix)
- Name **Flimmer**, Motiv: warmes Flimmern des Bildschirms
- Logo als **SVG**: abgerundetes Bildschirm-Rechteck, weiches warmes Glühen (Gradient),
dezentes Play-Dreieck; Wortmarke in moderner, leicht gerundeter Sans
- Drei Varianten: **Icon**, **Icon + Wortmarke horizontal**, **monochrom**
- Favicon + PWA-Icons (inkl. **maskable**) aus dem Icon generiert
- Farbwelt: sehr dunkles Blauviolett/Anthrazit als Grund, Signatur = **Glow-Gradient
Bernstein → Magenta**; Light Mode = dieselben Akzente auf warmgrauem Grund
- **Alle Kombinationen müssen WCAG AA erfüllen**
- UI: posterlastig, großzügige Karten mit sanftem Hover-Glow, runde Ecken, weiche
Verläufe, ruhige Mikro-Animationen (Aufglimmen beim Abhaken)
- Logo + Name konsistent in Header, Login, E-Mail-/Notification-Templates, README
## Arbeitsregeln
- **Git-Repo** mit Remote `origin` → `https://git.wilde-server.de/florian.wilde/flimmer.git`, Branch `main`
- **Conventional Commits** (`feat:`, `fix:`, `chore:`, `docs:` …), Nachrichten deutsch
- **Kleine Commits** nach jedem abgeschlossenen Schritt — kein Riesen-Commit
- `.env` **niemals** committen (nur `.env.example`)
- **CHANGELOG.md** im Keep-a-Changelog-Format, SemVer ab 0.1.0; jede Etappe = neue Minor-Version
- Pro Version: **Git-Tag** `vX.Y.Z` + **Gitea-Release** (via Gitea-MCP, `gh`/`tea` sind nicht installiert),
Titel = Version, Notes = Changelog-Abschnitt; zusätzlich `releases/vX.Y.Z.md` ablegen
- **DEVLOG.md**: pro Arbeitsphase Start-/Endzeit per `date`-Befehl (nicht schätzen) + Kurzbeschreibung;
je Etappe Summe, am Ende Gesamtübersicht
- Versionsnummer aus `package.json` im UI anzeigen (Footer/Einstellungen)
- Umgebung: **Windows + PowerShell/Git-Bash**, VS Code. `curl` → `curl.exe`. Keine Desktop-Benachrichtigungen.
## Etappen
1. **Projektgerüst, Branding, Docker-Compose, DB-Schema, Auth** → v0.1.0
2. **TMDB-Anbindung**: Suche, Detailimport, Episodendaten, Bild-Cache → v0.2.0
3. **Kern-Tracking**: Bibliothek, Status, Episodenfortschritt, Watchlist → v0.3.0
4. **Universen** mit Reihenfolgen und Fortschritt → v0.4.0
5. **Dashboard, Kalender, Statistiken** → v0.5.0
6. **Benachrichtigungen, Sync-Job, Import/Export, REST-API, PWA-Feinschliff** → v0.6.0
## Ausdrücklich gewünscht (nicht vergessen!)
- [ ] **Bebilderte Anleitung** `docs/ANLEITUNG.md` mit **Screenshots** der laufenden App
(Playwright gegen die geseedete Instanz, Bilder nach `docs/screenshots/`)
- [ ] Papierkorb (30 Tage) statt hartem Löschen + **Undo** für „als gesehen markiert"
- [ ] Seed-Skript mit Beispieldaten
- [ ] Backup-Hinweise (DB-Dump) in der README
- [ ] Healthcheck `/api/health`
- [ ] Öffentliche Profilseite (abschaltbar)
- [ ] Rewatch-Tracking (Durchläufe, bei Serien pro Durchlauf)
- [ ] Streaming-Verfügbarkeit (TMDB Watch Providers), Region konfigurierbar, Standard DE
- [ ] Import: Trakt.tv-Export + CSV; Export: CSV/JSON
- [ ] Benachrichtigungen: SMTP, ntfy, Gotify, generischer Webhook — pro Nutzer
- [ ] Streamingdienste mit konsistenten Akzentfarben/Badges im ganzen UI
- [ ] Optional per ENV: OIDC/SSO (Authelia, Keycloak)
- [ ] Registrierung durch Admin abschaltbar; erster Nutzer wird Admin
## Wichtige technische Merkposten
- **Next 16**: Request-APIs sind async (`cookies()`, `headers()`, `params`,
`searchParams`). `middleware.ts` heißt jetzt `proxy.ts`. Turbopack ist Standard.
Breaking Changes stehen in `node_modules/next/dist/docs/01-app/02-guides/upgrading/version-16.md`.
- **Prisma 7**: keine `url` im Schema — Treiber-Adapter (`@prisma/adapter-pg`)
im Client, URL in `prisma.config.mjs`. Generator ist `prisma-client`
(TypeScript-Ausgabe nach `src/generated/prisma`, gitignored).
Config bewusst `.mjs`, damit die CLI im Produktionsimage ohne TS-Loader läuft.
- **Tailwind v4**: `@theme inline` reicht die `--fl-*`-Variablen durch,
`@custom-variant dark` hängt an `[data-theme="dark"]`.
- **Zwei Verläufe**: `--fl-gradient` für Flächen, `--fl-gradient-ink` für Text
(im Light Mode abgedunkelt, sonst kein AA). Logo-Stops `--fl-brand-1/2/3`.
- **Dev-Umgebung**: Postgres auf `localhost:5439` (`docker-compose.dev.yml`),
Dev-Server auf **Port 3011** (3000 und 3010 sind von anderen Projekten belegt).
- **Screenshots**: `node scripts/shot.mjs <url> <ziel.png> [w] [h] [theme]`.
Achtung: das Skript meldet sich **nicht** an — bei geschützten Seiten entsteht
kommentarlos ein Bild der Anmeldemaske. Für angemeldete Ansichten den
Login-Weg aus `scripts/screenshots.mjs` nachbauen.
- Next hängt selbst einen Block an diese Datei an — der bleibt drin.
## Fortschritt
- ✅ **Etappe 1** (v0.1.0) — Gerüst, Branding, Docker, Schema, Auth. 38 min.
- ✅ **Etappe 2** (v0.2.0) — TMDB: Suche, Import, Episoden, Bild-Cache. 14 min.
- ✅ **Etappe 3** (v0.3.0) — Bibliothek, Status, Episodenfortschritt, Papierkorb. 24 min.
- ✅ **Etappe 4** (v0.4.0) — Universen mit Reihenfolgen, Freigaben. 14 min.
- ✅ **Etappe 5** (v0.5.0) — Übersicht, Kalender, Statistik. 15 min.
- ✅ **Etappe 6** (v0.6.0) — Benachrichtigungen, Abgleich, Import/Export, REST-API, PWA, Anleitung. 31 min.
**Alle sechs Etappen abgeschlossen. Gesamtzeit: 2 h 16 min.**
### Nützliches für spätere Arbeiten
- Suche ohne TMDB-Schlüssel ausprobieren:
`npm run tmdb:stub` und dann
`TMDB_API_KEY=stub TMDB_BASE_URL=http://127.0.0.1:3099/3 PORT=3011 npm run dev`
- Screenshots neu aufnehmen: `npm run screenshots` (nimmt auf und verkleinert)
- `npm test` läuft seriell gegen die Dev-Datenbank, braucht keinen TMDB-Schlüssel
- Deutsche Anführungszeichen (`„…"`) niemals in JS-**String-Literalen** —
das ASCII-Schlusszeichen beendet den String. In JSX-Text und Kommentaren ok.
- Heredocs im Bash-Tool sind bei langen TSX-Dateien unzuverlässig — dann das
Write-Werkzeug benutzen.
- **Klickwege niemals gegen `npm run dev` prüfen.** Unter headless Chromium
scheitert der HMR-Socket (`ERR_INVALID_HTTP_RESPONSE`), dadurch hydratisiert
**keine** Seite und kein Knopf reagiert — ohne Seitenfehler, ohne
fehlgeschlagene Anfrage, es passiert einfach nichts. Sieht aus wie ein Fehler
im eigenen Code, ist aber die Umgebung. Stattdessen
`npm run build` und `PORT=3012 npm start`, dann dagegen klicken.
Formulare täuschen zusätzlich: die Anmeldung funktioniert auch ohne
JavaScript, wirkt also intakt.
- Vor `npm start` prüfen, ob der Port noch von einem früheren Lauf belegt ist —
sonst startet der neue Server gar nicht und man testet den alten Bau.
- Testdaten nach Klickproben wieder herstellen: die Proben schreiben in die
geseedete Entwicklungsdatenbank.
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.
This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
<!-- END:nextjs-agent-rules -->