298 lines
4.2 KiB
Markdown
298 lines
4.2 KiB
Markdown
💍 Wedding App – Svenja & Dominic
|
||
|
||
Eine private, moderne Hochzeits-Webanwendung für eingeladene Gäste.
|
||
|
||
Die Anwendung ermöglicht eine geschützte Registrierung, RSVP-Verwaltung, Foto-Uploads sowie den Zugriff auf alle relevanten Informationen rund um die Hochzeit – in einem eleganten, mobilen Design.
|
||
|
||
🎯 Projektziel
|
||
|
||
Die Wedding-App soll:
|
||
|
||
unter dem Link https://www.svenja-dominic-hochzeit.de/ zum login führen.
|
||
|
||
Gästen einen passwortgeschützten Zugang bieten
|
||
|
||
Zu- und Absagen verwalten (inkl. Begleitperson)
|
||
|
||
eine gemeinsame Fotogalerie bereitstellen
|
||
|
||
Informationen zur Location, Hotels in der Nähe, Taxi und Ablauf anzeigen
|
||
|
||
eine eingebettete Google Maps Karte enthalten
|
||
|
||
einen prominenten Link zur offiziellen Website der Hochzeitslocation anzeigen
|
||
|
||
Einen Switch auf Englisch haben.
|
||
|
||
Die Seite soll modern, ästhetisch und mobil optimiert sein.
|
||
|
||
🎨 Design-Anforderung (WICHTIG)
|
||
|
||
Die Anwendung soll:
|
||
|
||
modern, elegant und hochwertig wirken
|
||
|
||
mobil-first entwickelt werden
|
||
|
||
viel Weißraum verwenden
|
||
|
||
runde Karten mit sanften Schatten nutzen
|
||
|
||
eine konsistente Farbpalette haben (z. B. Beige, Creme, Dunkelgrün, Gold-Akzente)
|
||
|
||
klare Typografie verwenden (z. B. Google Fonts)
|
||
|
||
dezente Hover-Animationen besitzen
|
||
|
||
Seitenstruktur
|
||
|
||
Mindestens folgende Seiten müssen umgesetzt werden:
|
||
|
||
Login / Landing Page (mit Hero-Section)
|
||
|
||
Dashboard
|
||
|
||
RSVP-Bereich
|
||
|
||
Upload-Seite
|
||
|
||
Galerie
|
||
|
||
Informationsseiten:
|
||
|
||
Ablauf
|
||
|
||
Hotels
|
||
|
||
Taxi
|
||
|
||
Location
|
||
|
||
🗺 Location-Seite Anforderungen
|
||
|
||
Die Location-Seite muss enthalten:
|
||
|
||
Google Maps Embed (iframe)
|
||
|
||
Name der Location
|
||
|
||
Adresse
|
||
|
||
Einen deutlich sichtbaren Button:
|
||
|
||
„Zur Location-Webseite“
|
||
|
||
Dieser Button muss:
|
||
|
||
in neuem Tab öffnen (target="_blank")
|
||
|
||
rel="noopener" verwenden
|
||
|
||
URL aus Environment Variable beziehen
|
||
|
||
Konfigurierbare Variablen:
|
||
|
||
LOCATION_NAME
|
||
|
||
LOCATION_ADDRESS
|
||
|
||
LOCATION_WEBSITE_URL
|
||
|
||
GOOGLE_MAPS_EMBED_URL
|
||
|
||
🔐 Login & Registrierung
|
||
|
||
Zugriff nur mit Event-Passwort
|
||
|
||
Passwort wird als Environment Variable gespeichert:
|
||
|
||
EVENT_PASSWORD
|
||
|
||
Registrierung:
|
||
|
||
Gast gibt Event-Passwort ein
|
||
|
||
Gast gibt seinen Namen ein
|
||
|
||
Nach erfolgreicher Prüfung → Weiterleitung zum Dashboard
|
||
|
||
Session-basiert (Flask Sessions)
|
||
|
||
Keine E-Mail-Verifikation
|
||
Kein Rollen-System
|
||
Keine öffentliche Registrierung
|
||
|
||
|
||
📝 RSVP-System
|
||
|
||
Im Dashboard kann der Gast auswählen:
|
||
|
||
Ich komme
|
||
|
||
Ich komme nicht
|
||
|
||
Ich bringe eine Begleitperson mit (nur wenn attending = true)
|
||
|
||
Daten werden persistent in der Datenbank gespeichert.
|
||
|
||
📸 Foto-Upload
|
||
|
||
Erlaubte Formate: jpg, jpeg, png
|
||
|
||
Dateigröße begrenzen (konfigurierbar)
|
||
|
||
Speicherung in /uploads
|
||
|
||
Dateinamen müssen sanitisiert werden
|
||
|
||
Path Traversal verhindern
|
||
|
||
Upload wird in Datenbank referenziert
|
||
|
||
🖼 Galerie
|
||
|
||
Alle Gäste sehen alle Bilder
|
||
|
||
Responsive Grid
|
||
|
||
Optional: einfache Modal-Ansicht bei Klick
|
||
|
||
🧱 Datenbank (SQLite)
|
||
Tabelle: guests
|
||
|
||
id (Primary Key)
|
||
|
||
name (String, required)
|
||
|
||
attending (Boolean, nullable)
|
||
|
||
plus_one (Boolean, default False)
|
||
|
||
created_at (Timestamp)
|
||
|
||
Tabelle: uploads
|
||
|
||
id (Primary Key)
|
||
|
||
filename
|
||
|
||
uploaded_by (Guest ID)
|
||
|
||
uploaded_at (Timestamp)
|
||
|
||
🧪 Entwicklungsphasen
|
||
Phase 1 – MVP
|
||
|
||
Authentifizierung
|
||
|
||
Datenbank
|
||
|
||
RSVP
|
||
|
||
Phase 2
|
||
|
||
Upload
|
||
|
||
Galerie
|
||
|
||
Phase 3
|
||
|
||
Informationsseiten
|
||
|
||
Location + Google Maps
|
||
|
||
Externer Location-Link
|
||
|
||
Phase 4
|
||
|
||
UI-Feinschliff
|
||
|
||
Sicherheitsverbesserungen
|
||
|
||
🧰 Technischer Stack
|
||
|
||
Python 3.12
|
||
|
||
Flask
|
||
|
||
Gunicorn
|
||
|
||
uv (Dependency Management)
|
||
|
||
SQLite
|
||
|
||
Docker
|
||
|
||
Docker Compose
|
||
|
||
Optional: Nginx + Certbot (Production)
|
||
|
||
📦 Dependency Management
|
||
|
||
Keine requirements.txt
|
||
|
||
Nutzung von uv
|
||
|
||
Abhängigkeiten in pyproject.toml
|
||
|
||
uv.lock wird committed
|
||
|
||
Docker nutzt:
|
||
|
||
uv sync --frozen --no-dev
|
||
|
||
🐳 Docker Anforderungen
|
||
|
||
Base Image: python:3.12-slim
|
||
|
||
uv im Container installiert
|
||
|
||
Gunicorn als Produktionsserver
|
||
|
||
Persistente Volumes für:
|
||
|
||
uploads
|
||
|
||
SQLite-Datenbank
|
||
|
||
Startbefehl:
|
||
|
||
uv run gunicorn -b 0.0.0.0:8000 app:app
|
||
|
||
🔒 Sicherheitsanforderungen
|
||
|
||
Event-Passwort darf niemals im Frontend erscheinen
|
||
|
||
Upload-Dateitypen validieren
|
||
|
||
Dateigröße limitieren
|
||
|
||
HTTPS verpflichtend im Produktivbetrieb
|
||
|
||
Keine unnötigen Features implementieren
|
||
|
||
❌ Nicht-Ziele
|
||
|
||
Kein Admin-Panel
|
||
|
||
Keine E-Mail-Funktion
|
||
|
||
Kein Payment
|
||
|
||
Kein OAuth
|
||
|
||
Keine Cloud-Storage-Integration
|
||
|
||
Keine Microservices
|
||
|
||
💡 Design-Philosophie
|
||
|
||
Schön vor komplex
|
||
|
||
Einfach vor überengineered
|
||
|
||
Wartbar vor clever
|
||
|
||
Modern, aber nicht verspielt
|
||
|
||
Mobil optimiert |