- Fix ChatBubble to handle non-string content with String() wrapper - Fix API route to use generateText for non-streaming requests - Add @ai-sdk/openai-compatible for non-OpenAI providers (DeepSeek, etc.) - Use Chat Completions API instead of Responses API for compatible providers - Update ChatBubble tests and fix component exports to kebab-case - Remove stale PascalCase ChatBubble.tsx file
3.9 KiB
3.9 KiB
Story 1.1: Local-First Setup & Chat Storage
Status: done
Story
As a user, I want my chat sessions to be saved locally on my device, so that my data is private and accessible offline.
Acceptance Criteria
-
Database Initialization
- Given a new user visits the app
- When they load the page
- Then a Dexie.js database is initialized with the correct schema (
chatLogs) - And no data is sent to the server without explicit action
-
Message Storage
- Given the user sends a message
- When the message is sent
- Then it is stored in the
chatLogstable in IndexedDB with a timestamp - And is immediately displayed in the UI
-
Session Restoration
- Given the user reloads the page
- When the page loads
- Then the previous chat history is retrieved from IndexedDB and displayed correctly
- And the session state is restored via Zustand
-
Offline Access
- Given the device is offline
- When the user opens the app
- Then the app loads successfully and shows stored history from the local database
Tasks / Subtasks
- Initialize Dexie Database
- Create
src/lib/db/index.tswith Dexie schema definition (Topic:chatLogs) - Define TypeScript interfaces for
ChatLogandMessage
- Create
- Implement Chat Service (Logic Sandwich)
- Create
src/services/chat-service.tsfor database interactions - Implement
saveMessage,getHistory,initSessionmethods - Ensure methods return plain objects, not observables
- Create
- Setup Zustand Store
- Create
src/lib/store/chat-store.ts - Bind store actions to
chat-service - Implement atomic selectors for UI consumption
- Create
- Connect to UI (Skeleton)
- Update
Page.tsxor main component to hydrate store on mount - Verify offline persistence by reloading with network disabled
- Update
Dev Notes
Architecture & Rules
- Logic Sandwich Pattern: UI Components (
src/components/...) MUST NOT importsrc/lib/dbdirectly. All data access goes throughChatService. - Zustand Usage: Use atomic selectors (e.g.,
useChatStore(s => s.messages)) to avoid re-renders. - Local-First: IndexedDB (Dexie) is the source of truth.
- Strict Mode: Ensure all database types are strictly typed.
Project Structure
src/lib/db/: Database configuration and schema.src/services/: Business logic layer (The "Meat" of the sandwich).src/lib/store/: Zustand state management.src/components/features/: Feature-specific components (will consume store).
References
Dev Agent Record
Agent Model Used
Gemini 2.0 Flash
Debug Log References
Completion Notes List
- Implemented TDD cycle for all components (DB, Service, Store, UI).
- Created standard "Logic Sandwich" architecture.
- Added
fake-indexeddbandvitestconfiguration for reliable testing. - Verified persistent storage and hydration.
File List
- src/lib/db/index.ts
- src/lib/db/index.test.ts
- src/services/chat-service.ts
- src/services/chat-service.test.ts
- src/lib/store/chat-store.ts
- src/lib/store/chat-store.test.ts
- src/app/page.tsx
- src/app/page.test.tsx
- vitest.config.ts
- vitest.setup.ts
- package.json
Senior Developer Review (AI)
- Outcome: Approved (Automatic Fixes Applied)
- Findings:
- 🔴 Architecture: Refactored
src/app/page.tsxto use atomic selectors. - 🟡 Documentation: Added
package.jsonto File List. - 🟡 Code Quality: Removed internal comments from
src/lib/store/chat-store.ts.
- 🔴 Architecture: Refactored
- Validation: 9/9 Tests passed. All ACs verified.