# fete ## Grundsätze * Soll als PWA im Browser laufen * Damit es sich wie eine normale app anfühlt * Soll ein kleiner Helfer sein, den man schnell mal nutzen kann * Ich will es mir selbst hosten können * Das schließt eigentlich schon AI features aus und das ist okay * Privacy als first class citizen * Schon das Produktdesign muss mit privacy im sinn entworfen werden * Keine Registrierung, kein login notwendig (nur z.B. einen code, um den "raum" zu finden oder so) * Alternativ könnten etwaige anfallende Daten auch im local storage gespeichert werden ## Die Idee Eine alternative zu Facebook Event Gruppen oder Telegram Gruppen, in denen eine Veranstaltung bekanntgegeben wird und Teilnahmen bestätigt werden ### Zielbild Person erstellt via App eine Veranstaltung und schickt seine Freunden irgendwie via Link eine Einladung. Freunde können zurückmelden, ob sie kommen oder nicht. ## Gedankensammlung * So ne Art Landingpage zu jedem Event * Ein Link pro Event, den man z.B. in ne WhatsApp-Gruppe werfen kann * Was, wie, wann, wo? * Irgendwie auch Designbar, sofern man das will * RSVP: "Ich komme" (mit Name) / "Ich komme nicht" (optional mit Name) * Wird serverseitig gespeichert + im LocalStorage gemerkt * Duplikatschutz: Kein perfekter Schutz ohne Accounts, aber gegen versehentliche Doppeleinträge reicht Gerätebindung via LocalStorage * Gegen malicious actors (Fake-Namen spammen etc.) kann man ohne Accounts wenig machen — akzeptables Risiko (vgl. spliit) * "Veranstaltung merken/folgen": Rein lokal, kein Serverkontakt, kein Name nötig * Löst das Multi-Geräte-Problem: Am Handy zugesagt, am Laptop einfach "Folgen" drücken * Auch nützlich für Unentschlossene, die sich das Event erstmal merken wollen * View für den Veranstalter: * Updaten der Veranstaltung * Einsicht angemeldete Gäste, kann bei Bedarf Einträge entfernen * Featureideen: * Organisator kann einstellen, ob Attendee-Namensliste öffentlich auf der Event-Seite sichtbar ist (default: nur für Organisator). Wenn öffentlich, muss im RSVP-Bottom-Sheet eine Warnung angezeigt werden, dass der Name öffentlich sichtbar sein wird. * Link-Previews (OpenGraph Meta-Tags): Generische OG-Tags mit App-Branding (z.B. "fete — Du wurdest eingeladen") damit geteilte Links in WhatsApp/Signal/Telegram hübsch aussehen. Keine Event-Daten an Crawler aus Privacy-Gründen. → Eigene User Story. * Kalender-Integration: .ics-Download + optional webcal:// für Live-Updates bei Änderungen * Änderungen zum ursprünglichen Inhalt (z.b. geändertes datum/ort) werden iwi hervorgehoben * Veranstalter kann Updatenachrichten im Event posten, pro Device wird via LocalStorage gemerkt was man schon gesehen hat (Badge/Hervorhebung für neue Updates) * QR Code generieren (z.B. für Plakate/Flyer) * Ablaufdatum als Pflichtfeld, nach dem alle gespeicherten Daten gelöscht werden * Übersichtsliste im LocalStorage: Alle Events die man zugesagt oder gemerkt hat (vgl. spliit) * RSVP editieren: Gast kann seine bestehende Zusage bearbeiten (Name ändern via PUT mit rsvpToken) oder zurückziehen (DELETE mit rsvpToken). Bottom Sheet öffnet sich im Edit-Mode mit pre-filled Name + "Zusage zurückziehen"-Button. Später ergänzen: "Absagen und merken" (Kombination mit 011-bookmark-event). Ausgelagert aus 008-rsvp um den Scope klein zu halten. * Organizer-Gästeliste: Namensliste der Zusagen nur für Organisator sichtbar (über Organizer-Link). Gehört thematisch zu 009-guest-list, nicht zu 008-rsvp. * Sicherheit/Missbrauchsschutz: * Nicht-erratbare Event-Tokens (z.B. UUIDs) * Event-Erstellung ist offen, kein Login/Passwort/Invite-Code nötig * Max aktive Events als serverseitige Konfiguration (env variable) * Honeypot-Felder in Formularen (verstecktes Feld das nur Bots ausfüllen → Anfrage ignorieren) * Abgrenzungskriterien * KEIN Chat * KEIN Discovery Feature über die App: Ohne Zugangslink geht nichts * KEINE Planung des Events! Also kein "wer macht/bringt was?", "was machen wir überhaupt?" ## Getroffene Designentscheidungen Die folgenden Punkte wurden in Diskussionen bereits geklärt und sind verbindlich. * RSVP-System: * Ein Link pro Event (NICHT individuelle Einladungslinks pro Person — zu umständlich für den Veranstalter) * Gäste geben beim RSVP einen Namen an, das reicht * Duplikate durch versehentliche Mehrfachanmeldung: LocalStorage-Gerätebindung reicht als Schutz * Bewusste Doppelanmeldung/Spam: Akzeptables Risiko, Veranstalter kann Einträge manuell löschen * Geräte-Sync ohne Account ist nicht sauber lösbar und das ist okay * Missbrauchsschutz: * Rate Limiting: Bewusst rausgelassen — zu viel Infra-Overhead für den Scope * Captcha: Bewusst rausgelassen — entweder Privacy-Problem (Google) oder hässlich * Admin-Passwort/Invite-Code für Event-Erstellung: Bewusst rausgelassen — die App soll organisch weitergegeben werden können * Erfahrungswert: Spliit-Instanz läuft auch komplett offen ohne nennenswerte Probleme * Stattdessen pragmatische Maßnahmen: Nicht-erratbare Tokens, Ablaufdatum als Pflichtfeld, Max Events per Konfiguration, Honeypot-Felder * Zielgruppe: * Primär Freundeskreise, nicht die breite Öffentlichkeit * Trotzdem: Die App hängt im Internet, also muss man grundlegende Absicherung haben * Architektur (bereits entschieden): * SPA + RESTful API Backend, kein SSR * Datenbank: PostgreSQL, wird separat gehostet (nicht im App-Container — der Hoster betreibt seinen eigenen Postgres) * Organizer-Authentifizierung: Zwei separate UUIDs pro Event — ein öffentliches Event-Token (in der URL, für Gäste) und ein geheimes Organizer-Token (in localStorage, für Verwaltung). Interne DB-ID ist ein Implementierungsdetail. * App wird als einzelner Docker-Container ausgeliefert, verbindet sich per Konfiguration (env variable) mit der externen Postgres-Instanz * Techstack: * Backend: Java (neuste LTS Version), Spring Boot, Maven, Hexagonal/Onion Architecture * Frontend: Vue 3 (mit Vite als Bundler, TypeScript, Vue Router) * Architekturentscheidungen die NOCH NICHT getroffen wurden (hier darf nichts eigenmächtig entschieden werden!): * (derzeit keine offenen Architekturentscheidungen) ## Nicht umgesetzte Feature-Ideen (ehemals Specs 009–026) ### 009 – Gästeliste Organisator sieht alle RSVPs (Name, Status) und kann einzelne Einträge löschen. * Nur mit gültigem Organizer-Token sichtbar * Gäste ohne Token sehen keine Gästeliste * Löschung serverseitig validiert ### 010 – Event bearbeiten Organisator kann Titel, Beschreibung, Datum, Ort und Ablaufdatum ändern. * Formular vorausgefüllt mit aktuellen Werten * Ablaufdatum muss in der Zukunft liegen * Ohne Organizer-Token kein Edit-UI sichtbar ### 011 – Event merken/bookmarken Gäste können Events lokal merken, ohne RSVP abzugeben — rein clientseitig via localStorage. * Kein Serverkontakt nötig * Unabhängig vom RSVP-Status * Auch bei abgelaufenen Events möglich ### 012 – Lokale Event-Übersicht Startseite (`/`) zeigt alle getrackten Events (erstellt, zugesagt, gemerkt) aus localStorage. * Zeigt Titel, Datum, Beziehungstyp (Organisator/Gast/Gemerkt) * Vergangene Events als "beendet" markiert * Einträge können entfernt werden ### 013 – Kalender-Export .ics-Download (RFC 5545) mit Event-Details, optional webcal:// für Live-Updates. * Stabile UID aus Event-Token (Re-Import aktualisiert statt dupliziert) * Bei Absage: STATUS:CANCELLED im .ics * Kein externer Kalenderservice kontaktiert ### 014 – Änderungen hervorheben Geänderte Felder werden visuell hervorgehoben, wenn der Gast seit der letzten Änderung nicht mehr auf der Seite war. * Server trackt `last_edited_at` + geänderte Feldnamen * Client speichert `last_seen_at` in localStorage * Privacy-freundlich: kein serverseitiges Read-Tracking ### 015 – Organisator-Updates Organisator kann Textnachrichten im Event posten (Pinnwand-Stil). * Chronologisch sortiert, löschbar durch Organisator * Nach Ablauf kein Posting mehr möglich * Ohne Organizer-Token kein Compose-UI ### 016 – Gast-Benachrichtigungen Badge/Indikator bei ungelesenen Organisator-Updates, rein clientseitig via localStorage. * Eigener Timestamp `updates_last_seen_at` (getrennt von Feld-Änderungen) * Kein Indikator beim ersten Besuch * Kein serverseitiges Tracking (Privacy) ### 017 – QR-Code Event-Seite zeigt QR-Code mit der öffentlichen Event-URL. * Serverseitig generiert (kein externer QR-Service) * Download als SVG oder hochauflösendes PNG * Auch bei abgelaufenen Events verfügbar ### 018 – Datenlöschung Automatische Löschung aller Event-Daten nach Ablaufdatum (Privacy-Garantie). * Scheduled Job oder Lazy Cleanup bei Zugriff * Löscht Event, RSVPs, Updates, Bilder, Metadaten * Idempotent, kein PII im Log ### 019 – Instanz-Limit `MAX_ACTIVE_EVENTS` als Env-Variable begrenzt aktive Events für Self-Hoster. * Nur nicht-abgelaufene Events zählen * Unset/leer = unbegrenzt * Serverseitige Durchsetzung bei Event-Erstellung ### 020 – PWA Web App Manifest + Service Worker für Installierbarkeit und Offline-Caching. * Standalone-Modus ohne Browser-Chrome * Icon + Name auf Home-Screen * Alle Assets selbstgehostet ### 021 – Farbthemen Organisator wählt bei Erstellung ein vordefiniertes Farbthema für die Event-Seite. * Nur auf der Gast-Seite angewendet (nicht global) * Änderbar beim Bearbeiten * Unabhängig von Dark/Light Mode ### 022 – Headerbild Organisator sucht Headerbild über integrierte Unsplash-Suche. * Serverseitig geproxied (Client kontaktiert nie Unsplash) * Bild lokal gespeichert + Unsplash-Attribution * Feature deaktiviert wenn kein API-Key konfiguriert ### 023 – Dark Mode App erkennt `prefers-color-scheme` und bietet manuellen Toggle. * Manuelle Auswahl in localStorage gespeichert * Gilt für globales App-Chrome, nicht Event-Farbthemen * Beide Modi WCAG AA konform ### 024 – Event absagen Organisator kann Event absagen (mit optionaler Nachricht, Einweg-Transition). * RSVPs werden nach Absage abgelehnt * Absage-Nachricht nachträglich editierbar * Kann nicht rückgängig gemacht werden * Wenn Organisator Event auf der Eventlistenseite löscht, muss dabei das Event abgesagt werden (nicht nur lokal entfernen) ### 025 – Event löschen Organisator löscht Event permanent und unwiderruflich. * Entfernt alle zugehörigen Daten sofort * localStorage-Eintrag wird entfernt, Redirect zu `/` * Funktioniert in jedem Event-Status ### 026 – 404-Seite Catch-all Route für ungültige Pfade mit "Seite nicht gefunden" und Link zur Startseite. * Folgt dem Design System (Electric Dusk + Sora) * WCAG AA konform * Verhindert leere Seiten bei Fehlnavigation