# Umsetzungsplan API- und DB-Anbindung Version: `0.5.0` Status: Hybrid-MVP weitgehend umgesetzt. Remote-User speichern Events, Settings und Bilder ueber die API; der lokale Demo-User bleibt browserlokal und startet leer. ## Ziel Die Quasar-App soll zwei bewusst getrennte Speicherwege unterstuetzen: - **Remote/API-User**: `user1@thats-me.app` bis `user6@thats-me.app`, Passwort `pass`. Diese User speichern Events, Timeline-Einstellungen und Bilder serverseitig ueber die Laravel-API. - **Lokaler Demo-User**: `Demo`. Dieser User startet leer und speichert weiterhin ausschliesslich im Browser Storage. Seine Daten werden nicht an die API uebertragen und sind nicht global oder fuer AI/API-Prozesse sichtbar. Der erste Umsetzungsstand soll praesentationstaugliche Backend-User ermoeglichen, ohne den lokalen Testmodus zu entfernen. ## Grundregeln - Remote-User werden immer ueber Laravel authentifiziert. - Lokale Demo-Daten bleiben privat im Browser und verlassen das Geraet nicht. - Backend-Abfragen werden immer ueber den authentifizierten User eingeschraenkt. - Bilder von Remote-Usern werden serverseitig gespeichert und usergebunden ausgeliefert. - `client_id` bleibt die stabile Frontend-ID fuer Events und dient spaeter als Sync-Bruecke. - IndexedDB bleibt fuer lokale Demo-Daten und optionalen Cache erhalten, ist fuer Remote-User aber nicht die fuehrende Datenquelle. ## Aktueller Umsetzungsstand Stand: 2026-06-03 Abgeschlossen: - **Phase 1 Backend-Basis**: Laravel-API, Passport, Demo-API-User und geschuetzte Endpunkte sind vorbereitet. - **Phase 2 API-Login**: Quasar kann `user1@thats-me.app` bis `user6@thats-me.app` ueber die API anmelden; Tokens werden im Frontend zentral verwaltet. - **Phase 3 Hybrid-Auth**: Es gibt einen festen lokalen `Demo`-User ohne API-Login. Dieser startet leer und schreibt keine API-SyncQueue-Eintraege. - **Phase 4 Remote-Events**: Remote-Events werden direkt per API erstellt, geladen, aktualisiert und geloescht. - **Phase 5 Remote-Settings**: Timeline-, App- und LifeWave-Settings werden pro Remote-User serverseitig als JSON gespeichert. - **Phase 6 Serverseitige Bilder**: Event-Bilder und Settings-Hintergrundbilder werden fuer Remote-User serverseitig gespeichert, optimiert und geschuetzt ausgeliefert. Noch offen: - **Phase 7 Praesentationsdaten**: Struktur und Inhalte fuer kontrollierte Beispiel-/Praesentationsdaten pro API-User. - **Phase 8 Abschlussdokumentation**: API-Vertrag, Datenmodell und Security-Checkliste koennen auf Basis der jetzigen Umsetzung finalisiert werden. Wichtige technische Entscheidungen: - Remote-User nutzen die Laravel-API als fuehrende Datenquelle. - Lokale Demo-Daten bleiben in IndexedDB/localStorage und werden nicht an die API gesendet. - Geschuetzte Bilder werden im Frontend per Bearer Token geladen und als Blob-URL angezeigt. - Event-Bilder haben drei Varianten: - Timeline/Dot-Thumbnail: 320x320px, quadratisch gecroppt. - Event-Panel/Preview: maximal 900px laengste Kante, JPEG-Qualitaet 84. - Original/Download-Basis: maximal 3508px laengste Kante, JPEG-Qualitaet 90. - Settings-Hintergrundbilder werden separat pro User gespeichert: maximal 1600px laengste Kante, JPEG-Qualitaet 86. Wichtige Dokumentationsquelle: - `migration-log.md` enthaelt die chronologische Umsetzung mit geaenderten Dateien, Tests und QA-Hinweisen. ## Phase 1: Backend-Basis Pruefen Und Vorbereiten Ziel: Die bestehende Laravel-API lauffaehig, migriert und fuer API-User nutzbar machen. Status: Abgeschlossen. Umgesetzt: - `user1` bis `user6` werden idempotent ueber den Database Seeder angelegt. - Alle sechs API-User nutzen das Passwort `pass`. - Ein Passport Personal Access Client fuer den `users` Provider wird bei Bedarf idempotent angelegt. - API-Endpunkte sind ohne Token geschuetzt. - CORS wurde fuer die Quasar-App-Origin konfiguriert. Aufgaben: - Migrationen fuer `users`, Passport-Tabellen und `events` pruefen und ausfuehren. - Sicherstellen, dass Passport fuer API-Token in der lokalen Umgebung funktioniert. - Demo-Seeder fuer `user1` bis `user6` anlegen oder erweitern. - Passwort fuer alle sechs API-User auf `pass` setzen. - Bestehenden Test-User nicht als Praesentationsuser verwenden. - CORS/API-Erreichbarkeit von `app.thats-me.test` nach `api.thats-me.test` pruefen. Akzeptanzkriterien: - `user1` bis `user6` existieren in der Datenbank. - Jeder User kann serverseitig authentifiziert werden. - `/api/user` liefert mit Token den passenden User. - Ohne Token sind API-Endpunkte geschuetzt. Tests/Dokumentation: - Feature-Test fuer API-Login. - Feature-Test fuer geschuetzten Zugriff ohne Token. - Dokumentieren, welche Seeder und Migrations ausgefuehrt wurden. ## Phase 2: API-Login Fuer Quasar Ziel: Die Quasar-App kann Remote-User ueber die Laravel-API anmelden. Status: Abgeschlossen. Umgesetzt: - `POST /api/login` validiert Laravel-User und erstellt Passport Bearer Tokens. - `POST /api/logout` widerruft den aktuellen Token. - Frontend nutzt `src/services/apiClient.js` als zentralen API-Client. - Token-Ablage erfolgt in IndexedDB `meta.accessToken`. - Login-Fehler werden auf der Login-Seite verstaendlich angezeigt. - Bei `app.thats-me.test` wird automatisch `https://api.thats-me.test/api` als API-Basis genutzt, sofern `VITE_API_BASE` nicht gesetzt ist. - Bei Live-Hosts unter `thats-me.app` wird automatisch `https://api.thats-me.app/api` als API-Basis genutzt. Aufgaben: - `POST /api/login` implementieren. - `POST /api/logout` implementieren. - Response-Struktur fuer Login festlegen: Token, User-ID, Name, E-Mail, Storage-Modus `remote`. - Frontend-API-Client fuer authentifizierte Requests anlegen. - Token-Ablage im Frontend festlegen und konsistent nutzen. - Fehlertexte fuer falsche Zugangsdaten sauber zur Login-Seite durchreichen. Akzeptanzkriterien: - Login mit `user1@thats-me.app` und `pass` funktioniert. - Falsches Passwort liefert einen klaren Fehler. - Logout entfernt den Token im Frontend. - Router erkennt Remote-Login als authentifiziert. Tests/Dokumentation: - Feature-Test fuer erfolgreichen Login. - Feature-Test fuer falsche Zugangsdaten. - Manuelle QA: Login, Reload, Logout. ## Phase 3: Hybrid-Auth Im Frontend Ziel: Frontend unterscheidet klar zwischen lokalem Demo-Modus und Remote-Usern. Status: Abgeschlossen und manuell bestaetigt. Umgesetzt: - Fester lokaler User `Demo` mit `mode: local`. - `Demo` benoetigt kein Passwort. - `Demo` startet leer und seeded keine 500 Beispiel-Events mehr. - Lokale User-Erstellung wurde entfernt. - Remote-User-Liste enthaelt `user1` bis `user6`. - Lokale Demo-Events bleiben in IndexedDB und werden nicht in die SyncQueue geschrieben. - Wechsel zwischen Demo und Remote-Usern ist ueber `userId`/`mode` getrennt. Aufgaben: - Auth-Store um `mode: 'local' | 'remote'` erweitern. - Lokalen User `Demo` definieren. - `Demo` startet leer und nutzt Browser Storage. - Remote-User-Liste fuer `user1` bis `user6` anzeigen. - Lokale User-Erstellung per Plus-Button entfernen oder durch "Lokalen Demo-Modus starten" ersetzen. - Router-Guard auf lokalen und remote Auth-Modus anpassen. Akzeptanzkriterien: - `Demo` kann ohne API gestartet werden. - `Demo` startet ohne automatisch generierte 500 Events. - `user1` bis `user6` laufen ueber API-Login. - Wechsel zwischen Demo und Remote-Usern vermischt keine Daten. Tests/Dokumentation: - Frontend-Lint ausfuehren. - Manuelle QA: Demo starten, Event anlegen, Reload, Daten bleiben lokal. - Manuelle QA: Remote-User einloggen, Reload, Token/Auth bleibt konsistent. ## Phase 4: Events Remote Persistieren Ziel: Events von Remote-Usern werden in der Datenbank gespeichert und aus der API geladen. Status: Abgeschlossen. Umgesetzt: - Remote-Events werden beim Login/Reload ueber `GET /api/events` geladen. - Create/Update/Delete fuer Remote-Events laufen direkt ueber `POST`, `PUT` und `DELETE` gegen die Event-API. - Events sind serverseitig ueber den authentifizierten User isoliert. - Frontend haelt Remote-Events nur als lokalen Cache in IndexedDB. - Lokaler Demo-User bleibt browserlokal. Aufgaben: - Bestehende `events`-Tabelle mit Frontend-Modell abgleichen. - Fehlende Felder ergaenzen: mindestens `location`, `key_image_title`; Medien zunaechst ueber eigene Medientabelle. - Event-Requests und `EventResource` erweitern. - Vorhandene Event-API gegen User-Isolation testen. - Frontend-Events-Store ueber Storage-Schicht anbinden: - `local`: Dexie wie bisher. - `remote`: Laravel API. - Create, Update, Delete fuer Remote-Events direkt an API senden. - Lokale SyncQueue fuer Remote-User nur als spaetere Retry-/Offline-Schicht behandeln. Akzeptanzkriterien: - Remote-User sieht nach Reload seine Events wieder. - Andere Remote-User sehen diese Events nicht. - Lokaler `Demo`-User bleibt vollstaendig browserlokal. - Event-Felder aus dem aktuellen Panel bleiben erhalten. Tests/Dokumentation: - Feature-Tests fuer Event CRUD. - Feature-Test fuer Fremdzugriff zwischen Usern. - Manuelle QA mit `user1` und `user2`. ## Phase 5: Timeline-Settings Remote Speichern Ziel: Timeline- und App-Einstellungen werden fuer Remote-User serverseitig gespeichert. Status: Abgeschlossen. Umgesetzt: - Tabelle `user_settings` speichert ein JSON-Dokument pro User. - `GET /api/settings` und `PUT /api/settings` sind usergebunden hinter `auth:api`. - Gespeichert werden u.a. Appearance, Accent Color, Sprache, LifeWave/Floating-Lines, Emotion-Gradient, Timeline-Zoom, Timeline-Scroll, Presets, aktives Preset und `showFps`. - Remote-Settings werden beim Userwechsel aus der API geladen und lokal nur gecacht. - Lokaler Demo-User nutzt weiterhin `localStorage`. Aufgaben: - Tabelle `user_settings` anlegen. - Model und Beziehung zu `User` ergaenzen. - Endpunkte anlegen: - `GET /api/settings` - `PUT /api/settings` - Settings als JSON speichern, inklusive Timeline-Zoom, Scroll-Position, Floating-Lines, Farben, Sprache, Presets und aktivem Preset. - Settings-Store ueber Storage-Schicht anbinden: - `local`: `localStorage`. - `remote`: API. Akzeptanzkriterien: - Remote-User behaelt Timeline-Settings nach Reload und Geraetewechsel. - Lokaler `Demo`-User behaelt Settings nur im Browser. - Settings anderer User sind nicht lesbar. Tests/Dokumentation: - Feature-Test fuer GET/PUT Settings. - Feature-Test fuer User-Isolation. - Manuelle QA: Settings aendern, Reload, anderer User pruefen. ## Phase 6: Serverseitige Bilder Fuer Remote-User Ziel: Bilder von Remote-Events werden serverseitig gespeichert und sicher usergebunden ausgeliefert. Status: Abgeschlossen fuer Event-Bilder und Settings-Hintergrundbilder. Umgesetzt: - Tabelle `event_media` speichert Event-Medien user- und eventgebunden. - Upload, Liste, Anzeige und Loeschen von Event-Medien sind implementiert. - Event-Bilder werden als Thumbnail, Preview und Original-Variante erzeugt. - Key Images liegen in der Collection `key_image`, Galerie-Bilder in `gallery`. - Geschuetzte Event-Bildrouten pruefen `event_media.user_id` gegen den authentifizierten User. - Frontend laedt geschuetzte Bild-URLs mit Bearer Token als Blob. - Settings-Hintergrundbilder werden ueber eigene Endpunkte gespeichert: - `POST /api/settings/media/background` - `GET /api/settings/media/background` - `DELETE /api/settings/media/background` - Lokaler Demo-User speichert Bilder weiterhin lokal bzw. als Browser-Daten. Aufgaben: - Tabelle `event_media` anlegen. - Model, Factory und Beziehung zu `User` und `Event` anlegen. - Geschuetzten Storage-Bereich definieren. - Upload-Endpunkt anlegen: `POST /api/events/{event}/media`. - Medienliste laden: `GET /api/events/{event}/media`. - Medien loeschen: `DELETE /api/events/{event}/media/{media}`. - Auslieferung pruefen: - Thumbnail/Preview, falls vorhanden. - Original nur nach Auth-Pruefung. - Frontend-EventPanel fuer Remote-User auf Upload umstellen. - Lokaler `Demo`-User speichert Bilder weiter lokal. Akzeptanzkriterien: - Remote-User kann Bild zu Event hochladen. - Bild ist nach Reload wieder sichtbar. - Andere User koennen das Bild nicht abrufen. - Lokaler Demo-Modus funktioniert unveraendert lokal. Tests/Dokumentation: - Feature-Test fuer Upload. - Feature-Test fuer Fremdzugriff auf Medien. - Feature-Test fuer Loeschen. - Dokumentieren, wo Dateien gespeichert werden und welche Limits gelten. ## Phase 7: Praesentationsdaten Fuer API-User Ziel: Die sechs API-User koennen gezielt mit Beispielinhalten fuer Praesentationen befuellt werden. Status: Offen, naechster sinnvoller Umsetzungsschritt. Aufgaben: - Entscheiden, welche Beispiel-Events pro User angelegt werden. - Seeder fuer Praesentationsdaten vorbereiten. - Bilder entweder als Fixture-Dateien oder ueber dokumentierten Upload-Prozess einspielen. - Sicherstellen, dass `Demo` leer bleibt. - AI/API-Zugriff konzeptionell dokumentieren: welche Endpunkte laden Userdaten, welche Auth ist noetig. Akzeptanzkriterien: - `user1` bis `user6` haben kontrollierte Praesentationsdaten. - Beispielbilder sind serverseitig vorhanden. - Lokaler Demo-Modus bleibt leer und privat. Tests/Dokumentation: - Seeder-Ausfuehrung dokumentieren. - Manuelle QA pro User. - Liste der Praesentationsdaten pflegen. Empfohlene Umsetzung: 1. Kleine Datendefinition fuer Praesentationsdaten erstellen, z.B. `backend/database/seeders/PresentationDataSeeder.php` plus strukturierte Arrays. 2. Pro User entscheiden, ob er leer bleibt oder eine eigene Story bekommt: - `user1`: Standard-Praesentation mit wenigen Events. - `user2`: Bildlastige Galerie-Demo. - `user3`: Settings-/LifeWave-Demo. - `user4` bis `user6`: Reserve oder alternative Stories. 3. Seeder idempotent bauen: - Events ueber stabile `client_id` upserten. - Medien nicht doppelt anlegen. - Settings pro User per `updateOrCreate` setzen. 4. Beispielbilder entweder als Fixture-Dateien in einem dokumentierten Ordner ablegen oder bewusst ueber die App hochladen. 5. Nach dem Seed pro User manuell pruefen: - Login. - Timeline sichtbar. - Event-Panel oeffnet. - Bilder laden als Thumbnail/Preview. - Settings werden korrekt angewendet. Wichtig: - `Demo` darf durch den Seeder nicht veraendert werden. - Praesentationsdaten sollten wiederholbar eingespielt werden koennen, ohne Dubletten zu erzeugen. - Fuer echte Praesentationen sollten keine zufaelligen `crypto.randomUUID()` IDs verwendet werden, sondern stabile `client_id` Werte aus der Datendefinition. ## Phase 8: Dokumentation Und Abschluss Pro Umsetzungsschritt Ziel: Jeder Schritt bleibt nachvollziehbar und kann spaeter fortgesetzt werden. Pflicht pro Umsetzungsschritt: - Datum und Version. - Geaenderte Dateien. - Betroffene Tabellen. - Betroffene API-Endpunkte. - Sicherheitsregel: Wie wurde User-Isolation geprueft? - Ausgefuehrte Tests. - Manuelle QA. - Offene Punkte. Empfohlene Dokumente in diesem Ordner: - `README.md`: Zielbild und Gesamtuebersicht. - `implementation-plan.md`: dieser abarbeitbare Plan. - `api-contract.md`: konkrete Request-/Response-Strukturen. - `data-model.md`: Tabellen, Relationen und Felder. - `migration-log.md`: chronologische Umsetzungsschritte. - `security-checklist.md`: Auth, User-Isolation und Medienzugriff. ## Aktuelle Offene Entscheidungen - Ob die aktuellen Upload-Limits dauerhaft reichen: aktuell 10 MB pro Bild. - Ob die erlaubten Bildtypen `jpg`, `jpeg`, `png`, `webp` fuer den MVP ausreichen. - Ob Praesentationsdaten per Seeder oder ueber ein Admin-/Import-Skript gepflegt werden. - Wie der spaetere AI-Zugriff authentifiziert wird. - Ob fuer groessere Medienverarbeitung spaeter Queue-Jobs statt synchroner Verarbeitung eingesetzt werden. - Ob alte, lokal gespeicherte Remote-Daten aktiv migriert oder bewusst ignoriert werden. ## Naechster Konkreter Schritt Mit Phase 7 starten: 1. Inhaltliche Rollen fuer `user1` bis `user6` festlegen. 2. Datensatzstruktur fuer Praesentationsdaten definieren. 3. Idempotenten `PresentationDataSeeder` vorbereiten. 4. Optional Fixture-Bilder festlegen. 5. Seeder lokal ausfuehren und pro User manuell pruefen. ## Arbeitsnotizen Fuer Fortsetzung Relevante Frontend-Dateien: - `frontend/src/stores/auth.js`: Remote-User, Demo-User, Login/Logout, Token-Handling. - `frontend/src/stores/events.js`: lokale Demo-Events und Remote-Event-API-Anbindung. - `frontend/src/stores/settings.js`: lokale und remote Settings-Persistenz. - `frontend/src/components/EventPanel.vue`: Event-Bild-Upload und Galerie. - `frontend/src/components/LifeWaveSettings.vue`: Settings-Hintergrundbild-Upload. - `frontend/src/composables/useImageCache.js`: geschuetzte Bildpfade als Blob laden. Relevante Backend-Dateien: - `backend/routes/api.php`: API-Routen. - `backend/app/Http/Controllers/Api/AuthController.php`: Login/Logout. - `backend/app/Http/Controllers/Api/EventController.php`: Event-CRUD und Sync. - `backend/app/Http/Controllers/Api/EventMediaController.php`: Event-Medien. - `backend/app/Http/Controllers/Api/SettingsController.php`: Settings JSON. - `backend/app/Http/Controllers/Api/SettingsMediaController.php`: Settings-Hintergrundbilder. - `backend/app/Services/EventMediaImageProcessor.php`: Bildvarianten fuer Event-Medien. - `backend/database/seeders/DatabaseSeeder.php`: API-User und Passport Client. Relevante Tests: - `backend/tests/Feature/Api/AuthTest.php` - `backend/tests/Feature/Api/EventTest.php` - `backend/tests/Feature/Api/EventMediaTest.php` - `backend/tests/Feature/Api/SettingsTest.php` Empfohlene Checks nach Aenderungen: ```bash cd backend vendor/bin/pint --dirty --format agent php artisan test --compact tests/Feature/Api/AuthTest.php tests/Feature/Api/EventTest.php tests/Feature/Api/EventMediaTest.php tests/Feature/Api/SettingsTest.php cd ../frontend npm run lint ```