Commit Graph
29 Commits
Author SHA1 Message Date
Florian Wilde 0e51df7bad feat: Diagramme als handgeschriebenes SVG
Ohne Chart-Bibliothek: die Diagramme sind schlicht, sollen sich an die
Design-Tokens halten und in beiden Farbschemata funktionieren.

Die Serienfarben sind abgedunkelte Signaturfarben. Sie bestehen in beiden
Modi die Pruefungen auf Helligkeitsband, Saettigung, Farbfehlsichtigkeit
(schlechtestes Paar 12,1 unter Deuteranopie) und Kontrast; die vollen
Signaturtoene waeren auf dunklem Grund zu hell.

Markenfarben der Dienste kommen nur zum Zug, wenn sie auf hellem und dunklem
Grund mindestens 3:1 erreichen — sonst faellt der Balken je nach Farbschema
in den Hintergrund.
2026-09-01 19:54:15 +02:00
Florian Wilde b53ee828ba feat: Auswertungen für Übersicht, Kalender und Statistik
Alles wird aus den Sichtungen berechnet — es gibt keine fortgeschriebenen
Zähler, die auseinanderlaufen könnten. Zeitreihen laufen als SQL, weil Prisma
keine Gruppierung nach Monat kennt.

Der Monatsschlüssel kommt bewusst als Text aus der Datenbank: date_trunc
liefert Mitternacht in der Sitzungszeitzone, JavaScript legt beim Vergleich
die lokale Zone an — zwei Stunden Versatz genügen, damit kein Schlüssel mehr
passt und das Diagramm leer bleibt.
2026-09-01 19:54:15 +02:00
Florian Wilde ed6011384a feat: Beispieluniversum im Seed und Notizen fuer 0.4.0 v0.4.0 2026-09-01 19:39:35 +02:00
Florian Wilde 5cf4fc48a6 fix: server-only-Kette aus dem Browser-Bundle lösen
Die Posterkachel zog über lib/images.ts die serverseitige Cache-Logik in den
Browser-Bundle, sobald sie aus einer Client-Komponente heraus gerendert wurde
— der Build brach ab, sobald eine solche Seite dazukam.

Die reine URL-Bildung liegt jetzt in lib/image-url.ts und darf überall
verwendet werden; Abruf und Dateicache bleiben hinter server-only.
2026-09-01 19:39:34 +02:00
Florian Wilde 5ee6946fd5 feat: Oberfläche für Universen
Umsortieren geht per Ziehen und über Pfeilknöpfe: reines Drag & Drop wäre mit
Tastatur nicht bedienbar und auf dem Handy fummelig — die Knöpfe sind der
verlässliche Weg, das Ziehen der bequeme.

Die Erscheinungsreihenfolge lässt sich gar nicht erst anfassen, weil sie sich
aus den Daten ergibt.
2026-09-01 19:39:32 +02:00
Florian Wilde 90497ddc3b test: Universen absichern
12 Tests für Reihenfolgen, Fortschritt über Filme und Serien hinweg,
Freigaben mit Lese- und Schreibrecht sowie die Rechteprüfung gegenüber
Fremden.
2026-09-01 19:39:32 +02:00
Florian Wilde 190d7b3796 feat: Universen mit mehreren Reihenfolgen und Fortschritt
Zwei Dinge unterscheiden ein Universum von einer Liste: es hat mehrere
Reihenfolgen, und der Fortschritt ist der des jeweiligen Betrachters.

Die Erscheinungsreihenfolge wird aus den Erscheinungsdaten berechnet und nie
gespeichert — sie stimmt damit immer, auch wenn später Titel dazukommen.
Alles andere ist frei sortierbar.

