- Add 'Twilight Velvet' color palette to globals.css with OKLCH values - Update SettingsPage headers, cards, and dialogs to use semantic theme variables - Update HistoryCard, HistoryFeed, and DraftContent to support dark mode - Update ProviderSelector and ProviderList to use custom card background (#2A2A3D) - Add ThemeToggle component with improved visibility - Ensure consistent use of 'bg-card', 'text-foreground', and 'text-muted-foreground'
374 lines
14 KiB
Markdown
374 lines
14 KiB
Markdown
---
|
|
stepsCompleted: ['step-01-validate-prerequisites', 'step-02-design-epics', 'step-03-create-stories', 'step-04-final-validation']
|
|
inputDocuments:
|
|
- /home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/prd.md
|
|
- /home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/architecture.md
|
|
- /home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/ux-design-specification.md
|
|
---
|
|
|
|
# Brachnha - Epic Breakdown
|
|
|
|
## Overview
|
|
|
|
This document provides the complete epic and story breakdown for Brachnha, decomposing the requirements from the PRD, UX Design, and Architecture requirements into implementable stories.
|
|
|
|
## Requirements Inventory
|
|
|
|
### Functional Requirements
|
|
|
|
FR1: System can detect "Venting" vs. "Insight" intent from initial user input.
|
|
FR2: "Teacher Agent" can generate probing questions to elicit specific missing details based on the user's initial input.
|
|
FR3: "Ghostwriter Agent" can transform the structured interview data into a grammatically correct and structured "Enlightenment" artifact (e.g., Markdown post).
|
|
FR4: Users can "Regenerate" the outcome with specific critique (e.g., "Make it less corporate", "Focus more on the technical solution").
|
|
FR5: System provides a "Fast Track" option to bypass the interview and go straight to generation for advanced users.
|
|
FR6: Users can view a chronological feed of past "Enlightenments" (history).
|
|
FR7: Users can "One-Click Copy" the formatted text to clipboard.
|
|
FR8: Users can delete past entries.
|
|
FR9: Users can edit the generated draft manually before exporting.
|
|
FR10: Users can access the app and view history while offline.
|
|
FR11: Users can complete a full "Venting Session" offline; system queues generation for reconnection.
|
|
FR12: System actively prompts users to "Add to Home Screen" (A2HS) upon meeting engagement criteria.
|
|
FR13: System stores all chat history locally (persistent client-side storage) by default.
|
|
FR14: Users can export their entire history as a JSON/Markdown file.
|
|
FR15: Users can configure a custom OpenAI-compatible Base URL (e.g., `https://api.deepseek.com/v1`).
|
|
FR16: Users can securely save API Credentials (stored in local storage, never transmitted to backend).
|
|
FR17: Users can specify the Model Name (e.g., `gpt-4o`, `deepseek-chat`).
|
|
FR18: System validates the connection to the custom provider upon saving.
|
|
FR19: Users can switch between configured providers globally.
|
|
FR20: System presents a lock screen upon initial load if not authenticated.
|
|
FR21: System validates user-entered password against server-side `APP_PASSWORD`.
|
|
FR22: Authenticated session persists (via secure cookie) to prevent frequent logouts on personal devices.
|
|
|
|
### NonFunctional Requirements
|
|
|
|
NFR1: (Chat Latency) The "Teacher" agent must generate the first follow-up question within **< 3 seconds** to maintain conversational flow.
|
|
NFR2: (App Load Time) The app must be interactive (Time to Interactive) in **< 1.5 seconds** on 4G networks.
|
|
NFR3: (Data Sovereignty) User chat logs AND API Keys are stored **100% Client-Side** (persistent client-side storage). No user content or keys are sent to any middle-man server.
|
|
NFR4: (Inference Privacy) Data sent to the user-configured LLM API must be stateless (not used for training, subject to provider terms).
|
|
NFR5: (Offline Behavior) The app shell and local history must remain accessible in Aeroplane Mode. Active Chat interactions will be unavailable offline as they require live LLM access.
|
|
NFR6: (Data Persistence) Drafts must be auto-saved locally every **2 seconds** to prevent data loss.
|
|
NFR7: (Visual Accessibility) Dark Mode is the default. Contrast ratios must meet **WCAG AA** standards to reduce eye strain for late-night users.
|
|
NFR8: (Secure Key Storage) API Keys must be encrypted at rest or stored in secure local storage capabilities where possible, and never included in exports/logs.
|
|
NFR9: (Gatekeeper Security) The app must restrict access to the UI via a simple, high-protection login screen backed by a server-side `APP_PASSWORD` environment variable. This protects personal deployments (VPS) from unauthorized public access.
|
|
|
|
### Additional Requirements
|
|
|
|
- [Architecture] Use Next.js 14+ (App Router) with ShadCN UI and Tailwind CSS.
|
|
- [Architecture] Use Zustand v5 for Global State Management.
|
|
- [Architecture] Use Dexie.js v4.2.1 for Client-Side Database (IndexedDB).
|
|
- [Architecture] Use Service Workers for Offline capabilities.
|
|
- [Architecture] Implement "Logic Sandwich" Service Layer Pattern (UI -> Store -> Service -> DB).
|
|
- [Architecture] Vercel Edge Runtime for API Routes (Proxy).
|
|
- [UX] Mobile-First Design targeting 375px+ screens; Desktop centered max 600px.
|
|
- [UX] "Morning Mist" Theme (Pastel/Calm colors).
|
|
- [UX] Custom Chat Bubbles (Telegram-style).
|
|
- [UX] Slide-Up Draft View for "Magic Moment".
|
|
- [UX] Accessibility: WCAG AA Compliance, High Refresh Rate support.
|
|
|
|
### FR Coverage Map
|
|
|
|
FR1: Epic 3 - Venting Intent Detection
|
|
FR2: Epic 3 - Teacher Agent Elicitation
|
|
FR3: Epic 3 - Ghostwriter Artifact Generation
|
|
FR4: Epic 3 - Regeneration & Critique
|
|
FR5: Epic 3 - Fast Track Mode
|
|
FR6: Epic 4 - History Feed
|
|
FR7: Epic 4 - One-Click Copy
|
|
FR8: Epic 4 - Delete Entry
|
|
FR9: Epic 4 - Manual Editing
|
|
FR10: Epic 4 - Offline Access
|
|
FR11: Epic 4 - Offline Queueing
|
|
FR12: Epic 4 - A2HS Prompt
|
|
FR13: Epic 4 - Local Storage Persistence
|
|
FR14: Epic 4 - Data Export
|
|
FR15: Epic 2 - Custom Base URL
|
|
FR16: Epic 2 - Secure Credential Storage
|
|
FR17: Epic 2 - Model Selection
|
|
FR18: Epic 2 - Connection Validation
|
|
FR19: Epic 2 - Provider Switching
|
|
FR20: Epic 1 - Lock Screen UI
|
|
FR21: Epic 1 - Password Validation
|
|
FR22: Epic 1 - Session Persistence
|
|
|
|
## Epic List
|
|
|
|
### Epic 1: Gatekeeper Security
|
|
|
|
Establish a secure perimeter for the application to prevent unauthorized access in public deployment scenarios (VPS).
|
|
|
|
### Story 1.1: Security Middleware & Lock Screen
|
|
|
|
As a Personal User,
|
|
I want the application to block all access until I log in,
|
|
So that my private journal remains secure on the public web.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am an unauthenticated user accessing any route
|
|
**When** I load the page
|
|
**Then** I should be redirected to `/login`
|
|
**And** I should see a simple "Enter Password" screen
|
|
**And** I should not see any application UI or data
|
|
|
|
### Story 1.2: Server-Side Validation (APP_PASSWORD)
|
|
|
|
As a System Admin (User),
|
|
I want to secure the app with a server-side environment variable,
|
|
So that I don't need to manage a database of users.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I have set `APP_PASSWORD` in my `.env`
|
|
**When** I enter the matching password into the login form
|
|
**Then** The server should validate it
|
|
**And** Return a secure HTTP-only cookie
|
|
**And** Allow access to the app
|
|
|
|
**Given** I enter the wrong password
|
|
**When** I submit the form
|
|
**Then** I should see an invalid password error
|
|
|
|
### Story 1.3: Session Persistence
|
|
|
|
As a Daily User,
|
|
I want my login to be remembered for 30 days,
|
|
So that I don't have to type the password every time I open the app on my phone.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I have successfully logged in
|
|
**When** I close and reopen the browser
|
|
**Then** I should remain logged in without re-entering the password
|
|
|
|
**Given** I click "Logout" in settings
|
|
**When** I confirm
|
|
**Then** My session cookie should be destroyed
|
|
**And** I should be redirected to the login screen
|
|
|
|
### Epic 2: Project Calibration (BYOD Setup)
|
|
|
|
Enable users to configure and manage their own AI provider connections, ensuring privacy and operational capability.
|
|
|
|
### Story 2.1: Settings Feature Shell
|
|
|
|
As a User,
|
|
I want a dedicated settings area,
|
|
So that I can manage my application preferences and configurations.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am on the home screen
|
|
**When** I tap the "Settings" icon
|
|
**Then** A settings sheet or page should open
|
|
**And** I should see navigation tabs (General, AI Providers)
|
|
**And** I should see a Theme Toggle (Light/Dark)
|
|
|
|
### Story 2.2: Provider Management (CRUD)
|
|
|
|
As a Power User,
|
|
I want to add my own custom LLM provider (like DeepSeek or OpenAI),
|
|
So that I can control the cost and intelligence behind the app.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am in the AI Providers settings tab
|
|
**When** I tap "Add Provider"
|
|
**Then** I should see a form for Name, Base URL, API Key, and Model Name
|
|
**And** I should be able to save this configuration to my local device
|
|
|
|
**Given** I have an existing provider
|
|
**When** I edit it
|
|
**Then** The changes should be saved locally
|
|
|
|
### Story 2.3: Secure Credentials Storage
|
|
|
|
As a Privacy-Conscious User,
|
|
I want my API keys to be stored securely on my device,
|
|
So that they are never exposed to a third-party server.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I save a new provider with an API Key
|
|
**When** The data is persisted to localStorage
|
|
**Then** The API Key should be obfuscated (e.g., Base64 or encrypted)
|
|
**And** It should NOT be visible in plain text in the storage inspector
|
|
**And** It should never be logged in the console
|
|
|
|
### Story 2.4: Connection Validation
|
|
|
|
As a User,
|
|
I want to know if my API key works before I save it,
|
|
So that I don't get errors later when trying to chat.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am adding a provider
|
|
**When** I fill in the details and tap "Test Connection"
|
|
**Then** The system should make a call to the provider's API (e.g., list models)
|
|
**And** Show a "Success" or "Error" message appropriately
|
|
**And** Block saving if the validation fails (optional, but recommended warning)
|
|
|
|
### Story 2.5: Active Provider Switcher
|
|
|
|
As a User,
|
|
I want to easily switch between my configured providers,
|
|
So that I can use a cheaper model for simple tasks and a smarter one for complex vents.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I have multiple providers configured
|
|
**When** I select a different provider as "Active"
|
|
**Then** All future chat requests should use that provider's credentials
|
|
**And** The UI should reflect the currently active provider
|
|
|
|
### Epic 3: The Venting Ritual (Core)
|
|
|
|
Implement the core dual-agent pipeline that transforms user stress into structured insights via a guided chat interface.
|
|
|
|
### Story 3.1: Chat Interface & State
|
|
|
|
As a User,
|
|
I want a familiar chat interface,
|
|
So that I can express myself naturally without learning a new tool.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I open the app
|
|
**When** I am on the home screen
|
|
**Then** I should see a chat input at the bottom
|
|
**And** I should simply tap to start typing
|
|
**And** My messages should appear in "User Bubbles" (Right aligned)
|
|
**And** AI responses should appear in "AI Bubbles" (Left aligned) with a typing indicator
|
|
|
|
### Story 3.2: Teacher Agent (Elicitation Logic)
|
|
|
|
As a Learner,
|
|
I want the AI to ask me probing questions,
|
|
So that I can uncover the deeper lesson behind my frustration.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I send a message like "I feel stupid"
|
|
**When** The "Teacher" agent processes it
|
|
**Then** It should NOT just say "It's okay"
|
|
**And** It SHOULD ask a follow-up question like "What specifically made you feel that way?"
|
|
**And** It should maintain a supportive, non-judgmental tone
|
|
|
|
### Story 3.3: Ghostwriter Agent (Draft Generation)
|
|
|
|
As a User,
|
|
I want a focused "Drafting" moment,
|
|
So that I know when the venting is over and the value is created.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I have answered the Teacher's questions
|
|
**When** Sufficient context is gathered OR I tap "Draft It"
|
|
**Then** The system should trigger the "Ghostwriter" agent
|
|
**And** It should consume the chat history
|
|
**And** It should generate a structured markdown artifact (Title, Insight, Lesson)
|
|
|
|
### Story 3.4: Draft Review UI (Slide-Up)
|
|
|
|
As a User,
|
|
I want to see the generated insight clearly,
|
|
So that I can feel a sense of accomplishment.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** The Ghostwriter has finished
|
|
**When** The draft is ready
|
|
**Then** A "Slide-Up" sheet (or modal) should appear
|
|
**And** It should display the content with nice typography (Serif headers)
|
|
**And** It should have "Thumbs Up" (Keep) and "Thumbs Down" (Refine) buttons
|
|
|
|
### Story 3.5: Regeneration Loop (Refinement)
|
|
|
|
As a User,
|
|
I want to critique the draft if it's wrong,
|
|
So that the final result feels authentic to me.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I see a draft I don't like
|
|
**When** I tap "Thumbs Down"
|
|
**Then** The sheet should close
|
|
**And** The AI should ask "What needs to be changed?"
|
|
**And** My response should trigger a regeneration of the draft
|
|
|
|
### Epic 4: Journey Management (History & Offline)
|
|
|
|
Provide long-term value through history management, offline reliability, and data portability.
|
|
|
|
### Story 4.1: History Feed UI
|
|
|
|
As a User,
|
|
I want to browse my past "Legacy Logs",
|
|
So that I can reflect on my growth over time.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I tap the "History" tab
|
|
**When** The list loads
|
|
**Then** I should see a chronological list of cards
|
|
**And** Each card should show Date, Title, and a short summary
|
|
**And** It should support infinite scroll or pagination
|
|
|
|
### Story 4.2: Detailed Artifact View
|
|
|
|
As a User,
|
|
I want to read a specific past insight,
|
|
So that I can reuse the content for my blog or resume.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am on the History Feed
|
|
**When** I tap a card
|
|
**Then** The "Detailed View" (similar to the Draft View) should open
|
|
**And** I should see the full formatted content
|
|
**And** I should NOT be able to "Regenerate" (it is read-only history)
|
|
|
|
### Story 4.3: Action Menu (Export/Delete)
|
|
|
|
As a User,
|
|
I want to manage my individual entries,
|
|
So that I can delete bad ones or copy good ones.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am viewing a History Card
|
|
**When** I tap the "..." menu
|
|
**Then** I should see "Copy to Clipboard" and "Delete"
|
|
**And** Tapping "Delete" should prompt for confirmation
|
|
**And** Confirming should remove it from the database immediately
|
|
|
|
### Story 4.4: Offline Sync Queue
|
|
|
|
As a Commuter,
|
|
I want to vent even when I have no signal (Offline),
|
|
So that I don't lose the thought.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am offline (Airplane Mode)
|
|
**When** I attempt to start a chat or send a message
|
|
**Then** The UI should allow it
|
|
**And** The system should queue the action in `syncQueue` (IndexedDB)
|
|
**And** It should show a "Waiting for connection..." status
|
|
**When** Connection is restored
|
|
**Then** The queue should auto-process
|
|
|
|
### Story 4.5: Data Export Utility
|
|
|
|
As a User,
|
|
I want to download all my data,
|
|
So that I have a backup independent of this browser.
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
**Given** I am in Settings
|
|
**When** I tap "Export All Data"
|
|
**Then** The system should gather all Chat Logs and Drafts
|
|
**And** Generate a downloadable JSON or Markdown file
|
|
**And** Trigger the browser download prompt
|