thats-me/frontend/dev/db-api-connect/migration-log.md

469 lines
19 KiB
Markdown

# Migration Log
## 2026-06-05 - Live-Deployment API-Login
Status: Live-Login gegen `https://api.thats-me.app` erfolgreich hergestellt.
### Problem
- Das Live-Frontend lief zuerst gegen eine falsche API-Basisadresse.
- Korrekte API-Basis ist `https://api.thats-me.app/api`.
- Danach blockierte CORS Requests von `https://thats-me.app`.
- Nach dem CORS-Fix kam der Request bis Laravel durch, scheiterte aber mit `Invalid key supplied` beim Passport-Token.
### Ursache
- `frontend/src/services/apiClient.js` normalisierte bisher nur `https://api.thats-me.test` automatisch auf `/api`.
- `backend/config/cors.php` erlaubte nur lokale `.test`- und localhost-Origins.
- Auf dem Live-Server fehlten bzw. griffen keine gueltigen Laravel-Passport-Keys fuer `createToken()`.
### Umsetzung
- `frontend/src/services/apiClient.js` nutzt fuer Live-Hosts unter `thats-me.app` automatisch `https://api.thats-me.app/api`.
- `VITE_API_BASE=https://api.thats-me.app` wird automatisch zu `https://api.thats-me.app/api` normalisiert.
- `backend/config/cors.php` erlaubt zusaetzlich:
- `https://thats-me.app`
- `https://www.thats-me.app`
- `https://app.thats-me.app`
- Auf dem Live-Server wurden Passport-Keys/Config korrigiert, danach war der Login erfolgreich.
### Live-Kommandos
```bash
php artisan passport:keys --force
php artisan db:seed --class=DatabaseSeeder --no-interaction
php artisan optimize:clear
php artisan config:cache
```
### Pruefung
- Browser-Login im Live-Frontend gegen `https://api.thats-me.app/api/login` funktioniert.
- CORS-Fehler fuer `https://thats-me.app` ist behoben.
- Passport-Fehler `Invalid key supplied` ist behoben.
## 2026-06-03 - Phase 3 Hybrid-Auth Demo-Modus
Version: `0.2.1`
Status: Abgeschlossen fuer festen lokalen Demo-User ohne API-Sync.
### Geaenderte Dateien
- `frontend/src/pages/LoginPage.vue`
- `frontend/src/stores/auth.js`
- `frontend/src/stores/events.js`
- `frontend/dev/db-api-connect/migration-log.md`
### Umsetzung
- Es gibt jetzt einen festen lokalen User `Demo` mit `mode: local`.
- Die Login-Auswahl zeigt `Demo` zusaetzlich zu den sechs API-Usern.
- Fuer `Demo` ist kein Passwort noetig; der Login-Button zeigt `Demo lokal starten`.
- Lokale User-Erstellung und lokale `userN@thats-me.app`-Custom-User wurden aus der Auth-Liste entfernt.
- `Demo` startet leer und seeded keine Beispiel-Events mehr.
- Lokale Demo-Events bleiben in IndexedDB, werden aber nicht mehr in die lokale SyncQueue geschrieben.
- Remote-User `user1` bis `user6` bleiben unveraendert API-basiert.
### Sicherheitsregel
Der Demo-Modus verwendet keinen API-Login und keinen Bearer Token. Events im Demo-Modus bleiben browserlokal in IndexedDB und werden nicht als API-Sync-Auftrag vorgemerkt.
### Ausgefuehrte Kommandos
```bash
npm run lint
```
### Testergebnis
- `npm run lint`: erfolgreich.
### Manuelle QA
- Noch nicht im Browser durchgeklickt.
- Erwartete QA: `Demo` auswaehlen, ohne Passwort starten, leere Timeline sehen, Event anlegen, Reload pruefen. Danach mit `user1@thats-me.app` einloggen und sicherstellen, dass keine Demo-Events sichtbar sind.
## 2026-06-03 - Nachtrag Settings-Hintergrundbilder
Status: Abgeschlossen fuer serverseitige Settings-Hintergrundbilder bei Remote-Usern.
### Geaenderte Dateien
- `backend/app/Http/Controllers/Api/SettingsMediaController.php`
- `backend/app/Http/Requests/StoreSettingsMediaRequest.php`
- `backend/routes/api.php`
- `backend/tests/Feature/Api/SettingsTest.php`
- `frontend/src/components/LifeWaveSettings.vue`
- `frontend/src/composables/useImageCache.js`
- `frontend/src/layouts/LifeWaveLayout.vue`
- `frontend/src/stores/settings.js`
- `frontend/dev/db-api-connect/migration-log.md`
### Betroffene API-Endpunkte
- `POST /api/settings/media/background`
- `GET /api/settings/media/background`
- `DELETE /api/settings/media/background`
### Umsetzung
- Remote-User laden eigene LifeWave-Hintergrundbilder nicht mehr als Data-URL in das Settings-JSON.
- Der Backend-Endpunkt speichert pro User ein optimiertes JPEG unter dem privaten `local` Disk.
- Hintergrundbilder werden auf maximal 1600px laengste Kante und JPEG-Qualitaet 86 reduziert.
- Die Settings speichern nur den geschuetzten Pfad `/settings/media/background`.
- Das Frontend laedt geschuetzte Settings-Bilder wie Event-Medien per Bearer Token als Blob und verwendet die Blob-URL als CSS-Hintergrund.
- Der lokale Demo-/Browser-Modus nutzt weiterhin die bestehende Data-URL-Komprimierung im Browser.
### Sicherheitsregel
Alle Settings-Medienrouten liegen hinter `auth:api`. Dateien werden usergebunden unter `settings-media/{userId}/background.jpg` gespeichert und nur fuer den authentifizierten User ausgeliefert.
### Ausgefuehrte Kommandos
```bash
vendor/bin/pint --dirty --format agent
php artisan test --compact tests/Feature/Api/SettingsTest.php
npm run lint
```
### Testergebnis
- `tests/Feature/Api/SettingsTest.php`: 8 Tests, 32 Assertions, erfolgreich.
- `npm run lint`: erfolgreich.
## 2026-06-03 - Phase 6 Serverseitige Bilder Fuer Remote-User
Version: `0.4.0`
Status: Abgeschlossen fuer serverseitige Remote-Eventbilder, Thumbnail-Erzeugung und geschuetzte Auslieferung.
### Geaenderte Dateien
- `backend/app/Http/Controllers/Api/EventController.php`
- `backend/app/Http/Controllers/Api/EventMediaController.php`
- `backend/app/Http/Requests/StoreEventMediaRequest.php`
- `backend/app/Http/Resources/EventMediaResource.php`
- `backend/app/Http/Resources/EventResource.php`
- `backend/app/Models/Event.php`
- `backend/app/Models/EventMedia.php`
- `backend/app/Services/EventMediaImageProcessor.php`
- `backend/config/cors.php`
- `backend/database/factories/EventMediaFactory.php`
- `backend/database/migrations/2026_06_03_131801_create_event_media_table.php`
- `backend/database/migrations/2026_06_03_133403_add_preview_paths_to_event_media_table.php`
- `backend/routes/api.php`
- `backend/tests/Feature/Api/EventMediaTest.php`
- `frontend/src/components/EventPanel.vue`
- `frontend/src/composables/useImageCache.js`
- `frontend/src/stores/events.js`
- `frontend/dev/db-api-connect/migration-log.md`
### Betroffene Tabellen
- `event_media`
- `events`
- `users`
### Betroffene API-Endpunkte
- `GET /api/events/{event}/media`
- `POST /api/events/{event}/media`
- `DELETE /api/events/{event}/media/{media}`
- `GET /api/event-media/{media}/thumb`
- `GET /api/event-media/{media}/preview`
- `GET /api/event-media/{media}/original`
- `GET /api/events`
### Umsetzung
- Remote-Bilder werden auf dem Laravel-Server unter dem privaten `local` Disk gespeichert.
- Uploads werden user- und eventgebunden in `event_media` abgelegt.
- Server erzeugt drei JPEG-Varianten: 320px Thumbnail fuer Timeline/Dots, 900px Preview fuer Event-Panel/Galerie und ein Original mit maximal 3508px laengster Kante fuer A4 bei 300 DPI.
- Key Images verwenden die Collection `key_image`; weitere Bilder verwenden `gallery`.
- Beim Ersetzen eines Key Images wird das alte Key Image inklusive Dateien entfernt.
- Geschuetzte Bildauslieferung prueft den authentifizierten User gegen `event_media.user_id`.
- Event-API liefert Medien-Metadaten mit `thumbnailUrl` und `originalUrl`.
- Frontend-Remote-Uploads gehen direkt an `/api/events/{id}/media`.
- Frontend laedt geschuetzte Bildpfade mit Bearer Token als Blob und verwendet lokale Blob-URLs fuer `<img>`.
- Timeline/Dots nutzen `thumbnailUrl`, Event-Panel und Galerie nutzen `previewUrl`, ein spaeterer Download kann `originalUrl` verwenden.
- Fuer Medien, die vor der Preview-Variante hochgeladen wurden, faellt `/preview` auf das vorhandene Thumbnail zurueck.
- Leere Medienpfade werden beim Loeschen ignoriert, damit Altbestaende ohne Preview-Datei keine 500er ausloesen.
- CORS ist fuer `https://app.thats-me.test` und lokale App-Dev-Origins explizit konfiguriert.
- Lokale Demo-/Browser-Bilder bleiben unveraendert als lokale Data-URLs.
### Sicherheitsregel
Alle Medienrouten liegen hinter `auth:api`. Event-Medien werden nur ueber Events des authentifizierten Users angelegt, gelesen oder geloescht. Direkter Zugriff auf fremde `event_media` IDs liefert `404`.
### Ausgefuehrte Kommandos
```bash
vendor/bin/pint --dirty --format agent
php artisan optimize:clear
php artisan test --compact tests/Feature/Api/EventMediaTest.php
php artisan migrate --no-interaction
npm run lint
php artisan test --compact tests/Feature/Api/EventMediaTest.php tests/Feature/Api/EventTest.php tests/Feature/Api/AuthTest.php tests/Feature/Api/SettingsTest.php
php artisan migrate:status
```
### Testergebnis
- `tests/Feature/Api/EventMediaTest.php`: 9 Tests, erfolgreich.
- API-Feature-Tests: 33 Tests, 133 Assertions, erfolgreich.
- `npm run lint`: erfolgreich.
- `php artisan migrate:status`: `2026_06_03_131801_create_event_media_table` ist in Batch 2 ausgefuehrt.
### Manuelle QA
- Noch nicht im Browser vollstaendig durchgeklickt.
- Erwartete QA: Remote-User einloggen, Key Image hochladen, Galerie-Bild hochladen, Seite neu laden, zweiten Browser mit gleichem User oeffnen, Thumbnail und Original in Galerie pruefen, Bild loeschen und DB/Storage pruefen.
### Offene Punkte
- Thumbnail-Groesse und JPEG-Qualitaet sind aktuell feste MVP-Werte.
- Originalbilder werden aktuell mit JPEG-Qualitaet 90 gespeichert.
- Previewbilder werden aktuell mit maximal 900px laengster Kante und JPEG-Qualitaet 84 gespeichert.
- Spaeter koennen Queue-Jobs fuer groessere Medienverarbeitung und weitere Varianten ergaenzt werden.
- Upload-Limit ist aktuell 10 MB pro Bild.
## 2026-06-03 - Phase 5 Timeline-Settings Remote Speichern
Version: `0.3.0`
Status: Abgeschlossen fuer Remote-Settings von API-Usern.
### Geaenderte Dateien
- `backend/app/Http/Controllers/Api/SettingsController.php`
- `backend/app/Http/Requests/UpdateSettingsRequest.php`
- `backend/app/Models/User.php`
- `backend/app/Models/UserSetting.php`
- `backend/database/factories/UserSettingFactory.php`
- `backend/database/migrations/2026_06_03_130123_create_user_settings_table.php`
- `backend/routes/api.php`
- `backend/tests/Feature/Api/SettingsTest.php`
- `frontend/src/stores/settings.js`
- `frontend/dev/db-api-connect/migration-log.md`
### Betroffene Tabellen
- `user_settings`
- `users`
### Betroffene API-Endpunkte
- `GET /api/settings`
- `PUT /api/settings`
### Umsetzung
- Pro User wird ein JSON-Dokument in `user_settings.settings` gespeichert.
- `GET /api/settings` liefert die Settings des authentifizierten Users oder `null`.
- `PUT /api/settings` erstellt oder aktualisiert die Settings des authentifizierten Users.
- Frontend-Remote-User laden Settings beim Userwechsel/Login aus der API.
- Frontend-Remote-User speichern Settings per API und halten `localStorage` nur als lokalen Cache.
- Lokale Demo-/Browser-User bleiben auf `localStorage`.
- Gespeichert werden unter anderem Appearance, Accent Color, Sprache, Floating-Lines, Emotion-Gradient, Timeline-Zoom, Timeline-Scroll, Presets, aktives Preset und `showFps`.
### Sicherheitsregel
Die Settings-Routen liegen hinter `auth:api`. Der Controller greift ausschliesslich ueber `$request->user()->settings()` auf Daten zu, dadurch sind Settings anderer User weder lesbar noch ueberschreibbar.
### Ausgefuehrte Kommandos
```bash
vendor/bin/pint --dirty --format agent
php artisan optimize:clear
php artisan test --compact tests/Feature/Api/SettingsTest.php
php artisan migrate --no-interaction
php artisan migrate:status
npm run lint
php artisan test --compact tests/Feature/Api/SettingsTest.php tests/Feature/Api/AuthTest.php tests/Feature/Api/EventTest.php
```
### Testergebnis
- `tests/Feature/Api/SettingsTest.php`: 5 Tests, 19 Assertions, erfolgreich.
- `tests/Feature/Api/SettingsTest.php tests/Feature/Api/AuthTest.php tests/Feature/Api/EventTest.php`: 24 Tests, 97 Assertions, erfolgreich.
- `npm run lint`: erfolgreich.
- `php artisan migrate:status`: `2026_06_03_130123_create_user_settings_table` ist ausgefuehrt.
### Manuelle QA
- Noch nicht im Browser gegen zwei Browserprofile durchgeklickt.
- Erwartete QA: mit API-User einloggen, Appearance/Accent/Floating-Lines/Timeline-Zoom aendern, in zweitem Browser mit gleichem User einloggen und Settings pruefen.
### Offene Punkte
- Serverseitige Bilder fuer Remote-User folgen in Phase 6.
- Der lokale `Demo`-User als sauber getrennter Browser-only Modus bleibt fuer Phase 3 noch offen.
## 2026-06-03 - Phase 2 API-Login Fuer Quasar
Version: `0.2.0`
Status: Abgeschlossen fuer Backend-Login, Logout, Token-Ablage im Frontend und Remote-User-Auswahl im Login.
### Geaenderte Dateien
- `backend/app/Http/Controllers/Api/AuthController.php`
- `backend/app/Http/Requests/LoginRequest.php`
- `backend/database/seeders/DatabaseSeeder.php`
- `backend/routes/api.php`
- `backend/tests/Feature/Api/AuthTest.php`
- `frontend/src/pages/LoginPage.vue`
- `frontend/package.json`
- `frontend/src/router/index.js`
- `frontend/src/services/apiClient.js`
- `frontend/src/services/syncService.js`
- `frontend/src/stores/auth.js`
- `frontend/dev/db-api-connect/migration-log.md`
### Betroffene Tabellen
- `users`
- `oauth_clients`
- `oauth_access_tokens`
### Betroffene API-Endpunkte
- `POST /api/login`
- `POST /api/logout`
- `GET /api/user`
### Umsetzung
- `POST /api/login` validiert E-Mail und Passwort gegen Laravel-User.
- Erfolgreicher Login erzeugt einen Passport Personal Access Token fuer die Quasar-App.
- Login-Response liefert Token, Token-Typ und Userdaten mit `mode: remote`.
- `POST /api/logout` widerruft den aktuellen Token.
- `DatabaseSeeder` legt zusaetzlich einen Passport Personal-Access-Client fuer den `users` Provider an, falls noch keiner existiert.
- Frontend hat mit `src/services/apiClient.js` einen zentralen API-Client inklusive Token-Ablage in IndexedDB `meta.accessToken`.
- `syncService` nutzt denselben API-Client und vermeidet dadurch doppelte Token-Logik.
- `auth` Store fuehrt `user1@thats-me.app` bis `user6@thats-me.app` als Remote-User.
- Login-Seite nutzt async API-Login, zeigt die sechs API-Accounts und entfernt den sichtbaren User-Anlegen-Button.
- Router erkennt gespeicherte Remote-Auth nach Reload ueber die persistierte Auth-Struktur.
- Frontend-Lint-Script nutzt den funktionierenden `src/**/*.{js,cjs,mjs,vue}` Glob.
### Sicherheitsregel
Falsche Zugangsdaten liefern Validierungsfehler ohne Token. Geschuetzte Endpunkte bleiben hinter `auth:api`; Logout widerruft den Bearer Token serverseitig.
### Ausgefuehrte Kommandos
```bash
vendor/bin/pint --dirty --format agent
php artisan test --compact tests/Feature/Api/AuthTest.php
php artisan test --compact tests/Feature/Api/AuthTest.php tests/Feature/Api/EventTest.php
php artisan db:seed --class=DatabaseSeeder --no-interaction
npm run lint
```
### Testergebnis
- `tests/Feature/Api/AuthTest.php`: 7 Tests, 43 Assertions, erfolgreich.
- `tests/Feature/Api/AuthTest.php tests/Feature/Api/EventTest.php`: 19 Tests, 78 Assertions, erfolgreich.
- `npm run lint`: erfolgreich.
### Manuelle QA
- Browser-Login wurde noch nicht manuell durchgeklickt.
- Der Backend-Seed wurde gegen die lokale Datenbank erneut ausgefuehrt.
### Offene Punkte
- Phase 3 fuehrt den lokalen `Demo`-User sauber als getrennten Browser-only Modus ein.
- Phase 4 stellt die Event-Persistenz fuer Remote-User von lokaler Dexie-Fuehrung auf API-Fuehrung um.
### Nachtrag 2026-06-03
- `frontend/src/services/apiClient.js` nutzt bei `app.thats-me.test` ohne explizites `VITE_API_BASE` automatisch `https://api.thats-me.test/api`.
- `frontend/src/services/apiClient.js` nutzt bei Live-Hosts unter `thats-me.app` automatisch `https://api.thats-me.app/api`.
- Damit laufen Login-Requests nicht mehr versehentlich gegen den Quasar-Devserver-Pfad `/api`.
- `VITE_API_BASE=https://api.thats-me.test` und `VITE_API_BASE=https://api.thats-me.app` werden automatisch um `/api` ergaenzt.
- `backend/config/cors.php` erlaubt fuer Live zusaetzlich `https://thats-me.app`, `https://www.thats-me.app` und `https://app.thats-me.app`.
- Im Dev-Modus wird die vollstaendige API-Request-URL mit `API request: ...` in die Browser-Konsole geschrieben.
- `frontend/src/stores/auth.js` loggt Remote-Login-Fehler zusaetzlich in der Browser-Konsole.
- Geprueft mit `npm run lint` und `php artisan test --compact tests/Feature/Api/AuthTest.php`.
### Nachtrag Remote-Events 2026-06-03
- `frontend/src/stores/events.js` laedt Events fuer Remote-User beim Login direkt ueber `GET /api/events`.
- Remote-Create, Remote-Update und Remote-Delete laufen fuer API-User jetzt direkt ueber `POST /api/events`, `PUT /api/events/{id}` und `DELETE /api/events/{id}`.
- IndexedDB bleibt fuer Remote-User nur Cache; fuehrend ist die API.
- Neue Browser laden vorhandene Remote-Events direkt aus der Datenbank.
- Geprueft mit `npm run lint` und `php artisan test --compact tests/Feature/Api/EventTest.php tests/Feature/Api/AuthTest.php`.
## 2026-06-03 - Phase 1 Backend-Basis
Version: `0.1.0`
Status: Abgeschlossen fuer Backend-Basis, Demo-API-User und geschuetzte API-Pruefungen.
### Geaenderte Dateien
- `backend/database/seeders/DatabaseSeeder.php`
- `backend/tests/Feature/Api/AuthTest.php`
- `frontend/dev/db-api-connect/migration-log.md`
### Betroffene Tabellen
- `users`
- `events`
- `oauth_auth_codes`
- `oauth_access_tokens`
- `oauth_refresh_tokens`
- `oauth_clients`
- `oauth_device_codes`
- `cache`
- `jobs`
- `sessions`
- `password_reset_tokens`
### Betroffene API-Endpunkte
- `GET /api/user`
- `GET /api/events`
### Umsetzung
- Lokale MySQL-Datenbank `thats-me` wurde angelegt, falls sie noch nicht vorhanden war.
- Alle vorhandenen Backend-Migrationen wurden ausgefuehrt.
- `DatabaseSeeder` wurde idempotent gemacht.
- `user1@thats-me.app` bis `user6@thats-me.app` werden mit Passwort `pass` angelegt oder aktualisiert.
- Der bestehende `test@example.com` bleibt als separater Test-User erhalten und wird nicht als Praesentationsuser verwendet.
- Feature-Tests pruefen geschuetzten API-Zugriff ohne Token, Rueckgabe des authentifizierten Users und die Seeder-User inklusive Passwort.
### Sicherheitsregel
Die geschuetzten API-Routen liegen weiterhin hinter `auth:api`. Ohne Token liefern `GET /api/user` und `GET /api/events` einen unauthorisierten Status. Mit Passport-Testauthentifizierung liefert `GET /api/user` nur den authentifizierten User.
### Ausgefuehrte Kommandos
```bash
vendor/bin/pint --dirty --format agent
php artisan test --compact tests/Feature/Api/AuthTest.php
php artisan test --compact tests/Feature/Api
php artisan migrate --no-interaction
php artisan db:seed --class=DatabaseSeeder --no-interaction
php artisan migrate:status
```
### Testergebnis
- `tests/Feature/Api/AuthTest.php`: 4 Tests, 24 Assertions, erfolgreich.
- `tests/Feature/Api`: 16 Tests, 59 Assertions, erfolgreich.
- `php artisan migrate:status`: alle vorhandenen Migrationen in Batch 1 ausgefuehrt.
### Manuelle QA
- Nicht im Browser geprueft, da Phase 1 noch keine Frontend-Anbindung enthaelt.
- CORS/API-Erreichbarkeit von `app.thats-me.test` nach `api.thats-me.test` bleibt fuer Phase 2/3 offen, sobald die Login-Route und der Frontend-Client angebunden werden.
### Offene Punkte
- Echte Login-/Logout-Endpunkte fuer Quasar folgen in Phase 2.
- Token-Erzeugung fuer das Frontend wird in Phase 2 finalisiert.
- Frontend-Demo-Modus und Remote-User-Auswahl folgen in Phase 3.