- Migrated to Dexie.js for IndexedDB management - Added optimistic UI for tasting notes with 'Wartet auf Sync' badge - Implemented background caching for tags and buddies - Unified scanning and tasting sync in a global UploadQueue
104 lines
3.7 KiB
Plaintext
104 lines
3.7 KiB
Plaintext
Code-Snippet
|
|
|
|
sequenceDiagram
|
|
autonumber
|
|
participant User
|
|
participant UI as Next.js UI (Optimistic)
|
|
participant IDB as Local DB (Dexie/IndexedDB)
|
|
participant Sync as Sync Worker / Service
|
|
participant SupabaseStorage as Supabase Storage (Images)
|
|
participant SupabaseDB as Supabase Database (Tables)
|
|
|
|
box rgb(33, 37, 41) Offline Phase (Messekeller)
|
|
Note over User, IDB: User hat kein Internet
|
|
User->>UI: Macht Foto & trägt Whisky ein
|
|
UI->>UI: Konvertiert Foto zu Blob/Base64
|
|
UI->>IDB: Speichert "Draft" (Blob + Daten + tasted_at)
|
|
UI->>UI: Generiert lokale Blob-URL
|
|
UI-->>User: Zeigt Eintrag sofort an (Optimistic UI)
|
|
Note right of UI: UI zeigt Status "Wartet auf Sync..."
|
|
end
|
|
|
|
box rgb(13, 17, 23) Online / Sync Phase
|
|
Sync->>Sync: Event: 'online' detected
|
|
Sync->>IDB: Hole alle Items aus 'sync_queue'
|
|
|
|
loop Für jeden Eintrag in Queue
|
|
alt Hat Bild?
|
|
Sync->>SupabaseStorage: Upload Blob (Bucket: 'tastings')
|
|
activate SupabaseStorage
|
|
SupabaseStorage-->>Sync: Return Public Public URL
|
|
deactivate SupabaseStorage
|
|
else Kein Bild
|
|
Sync->>Sync: Nutze Placeholder URL / Null
|
|
end
|
|
|
|
Sync->>SupabaseDB: INSERT row (mit neuer Image URL & tasted_at)
|
|
activate SupabaseDB
|
|
SupabaseDB-->>Sync: Success (New ID)
|
|
deactivate SupabaseDB
|
|
|
|
Sync->>IDB: Lösche Eintrag aus 'sync_queue'
|
|
Sync->>UI: Trigger Re-Fetch / Update State
|
|
UI-->>User: Status ändert sich zu "Gespeichert ✔"
|
|
end
|
|
end
|
|
|
|
Der Prompt für das LLM (Copy & Paste)
|
|
|
|
Wenn du das nun programmieren lassen willst, kopiere alles zwischen den Trennlinien und gib es dem LLM. Es enthält das Diagramm und die technischen Instruktionen.
|
|
|
|
START PROMPT
|
|
|
|
Ich entwickle eine Offline-First Whisky Tasting App mit Next.js, Supabase und Dexie.js (IndexedDB). Bitte implementiere die Logik für den Datensync basierend auf dem folgenden Architektur-Diagramm.
|
|
|
|
Technologie-Stack:
|
|
|
|
Frontend: Next.js (React)
|
|
|
|
Local DB: Dexie.js (für IndexedDB Wrapper)
|
|
|
|
Remote DB: Supabase (PostgreSQL + Storage)
|
|
|
|
State: React Query (TanStack Query)
|
|
|
|
Wichtige Anforderungen:
|
|
|
|
Zwei Zeitstempel: Beachte den Unterschied zwischen created_at (wann es in Supabase ankommt) und tasted_at (wann der User den Button gedrückt hat). tasted_at muss lokal erfasst und hochgeladen werden.
|
|
|
|
Image Handling: Bilder werden lokal als Blob gespeichert. Beim Sync muss ZUERST das Bild in den Supabase Storage hochgeladen werden, um den public_url String zu erhalten. ERST DANN darf der Datenbank-Eintrag (Insert) erfolgen.
|
|
|
|
Optimistic UI: Die UI muss Daten aus Dexie (useLiveQuery von Dexie oder ähnlich) und Supabase gemischt anzeigen, damit der User keinen Unterschied merkt.
|
|
|
|
Hier ist das Ablaufdiagramm (Mermaid):
|
|
Code-Snippet
|
|
|
|
sequenceDiagram
|
|
participant User
|
|
participant UI as Next.js UI
|
|
participant IDB as Local DB (Dexie)
|
|
participant Sync as Sync Function
|
|
participant Supabase as Supabase Cloud
|
|
|
|
Note over User, IDB: Offline Action
|
|
User->>UI: Save Dram (Photo + Notes)
|
|
UI->>IDB: Add to table 'tasting_queue' (Blob, Data, tasted_at)
|
|
UI-->>User: Show entry immediately (via Blob URL)
|
|
|
|
Note over Sync, Supabase: Sync Process (Background)
|
|
Sync->>IDB: Check for items in 'tasting_queue'
|
|
loop For each Item
|
|
Sync->>Supabase: Upload Image Blob -> Get URL
|
|
Sync->>Supabase: Insert Database Row (with Image URL)
|
|
Sync->>IDB: Delete from 'tasting_queue'
|
|
end
|
|
|
|
Bitte erstelle mir:
|
|
|
|
Das Dexie Schema (db.ts).
|
|
|
|
Die Sync-Funktion, die prüft ob wir online sind und die Queue abarbeitet.
|
|
|
|
Einen React Hook, der diesen Sync automatisch triggert, sobald die Verbindung wieder da ist.
|
|
|
|
END PROMPT |