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