thats-me/frontend/dev/db-api-connect/implementation-plan.md

428 lines
17 KiB
Markdown

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