Ein geteiltes Universum zeigt jeder Person ihren eigenen Stand; bei Serien
schrumpft die Restlaufzeit anteilig mit den gesehenen Episoden.
2026-09-01 19:39:31 +02:00
Florian Wilde e2565b600f docs: Changelog, Release-Notes und DEVLOG für 0.3.0 v0.3.0 2026-09-01 19:24:53 +02:00
Florian Wilde a3c74c157b fix: Build-Absturz durch zu viele Worker
Mit einem Build-Worker je Kern stürzte das Einsammeln der Seitendaten auf
einer 18-Kern-Maschine reproduzierbar ab (0xC0000409) — jeder Worker zieht
eine eigene Prisma-Engine hoch. Vier Worker sind schnell genug und laufen
zuverlässig.
2026-09-01 19:24:52 +02:00
Florian Wilde 6f5bdcc20c feat: Beispielbibliothek mit lokal erzeugten Postern
Flimmer ist eine posterlastige Anwendung — ohne Bilder sieht die
Beispielbibliothek aus wie ein Fehler statt wie eine Bibliothek. Echte
TMDB-Poster lassen sich nicht mitliefern, also entstehen abstrakte Poster im
Flimmer-Look direkt im Bild-Cache.

Der Katalog ist bewusst erfunden: das Seed-Skript soll ohne TMDB-Schlüssel
laufen und keine fremden Metadaten ins Repository ziehen. Die Sichtungen sind
über die letzten Monate verteilt, damit Kalender und Statistik später etwas
zu zeigen haben.
2026-09-01 19:24:52 +02:00
Florian Wilde f9ce2f7021 feat: Bibliotheksseite, Papierkorb und manuelles Anlegen
Die Detailseite hängt jetzt an der internen Titel-ID statt an der TMDB-ID —
nur so bekommen manuell angelegte Titel dieselbe Seite. Treffer aus der Suche
laufen über /tmdb/<art>/<id>, das den Titel holt und weiterleitet.

Der Fortschritt einer ganzen Liste wird in einer Abfrage gezählt statt je
Eintrag; bei 300 Titeln wären das sonst 300 Rundreisen zur Datenbank.

Entfernte Titel wandern für 30 Tage in den Papierkorb und behalten ihren
Fortschritt.
2026-09-01 19:24:51 +02:00
Florian Wilde f613136e8a feat: Bedienelemente für Bibliothek und Episodenfortschritt
Server-Aktionen prüfen die Sitzung jeweils selbst — auf Angaben aus dem
Formular ist beim Zugriffsschutz kein Verlass.

Häkchen reagieren sofort und werden zurückgedreht, wenn der Server
widerspricht: Abhaken soll sich anfühlen wie ein Schalter, nicht wie ein
Formular. Jede Sichtungsaktion meldet sich unten kurz zurück und lässt sich
von dort zurücknehmen — die Wirkung passiert weit weg vom Klick.
2026-09-01 19:24:51 +02:00
Florian Wilde 4c3c878980 test: Kern-Tracking absichern
14 Tests für Aufnehmen, Abhaken, Fortschritt ohne Specials, Rewatch,
Papierkorb, Rückgängig und den Zugriffsschutz zwischen Nutzern.

Die Testdateien laufen jetzt seriell: parallel räumten sie sich gegenseitig
die gemeinsamen Katalog-Fixtures weg.
2026-09-01 19:24:50 +02:00
Florian Wilde bb6ce4ab35 feat: Kern-Tracking mit Sichtungen, Fortschritt und Rewatches
Grundgedanke: Eine Sichtung ist die einzige Wahrheit darüber, was jemand
gesehen hat. Fortschritt, „nächste Episode" und später die Statistik werden
daraus berechnet, nichts davon wird doppelt gespeichert.

Rewatches zählen über einen Durchlaufzähler am Eintrag. Ein neuer Durchlauf
setzt den Fortschritt zurück, die alten Sichtungen bleiben stehen — sonst
verlöre die Schauzeit-Statistik jedes Mal ihre Geschichte.

Der Status ergibt sich aus den Sichtungen: die erste Episode startet, die
letzte schließt ab. Pausiert und Abgebrochen bleiben unangetastet — wer
bewusst pausiert hat, will das nicht durch ein Häkchen aufgehoben bekommen.
2026-09-01 19:24:49 +02:00
Florian Wilde 9ecaaf03a9 docs: Changelog, Release-Notes und DEVLOG für 0.2.0 v0.2.0 2026-09-01 19:00:14 +02:00
Florian Wilde 75128d1bf2 test: Importpfad gegen nachgebildete TMDB-Antworten prüfen
npm test läuft ohne TMDB-Schlüssel gegen die Entwicklungsdatenbank und deckt
Kopfdaten, Staffeln, Episoden, Streamingdienste je Region, wiederholten
Import und die Auffrischlogik ab.

