Files
brachnha-insight/_bmad-output/planning-artifacts/architecture.md
Max 3fbbb1a93b Initial commit: Brachnha Insight project setup
- 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>
2026-01-26 12:28:43 +07:00

17 KiB

stepsCompleted, inputDocuments, workflowType, project_name, user_name, date, status, completedAt
stepsCompleted inputDocuments workflowType project_name user_name date status completedAt
1
2
3
4
5
6
7
8
/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
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

  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:

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):

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)
  • 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

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

  • 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:

  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).