CI / pruefen (pull_request) Canceled after 0s
Errungenschaften und die Auswahlliste fuer unbekannte Jellyfin-Titel. Changelog, Release-Notiz, DEVLOG und Projektgedaechtnis nachgezogen. Die Anleitung hat ihre beiden Abschnitte schon mit den jeweiligen Issues bekommen — Errungenschaften mit Screenshot, „Titel, die Flimmer noch nicht kennt" im Jellyfin-Kapitel.
567 lines
29 KiB
Markdown
567 lines
29 KiB
Markdown
# Changelog
|
|
|
|
Alle nennenswerten Änderungen an Flimmer stehen in dieser Datei.
|
|
|
|
Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/),
|
|
die Versionierung [Semantic Versioning](https://semver.org/lang/de/).
|
|
|
|
## [Unveröffentlicht]
|
|
|
|
## [0.9.0] — 2026-09-02
|
|
|
|
**Errungenschaften** — Abzeichen für erreichte Meilensteine. Dazu die
|
|
**Auswahlliste** beim Jellyfin-Abgleich, ohne die die Anbindung auf einer
|
|
gewachsenen Mediathek kaum etwas ausrichtete.
|
|
|
|
> ⚠️ **Beim Aktualisieren kommt eine Migration mit** (`errungenschaften`). Der
|
|
> Container spielt sie beim Start selbst ein; `./update.sh` legt vorher eine
|
|
> Sicherung an.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Errungenschaften.** Zwanzig feste Abzeichen, dazu dynamische für
|
|
vollständig gesehene Filmreihen und abgeschlossene Universen. Zu finden
|
|
unten auf der Statistikseite.
|
|
|
|
Sie tauchen auf, wenn etwas erreicht ist, und bleiben dann — **keine
|
|
Streaks**, die reißen, wenn man eine Woche nichts schaut, keine
|
|
Fortschrittsbalken, die drängeln. Wer eine Sichtung zurücknimmt, verliert
|
|
kein Abzeichen; es wieder einzukassieren wäre kleinlich.
|
|
|
|
Ein paar davon: *Der lange Atem* (eine Serie mit hundert Episoden komplett),
|
|
*Treu geblieben* (über ein Jahr an demselben Titel), *Durchgemacht*
|
|
(zwischen drei und fünf Uhr morgens abgehakt), *Zeitreisender* (Titel aus
|
|
sieben Jahrzehnten), *Strenges Urteil* (einmal die Note 1 vergeben).
|
|
|
|
Für **ganze Filmreihen** braucht es keine gepflegte Liste: TMDB gruppiert
|
|
sie selbst, und die Zugehörigkeit steht beim Import schon am Titel. Wer alle
|
|
Spider-Man-Filme gesehen hat, bekommt sie als Reihe angerechnet. Für
|
|
bekannte Reihen gibt es einen eigenen Namen, sonst heißt es schlicht „Reihe
|
|
komplett — …".
|
|
|
|
Beim ersten Öffnen wird die ganze Historie einmal **stumm** ausgewertet —
|
|
eine gewachsene Bibliothek soll nicht zwei Dutzend Meldungen auf einmal
|
|
auslösen. Erst danach wird gemeldet, was neu dazukommt. Auf dem öffentlichen
|
|
Profil lassen sich die Abzeichen zeigen oder ausblenden.
|
|
|
|
- **Auswahlliste für Jellyfin-Titel, die Flimmer nicht kennt.** Beim ersten
|
|
Abgleich einer gewachsenen Mediathek passierte bisher etwas Ernüchterndes:
|
|
Jellyfin meldet tausend Einträge, und Flimmer ordnet **keinen einzigen** zu,
|
|
weil der Katalog sie nicht kennt.
|
|
|
|
Jetzt steht unter dem Bericht eine Liste zum Anhaken. Was ausgewählt ist,
|
|
holt Flimmer von TMDB — bei Serien samt Staffeln und Episoden — und nimmt es
|
|
mit „hab ich · Jellyfin" in die Bibliothek auf.
|
|
|
|
Die Liste fasst zusammen: Führt Jellyfin drei Dateien zum selben Film
|
|
(Extended Edition, zweite Fassung), steht er einmal da, mit dem Vermerk, wie
|
|
viele Dateien darauf zeigen. Einträge, denen in Jellyfin die TMDB-Kennung
|
|
fehlt, bleiben sichtbar, sind aber nicht auswählbar — dort kann Flimmer
|
|
nichts holen.
|
|
|
|
Geholt werden hundert je Lauf; der Rest bleibt für den nächsten Klick. Ein
|
|
einzelner Fehlschlag beendet den Lauf nicht, und **aus der Liste verschwindet
|
|
nur, was tatsächlich ankam**.
|
|
|
|
### Geändert
|
|
|
|
- Der Bericht des Medienserver-Abgleichs war auf **50 Einträge** gekürzt —
|
|
bei über tausend gelesenen ein Blick durchs Schlüsselloch. Jetzt bis 1000,
|
|
und was darüber hinausgeht, wird gezählt statt stillschweigend
|
|
abgeschnitten.
|
|
- Das Häkchen beim Abgleich heißt jetzt „**Bekannte** Titel dabei in die
|
|
Bibliothek aufnehmen". Es nimmt auf, was Flimmer *kennt*; die neue
|
|
Auswahlliste holt, was es *nicht kennt*. Der Unterschied stand vorher
|
|
nirgends — und war der Grund, warum das Häkchen bei einer frischen Instanz
|
|
nichts bewirkte.
|
|
- Einblendungen kennen einen dritten Ton für Erfolge.
|
|
- `npm run screenshots` hebt für Ausschnittaufnahmen die klebende Kopfleiste
|
|
auf; sie legte sich sonst über die Überschrift.
|
|
|
|
### Behoben
|
|
|
|
- Im Bericht stand eine Serie als **Film**, weil der Typ aus dem Umkehrschluss
|
|
„keine Episode, also Film" abgeleitet wurde. Er kommt jetzt aus dem Item.
|
|
|
|
### Getestet
|
|
|
|
93 Tests (vorher 78). Neu: der Regelkatalog der Errungenschaften samt
|
|
Stummschaltung, Entdopplung und Zeitzonenrechnung; die Auswahlliste samt
|
|
Zusammenfassung, Fehlschlägen und Rechteprüfung.
|
|
|
|
Ein Test hat dabei einen Fehler gefunden, den man leicht übersieht: Die Regel
|
|
„zwischen drei und fünf Uhr" las die Stunde aus der formatierten Zeichenkette,
|
|
und auf Deutsch liefert das System dafür **„03 Uhr"** — als Zahl gelesen wird
|
|
daraus nichts. Das Abzeichen wäre nie vergeben worden.
|
|
|
|
### Anleitung
|
|
|
|
`docs/ANLEITUNG.md` hat zwei neue Abschnitte: **Errungenschaften** mit
|
|
Screenshot und **Titel, die Flimmer noch nicht kennt** im Jellyfin-Kapitel.
|
|
|
|
|
|
## [0.8.0] — 2026-09-02
|
|
|
|
Zwei größere Bausteine: **Anmeldung per Passkey** und die **Jellyfin-Anbindung**.
|
|
Dazu vier Nacharbeiten aus dem laufenden Betrieb.
|
|
|
|
> ⚠️ **Beim Aktualisieren kommen zwei Migrationen mit** (`passkeys`,
|
|
> `medienserver`). Der Container spielt sie beim Start selbst ein; `./update.sh`
|
|
> legt vorher eine Sicherung an.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Anmeldung per Passkey (WebAuthn).** Windows Hello, Face ID, Touch ID oder
|
|
ein Sicherheitsschlüssel — statt Passwort. Anlegen und verwalten unter
|
|
*Einstellungen → Passkeys*, anmelden über „Mit Passkey anmelden" **ohne
|
|
vorherige E-Mail-Eingabe**.
|
|
|
|
Ein Passkey ist der dritte Weg in denselben Trichter: am Ende steht dieselbe
|
|
Sitzung wie bei Passwort und OIDC. Das Passwort bleibt daneben bestehen, und
|
|
den letzten verbleibenden Anmeldeweg lässt Flimmer nicht entfernen.
|
|
|
|
Drei Dinge, die beim Selbsthosten zählen:
|
|
- **HTTPS ist Pflicht** (Ausnahme: `localhost`). Läuft die Instanz über
|
|
einfaches HTTP, verschwindet die Verwaltung mit einem Hinweis, statt einen
|
|
kryptischen Browserfehler zu zeigen.
|
|
- Der Hostname kommt aus `APP_URL`, nicht aus dem `Host`-Header — hinter
|
|
einem Reverse Proxy hinge er sonst am falschen Namen.
|
|
- **Ein Domainwechsel entwertet alle Passkeys.** Sie sind fest an den
|
|
Hostnamen gebunden und müssen danach neu angelegt werden.
|
|
|
|
Abschaltbar über `ENABLE_PASSKEYS`.
|
|
|
|
- **Jellyfin anbinden** — Bestand und Sichtungen übernehmen, unter
|
|
*Einstellungen → Medienserver*.
|
|
|
|
Zugeordnet wird über die **TMDB-Kennung**, die Jellyfin zu jedem Item
|
|
mitliefert; dieselbe Kennung, auf der Flimmers Katalog ohnehin aufbaut. Kein
|
|
Raten über Titel und Jahreszahlen — die Zuordnung ist eindeutig oder sie
|
|
findet nicht statt. Was Jellyfin ohne Kennung führt, landet im Bericht.
|
|
|
|
Angemeldet wird mit Benutzername und Passwort, **nicht** mit einem
|
|
API-Schlüssel: mit einem Schlüssel liefert Jellyfin den Bestand ohne
|
|
Gesehen-Status, und zwar ohne Fehlermeldung. Der Verbindungstest prüft das
|
|
ausdrücklich nach und sagt es. Das Zugangstoken liegt verschlüsselt in der
|
|
Datenbank (AES-256-GCM, Schlüssel aus `AUTH_SECRET`), das Passwort wird nicht
|
|
gespeichert.
|
|
|
|
Der Abgleich ist eine **Einbahnstraße**: er ergänzt und löscht nie etwas, das
|
|
in Flimmer steht. Fehlende Titel werden nur mit gesetztem Häkchen
|
|
aufgenommen — im täglichen Lauf also nie. Danach läuft er im
|
|
Hintergrundlauf mit.
|
|
|
|
*Grenze der Quelle:* Jellyfin kennt `PlayCount` und `LastPlayedDate`, aber
|
|
keine Liste einzelner Sichtungen. Ein dreimal gesehener Film kommt deshalb
|
|
mit **einem** Termin an, nicht mit drei. Das steht auch in der Anleitung.
|
|
|
|
Das Zurückschreiben nach Jellyfin (Stufe 3) ist noch nicht dabei; das Feld
|
|
liegt im Datenmodell bereit.
|
|
|
|
- **Standardreihenfolge je Universum.** Welche Reihenfolge beim Öffnen
|
|
erscheint, lässt sich jetzt festlegen — wer Schreibrecht hat, setzt sie für
|
|
alle. Die Rangfolge bleibt schlicht: Adresse schlägt Standard schlägt erste.
|
|
Über die Schnittstelle mit `PATCH /api/v1/universen/{id}`.
|
|
|
|
### Geändert
|
|
|
|
- **Rückmeldung beim Tippen** in Suche und Bibliothek. Beim Suchen wird das
|
|
Trefferraster gedämpft und auf `aria-busy` gesetzt, der Hinweis „sucht …"
|
|
steht jetzt auch in der Bibliothek. Die alten Treffer bleiben sichtbar —
|
|
sie verschwinden zu lassen ließe die Liste bei jedem Tastendruck springen.
|
|
Die Sammelverzögerung liegt einheitlich bei 250 ms.
|
|
|
|
- **`update.sh` erkennt jetzt den Container-Zustand.** Schlägt die Abfrage über
|
|
den veröffentlichten Port fehl, zählt der Healthcheck des Containers —
|
|
hinter einem Reverse Proxy ist der App-Port oft gar nicht auf dem Host
|
|
veröffentlicht, und das Skript meldete dann einen Fehlschlag, obwohl das
|
|
Update sauber durchgelaufen war. Im Fehlerfall nennt es außerdem den Zustand
|
|
und ordnet ihn ein.
|
|
|
|
*Zur Klarstellung:* Der Changelog zu 0.7.1 führte diese Rückfallprüfung
|
|
bereits auf. Sie war dort beschrieben, aber nicht umgesetzt — jetzt ist sie
|
|
es.
|
|
|
|
- Die Entwicklungsdatenbank hat einen eigenen Compose-Projektnamen
|
|
(`flimmer-dev`). Vorher leiteten beide Compose-Dateien ihn aus dem
|
|
Verzeichnis ab, und ein `docker compose down -v` auf dem Produktivstack nahm
|
|
das Volume der Entwicklungsdatenbank mit.
|
|
|
|
### Behoben
|
|
|
|
- **Ein als gesehen markierter Film ließ sich nicht mehr zurücksetzen.** Im
|
|
Zustand „gesehen" stand statt eines Knopfes ein Etikett ohne Klickziel, und
|
|
eine Gegenfunktion gab es nicht — Serien hatten längst einen Umschalter,
|
|
Filme nur einen Hinweg. Die grüne Plakette ist jetzt klickbar.
|
|
Zurückgenommen wird dabei **nur der laufende Durchlauf**: wer einen Film
|
|
dreimal gesehen hat, verliert die früheren Sichtungen nicht.
|
|
|
|
- **Die Beschriftungen im Titelraster sprangen**, sobald ein Titel zweizeilig
|
|
umbrach — die Metazeile saß dann eine Zeilenhöhe tiefer als bei den Nachbarn,
|
|
und die Reihen waren unterschiedlich hoch. Der Titelblock belegt jetzt immer
|
|
zwei Zeilen; in der Bibliothek wird zusätzlich der Platz des
|
|
Fortschrittsbalkens freigehalten, den es nur bei Serien gibt.
|
|
|
|
### Getestet
|
|
|
|
78 Tests (vorher 52). Neu dazu: Passkey-Verwaltung samt Aussperrsperre, der
|
|
Jellyfin-Abgleich gegen nachgebildete Antworten, die Standardreihenfolge samt
|
|
Eindeutigkeit, und das Zurücknehmen einer Filmsichtung über
|
|
Durchlaufgrenzen hinweg.
|
|
|
|
Zusätzlich wurden die Klickwege gegen einen **Produktionsbau** geprüft — die
|
|
Passkey-Anmeldung mit einem virtuellen Authenticator, der Jellyfin-Abgleich
|
|
gegen einen nachgebildeten Server samt des Falls, in dem der Gesehen-Status
|
|
fehlt.
|
|
|
|
|
|
## [0.7.1] — 2026-09-01
|
|
|
|
### Hinzugefügt
|
|
|
|
- **`update.sh`** für den Betrieb unter Linux — ausführbar im Repository
|
|
hinterlegt, also direkt nach dem Klonen startklar. Der Ablauf: Datenbank
|
|
sichern, Änderungen holen, Image bauen, neu starten, warten bis die Instanz
|
|
wieder antwortet.
|
|
|
|
Grundhaltung: erst sichern, dann anfassen. Schlägt die Sicherung fehl, bricht
|
|
das Skript ab, statt weiterzumachen. Geht danach etwas schief, nennt es den
|
|
**konkreten** Weg zurück — mit dem Commit, zu dem man zurückspringt, und der
|
|
Datei, die man einspielt, nicht bloß dem Rat, ein Backup zu haben.
|
|
|
|
Weitere Eigenheiten:
|
|
- Lokale Änderungen im Arbeitsverzeichnis werden erkannt; `git pull`
|
|
unterbleibt dann, statt sie zu überfahren.
|
|
- Erreichbarkeit wird über den veröffentlichten Port geprüft und, falls der
|
|
nicht nach außen geht (Reverse Proxy im selben Docker-Netz), über den
|
|
Healthcheck des Containers.
|
|
- Alte Sicherungen werden aufgeräumt, die letzten zehn bleiben (`--behalte N`).
|
|
- Kommt mit `docker compose` und dem alten `docker-compose` zurecht.
|
|
|
|
- `APP_PORT` in der `.env.example` — der Port stand bisher nur in der
|
|
Compose-Datei als Vorgabewert.
|
|
|
|
## [0.7.0] — 2026-09-01
|
|
|
|
„Hab ich" — Titel, die in der eigenen Sammlung liegen. Dazu die Nacharbeiten
|
|
aus der Abnahme: das Docker-Image wurde zum ersten Mal wirklich gebaut und
|
|
gestartet, und dabei kamen Fehler ans Licht, die nur der echte Containerstart
|
|
zeigt.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Eigene Sammlung**: Jeder Eintrag lässt sich als „hab ich" markieren, mit
|
|
Angabe wo — Jellyfin, Plex, Emby, NAS, Blu-ray, DVD oder frei getippt.
|
|
Bewusst getrennt vom Feld „wo schaue ich das": Streaming-Verfügbarkeit kommt
|
|
und geht, der gekaufte Film auf dem Heimserver bleibt. Gerade die Titel, die
|
|
nirgends mehr laufen, will man ja wiederfinden.
|
|
- Abzeichen auf der Posterkachel und im Kopf der Detailseite
|
|
- Auf der Detailseite steht die Sammlung **vor** der Streaming-Verfügbarkeit
|
|
— was man hat, ist die verlässlichere Antwort auf „wo kann ich das schauen"
|
|
- Eigener Filter in der Bibliothek samt Zähler
|
|
- In Export (CSV und JSON), CSV-Import und REST-API (`?sammlung=1` beim
|
|
Lesen, `owned` und `ownedSource` beim Ändern)
|
|
|
|
### Behoben
|
|
|
|
- **Der Container konnte seine Migrationen nicht einspielen.** Das Laufzeitimage
|
|
bekam die Prisma-CLI, indem einzelne Ordner aus `node_modules` kopiert wurden
|
|
— dabei fehlten transitive Abhängigkeiten von `@prisma/config` (`effect` und
|
|
weitere). Die CLI wird jetzt in einer eigenen Build-Stufe vollständig
|
|
installiert und liegt im Laufzeitimage unter `/node_modules`, wo sie den
|
|
getracten Abhängigkeitsbaum der Anwendung nicht stört.
|
|
|
|
- **Der Build hing im Container am Schriftabruf.** `next/font/google` lädt
|
|
Outfit beim Bauen von Google herunter — das macht den Build von einer
|
|
Netzverbindung abhängig und blieb im Container hängen. Die variable Fassung
|
|
liegt jetzt als Datei im Repository; weder beim Bauen noch zur Laufzeit geht
|
|
eine Anfrage nach außen. Für eine selbst gehostete Anwendung ist das ohnehin
|
|
das Richtige.
|
|
- **npm blockierte Prismas Install-Skripte** (Voreinstellung seit npm 11),
|
|
wodurch im Image die plattformpassende Engine fehlen konnte. Sie sind jetzt
|
|
gezielt für `prisma` und `@prisma/engines` erlaubt statt pauschal.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Erscheinungsmeldung für Watchlist-Filme.** Der Schalter dafür stand schon im
|
|
Profil, verschickt wurde bisher nichts. Betrachtet wird ein Zeitfenster der
|
|
letzten Tage statt eines Zustandswechsels — TMDB verschiebt Termine
|
|
gelegentlich, und ein einmal verpasstes Datum soll die Meldung nicht für
|
|
immer verhindern.
|
|
- **Gitea-Actions-Workflows**: `ci.yml` prüft bei jedem Push Typen, Tests und
|
|
Produktionsbuild gegen eine echte PostgreSQL-Instanz; `release.yml` legt beim
|
|
Pushen eines Versions-Tags das Release mit den Notizen aus
|
|
`releases/vX.Y.Z.md` an.
|
|
- Diagrammfarben und ihre Prüfwerte in `docs/DESIGN.md` festgehalten; das
|
|
öffentliche Profil in die Anleitung aufgenommen.
|
|
|
|
### Entfernt
|
|
|
|
- Die ungenutzte `images`-Konfiguration in `next.config.ts`. `next/image` kommt
|
|
nirgends zum Einsatz — damit entfällt auch das sicherheitsrelevant aussehende
|
|
`dangerouslyAllowSVG`, das ohnehin wirkungslos war.
|
|
|
|
## [0.6.0] — 2026-09-01
|
|
|
|
Der Rest: Benachrichtigungen, Abgleich, Import und Export, Schnittstelle, PWA
|
|
— und eine bebilderte Anleitung.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Benachrichtigungen** über vier Wege: E-Mail (SMTP), ntfy, Gotify und ein
|
|
generischer Webhook, der zugleich Discord, Slack und Mattermost bedient.
|
|
Jeder Nutzer richtet seine Kanäle selbst ein, kann sie einzeln stummschalten
|
|
und mit einer Testnachricht ausprobieren. Dieselbe Meldung geht nie zweimal
|
|
raus — auch ein Fehlversuch wird protokolliert, sonst spammt der nächste Lauf
|
|
den Kanal voll, sobald er wieder erreichbar ist. Die E-Mail-Vorlage trägt
|
|
Logo und Farbwelt von Flimmer.
|
|
- **Täglicher Abgleich**: frischt laufende Serien bei TMDB auf, meldet neue
|
|
Episoden und neu verfügbare Watchlist-Titel, räumt Papierkorb und abgelaufene
|
|
Sitzungen. Eingebauter Zeitplan über `ENABLE_SCHEDULER` und `SYNC_HOUR`, von
|
|
außen anstoßbar über `/api/cron/sync` mit `CRON_SECRET`, und in der
|
|
Verwaltung per Knopfdruck. Ein einzelner Titel kann den Lauf nicht kippen.
|
|
- **Import** aus Trakt.tv (JSON, egal ob Watchlist, History, Ratings oder
|
|
Collection) und aus CSV mit Komma oder Semikolon. Der Import überschreibt
|
|
nichts: was schon in der Bibliothek liegt, bleibt unangetastet.
|
|
- **Export** der eigenen Daten als CSV oder als JSON mit allen Sichtungen und
|
|
Universen.
|
|
- **REST-API** unter `/api/v1` mit persönlichen API-Schlüsseln: Bibliothek
|
|
lesen und pflegen, Episoden abhaken und zurücknehmen, suchen, Kalender,
|
|
Statistik, Universen, Export. Beschreibung als OpenAPI 3.1 unter
|
|
`/api/v1/openapi.json`, dazu `docs/API.md` mit Beispielen.
|
|
- **Einstellungsseiten** für Profil, Region, Passwort, Benachrichtigungen,
|
|
API-Schlüssel sowie Import und Export.
|
|
- **Verwaltungsbereich**: Instanzname, Registrierung öffnen und schließen,
|
|
öffentliche Profile erlauben, Konten sperren und Rechte vergeben, Abgleich
|
|
anstoßen und der Zustand der Instanz auf einen Blick. Die letzte
|
|
Administration lässt sich nicht entmachten.
|
|
- **Öffentliche Profilseite** unter `/u/<adresse>` — Zahlen und zuletzt
|
|
Gesehenes, aber keine Notizen, keine Watchlist, keine E-Mail-Adresse.
|
|
Abschaltbar durch den Nutzer *und* instanzweit durch den Betreiber.
|
|
- **PWA-Feinschliff**: eigener Service Worker (Poster aus dem Zwischenspeicher,
|
|
Seiten zuerst aus dem Netz, Offline-Rückfall) und eine Offline-Seite.
|
|
- **`TMDB_BASE_URL`** für Instanzen hinter einem eigenen Proxy — und für den
|
|
mitgelieferten TMDB-Ersatz `scripts/tmdb-stub.mjs`, mit dem sich die Suche
|
|
ohne Schlüssel aus den Beispieldaten ausprobieren lässt.
|
|
- **Bebilderte Anleitung** `docs/ANLEITUNG.md` mit 18 Screenshots aus der
|
|
laufenden Instanz, aufgenommen von `npm run screenshots`.
|
|
- **9 weitere Tests** für CSV- und Trakt-Import, Export, das Aufräumen des
|
|
Papierkorbs und den Schutz vor Doppelversand — zusammen 49.
|
|
|
|
## [0.5.0] — 2026-09-01
|
|
|
|
Übersicht, Kalender und Statistik.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Übersicht** mit „Weiterschauen" (laufende Serien samt nächster Episode,
|
|
Fortschritt und „+1 Episode" direkt aus der Kachel), den Ausstrahlungen der
|
|
nächsten vier Wochen und den Watchlist-Titeln, die zuletzt auf einem Dienst
|
|
verfügbar geworden sind.
|
|
- **Kalender** als Monatsraster mit Blättern und Sprung zum heutigen Tag,
|
|
darunter die Termine des Monats als Liste. Ausgezeichnet als Tabelle — ein
|
|
Kalender *ist* eine Tabelle, und mit Screenreader wird daraus dann
|
|
„Woche 3, Donnerstag, 24." statt einer ununterscheidbaren Kachelwüste.
|
|
- **Statistikseite** mit Gesamtschauzeit, Episoden und Filmen je Monat als
|
|
Diagramm, Verteilung nach Streamingdienst und Genre, Jahresrückblick
|
|
(„2026 in Zahlen") sowie den Listen „wo die meiste Zeit hinging" und
|
|
„deine besten Bewertungen". Alles aus den Sichtungen gerechnet, Rewatches
|
|
zählen mit.
|
|
- **Diagramme als handgeschriebenes SVG** — ohne Chart-Bibliothek, dafür an
|
|
den Design-Tokens. Die beiden Serienfarben sind abgedunkelte Varianten der
|
|
Signaturfarben; sie bestehen in **beiden** Farbschemata die Prüfungen auf
|
|
Helligkeitsband, Sättigung, Farbfehlsichtigkeit und Kontrast. Die vollen
|
|
Signaturtöne wären auf dunklem Grund zu hell. Legende, Achsenwerte,
|
|
Tooltip beim Überfahren und eine für Screenreader hinterlegte Tabelle
|
|
sorgen dafür, dass die Aussage nie allein an der Farbe hängt.
|
|
- Markenfarben der Streamingdienste in der Verteilung, aber nur, wenn sie auf
|
|
hellem *und* dunklem Grund mindestens 3:1 erreichen — sonst der geprüfte
|
|
Standardton.
|
|
- **7 weitere Tests** für Gesamtzahlen, Monatsgruppierung, Jahresrückblick,
|
|
„Weiterschauen" und den Kalenderzeitraum.
|
|
|
|
### Behoben
|
|
|
|
- Das Monatsdiagramm blieb leer, obwohl Sichtungen vorlagen: `date_trunc`
|
|
liefert Mitternacht in der Zeitzone der Datenbanksitzung, JavaScript legte
|
|
beim Abgleich die lokale Zone an — zwei Stunden Versatz genügten, damit kein
|
|
einziger Monatsschlüssel mehr passte. Der Schlüssel kommt jetzt als Text
|
|
(„2026-04") aus der Datenbank.
|
|
- Eine laufende Serie, bei der man auf dem Stand ist, gilt als „abgeschlossen"
|
|
und verschwand damit aus dem Kalender — dabei will man die nächste Folge
|
|
dort erst recht sehen. Jetzt fällt nur Abgebrochenes heraus.
|
|
- Der SVG-Titel des Diagramms brach die Hydration: React behandelt `<title>`
|
|
als Dokument-Metadatum und hebt es aus dem SVG heraus. Die Beschriftung
|
|
hängt jetzt als `aria-label` am `<svg>`.
|
|
|
|
## [0.4.0] — 2026-09-01
|
|
|
|
Universen: zusammengehörige Titel, mehrere Reihenfolgen, ein Gesamtfortschritt.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Universen** aus beliebigen Filmen **und** Serien — MCU, Star Wars,
|
|
Wizarding World oder was auch immer zusammengehört.
|
|
- **Mehrere Reihenfolgen je Universum**. Die Erscheinungsreihenfolge wird aus
|
|
den Erscheinungsdaten berechnet und nie gespeichert — sie stimmt damit immer.
|
|
Weitere Reihenfolgen (Story-Chronologie, Einsteiger-Route) sind frei
|
|
sortierbar, per Ziehen **und** über Pfeilknöpfe. Reines Drag & Drop wäre mit
|
|
Tastatur nicht bedienbar und auf dem Handy fummelig.
|
|
- **TMDB-Collections als Startpunkt**: Reihen, die in der eigenen Bibliothek
|
|
vorkommen, lassen sich mit einem Klick übernehmen.
|
|
- **Universums-Detailseite** mit nummerierter Liste, Gesamtfortschritt
|
|
(„4 von 7 abgeschlossen, 21 h 21 min gesehen"), hervorgehobenem
|
|
„Als Nächstes dran" und der Restlaufzeit bis zum Ende des Universums.
|
|
Bei Serien schrumpft die Restzeit anteilig mit den gesehenen Episoden.
|
|
- **Teilen** mit anderen Konten der Instanz, wahlweise nur zum Ansehen oder
|
|
zum gemeinsamen Pflegen. Der Fortschritt ist dabei immer der des
|
|
jeweiligen Betrachters — ein geteiltes Universum zeigt jeder Person ihren
|
|
eigenen Stand. Löschen bleibt dem Besitzer vorbehalten.
|
|
- **12 weitere Tests** für Reihenfolgen, Fortschrittsberechnung über Filme und
|
|
Serien hinweg, Freigaben und die Rechteprüfung.
|
|
- Beispieluniversum im Seed: die Sternenpfad-Reihe mit fünf Filmen, zwei
|
|
Serien und einer abweichenden Story-Chronologie.
|
|
|
|
### Behoben
|
|
|
|
- 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`, der Dateicache bleibt
|
|
serverseitig.
|
|
|
|
## [0.3.0] — 2026-09-01
|
|
|
|
Das Kernstück: Bibliothek, Status und Episodenfortschritt.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Bibliothek** als Posterraster mit Volltextsuche und Filtern nach Status,
|
|
Typ, Genre, Streamingdienst und Tag; Sortierung nach zuletzt aktualisiert,
|
|
hinzugefügt, Titel, Bewertung oder Erscheinungsjahr. Der gesamte Filterstand
|
|
steht in der URL und ist damit teilbar.
|
|
- **Fünf Status** je Eintrag (Schaue gerade, Pausiert, Abgeschlossen,
|
|
Abgebrochen, Watchlist). Der Status ergibt sich beim Abhaken von selbst:
|
|
die erste Episode startet einen Titel, die letzte schließt ihn ab.
|
|
Pausiert und Abgebrochen bleiben unangetastet — wer bewusst pausiert hat,
|
|
will das nicht durch eine Sichtung aufgehoben bekommen.
|
|
- **Episodenfortschritt**: einzeln abhaken, ganze Staffel auf einmal,
|
|
„bis hierhin gesehen" für den Einstieg mitten in einer Staffel, und ein
|
|
**„+1 Episode"**-Knopf, der genau die nächste offene Episode nimmt.
|
|
Häkchen reagieren sofort und werden zurückgedreht, wenn der Server
|
|
widerspricht; beim Abhaken glimmt die Zeile einmal warm auf.
|
|
- **„Als Nächstes dran"** mit Episodencode, Titel und Ausstrahlungsdatum;
|
|
Fortschritt in Prozent auf Basis der echten Episodenzahl, dazu die
|
|
verbleibende Laufzeit.
|
|
- **Rewatch-Zählung**: ein neuer Durchlauf setzt den Fortschritt zurück, die
|
|
Sichtungen des vorherigen bleiben für die Statistik erhalten. Bei Filmen
|
|
zählt jeder Durchlauf einzeln.
|
|
- **Rückgängig** für jede Sichtungsaktion — die Rückmeldung am unteren Rand
|
|
nennt, was passiert ist, und nimmt es auf Klick zurück.
|
|
- **Pro Eintrag**: Bewertung von 1 bis 10, Notizfeld, eigene Tags und das Feld
|
|
„wo schaue ich das", das beim Aufnehmen einen Vorschlag aus der
|
|
Streaming-Verfügbarkeit erhält und jederzeit überschreibbar ist.
|
|
- **Papierkorb** statt hartem Löschen: entfernte Titel bleiben 30 Tage liegen
|
|
und behalten dabei ihren Fortschritt. Wird ein Titel erneut aufgenommen,
|
|
lebt derselbe Eintrag wieder auf.
|
|
- **Titel selbst anlegen** für alles, was TMDB nicht kennt. Solche Einträge
|
|
haben keine TMDB-ID und werden vom Abgleich nie angefasst.
|
|
- **Seed mit Beispielbibliothek**: erfundener Katalog aus 8 Serien und
|
|
10 Filmen samt lokal erzeugten Postern, dazu 18 Bibliothekseinträge und
|
|
85 Sichtungen über die letzten Monate verteilt.
|
|
- **21 Tests** decken Aufnehmen, Abhaken, Fortschritt, Rewatch, Papierkorb und
|
|
den Zugriffsschutz zwischen Nutzern ab.
|
|
|
|
### Geändert
|
|
|
|
- Die Detailseite liegt jetzt unter `/titel/<id>` und hängt 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.
|
|
- Die Zahl der Build-Worker ist auf vier begrenzt: mit einem Worker je Kern
|
|
stürzte der Build auf einer 18-Kern-Maschine reproduzierbar ab, weil jeder
|
|
Worker eine eigene Prisma-Engine hochzieht.
|
|
|
|
## [0.2.0] — 2026-09-01
|
|
|
|
Metadaten: Flimmer spricht mit TMDB.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **TMDB-Anbindung** für Suche (gemeinsam über Serien und Filme oder getrennt),
|
|
Detailabruf, Staffeln und Episoden, offizielle Collections sowie die
|
|
Streaming-Verfügbarkeit in der eingestellten Region. Zugang wahlweise über
|
|
den klassischen API-Schlüssel oder das Bearer-Token.
|
|
- **Gemeinsamer Katalog**: Titel werden über (Typ, TMDB-ID) dedupliziert — bei
|
|
mehreren Nutzern liegt jede Serie samt Episodenliste nur einmal in der
|
|
Datenbank. `ensureTitle` holt einen Titel nur, wenn er fehlt oder veraltet ist,
|
|
und fällt bei einem TMDB-Ausfall auf den lokalen Stand zurück.
|
|
- **Bild-Cache**: Poster und Hintergrundbilder werden einmal geholt und danach
|
|
über `/api/image` vom eigenen Server ausgeliefert. Größe und Pfad werden
|
|
streng geprüft, damit der Endpunkt kein offener Proxy wird.
|
|
- **Suchseite** mit Typfilter; die Anfrage steht in der URL und ist damit
|
|
teilbar. Getippte Eingaben werden kurz gesammelt, bevor gesucht wird.
|
|
- **Detailseite** je Titel mit Backdrop, Kopfdaten, Genres, Streamingdiensten
|
|
(mit den Akzentfarben der großen Anbieter) und aufklappbaren Staffeln samt
|
|
Episodenliste.
|
|
- **Testlauf ohne Schlüssel**: nachgebildete TMDB-Antworten unter `tests/` und
|
|
`npm test` prüfen den kompletten Importpfad gegen eine echte Datenbank.
|
|
|
|
### Behoben
|
|
|
|
- `importSeries` gab den Titel zurück, bevor Staffel- und Episodenzähler
|
|
geschrieben waren — die Zähler standen dadurch auf 0.
|
|
- Poster und Dienstlogos zeigten das kaputte Bildsymbol des Browsers, wenn ein
|
|
TMDB-Pfad ins Leere lief. Die Rückfalldarstellung liegt jetzt dauerhaft
|
|
darunter statt an einem `onError`-Handler zu hängen, der bei einem früh
|
|
gescheiterten Bild gar nicht mehr feuert.
|
|
|
|
## [0.1.0] — 2026-09-01
|
|
|
|
Erste lauffähige Etappe: Gerüst, Marke, Datenmodell und Anmeldung.
|
|
|
|
### Hinzugefügt
|
|
|
|
- **Projektgerüst** mit Next.js 16 (App Router), TypeScript, Tailwind CSS v4
|
|
und `standalone`-Build für schlanke Container.
|
|
- **Marke Flimmer**: Logo als SVG in drei Varianten (Bildmarke, Bildmarke mit
|
|
Wortmarke, monochrom) plus Maskable-Variante. Die Wortmarke ist aus Pfaden
|
|
konstruiert und braucht keine installierte Schrift.
|
|
- **Icon-Generator** (`npm run icons`): erzeugt Favicon (SVG und ICO),
|
|
PWA-Icons in sieben Größen, Maskable-Icons, Apple-Touch-Icon und OG-Bild
|
|
aus den SVG-Quellen.
|
|
- **Design-Tokens** als CSS-Variablen, über `@theme inline` an Tailwind
|
|
angebunden. Dunkles Standard-Theme und heller Modus mit Umschalter
|
|
(Dunkel / Hell / System), ohne Aufblitzen beim Laden. Alle Farbkombinationen
|
|
erfüllen WCAG AA; getrennte Verläufe für Flächen und Text sorgen dafür, dass
|
|
auch der Signaturverlauf im hellen Modus lesbar bleibt.
|
|
- **Datenmodell** (Prisma, PostgreSQL) für Konten, Katalog (Titel, Staffeln,
|
|
Episoden, Streamingdienste), persönliches Tracking, Universen mit
|
|
Reihenfolgen sowie Benachrichtigungen und Hintergrundläufe.
|
|
- **Authentifizierung**: Registrierung und Anmeldung mit E-Mail und Passwort
|
|
(bcrypt), Sitzungen als opake Token in der Datenbank mit httpOnly-Cookie.
|
|
Der erste registrierte Zugang wird automatisch Administrator; die
|
|
Registrierung lässt sich instanzweit abschalten.
|
|
- **Optionales SSO** über OIDC (Authorization Code mit PKCE) für Authelia,
|
|
Keycloak, Authentik und Verwandte — per Umgebungsvariablen aktivierbar,
|
|
mit Zuordnung zu vorhandenen Konten über die E-Mail-Adresse.
|
|
- **API-Schlüssel** je Nutzer als Grundlage für die spätere REST-API.
|
|
- **Docker-Compose-Setup** für den Selbstbetrieb (App und PostgreSQL,
|
|
persistente Volumes, Healthcheck) samt Entrypoint, der ausstehende
|
|
Migrationen beim Start einspielt.
|
|
- **Healthcheck** unter `/api/health`, der auch die Datenbank prüft.
|
|
- **PWA-Manifest** mit allen Icon-Größen.
|
|
- **Oberflächentexte** auf Deutsch, gebündelt in `src/i18n` und so aufgebaut,
|
|
dass weitere Sprachen als zusätzliche Datei dazukommen können.
|
|
- **Seed-Skript** mit Demo-Konten sowie README und Design-Dokumentation.
|
|
|
|
[Unveröffentlicht]: https://git.wilde-server.de/florian.wilde/flimmer/compare/v0.7.1...HEAD
|
|
[0.7.1]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.7.1
|
|
[0.7.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.7.0
|
|
[0.6.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.6.0
|
|
[0.5.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.5.0
|
|
[0.4.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.4.0
|
|
[0.3.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.3.0
|
|
[0.2.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.2.0
|
|
[0.1.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.1.0
|