Dabei aufgefallen: importSeries gab den Titel zurück, bevor die Staffel- und
Episodenzähler geschrieben waren — die Zähler standen auf 0.
2026-09-01 19:00:13 +02:00
Florian Wilde e11cb6abef feat: Suchseite und Titel-Detailseite
Die Suchanfrage steht in der URL: Treffer sind teilbar, der Zurück-Knopf
funktioniert, und die Suche selbst bleibt eine Server-Komponente.

Posterkacheln zeigen bei fehlendem Bild die Bildmarke über dem
Signaturverlauf. Die Rückfalldarstellung liegt dauerhaft unter dem Bild —
ein onError-Handler hilft nicht, wenn das Bild schon vor der Hydration
scheitert, und der Browser zeigt dann sein kaputtes Bildsymbol.
2026-09-01 19:00:13 +02:00
Florian Wilde cc0e498fe6 feat: Katalogschicht und lokaler Bild-Cache
Der Katalog ist bewusst gemeinsam für alle Nutzer und über (Typ, TMDB-ID)
dedupliziert: zehn Leute mit derselben Serie brauchen die Episodenliste nur
einmal. Persönliches steckt ausschließlich in LibraryEntry und Watch.

Poster laufen über /api/image statt direkt zu TMDB — einmal holen, danach
vom eigenen Server ausliefern. Größe und Pfad werden streng geprüft, damit
daraus kein offener Proxy wird.

Staffel 0 (Specials) wird importiert, zählt aber nicht zum Fortschritt;
Episoden ohne eigene Laufzeit fallen auf die durchschnittliche Episodenlänge
der Serie zurück.
2026-09-01 19:00:12 +02:00
Florian Wilde 4feb84c060 feat: TMDB-Client für Suche, Details und Episodendaten
Nur die Endpunkte, die Flimmer wirklich braucht, samt der Felder, die uns
interessieren. Antworten werden zehn Minuten zwischengespeichert, damit
Tippen im Suchfeld nicht jedes Zeichen einzeln nach draußen trägt.

Zugang wahlweise über den klassischen API-Schlüssel oder das Bearer-Token —
TMDB gibt beides aus, und Selbsthoster haben mal das eine, mal das andere.
2026-09-01 19:00:11 +02:00
Florian Wilde d1303d10f5 docs: Zeiten der Etappe 1 im DEVLOG festhalten v0.1.0 2026-09-01 18:47:06 +02:00
Florian Wilde b05dd1b01e feat: Healthcheck-Endpunkt für Reverse-Proxy und Monitoring
/api/health prüft die Datenbankverbindung mit und antwortet bei Ausfall mit
503 — eine App ohne Datenbank ist nicht gesund, auch wenn der Prozess läuft.
2026-09-01 18:46:55 +02:00
Florian Wilde 2e8e4df6cf docs: README, Design-Dokumentation, Changelog und Seed
README mit Installation, Update-Weg und Backup-Anleitung; docs/DESIGN.md
hält Marke, Farbwerte samt gemessener Kontraste und die Bausteine fest.
Changelog nach Keep a Changelog, Release-Notes zusätzlich unter releases/.
2026-09-01 18:46:49 +02:00
Florian Wilde 63d47b4ead feat: Docker-Compose-Setup zum Selbsthosten
Dreistufiges Image: Abhängigkeiten, Build, Laufzeit. Im Endbild landen nur
der standalone-Server, die statischen Dateien und die Prisma-CLI — letztere,
damit der Container ausstehende Migrationen beim Start selbst einspielt.

