APP als Hybrid Version - Anbindung an API
This commit is contained in:
parent
d054732bf5
commit
c1514999be
46 changed files with 3418 additions and 196 deletions
303
frontend/dev/db-api-connect/README.md
Normal file
303
frontend/dev/db-api-connect/README.md
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
# Entwicklungsplan DB/API-Anbindung
|
||||
|
||||
Version: `0.0.1`
|
||||
|
||||
Status: Konzept und Umsetzungsplan fuer die Anbindung der Quasar-App an das Laravel-Backend mit MySQL.
|
||||
|
||||
## Zielbild
|
||||
|
||||
Die App soll nicht mehr primaer auf browserlokaler Persistenz basieren. Laravel mit MySQL wird die fuehrende Datenquelle fuer User, Settings, Events, Presets und Medien. IndexedDB und `localStorage` duerfen spaeter weiter als Cache und Offline-Schicht genutzt werden, aber nicht als alleinige Wahrheit.
|
||||
|
||||
Das System geht konsequent vom eingeloggten User aus:
|
||||
|
||||
- Jeder User besitzt eigene Settings.
|
||||
- Jeder User besitzt eigene Timeline-Daten.
|
||||
- Jeder User besitzt eigene Events.
|
||||
- Jeder User besitzt eigene Medien, Images, Presets und spaeter Videos, Audios und Texte.
|
||||
- Kein User darf Medien, Events oder Settings eines anderen Users direkt oder indirekt lesen.
|
||||
- Teilen und Veröffentlichen wird spaeter bewusst als eigener Rechte- und Freigabeprozess umgesetzt.
|
||||
|
||||
## Versionsregel
|
||||
|
||||
Die aktuelle App-Version ist `0.0.1`.
|
||||
|
||||
Bei jeder weiteren Entwicklungsrunde muessen folgende Stellen mitgefuehrt werden:
|
||||
|
||||
- `frontend/package.json`
|
||||
- `frontend/src/config/appVersion.js`
|
||||
- `frontend/README.md`
|
||||
- dieses Planungsdokument, sofern sich Architektur, Datenmodell oder API-Verhalten aendern
|
||||
- spaetere Release Notes oder Migrationsdokumente
|
||||
|
||||
Versionen in der `0.x`-Phase duerfen Breaking Changes enthalten. Jede Aenderung am Datenmodell oder an API-Kontrakten muss trotzdem dokumentiert werden.
|
||||
|
||||
## Grundentscheidung
|
||||
|
||||
Wir verwenden direkt MySQL im Laravel-Backend. SQLite wird nicht als Zielsystem genutzt, weil die Anwendung mehrere Benutzer, geschuetzte Medien, Sync und spaetere Sharing-/Invite-Funktionen benoetigt. MySQL passt besser zu dauerhaftem Betrieb, Indizes, Relationen und wachsendem Medien-Metadatenbestand.
|
||||
|
||||
## Sicherheitsprinzip
|
||||
|
||||
Die Datenhoheit liegt beim User. Alle API-Abfragen muessen serverseitig ueber den authentifizierten User eingeschraenkt werden. Das Frontend darf keine fremden IDs als Vertrauensbasis liefern.
|
||||
|
||||
Regeln:
|
||||
|
||||
- Jede userbezogene Tabelle enthaelt `user_id`.
|
||||
- API-Controller filtern immer ueber `$request->user()`.
|
||||
- Policies pruefen Zugriff auf Events, Medien, Presets und Settings.
|
||||
- Storage-Pfade enthalten keine erratbaren oeffentlichen URLs.
|
||||
- Originalmedien werden nicht aus einem public disk ausgeliefert.
|
||||
- Medien werden ueber autorisierte Backend-Routen oder signierte, kurzlebige URLs bereitgestellt.
|
||||
- Thumbnails duerfen ebenfalls nur nach Berechtigungspruefung ausgeliefert werden.
|
||||
|
||||
## Datenmodell
|
||||
|
||||
Bestehende Basis:
|
||||
|
||||
- `users` existiert bereits.
|
||||
- `events` existiert bereits und hat bereits `user_id`.
|
||||
|
||||
Geplante Erweiterungen:
|
||||
|
||||
- `user_settings`
|
||||
- `user_id`
|
||||
- `settings` als JSON
|
||||
- `timeline_zoom`
|
||||
- `timeline_scroll_left`
|
||||
- `active_preset_id`
|
||||
- Timestamps
|
||||
|
||||
- `setting_presets`
|
||||
- `user_id`
|
||||
- `name`
|
||||
- `settings` als JSON
|
||||
- `is_public` fuer spaeteres Veröffentlichen von reinen Timeline-/Visual-Presets
|
||||
- Timestamps
|
||||
|
||||
- `events`
|
||||
- weiterhin strikt usergebunden
|
||||
- Erweiterung um Felder aus dem aktuellen Frontend, z. B. Key-Image-Titel, Farbdaten, Notizen und spaetere Event-Metadaten
|
||||
- `client_id` bleibt wichtig fuer Offline-/Sync-Kompatibilitaet
|
||||
|
||||
- `event_media`
|
||||
- `user_id`
|
||||
- `event_id`
|
||||
- `type`: image, video, audio, text
|
||||
- `title`
|
||||
- `original_path`
|
||||
- `thumbnail_path`
|
||||
- `mime_type`
|
||||
- `size`
|
||||
- `width`
|
||||
- `height`
|
||||
- `duration`
|
||||
- `sort_order`
|
||||
- `metadata` als JSON
|
||||
- Timestamps
|
||||
|
||||
- `event_media_variants`
|
||||
- optional spaeter, wenn mehrere Bildgroessen benoetigt werden
|
||||
- z. B. thumbnail, preview, original
|
||||
|
||||
- `timeline_shares`
|
||||
- spaeter
|
||||
- Einladung oder Share-Link fuer eine komplette Timeline
|
||||
- getrennt von Preset-Sharing
|
||||
- eigene Berechtigungen und Ablaufdaten
|
||||
|
||||
## Medienkonzept
|
||||
|
||||
Medien werden nicht als Data-URL in der Datenbank gespeichert. Die Datenbank speichert nur Metadaten und Storage-Pfade.
|
||||
|
||||
Upload-Ablauf:
|
||||
|
||||
1. Frontend laedt Datei an Laravel hoch.
|
||||
2. Backend validiert User, Dateityp und Groesse.
|
||||
3. Backend speichert Originaldatei in einem geschuetzten Storage-Bereich.
|
||||
4. Backend erzeugt Thumbnail oder Preview.
|
||||
5. Backend speichert Metadaten in `event_media`.
|
||||
6. API gibt Media-Objekt mit Thumbnail-Endpunkt zurueck.
|
||||
|
||||
Performance-Regel:
|
||||
|
||||
- Timeline und Event-Panel laden zuerst nur Thumbnails.
|
||||
- Originaldateien werden erst bei grosser Betrachtung oder Download geladen.
|
||||
- Videos und Audios bekommen spaeter eigene Preview-/Poster-Strategien.
|
||||
- Texte werden spaeter als eigener Media-Typ behandelt, nicht als Bilderspezialfall.
|
||||
|
||||
## API-Konzept
|
||||
|
||||
Geplante API-Gruppen unter `/api`:
|
||||
|
||||
- Auth
|
||||
- Login
|
||||
- Logout
|
||||
- aktueller User
|
||||
|
||||
- Settings
|
||||
- `GET /settings`
|
||||
- `PUT /settings`
|
||||
|
||||
- Presets
|
||||
- `GET /setting-presets`
|
||||
- `POST /setting-presets`
|
||||
- `PUT /setting-presets/{preset}`
|
||||
- `DELETE /setting-presets/{preset}`
|
||||
- spaeter: `POST /setting-presets/{preset}/publish`
|
||||
|
||||
- Events
|
||||
- `GET /events`
|
||||
- `POST /events`
|
||||
- `GET /events/{event}`
|
||||
- `PUT /events/{event}`
|
||||
- `DELETE /events/{event}`
|
||||
- `POST /events/sync`
|
||||
|
||||
- Event-Medien
|
||||
- `GET /events/{event}/media`
|
||||
- `POST /events/{event}/media`
|
||||
- `PUT /events/{event}/media/{media}`
|
||||
- `DELETE /events/{event}/media/{media}`
|
||||
- `GET /media/{media}/thumbnail`
|
||||
- `GET /media/{media}/original`
|
||||
|
||||
Alle Endpunkte muessen authentifiziert sein. Jeder Zugriff auf `{event}`, `{media}` oder `{preset}` muss serverseitig gegen `user_id` abgesichert werden.
|
||||
|
||||
## Frontend-Migration
|
||||
|
||||
Aktueller Zustand:
|
||||
|
||||
- Auth liegt in `localStorage`.
|
||||
- Zusaetzlich angelegte lokale Test-User liegen in `localStorage` unter `thatsme-users`.
|
||||
- Settings liegen in `localStorage`.
|
||||
- Events, SyncQueue und Medien liegen in IndexedDB.
|
||||
|
||||
Zwischenstand in Version `0.0.1`:
|
||||
|
||||
- Die urspruenglichen Demo-User `user1` bis `user5` behalten ihre bestehenden lokalen Daten.
|
||||
- Neue lokale User koennen auf der Login-Seite ueber den Plus-Button angelegt werden.
|
||||
- Neue lokale User starten mit leerer Timeline und bekommen keine automatisch generierten Test-Events.
|
||||
- Diese lokale User-Verwaltung ist nur eine Uebergangsloesung bis zur Laravel/MySQL-Auth.
|
||||
|
||||
Zielzustand:
|
||||
|
||||
- Auth laeuft ueber Laravel API.
|
||||
- Settings werden nach Login vom Backend geladen.
|
||||
- Events werden vom Backend geladen und im Store gehalten.
|
||||
- IndexedDB bleibt als Cache und optionale Offline-Queue.
|
||||
- Medien werden als Backend-URLs/IDs verwaltet, nicht mehr als Data-URLs im Event.
|
||||
|
||||
Schrittweise Migration:
|
||||
|
||||
1. API-Client im Frontend anlegen.
|
||||
2. Auth-Store auf Backend-Login vorbereiten.
|
||||
3. Settings-Store mit Backend-Laden/Speichern erweitern.
|
||||
4. Events-Store auf Backend-CRUD umstellen.
|
||||
5. Media-Upload ueber Backend einbauen.
|
||||
6. IndexedDB als Cache neu definieren und nicht mehr als Primaerspeicher behandeln.
|
||||
7. SyncQueue mit Server-Status und Konfliktregeln ueberarbeiten.
|
||||
|
||||
## Konflikt- und Sync-Regeln
|
||||
|
||||
Da spaeter Offline-Faehigkeit weiter sinnvoll ist, bleibt `client_id` wichtig.
|
||||
|
||||
Regeln:
|
||||
|
||||
- Jeder lokal erzeugte Datensatz bekommt eine stabile `client_id`.
|
||||
- Backend antwortet mit Server-ID und `updated_at`.
|
||||
- Bei Updates wird `updated_at` fuer Konflikterkennung genutzt.
|
||||
- Bei Medien wird Upload nicht stillschweigend ueberschrieben.
|
||||
- Konflikte werden spaeter sichtbar gemacht, nicht automatisch fremd geloest.
|
||||
|
||||
## Sharing spaeter
|
||||
|
||||
Preset-Sharing und Timeline-Sharing werden getrennt.
|
||||
|
||||
Preset-Sharing:
|
||||
|
||||
- Nur visuelle Timeline-/LifeWave-Einstellungen.
|
||||
- Keine Events.
|
||||
- Keine Medien.
|
||||
- Keine personenbezogenen Inhalte.
|
||||
|
||||
Timeline-Sharing:
|
||||
|
||||
- Spaeter ueber Einladung, Token oder freigegebene Empfaenger.
|
||||
- Enthält Settings, Events und Medien nur im explizit freigegebenen Umfang.
|
||||
- Zugriff muss widerrufbar sein.
|
||||
- Keine oeffentlichen, erratbaren Medienlinks.
|
||||
|
||||
## Umsetzungsphasen
|
||||
|
||||
Phase 1: Backend-Datenmodell
|
||||
|
||||
- Bestehende `events`-Tabelle mit aktuellem Frontend-Modell abgleichen.
|
||||
- Migrationen fuer `user_settings`, `setting_presets` und `event_media` erstellen.
|
||||
- Models, Relationships, Factories und Policies anlegen.
|
||||
- Tests fuer User-Isolation erstellen.
|
||||
|
||||
Phase 2: API-Basis
|
||||
|
||||
- API Resources und Form Requests erstellen.
|
||||
- Settings- und Preset-Endpunkte implementieren.
|
||||
- Event-Endpunkte usergesichert vervollstaendigen.
|
||||
- Tests fuer CRUD und Fremdzugriff schreiben.
|
||||
|
||||
Phase 3: Media Storage
|
||||
|
||||
- Geschuetzten Storage-Disk konfigurieren.
|
||||
- Upload-Endpunkte implementieren.
|
||||
- Thumbnail-Erzeugung vorbereiten.
|
||||
- Autorisierte Auslieferung fuer Thumbnail und Original bauen.
|
||||
- Tests fuer Zugriffsschutz und Dateitypen schreiben.
|
||||
|
||||
Phase 4: Frontend-Anbindung
|
||||
|
||||
- API-Service im Frontend erstellen.
|
||||
- Auth-Store an Backend anbinden.
|
||||
- Settings-Store vom Backend laden und speichern.
|
||||
- Events-Store CRUD und Sync an Backend anbinden.
|
||||
- EventPanel-Medienupload auf Server umstellen.
|
||||
|
||||
Phase 5: Migration aus Browserdaten
|
||||
|
||||
- Einmalige Importstrategie fuer lokale Demo-Daten definieren.
|
||||
- Pro User lokale Settings und Events optional zum Backend hochladen.
|
||||
- Danach lokale Daten nur noch als Cache nutzen.
|
||||
|
||||
Phase 6: Dokumentation und Stabilisierung
|
||||
|
||||
- API-Kontrakte dokumentieren.
|
||||
- Datenmodell dokumentieren.
|
||||
- Version aktualisieren.
|
||||
- Manuelle QA-Schritte dokumentieren.
|
||||
- Bekannte Grenzen und Folgeaufgaben festhalten.
|
||||
|
||||
## Dokumentationspflicht pro Schritt
|
||||
|
||||
Jede Umsetzung in diesem Bereich muss dokumentiert werden.
|
||||
|
||||
Pflicht je Schritt:
|
||||
|
||||
- Was wurde geaendert?
|
||||
- Welche Version betrifft es?
|
||||
- Welche Tabellen/API-Endpunkte sind betroffen?
|
||||
- Welche Sicherheitsregel wurde umgesetzt oder geprueft?
|
||||
- Welche Tests wurden ausgefuehrt?
|
||||
- Welche offenen Punkte bleiben?
|
||||
|
||||
Empfohlene Struktur fuer neue Dokumente in diesem Ordner:
|
||||
|
||||
- `README.md`: Gesamtplan und aktueller Stand
|
||||
- `data-model.md`: finale Tabellen und Beziehungen
|
||||
- `api-contract.md`: Request-/Response-Strukturen
|
||||
- `migration-log.md`: chronologische Umsetzungsschritte
|
||||
- `security-checklist.md`: Zugriffsschutz und Storage-Regeln
|
||||
|
||||
## Offene Entscheidungen
|
||||
|
||||
- Welche Laravel-Auth-Variante wird fuer die App final verwendet: vorhandenes Passport-Setup oder eine gezielte API-Token-Strategie?
|
||||
- Welche maximale Upload-Groesse gilt pro Datei und pro User?
|
||||
- Wo werden Originaldateien langfristig gespeichert: lokaler Storage, S3-kompatibel oder Synology C2?
|
||||
- Wann wird echte Offline-Synchronisation wieder aktiviert?
|
||||
- Wie detailliert soll spaeteres Timeline-Sharing steuerbar sein?
|
||||
|
||||
428
frontend/dev/db-api-connect/implementation-plan.md
Normal file
428
frontend/dev/db-api-connect/implementation-plan.md
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
# 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
|
||||
```
|
||||
469
frontend/dev/db-api-connect/migration-log.md
Normal file
469
frontend/dev/db-api-connect/migration-log.md
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue