# 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)
### 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

### 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

### 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

### 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

### 027 - Update der EventListe
* Irgendwie ein update der event liste, wenn man sie betritt oder wenn man mit touch die seite nach unten zieht (hier müssen wir noch überlegen, wie wir mit den verschiedenen update fällen umgehen und wie wir das update überhaupt requesten. Ich meine sowas wie: was ist, wenn das event nicht mehr gefunden wurde?)