Der Entrypoint wartet per TCP-Verbindung auf die Datenbank, statt dafür ein
zusätzliches Paket ins Laufzeitimage zu ziehen.
2026-09-01 18:46:48 +02:00
Florian Wilde 7f8ad716b6 feat: optionale SSO-Anmeldung über OIDC
Authorization Code mit PKCE, ID-Token gegen die JWKS des Anbieters geprüft.
Ohne Client-Bibliothek: Flimmer braucht genau einen Ablauf, dafür lohnt
keine weitere Abhängigkeit mit eigenem Versionsrhythmus.

Bekannte SSO-Kennungen werden verknüpft, sonst über die E-Mail-Adresse
einem vorhandenen Konto zugeordnet; das Anlegen neuer Konten lässt sich
per OIDC_AUTO_REGISTER unterbinden.
2026-09-01 18:46:47 +02:00
Florian Wilde b001e62695 feat: App-Hülle mit Header, Theme-Umschalter und Übersicht
Layout mit Inline-Skript, das data-theme setzt, bevor der erste Pixel
gemalt wird — sonst blitzt beim Laden das falsche Farbschema auf. Logo als
React-Komponente statt als Bilddatei: nimmt Theme-Farben an, spart einen
Netzwerkabruf und die Verläufe liegen einmalig im Root-Layout.

Im hellen Modus greifen eigene Tokens für Verlaufstext und Wortmarke; der
vollfarbige Signaturverlauf fällt auf warmem Weiß sonst unter WCAG AA.
2026-09-01 18:46:47 +02:00
Florian Wilde 01c0f9bc9f feat: Registrierung, Anmeldung und Sitzungen
Passwörter mit bcrypt, Sitzungen als opake Token in der Datenbank — im
Cookie steht das Klartext-Token, in der Tabelle nur dessen SHA-256. Damit
lassen sich einzelne Geräte gezielt abmelden, was reine JWT-Sitzungen nicht
hergeben.

Der erste registrierte Zugang wird automatisch Administrator, sonst käme
man nach dem Aufsetzen nicht in die Verwaltung. Die Registrierung ist
instanzweit abschaltbar; solange es keinen Nutzer gibt, bleibt sie offen.

Enthält außerdem API-Schlüssel je Nutzer als Grundlage für die spätere
REST-API und die Instanz-Einstellungen in der Tabelle AppSetting.
2026-09-01 18:46:27 +02:00
Florian Wilde 3e11e4ffb1 feat: Datenmodell für Katalog, Tracking und Universen
Prisma-Schema in vier Schichten: Konten und Zugang, gemeinsamer Katalog
(über die TMDB-ID dedupliziert), persönliches Tracking je Nutzer sowie
Universen mit mehreren Reihenfolgen. Dazu Benachrichtigungskanäle und
Protokoll der Hintergrundläufe.

Prisma 7 verlangt einen Treiber-Adapter statt der URL im Schema; die
Konfiguration liegt deshalb in prisma.config.mjs — bewusst als .mjs, damit
die CLI auch im schlanken Produktionsimage ohne TypeScript-Loader läuft.
2026-09-01 18:46:27 +02:00
Florian Wilde 488b99f7a1 feat: Flimmer-Branding mit Logo, Icons und Design-Tokens
Logo als SVG in drei Varianten (Icon, Icon+Wortmarke horizontal, monochrom);
die Wortmarke ist als Pfad konstruiert und braucht daher keine installierte
Schrift. Daraus generiert scripts/generate-icons.ts Favicon (SVG + ICO),
PWA-Icons, Maskable-Icons, Apple-Touch-Icon und OG-Bild.

Die Farbwelt liegt als CSS-Variablen in globals.css und wird ueber
@theme inline an Tailwind durchgereicht — Dark/Light und spaetere Themes
bauen darauf auf. Alle Kombinationen erfuellen WCAG AA.
2026-09-01 18:26:21 +02:00
Florian Wilde 0bdfd66c93 chore: Projektgeruest mit Next.js 16, TypeScript und Tailwind v4
Konfiguration fuer Next (standalone-Build), TypeScript, PostCSS/Tailwind,
.gitignore und .gitattributes. CLAUDE.md haelt die Projektentscheidungen
und den Arbeitsauftrag fest, DEVLOG.md die Zeiterfassung.
2026-09-01 18:26:21 +02:00