feat: implement tenant OAuth flow and guest achievements
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# 07 — Guest PWA
|
||||
# 07 — Guest PWA
|
||||
|
||||
Goal
|
||||
- Delight guests with a frictionless, installable photo experience that works offline, respects privacy, and requires no account.
|
||||
@@ -7,13 +7,13 @@ Non-Goals (MVP)
|
||||
- No comments or chat. No facial recognition. No public profiles. No videos.
|
||||
|
||||
Personas
|
||||
- Guest (attendee) — scans QR, uploads photos, browses and likes.
|
||||
- Host (tenant) — optionally shares event PIN with guests; moderates via Tenant Admin PWA.
|
||||
- Guest (attendee) — scans QR, uploads photos, browses and likes.
|
||||
- Host (tenant) — optionally shares event PIN with guests; moderates via Tenant Admin PWA.
|
||||
|
||||
Top Journeys
|
||||
- Join: Scan QR → Open event → Accept terms → Optional PIN → Land on Gallery.
|
||||
- Upload: Add photos → Review → Submit → Background upload → Success/Retry.
|
||||
- Browse: Infinite gallery → Filter (emotion/task) → Open photo → Like/Share → Back.
|
||||
- Join: Scan QR → Open event → Accept terms → Optional PIN → Land on Gallery.
|
||||
- Upload: Add photos → Review → Submit → Background upload → Success/Retry.
|
||||
- Browse: Infinite gallery → Filter (emotion/task) → Open photo → Like/Share → Back.
|
||||
|
||||
Core Features
|
||||
- Event access
|
||||
@@ -25,14 +25,14 @@ Core Features
|
||||
- Capture & upload
|
||||
- Choose from camera or library; limit file size; show remaining upload cap.
|
||||
- Client-side resize to sane max (e.g., 2560px longest edge); EXIF stripped client-side if available.
|
||||
- Assign optional emotion/task before submit; default to “Uncategorized”.
|
||||
- Assign optional emotion/task before submit; default to “Uncategorizedâ€.
|
||||
- Gallery
|
||||
- Masonry grid, lazy-load, pull-to-refresh; open photo lightbox with swipe.
|
||||
- Like (heart) with optimistic UI; share system sheet (URL to CDN variant).
|
||||
- Filters: emotion, featured, mine (local-only tag for items uploaded from this device).
|
||||
- Safety & abuse controls
|
||||
- Rate limits per device and IP; content-length checks; mime/type sniffing.
|
||||
- Upload moderation state: pending → approved/hidden; show local status.
|
||||
- Upload moderation state: pending → approved/hidden; show local status.
|
||||
- Privacy & legal
|
||||
- First run shows legal links (imprint/privacy); consent for push if enabled.
|
||||
- No PII stored; guest name is optional free text and not required by default.
|
||||
@@ -44,7 +44,7 @@ Screens
|
||||
- Upload Picker: camera/library, selection preview, emotion/task tagging.
|
||||
- Upload Queue: items with progress, retry, remove; background sync toggle.
|
||||
- Photo Lightbox: zoom, like, share; show emotion tags.
|
||||
- Settings: language, theme (system), clear cache, legal pages.
|
||||
- Settings Sheet: Gear-Icon im Header oeffnet eine Sheet-Ansicht mit editierbarem Gastnamen, eingebetteten Rechtsdokumenten (inkl. Zurueck-Navigation) und Cache-Leeren; Theme-Umschalter bleibt im Header.
|
||||
|
||||
Wireframes
|
||||
- See wireframes file at docs/wireframes/guest-pwa.md for low-fidelity layouts and flows.
|
||||
@@ -55,28 +55,27 @@ Core Pages (Pflichtseiten)
|
||||
- UI: Single input (QR deep link preferred, fallback PIN field) and Join button.
|
||||
- States: invalid/expired token, event closed, offline (allow PIN entry and queue attempt).
|
||||
- Profil-Setup (Name/Avatar)
|
||||
- Purpose: Optional personalization for likes/attribution.
|
||||
- UI: Name text field, optional avatar picker; one-time before first entry to event.
|
||||
- Behavior: Skippable; editable later in Settings.
|
||||
- Purpose: Optional personalisation fuer Likes/Statistiken; Name wird lokal im Browser gespeichert.
|
||||
- UI: Name-Feld mit Sofort-Validierung; Avatar folgt spaeter.
|
||||
- Behavior: Nicht verpflichtend, aber empfohlen; Name kann jederzeit im Settings Sheet angepasst oder geloescht werden.
|
||||
- Startseite (Home/Feed)
|
||||
- Purpose: Central hub; show event title/subheadline and CTAs.
|
||||
- Header: Event name + subheadline (e.g., “Dein Fotospiel zur Hochzeit”).
|
||||
- Info bar: “X Gäste online • Y Aufgaben gelöst”.
|
||||
- CTAs: „Aufgabe ziehen“ (random), „Wie fühlst du dich?“ (emotion picker), small link “Einfach ein Foto machen”.
|
||||
- Content: Gallery/Feed with photos + likes.
|
||||
- Purpose: Central hub; begruesst Gaeste mit ihrem hinterlegten Namen und fuehrt zu den wichtigsten Aktionen.
|
||||
- Header: Eventtitel plus Live-Kennzahlen (online Gaeste, geloeste Aufgaben); hero-card zeigt "Hey {Name}!".
|
||||
- Highlights: Drei CTA-Karten fuer Aufgabe ziehen, Direkt-Upload und Galerie sowie ein Button fuer die Upload-Warteschlange.
|
||||
- Content: EmotionPicker und GalleryPreview bilden weiterhin den Einstieg in Spielstimmung und aktuelle Fotos.
|
||||
- Aufgaben-Flow
|
||||
- Aufgaben-Picker: Choose random task or emotion mood.
|
||||
- Aufgaben-Detail (Karte): Task text, emoji tag, estimated duration, suggested group size; actions: take photo, new task (same mood), change mood.
|
||||
- Foto-Interaktion
|
||||
- Kamera/Upload: Capture or pick; progress + success message on completion; background sync.
|
||||
- Galerie/Übersicht: Grid/Feed; filters: Neueste, Beliebt, Meine; Like hearts.
|
||||
- Galerie/Übersicht: Grid/Feed; filters: Neueste, Beliebt, Meine; Like hearts.
|
||||
- Foto-Detailansicht: Fullscreen; likes/reactions; linked task + (optional) uploader name.
|
||||
- Motivation & Spiel
|
||||
- Achievements/Erfolge: Badges (e.g., Erstes Foto, 5 Aufgaben, Beliebtestes Foto); personal progress.
|
||||
- Optionale Ergänzungen
|
||||
- Slideshow/Präsentationsmodus: Auto-rotating gallery for TV/Beamer with likes/task overlay.
|
||||
- Onboarding: 1–2 “So funktioniert das Spiel” hints the first time.
|
||||
- Event-Abschluss: “Danke fürs Mitmachen”, summary stats, link/QR to online gallery.
|
||||
- Optionale Ergänzungen
|
||||
- Slideshow/Präsentationsmodus: Auto-rotating gallery for TV/Beamer with likes/task overlay.
|
||||
- Onboarding: 1–2 “So funktioniert das Spiel†hints the first time.
|
||||
- Event-Abschluss: “Danke fürs Mitmachenâ€, summary stats, link/QR to online gallery.
|
||||
|
||||
Technical Notes
|
||||
- Installability: PWA manifest + service worker; prompt A2HS on supported browsers.
|
||||
@@ -84,15 +83,15 @@ Technical Notes
|
||||
- Background Sync: use Background Sync API when available; fallback to retry on app open.
|
||||
- Accessibility: large tap targets, high contrast, keyboard support, reduced motion.
|
||||
- i18n: default `de`, fallback `en`; all strings in locale files; RTL not in MVP.
|
||||
- Media types: Photos only (no videos) — decision locked for MVP and v1.
|
||||
- Media types: Photos only (no videos) — decision locked for MVP and v1.
|
||||
- Realtime model: periodic polling (no WebSockets). Home counters every 10s; gallery delta every 30s with exponential backoff when tab hidden or offline.
|
||||
|
||||
API Touchpoints
|
||||
- GET `/api/v1/events/{slug}` — public event metadata (when open) + theme.
|
||||
- GET `/api/v1/events/{slug}/photos` — paginated gallery (approved only).
|
||||
- POST `/api/v1/events/{slug}/photos` — signed upload initiation; returns URL + fields.
|
||||
- POST (S3) — direct upload to object storage; then backend finalize call.
|
||||
- POST `/api/v1/photos/{id}/like` — idempotent like with device token.
|
||||
- GET `/api/v1/events/{slug}` — public event metadata (when open) + theme.
|
||||
- GET `/api/v1/events/{slug}/photos` — paginated gallery (approved only).
|
||||
- POST `/api/v1/events/{slug}/photos` — signed upload initiation; returns URL + fields.
|
||||
- POST (S3) — direct upload to object storage; then backend finalize call.
|
||||
- POST `/api/v1/photos/{id}/like` — idempotent like with device token.
|
||||
|
||||
Limits (MVP defaults)
|
||||
- Max uploads per device per event: 50
|
||||
@@ -100,10 +99,10 @@ Limits (MVP defaults)
|
||||
- Max resolution: 2560px longest edge per photo
|
||||
|
||||
Edge Cases
|
||||
- Token expired/invalid → Show “Event closed/invalid link”; link to retry.
|
||||
- No connectivity → Queue actions; show badge; retry policy with backoff.
|
||||
- Storage full → Offer to clear cache or deselect files.
|
||||
- Permission denied (camera/photos) → Explain and offer system shortcut.
|
||||
- Token expired/invalid → Show “Event closed/invalid linkâ€; link to retry.
|
||||
- No connectivity → Queue actions; show badge; retry policy with backoff.
|
||||
- Storage full → Offer to clear cache or deselect files.
|
||||
- Permission denied (camera/photos) → Explain and offer system shortcut.
|
||||
|
||||
Decisions
|
||||
- Videos are not supported (capture/upload strictly photos).
|
||||
|
||||
Reference in New Issue
Block a user