Files
brachnha-insight/_bmad-output/implementation-artifacts/1-1-local-first-setup-chat-storage.md
Max e9e6fadb1d fix: ChatBubble crash and DeepSeek API compatibility
- 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
2026-01-26 16:55:05 +07:00

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

  1. 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
  2. Message Storage

    • Given the user sends a message
    • When the message is sent
    • Then it is stored in the chatLogs table in IndexedDB with a timestamp
    • And is immediately displayed in the UI
  3. 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
  4. 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.ts with Dexie schema definition (Topic: chatLogs)
    • Define TypeScript interfaces for ChatLog and Message
  • Implement Chat Service (Logic Sandwich)
    • Create src/services/chat-service.ts for database interactions
    • Implement saveMessage, getHistory, initSession methods
    • Ensure methods return plain objects, not observables
  • Setup Zustand Store
    • Create src/lib/store/chat-store.ts
    • Bind store actions to chat-service
    • Implement atomic selectors for UI consumption
  • Connect to UI (Skeleton)
    • Update Page.tsx or main component to hydrate store on mount
    • Verify offline persistence by reloading with network disabled

Dev Notes

Architecture & Rules

  • Logic Sandwich Pattern: UI Components (src/components/...) MUST NOT import src/lib/db directly. All data access goes through ChatService.
  • 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-indexeddb and vitest configuration 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.tsx to use atomic selectors.
    • 🟡 Documentation: Added package.json to File List.
    • 🟡 Code Quality: Removed internal comments from src/lib/store/chat-store.ts.
  • Validation: 9/9 Tests passed. All ACs verified.