Nutzer-Wunsch 20.08.2026: "eine richtig geile kachel ... wo die leute mit
namen und tiktok namen mir eine nachricht schreiben können die ich in die
verwaltung kriege, und dann kann ich die ausgewählten über die
verwaltungsseite auf die website hinzufügen ... das wird mega persoenlich
zu den fans, bitte wirklich krass geil speziell."
- Neue, augenschonend gestaltete Einreich-Kachel auf stimmen.html: Name,
TikTok-Name (optional), Nachricht -- landet NIE automatisch oeffentlich,
sondern immer erst als Entwurf in der Verwaltung.
Warmer Babyblau/Rosé-Farbverlauf, wandernder Lichtschein, pulsierendes
Herz -- ersetzt die 3 ewigen "Hier steht bald..."-Platzhalterkarten.
- Neue Verwaltungs-Sektion "💬 Stimmen verwalten": Warteschlange (offene
zuerst), Freigeben/Ablehnen/Löschen pro Eintrag.
- Freigegebene Stimmen erscheinen automatisch in einer neuen, spezielleren
Zitat-Kartenoptik (großes Anführungszeichen, Name + TikTok-Chip) --
Abschnitt bleibt komplett unsichtbar, solange keine einzige freigegeben
wurde.
- Backend: neue Tabelle `testimonials` (Migration 0006), routes/
testimonials.js (oeffentliches Einreichen + Lesen freigegebener,
admin-Warteschlange + Status/Loeschen mit neuer TESTIMONIALS_MANAGE-
Berechtigung). 18 automatisierte Tests gegen eine Fake-DB bestanden.
- Alles per Playwright visuell durchgespielt: leerer Zustand, Einreichen
-> Erfolgsmeldung, freigegebene Stimmen-Anzeige, Verwaltungs-Warteschlange
mit allen Aktionen.
Backend-Teil (server-internal/, cloudflare-worker/migrations/) noch ohne
Deploy-Zugriff -- Dogi muss ihn manuell auf dogiintern ausrollen.
Co-Authored-By: Claude Opus 5 <[email protected]>
Nutzer-Wunsch 20.08.2026: "wuensch mir nur noch bissl farbe und sehr
wichtig ist dass ich auch spezielle live events da auch eintragen kann
in der verwaltungsseite so dass da eine zweite uhr erscheint wo die zeit
dann fuer dieses spezielle event laeuft."
- Neue Verwaltungs-Sektion "Spezielles Live-Event": Titel (Deutsch, wird
automatisch uebersetzt), echtes Datum+Uhrzeit, optionaler Link, Aktiv-
Schalter -- nur mit Titel + Zukunftsdatum aktivierbar.
- Zweite Uhr auf streamplan.html (Magenta/Violett statt Cyan/Gold, direkt
neben der bestehenden), nur sichtbar wenn ein Event aktiviert ist und
das Zieldatum noch nicht vorbei ist. Echter Countdown inkl. Tage (z.B.
"2T 03:14:59"), "Jetzt"-Zeiger zeigt wie bei Uhr 1 die tatsaechliche
Uhrzeit, der magentafarbene Fixpunkt markiert die Tageszeit des Events.
Zieldatum wird als UTC gespeichert -- jede besuchende Person sieht den
exakt richtigen Countdown in ihrer eigenen Zeitzone.
- "Bissl Farbe": bunter Farbverlauf (Cyan/Violett/Gold) auf dem aeusseren
Ring statt reinem Grauton, kraeftigerer Sweep-Farbschein.
- Backend: neue routes/special-event.js (getSpecialEventPublic nur bei
aktiv+zukuenftig, getSpecialEventAdmin fuer Entwuerfe, saveSpecialEvent
mit Validierung), 13 automatisierte Tests gegen eine Fake-DB bestanden.
- Bugfix unterwegs gefunden (Playwright-Screenshot, wiederholtes Muster
auf dieser Seite): .stream-radar-wrap blieb trotz [hidden]-Attribut
sichtbar (display:block ueberschreibt die eingebaute [hidden]-Regel bei
gleicher Spezifitaet) -- explizite Regel ergaenzt, per Playwright erneut
verifiziert (display:none bestaetigt).
Backend-Teil (server-internal/) noch ohne Deploy-Zugriff -- Dogi muss ihn
manuell auf dogiintern ausrollen, sonst bleibt die zweite Uhr unsichtbar.
Co-Authored-By: Claude Opus 5 <[email protected]>
Nutzer-Wunsch 20.08.2026: "diese zwei kisten sollen leer sein solang wie
ich nichts rein setze, am besten sollen die sogar immer nur erscheinen
wenn ich was rein setze und sie aktiviere ... wen ich drauf druecke dass
dann ein kleines fenster aufgeht wo das bild bissl groesser ist mit einem
groesseren text und beschreibung, und mit einem link ... die kacheln
sollen auch bissl spezieller sein."
- Kein hartkodierter Standardinhalt mehr auf der Startseite -- die Kachel
UND der ganze Abschnitt bleiben komplett unsichtbar, bis mindestens ein
Event in der Verwaltung ausgefuellt UND ueber einen neuen "Aktiv"-Schalter
freigeschaltet ist. Genau 1 aktives Event -> zentrierte Einzelkachel
statt halbleerem Zwei-Spalten-Raster.
- Klick auf eine Kachel oeffnet jetzt ein Detail-Fenster (groesseres Bild,
groesserer Titel/Text, optionaler direkter Link) statt sofort
wegzunavigieren.
- Kacheln bekommen einen goldenen Trophaeen-Akzent + dezenten wandernden
Lichtschimmer statt der neutralen Standardkarten-Optik.
- Bugfix unterwegs gefunden (Playwright-Screenshot): .jahres-event-card
blieb trotz [hidden]-Attribut sichtbar (dieselbe Ursache wie der
frühere .jahres-event-bild-Bug: display:block ueberschreibt die
eingebaute [hidden]-Regel bei gleicher Spezifitaet) -- explizite
[hidden]-Regel ergaenzt.
- Backend: server-internal/routes/events.js liefert oeffentlich NUR noch
aktivierte Slots aus (getEventsPublic), neuer authentifizierter Endpunkt
getEventsAdmin liefert der Verwaltung auch Entwuerfe zum Vorausfuellen.
10 automatisierte Tests gegen eine Fake-DB bestanden.
Backend-Teil (server-internal/) noch ohne Deploy-Zugriff -- Dogi muss ihn
manuell auf dogiintern ausrollen, sonst bleibt die Startseite beim alten
Verhalten (immer beide Slots zeigen, kein Aktiv-Schalter in der Verwaltung).
Co-Authored-By: Claude Opus 5 <[email protected]>
Naechste "Ausbaustufe" aus Dogfather_VanVan_Supporter_Abo.odt Abschnitt 20
(siehe Supporter-Abo-System.md), auf Nutzerwunsch "perfektioniere meine
Verwaltungsseite": Dogi/VanVan koennen in verwaltung.html eine Frage mit
2-6 Antwortoptionen auf Deutsch erstellen, automatische Uebersetzung beim
Speichern (gleiches Muster wie "Event des Jahres"). Jede aktive DogiCrew-
Person sieht die Abstimmung in ihrem Supporter-Bereich, stimmt genau einmal
ab (UNIQUE-Constraint in der DB, nicht nur Anwendungslogik), sieht danach
die Live-Ergebnisse. Admin-Seite zeigt Ergebnisbalken live, kann schliessen/
wiedereroeffnen/loeschen.
- Neue Migration 0005_supporter_polls.sql (supporter_polls,
supporter_poll_votes), neue Berechtigung POLLS_MANAGE.
- server-internal/routes/polls.js: 30 End-to-End-Tests gegen eine
Fake-DB bestanden (better-sqlite3 laesst sich lokal nicht kompilieren).
- verwaltung.html: neue "Abstimmungen"-Kiste im bestehenden
vw-overview-box-Stil (violett/pink Ergebnisbalken).
- supporter.html: neue "Aktuelle Abstimmung"-Karte im bestehenden
Gold-Look, Optionen -> Stimme -> Ergebnisbalken, alle 5 Sprachen.
Backend-Teil (server-internal/, cloudflare-worker/migrations/) noch ohne
Deploy-Zugriff -- Dogi muss ihn manuell auf dogiintern ausrollen.
Co-Authored-By: Claude Opus 5 <[email protected]>
Nutzer-Wunsch 20.08.2026: "will ich in der admin seite das selbst
gestalten können, mit bild und text und am besten auch einen link." Auf
Rueckfrage entschieden: Titel/Text nur auf Deutsch eingeben, die anderen
4 Sprachen werden beim Speichern automatisch uebersetzt (MyMemory, 0€,
kein API-Key) -- bewusste Ausnahme von der sonst geltenden "immer echte
Uebersetzung"-Regel, klar dokumentiert und im Admin-UI selbst als Hinweis
sichtbar. de-CH bekommt denselben deutschen Text (Dialekt ist keine von
Uebersetzungs-APIs unterstuetzte Zielsprache).
Backend (server-internal):
- routes/events.js: getEventsPublic (oeffentlich, keine Session),
saveEvent + uploadEventImage (beide hinter neuer EVENTS_MANAGE-
Berechtigung, Owner immer erlaubt). Speichert in der bereits
bestehenden app_settings-Tabelle (2 feste Slots) statt einer neuen
Tabelle -- es gibt nie mehr als genau 2 Events.
- lib/translate.js: MyMemory-Anbindung mit "fail closed auf Deutsch"
pro Sprache, falls der Dienst mal nicht antwortet.
- Bild-Upload per multer, zufaelliger Dateiname (crypto.randomUUID,
verhindert Path-Traversal ueber den Originalnamen komplett), 5 MB
Limit, nur jpeg/png/webp, Ablage unter /var/lib/dogfather-internal/
uploads/events (NICHT im Git-Ordner -- uebersteht Deploys), oeffentlich
ausgeliefert unter /uploads.
- Neue Berechtigung EVENTS_MANAGE im Katalog (Gruppe "Startseite").
Frontend:
- index.html: laedt /events-of-year beim Aufruf, ueberschreibt pro Slot
Datum/Titel/Text/Bild/Link NUR wenn dort tatsaechlich etwas gespeichert
ist -- bleibt der Abruf aus oder ist ein Slot leer, bleibt der bisherige
fest eingebaute Standardinhalt (dieselben zwei echten Events) stehen.
Kein Blocker, kein sichtbarer Fehler bei Ausfall.
- verwaltung.html: neue Sektion "🏆 Event des Jahres" (nur mit
EVENTS_MANAGE sichtbar), 2 Karten mit Bild-Upload+Vorschau, Datum,
Titel, Text, Link, eigenem Speichern-Knopf pro Event.
Ausfuehrlich getestet, weil server-internal wegen fehlender Visual-
Studio-Build-Tools auf dieser Windows-Maschine nicht lokal mit echtem
better-sqlite3 laufen kann: routes/events.js komplett isoliert gegen eine
Fake-DB getestet (11 Szenarien: oeffentlicher Abruf, fehlende Session,
Session ohne Recht, Owner, Rolle MIT EVENTS_MANAGE, alle Validierungen,
Bild-Upload inkl. falscher Dateityp, Abruf des hochgeladenen Bilds).
index.html per Playwright mit echtem Netzwerk-Mocking gegen zwei
Szenarien getestet (API nicht erreichbar -> Standardinhalt bleibt; API
liefert echte Daten -> nur der befuellte Slot wird ueberschrieben, der
leere bleibt Standard). Dabei einen echten CSS-Bug gefunden und behoben
(display:block auf .jahres-event-bild überschrieb die [hidden]-Regel des
Browsers, leeres Bild waere immer sichtbar gewesen). verwaltung.html per
Playwright mit gemocktem Login+API end-to-end getestet: Formular wird
korrekt vorbefuellt, Bild-Upload + Speichern senden die richtigen Daten.
WICHTIG: server-internal laeuft unter einem eigenen Systembenutzer
(dogiintern), auf den ich (claudian) bewusst KEINEN Zugriff habe -- diese
Aenderung kann ich anders als sonst nicht selbst bis auf den Server
bringen. Dogi muss den Deploy-Schritt fuer server-internal selbst
ausfuehren (git pull + npm install + Neustart des dogiintern-Dienstes).
Co-Authored-By: Claude Opus 5 <[email protected]>
- Login-Sperre war umgehbar: clientKey() vertraute dem Header CF-Connecting-IP.
Bei Cloudflare war das sicher (CF ueberschreibt ihn), auf dem eigenen Server nicht:
der Ursprungsserver ist auch direkt unter seiner IP erreichbar, dort konnte der
Header frei gesetzt und die 5-Versuche-Sperre komplett ausgehebelt werden
(nachgewiesen). Jetzt req.ip hinter trust proxy.
- Absturzsicherheit: Express 4 faengt Fehler aus async-Handlern nicht ab, eine
einzige fehlerhafte Anfrage konnte den ganzen Dienst beenden. wrap() um alle
Handler, zentraler Fehler-Handler, unhandledRejection/uncaughtException-Netz.
- Sicherheits-Header (X-Content-Type-Options, X-Frame-Options, Referrer-Policy,
Permissions-Policy, HSTS) wurden bisher nur ueber die Datei _headers gesetzt,
die auf dem eigenen Server wirkungslos ist. Jetzt im Express-Server.
- x-powered-by abgeschaltet.
- Datenschutzerklaerung/AGB: nannten Cloudflare als Hoster und eine Cloudflare-D1-
Datenbank. Jetzt korrekt netcup (Rechenzentrum Nuernberg) als Hoster, Cloudflare
als vorgeschaltetes CDN mit Drittlandhinweis.