--- stepsCompleted: [1, 2, 3, 4, 5, 6, 7, 8] inputDocuments: - /home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/product-brief-Test01-2026-01-20.md - /home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/prd.md - /home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/ux-design-specification.md workflowType: 'architecture' project_name: 'Test01' user_name: 'Max' date: '2026-01-21' status: 'complete' completedAt: '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 1. **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. 2. **Taxonomy (ShadCN Reference)** * *Pros:* Excellent reference for content apps. * *Cons:* Too complex/bloated for a focused "Venting" utility. 3. **Standard Next.js + "PWA Recipe" (Recommended)** * *Pros:* Cleanest slate, allows exact configuration of `next-pwa` for offline support without fighting boilerplate defaults. Fits the "ShadCN" philosophy of "add what you need." ### 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:** ```bash 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:** - **`/app` Directory:** 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:** 1. Initialize Project (Next.js + ShadCN). 2. Implement Dexie.js Schema (Data Layer). 3. Implement Zustand Store (State Layer). 4. Configure Service Worker (Offline Layer). 5. Implement Client-Side LLM Service (BYOD Integration). 6. (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):** ```ts type ApiResponse = { 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)` - **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:** 1. **Strictly separate UI from Logic:** UI components must receive data via props or strict selectors; never fetch data directly inside a purely presentational component. 2. **Use the "Service Layer" for DB ops:** Never call `db.table.add()` directly in a component. Call `ChatService.sendMessage()`. 3. **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 ```text 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/db` directly. They must use `services/`. - *Strict Rule:* Components NEVER make `fetch()` calls directly. Use `services/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 build` generates 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.ts` orchestrator 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:** 1. **Sync Failure UX:** Missing a defined UI pattern for "Permanent Sync Failure" (e.g., Toast with "Tap to Retry"). 2. **Service Isolation:** Need explicit rule that Services return *Plain Data*, not Database Observables, to decouple UI from Dexie. **Important Gaps:** 1. **Backoff Strategy:** `SyncManager` requires an exponential backoff policy for retries to avoid battery drain. ### Architecture Completeness Checklist **✅ Requirements Analysis** - [x] Project context and constraints analyzed - [x] Cross-cutting concerns (Offline, Privacy) mapped **✅ Architectural Decisions** - [x] Tech Stack: Next.js + Dexie + Zustand + Auth.js - [x] Deployment: Vercel Edge Functions **✅ Implementation Patterns** - [x] Structure: Feature-First Lite - [x] State: Atomic Selectors + Service Orchestration **✅ Project Structure** - [x] Complete file tree defined - [x] 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:** 1. Initialize project using Next.js CLI + ShadCN. 2. Setup Vercel Edge Proxy. 3. Implement Dexie.js Schema (Data Layer). 4. Implement Zustand Store (State Layer). 5. Configure Service Worker (Offline Layer).