- Next.js 14+ with App Router and TypeScript - Tailwind CSS and ShadCN UI styling - Zustand state management - Dexie.js for IndexedDB (local-first data) - Auth.js v5 for authentication - BMAD framework integration Co-Authored-By: Claude <noreply@anthropic.com>
17 KiB
stepsCompleted, inputDocuments, workflowType, project_name, user_name, date, status, completedAt
| stepsCompleted | inputDocuments | workflowType | project_name | user_name | date | status | completedAt | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
architecture | Test01 | Max | 2026-01-21 | complete | 2026-01-21 |
Architecture Decision Document
This document builds collaboratively through step-by-step discovery. Sections are appended as we work through each architectural decision together.
Project Context Analysis
Requirements Overview
Functional Requirements:
- Dual-Agent Pipeline: Core architectural pattern involving a "Teacher" agent for elicitation and a "Ghostwriter" agent for content generation.
- PWA / Offline Capability: "Local-First" architecture is mandatory. Must support full "Venting" session offline with a Client-Side Transaction Log to queue actions safely.
- Chat-to-Artifact Transformation: Distinct UI modes for Input (Chat) vs. Output (Card/Article).
- History & Persistence: Local storage (IndexedDB) of all chat logs and generated drafts. Privacy-first data handling.
Non-Functional Requirements:
- Performance: Low latency (<3s Response, <1.5s TTI). Client-Side Rendering (CSR) prioritized for Chat Views to avoid hydration mismatches.
- Privacy: 100% Client-Side storage for MVP. No user content sent to cloud persistence.
- Security: Client-Side Key Management (BYOD). User's API key stored locally and used directly from browser. Optional CORS proxy may be configured if provider doesn't support browser requests.
- Reliability: Service Worker caching for offline app shell and aggressive local auto-saving.
Scale & Complexity:
- Primary Domain: Mobile-First PWA (React/Next.js).
- Complexity Level: Medium. (State complexity is high due to offline sync and dual-agent interaction).
- Estimated Architectural Components: ~8 key components (Chat Engine, Agent Orchestrator, Storage Layer, Sync Manager, UI Shell, Draft Renderer, Global State Manager, API Proxy).
Technical Constraints & Dependencies
- Platform: Web (PWA) targeting Mobile Safari and Chrome on Android.
- Stack Preference: Next.js + Tailwind + ShadCN UI.
- State Management: Global State Manager (e.g., Zustand) required to decouple "Session State" from "UI View" (handling the slide-up draft view).
- Storage: IndexedDB (via wrapper) is the primary source of truth.
Cross-Cutting Concerns Identified
- Offline Sync & State Management: Robust handling of the "Sync Queue" to prevent data loss during connection drops.
- Theming: Consistent "Morning Mist" theme application.
- Agent Orchestration: Managing the conversational state (Teacher vs. Ghostwriter mode).
- Error Handling: Graceful degradation when LLM API fails.
Starter Template Evaluation
Primary Technology Domain
Web Application (PWA) - Focused on "Local-First" Mobile Experience.
Starter Options Considered
- T3 Stack (
create-t3-app)- Pros: Best-in-class type safety.
- Cons: Heavily optimized for Server-Side Logic (tRPC/Prisma) which conflicts with our "Offline/Local-First" requirement.
- Taxonomy (ShadCN Reference)
- Pros: Excellent reference for content apps.
- Cons: Too complex/bloated for a focused "Venting" utility.
- Standard Next.js + "PWA Recipe" (Recommended)
- Pros: Cleanest slate, allows exact configuration of
next-pwafor offline support without fighting boilerplate defaults. Fits the "ShadCN" philosophy of "add what you need."
- Pros: Cleanest slate, allows exact configuration of
Selected Starter: Standard Next.js 14+ (App Router)
Rationale for Selection: We selected the official Next.js CLI because our architectural constraints are unique (Local-First PWA). Most boilerplates optimize for "SaaS B2B" (Auth+Database+Stripe), which is the opposite of our "Offline+Privacy" needs. Constructing the stack via official CLIs ensures we don't carry dead weight.
Initialization Command:
npx create-next-app@latest . --typescript --tailwind --eslint
# Followed by:
npx shadcn-ui@latest init
npm install next-pwa zustand dexie
Architectural Decisions Provided by Starter:
Language & Runtime:
- TypeScript: Strict mode enabled for safety.
- Node/Runtime: Next.js App Router (React Server Components) - Note: We will use mostly Client Components for the PWA shell.
Styling Solution:
- Tailwind CSS: Utility-first styling (Standard).
- ShadCN UI: Component architecture (Copy-paste ownership).
Build Tooling:
- Turbopack: (Next.js default) for fast HMR.
- PostCSS: For Tailwind compilation.
Testing Framework:
- Not included by default. We will need to add Vitest + React Testing Library in the Implementation phase.
Code Organization:
/appDirectory: For routing (File-system based)./components: Flat structure for UI elements./lib: For utilities (ShadCN default).
Development Experience:
- HMR: Instant feedback.
- ESLint: Basic code quality.
Note: The specific "Offline PWA" configuration (Service Workers) will be our first major architectural implementation task.
Core Architectural Decisions
Data Architecture
Database Choice: IndexedDB (Client-Side)
- Library Choice: Dexie.js v4.2.1
- Rationale: Best-in-class TypeScript support and schema versioning logic (critical for PWA updates).
- Migration Strategy: Utilize Dexie's built-in
.version(x)syntax to handle local DB upgrades.
Authentication & Security
Auth Provider: None (Local-First BYOD)
- Rationale: No user accounts or login required. All data is local.
- Security Pattern: Client-Side Key Management (Primary).
- Why: Complies with PRD "Bring Your Own AI" requirement (FR-15, FR-16). User's API key is stored in
localStorage(with basic encoding) and sent directly to the LLM provider from the client. - Optional CORS Proxy: If a provider doesn't allow browser CORS, an optional stateless Edge Function can forward requests without storing keys.
Frontend Architecture
Global State: Zustand v5
- Rationale: Unopinionated and transient-update friendly (perfect for "Teacher is typing..." indicators without re-rendering the whole tree).
- PWA Strategy: Custom Service Worker (via
next-pwa). - Constraint: Must explicitly exclude Chat API routes from caching to prevent "stale vents."
Infrastructure & Deployment
Hosting: Vercel
- Rationale: Standard Next.js hosting for app shell delivery.
- Edge Functions: Optional stateless CORS proxy only (not used for key management).
Decision Impact Analysis
Implementation Sequence:
- Initialize Project (Next.js + ShadCN).
- Implement Dexie.js Schema (Data Layer).
- Implement Zustand Store (State Layer).
- Configure Service Worker (Offline Layer).
- Implement Client-Side LLM Service (BYOD Integration).
- (Optional) Setup CORS Proxy if needed for specific providers.
Note: The dependency chain of "Offline Sync" requires Dexie (Queue) + SW (Detection) + Zustand (UI) to all work in concert.
Implementation Patterns & Consistency Rules
Pattern Categories Defined
Critical Conflict Points Identified: 5 core areas (Naming, Structure, Format, Communication, Process).
Naming Patterns
Database Naming Conventions (Dexie.js):
- Tables:
camelCase(e.g.,userProfiles,chatLogs). Reason: Matches JS object property access (db.chatLogs.toArray()). - Primary Keys:
id(String UUID). Reason: Universal, easy to generate client-side before sync. - Indices:
camelCase(e.g.,createdAt).
API Naming Conventions:
- Endpoints: RESTful Plural Kebab-case (e.g.,
/api/chat-sessions). - Methods: Standard HTTP (GET, POST, PUT, DELETE).
- Internal Functions:
verbNoun(e.g.,fetchUserSession,syncOfflineQueue).
Structure Patterns
Project Organization (Feature-First Lite):
app/: Routes only. Minimal logic.components/ui/: Primitive ShadCN components (Button, Input).components/features/{feature}/: Feature-specific components (e.g.,chat/ChatWindow.tsx).lib/: Shared utilities (utils.ts) and configurations.store/: Zustand stores (useChatStore.ts).db/: Dexie database definition (db.ts).
Format Patterns
API Response Formats (Standardized Wrapper):
type ApiResponse<T> = {
success: boolean;
data?: T;
error?: { code: string; message: string };
timestamp: string; // ISO 8601
}
Communication Patterns
State Management (Zustand):
- Selectors: ALWAYS use atomic selectors to prevent re-renders.
- Bad:
const { messages, user } = useStore() - Good:
const messages = useStore((s) => s.messages)
- Bad:
- Actions: Co-located in the store definition.
Event System (Offline Sync):
- Offline Queue: Uses robust "Action Replay" pattern.
- Events:
noun.verb(e.g.,message.sent,session.archived).
Enforcement Guidelines
All AI Agents MUST:
- Strictly separate UI from Logic: UI components must receive data via props or strict selectors; never fetch data directly inside a purely presentational component.
- Use the "Service Layer" for DB ops: Never call
db.table.add()directly in a component. CallChatService.sendMessage(). - Handle "Loading" vs "Syncing": Distinguish between "fetching for the first time" (Skeleton UI) and "syncing background changes" (Subtle Spinner).
Pattern Enforcement:
- Linting: ESLint with strict import rules (e.g., no strict relative imports across features).
- Review: Any PR/Commit must pass the "Agent Consistency Check".
Project Structure & Boundaries
Complete Project Directory Structure
Test01/
├── src/
│ ├── app/ # Next.js App Router (PWA Shell)
│ │ ├── (main)/ # Main Layout (Nav + content)
│ │ │ ├── page.tsx # Home/Dashboard
│ │ │ ├── history/ # Past Vents
│ │ │ └── settings/ # User Preferences
│ │ ├── (session)/ # Immersive Layout (No Nav)
│ │ │ └── chat/ # Active Venting Session
│ │ ├── api/ # API Routes (Optional CORS proxy only)
│ │ │ └── llm-proxy/ # Optional: Stateless CORS forwarder
│ │ ├── layout.tsx
│ │ └── globals.css
│ ├── components/
│ │ ├── ui/ # ShadCN Primitives (Button, Card)
│ │ ├── features/ # Feature-Specific Logic
│ │ │ ├── chat/ # ChatWindow, Bubble, TypingIndicator
│ │ │ ├── artifacts/ # ReflectionCard, SummaryView
│ │ │ └── journal/ # HistoryList, heatmaps
│ │ └── layout/ # AppShell, BottomNav, Header
│ ├── lib/
│ │ ├── db/ # Database Layer
│ │ │ ├── schema.ts # Dexie Schema Definitions
│ │ │ └── client.ts # DB Instance Singleton
│ │ ├── llm/ # AI Service Adaptation (Client-Side)
│ │ │ ├── prompt-engine.ts
│ │ │ ├── stream-parser.ts
│ │ │ └── providers.ts # Provider configurations (OpenAI, DeepSeek, etc.)
│ │ └── utils.ts # Shared Helpers
│ ├── services/ # Application Logic Layer
│ │ ├── sync-manager.ts # Offline Queue Handler
│ │ ├── llm-service.ts # Client-Side LLM Integration
│ │ └── chat-service.ts # Orchestrator (DB <-> State <-> LLM)
│ └── store/ # Global State (Zustand)
│ ├── use-session.ts # Active Session State
│ └── use-settings.ts # Theme/Config State
├── public/
│ ├── manifest.json # PWA Manifest
│ └── icons/
└── next.config.mjs # PWA + Header Config
Architectural Boundaries
Service Boundaries (The "Logic Sandwich"):
- UI Components (View) -> Zustand Store (State) -> Service Layer (Logic) -> Dexie/LLM (Data).
- Strict Rule: Components NEVER import
lib/dbdirectly. They must useservices/. - Strict Rule: Components NEVER make
fetch()calls directly. Useservices/llm-service.ts.
Data Boundaries:
- Local: IndexedDB is the Source of Truth for User Data.
- Remote: LLM API is a Compute Engine, not a storage provider. No user data persists on the server.
- Secrets: API Keys are stored in
localStorage(with simple encryption/encoding) and never leave the client except to call the provider.
Development Workflow Integration
Build Process:
next buildgenerates the PWA Service Worker.- Edge Runtime is optional for CORS proxy only (if needed).
Deployment Structure:
- Vercel: Hosts the App Shell (+ optional CORS proxy).
- Client: Browsers host the Database (IndexedDB) and execute LLM requests directly.
Architecture Validation Results
Coherence Validation ✅
Decision Compatibility: The selected stack (Next.js App Router + Dexie.js + Zustand) is highly compatible. Dexie's asynchronous nature pairs well with Zustand's transient updates, ensuring the UI remains responsive even during heavy database sync operations.
Pattern Consistency: Implementation patterns strongly support the "Local-First" decision. The Service Layer pattern is critical for isolating the UI from the complexity of Dexie/Sync logic.
Requirements Coverage Validation ✅
Functional Requirements Coverage:
- Dual-Agent Pipeline: Supported by the
services/chat-service.tsorchestrator logic. - Offline Capability: Covered by the Sync Queue pattern in
services/sync-manager.ts. - Privacy: Enforced by the Local-First data boundary (User content stays in IndexedDB).
Non-Functional Requirements Coverage:
- Performance: Edge Runtime ensures <3s latency for non-cached requests.
- Reliability: Addressed by the "Action Replay" queue, though edge cases in sync failure need UI handling (see Gaps).
Implementation Readiness Validation ✅
Structure Completeness:
The src/ directory tree provides specific homes for every requirement. Usage of components/features/ vs components/ui/ is clear.
Gap Analysis Results
Critical Gaps:
- Sync Failure UX: Missing a defined UI pattern for "Permanent Sync Failure" (e.g., Toast with "Tap to Retry").
- Service Isolation: Need explicit rule that Services return Plain Data, not Database Observables, to decouple UI from Dexie.
Important Gaps:
- Backoff Strategy:
SyncManagerrequires an exponential backoff policy for retries to avoid battery drain.
Architecture Completeness Checklist
✅ Requirements Analysis
- Project context and constraints analyzed
- Cross-cutting concerns (Offline, Privacy) mapped
✅ Architectural Decisions
- Tech Stack: Next.js + Dexie + Zustand + Auth.js
- Deployment: Vercel Edge Functions
✅ Implementation Patterns
- Structure: Feature-First Lite
- State: Atomic Selectors + Service Orchestration
✅ Project Structure
- Complete file tree defined
- Integration boundaries established
Architecture Readiness Assessment
Overall Status: READY FOR IMPLEMENTATION (with Gaps to address) Confidence Level: HIGH
Implementation Handoff
First Implementation Priority: Initialize the Next.js PWA Shell and configure the Dexie Database Schema.
Architecture Completion Summary
Workflow Completion
Architecture Decision Workflow: COMPLETED ✅
Total Steps Completed: 8
Document Location: _bmad-output/planning-artifacts/architecture.md
Final Architecture Deliverables
📋 Complete Architecture Document
- Tech Stack: Next.js 14+ (App Router), Dexie.js 4.2.1, Zustand 5, Auth.js 5.
- Patterns: Service Layer ("Logic Sandwich"), Client-Side Transaction Log, Local-First.
- Structure: Feature-First organization with clear separation of UI, State, and Logic.
Implementation Handoff
For AI Agents: This architecture document is your complete guide for implementing Test01. Follow all decisions, patterns, and structures exactly as documented.
First Implementation Priority: Initialize the Next.js PWA Shell and configure the Dexie Database Schema.
Development Sequence:
- Initialize project using Next.js CLI + ShadCN.
- Setup Vercel Edge Proxy.
- Implement Dexie.js Schema (Data Layer).
- Implement Zustand Store (State Layer).
- Configure Service Worker (Offline Layer).