feat: initialize agent and claude skill libraries with comprehensive knowledge bases, workflow templates, and implementation artifacts.

This commit is contained in:
Vonic 2026-04-13 09:49:58 +07:00
parent 956d8c6322
commit b35b4337bb
2028 changed files with 565614 additions and 0 deletions

View file

@ -0,0 +1,388 @@
---
stepsCompleted: [1, 2, 3, 4, 5, 6, 7, 8]
lastStep: 8
status: 'complete'
completedAt: '2026-04-13T01:02:23+07:00'
inputDocuments: [
"/Users/luisphan/Documents/GitHub/SurfSense/_bmad-output/planning-artifacts/prd.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/index.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/architecture-backend.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/architecture-web.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/integration-architecture.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/deployment-guide.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/development-guide.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/api-contracts.md",
"/Users/luisphan/Documents/GitHub/SurfSense/docs/data-models.md"
]
workflowType: 'architecture'
project_name: 'SurfSense'
user_name: 'Luisphan'
date: '2026-04-13'
---
# 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:**
14 Functional Requirements (FRs) tập trung vào các domain chính sau:
- Xử lý dữ liệu (Document Ingestion, OCR, Chunking, Vector Storage).
- AI & Search (Hybrid Search, Graph RAG, Agentic reasoning, streaming response).
- Giao diện và tương tác (Streaming UI, Local-first caching, Offline mode).
- Cơ chế đồng bộ (Zero-sync giữa IndexedDB và Postgres).
=> Kiến trúc phân tán (Distributed) rõ rệt: xử lý nặng diễn ra ở Backend (FastAPI + Celery), còn tính năng Offline/Real-time yêu cầu Front-end (Next.js) phải có bộ đệm mạnh mẽ và đồng bộ liên tục.
**Non-Functional Requirements:**
7 NFRs đặc biệt nhấn mạnh vào hiệu năng và bảo mật:
- Performance: TTFT (Time To First Token) < 1.5s; Sync Latency < 3.0s. Định tuyến dữ liệu phải tối ưu (WebSockets/SSE) khả năng caching tỉnh vượt trội.
- Security: Row-level Security (RLS) để cô lập dữ liệu người dùng, xóa cache local tự động ngay khi logout.
- Offline-first: Logic và state UI phải hoạt động liền mạch ngay cả khi rớt mạng.
**Scale & Complexity:**
- Độ phức tạp của dự án (Complexity level): Mức độ Cao (High).
- Miền kỹ thuật chính (Primary domain): Full-stack Web3/AI (Next.js + FastAPI + Background queues).
- Số lượng Component ước tính: ~5 khối lớn (Web Client, API Gateway, Async Workers, Vector DB, Realtime Sync Service).
### Technical Constraints & Dependencies
- Giao thức đồng bộ: Bắt buộc sử dụng framework `@rocicorp/zero` ở front-end và xử lý JWT Auth tương ứng.
- AI Models & Frameworks: Cần tích hợp với hệ thống RAG pipeline qua FastAPI/Python.
- Cơ sở hạ tầng dữ liệu: Ràng buộc phải có PostgreSQL với pgvector extension cho việc tìm kiếm vector.
### Cross-Cutting Concerns Identified
- **Data Consistency & Conflict Resolution**: Quản lý rủi ro khi thay đổi offline trên IndexedDB cập nhật lên Postgres.
- **Security & Authorization**: Row-level security phải ánh xạ đúng tới logic middleware API.
- **Latency & Streaming Handling**: Luồng gửi dữ liệu tokens (AI responses) cần trơn tru, độc lập với đồng bộ Zero-sync.
## Starter Template Evaluation
### Primary Technology Domain
Full-stack Web3/AI Application (Next.js + FastAPI) based on project requirements analysis.
### Starter Options Considered
Dựa trên yêu cầu của PRD và hệ sinh thái công nghệ, tôi đã khảo sát các giải pháp Boilerplate/Starter template chuẩn công nghiệp:
**1. Dành cho Next.js (Front-end Web Client):**
Công cụ chính chủ `create-next-app` vẫn là bộ khung đáng tin cậy nhất. Nó linh hoạt cấu hình App Router, TailwindCSS và TypeScript. Vì SurfSense chạy mô hình Local-first đòi hỏi thiết lập bộ đệm Zero-sync (IndexedDB) cực kỳ đặc thù, việc dùng một boilerplate cồng kềnh chứa sẵn logic DB/Auth khác (như T3 Stack) sẽ dẫn tới rủi ro xung đột cao.
**2. Dành cho FastAPI (Backend API & Async Workers):**
- **Full Stack FastAPI Template (Official):** Chứa đủ SQLModel, Docker, rất tốt nhưng bị nhồi nhét sẵn React admin thừa kềnh càng.
- **Modern Standard Architecture (Custom):** Khuyến nghị tự thiết lập kiến trúc phân lớp chuẩn 2026 (`api`, `services`, `repositories`, `schemas`) sử dụng `uv` làm trình quản lý dependency và `Ruff` làm linter để tối ưu hiệu năng cho AI/Celery queue.
### Selected Starter: Official Next.js CLI & Custom Fast-Modern Async API
**Rationale for Selection:**
Hệ thống Agentic RAG và Zero-sync quá đặc thù, yêu cầu một khung xương sạch (clean foundation). Setup nguyên bản từ official tools giúp tránh "nợ kỹ thuật" (technical debt) khi scale, cho phép tích hợp trực tiếp Supabase RLS và Zero middle-tier dễ dàng.
**Initialization Command:**
```bash
# Frontend
npx create-next-app@latest surfsense-web
# Backend (Khởi tạo bằng uv)
uv venv
uv pip install fastapi uvicorn celery pydantic-settings sqlmodel psycopg2-binary
```
**Architectural Decisions Provided by Starter:**
**Language & Runtime:**
- Frontend: TypeScript, Node.js. (App Router).
- Backend: Python 3.11+, hỗ trợ Native Async.
**Styling Solution:**
- Frontend: Tích hợp sẵn Tailwind CSS.
**Build Tooling:**
- Frontend: Next.js Turbopack.
- Backend: Trình quản lý package `uv` (Nhanh hơn từ 10-100 lần so với pip truyền thống).
**Testing Framework:**
- Frontend: Sẵn sàng cấu hình Vitest.
- Backend: `pytest` chuẩn công nghiệp.
**Code Organization:**
- Frontend: `app/` directory (Strictly App Router usage, Client Components chỉ dùng cho Zero-sync hooks).
- Backend: Strict layered architecture: `api/` (Thin routers), `services/` (Business/AI logic), `repositories/` (Database access), `schemas/`, `models/`.
**Development Experience:**
- Hot module reloading (HMR) mượt mà cho Next CLI và Uvicorn.
- Linting/Formatting hợp nhất và siêu nhanh qua `Ruff` cho Python, `ESLint/Prettier` cho TypeScript.
**Note:** Project initialization using this command should be the first implementation story.
## Core Architectural Decisions
### Decision Priority Analysis
**Critical Decisions (Block Implementation):**
- Data Sync & Caching Layer (Quyết định cách Zero-sync giao tiếp với FastAPI & Postgres).
- Authentication & JWT Rotation (Quyết định sinh token cho Zero-sync client).
- Asynchronous Processing (Cách quản lý luồng chunking và RAG pipeline bên ngoài luồng chính).
**Important Decisions (Shape Architecture):**
- Component State Management (Zustand kết hợp với cache cục bộ của IndexedDB).
- Vector Storage Engine (Sử dụng pgvector trong cùng database gốc hay tách rời).
**Deferred Decisions (Post-MVP):**
- Multi-tenancy Scaling (Sẽ ưu tiên RLS chạy trong 1 instance DB cho MVP, Scale out sẽ quyết định sau).
### Data Architecture
- **Database Choice:** PostgreSQL 16+.
- **Vector Storage:** Extension `pgvector` (Version đã verify: `0.8.2`) tích hợp trực tiếp vào DB chính nhằm tận dụng ưu thế JOIN data và RLS.
- **ORM / Query Builder:** `SQLModel` trên Backend và auto-generated Schema của Prisma cung cấp DDL cho Zero-sync.
- **Caching & Local-First Strategy:** Dùng `@rocicorp/zero` (Version đã verify: `1.1.1`) đổ dữ liệu xuống IndexedDB, Next.js sẽ subscribe trực tiếp qua Zero cache thay vì gọi FETCH thông thường.
### Authentication & Security
- **Authentication Method:** JWT Token Auth do Backend FastAPI kiểm soát. Frontend nhận JWT và trao nó cho bộ khởi tạo `ZeroClient`.
- **Authorization Pattern:** Row-level Security (RLS) bắt buộc trên mọi tables Postgres. Logic từ FastAPI đến DB và luồng Zero repl-stream từ DB chọc xuống Next.js đều chịu chung bộ luật RLS này.
- **Security Middleware:** Áp dụng purge (làm sạch) lập tức IndexedDB & localStorage bằng hook `onLogout()`.
### API & Communication Patterns
- **API Design Patterns:**
- Standard RESTFul API cho các tác vụ CRUD thường và logic.
- **Server-Sent Events (SSE) / WebSockets:** Quyết định dùng SSE cho luồng Streaming Response của Agentic RAG vì nó mượt hơn, một chiều từ Server gửi câu trả lời về UI.
- Zero-sync protocol quản lý kết nối WebSocket cho dữ liệu đồng bộ tĩnh.
- **Job Orchestration:** Kết nối FastAPI và Celery Workers qua Redis Message Broker (`redis:7.4+`).
### Frontend Architecture
- **State Management:** Xử lý State toàn cục bằng `Zustand`. Data trả về từ backend đi thẳng vào UI (Offline-first approach), xử lý form với `react-hook-form`.
- **Component Architecture:** Next.js Server Components cho SEO và giao diện tĩnh; các tính năng tương tác với ZeroClient bắt buộc là Client Components (`"use client"`).
- **Styling:** Tailwind CSS + Radix UI / Shadcn (đảm bảo hỗ trợ Darkmode/Glassmorphism).
### Infrastructure & Deployment
- **Hosting Strategy:** Docker-Compose cho toàn bộ hệ thống (đáp ứng PRD local-first).
- **Environment Configuration:** Quản lý môi trường cứng qua `.env` kết nối bằng `pydantic-settings` (FastAPI).
- **Message Broker:** Redis phiên bản containerized.
### Decision Impact Analysis
**Implementation Sequence:**
1. Cấu hình Data Models (SQLModel + pgvector).
2. Thiết lập RLS Policies tại DB.
3. Kích hoạt `@rocicorp/zero` Sync Server và kết nối với Frontend.
4. Xây dựng SSE Streaming cho luồng AI RAG.
**Cross-Component Dependencies:**
- API Gateway thay đổi token Auth -> Zero Sync phải lập tức reset websocket và xin lại credentials.
- Schema Postgres nếu thay đổi -> Zero SDK phải sync lại type-safety ở Next.js.
## Implementation Patterns & Consistency Rules
### Pattern Categories Defined
**Critical Conflict Points Identified:**
Có 4 khu vực rủi ro cao nơi AI Agents dễ bị đụng độ:
1. Xung đột chữ hoa/thường giữa Python (thích snake_case) và TypeScript (thích camelCase).
2. Quy chuẩn cấu trúc JSON trả về từ FastAPI để Next.js (hoặc Zero-sync) dễ parse.
3. Cách gom nhóm files trên Next.js App Router.
4. Xử lý lỗi (Error handling) khi API throw 500 hay khi Zero offline.
### Naming Patterns
**Database Naming Conventions (Postgres/SQLModel):**
- **Tables:** Bắt buộc dùng `snake_case`, số nhiều (VD: `users`, `document_chunks`).
- **Columns:** Bắt buộc dùng `snake_case` (VD: `created_at`, `is_active`). KHÔNG DÙNG `camelCase` trong DB.
- **Foreign Keys:** Hậu tố `_id` (VD: `workspace_id`).
**API Naming Conventions:**
- **Endpoints:** Dùng `kebab-case` và danh từ số nhiều (VD: `/api/v1/knowledge-bases`).
- **Query Params:** Dùng `snake_case` ở phía raw URL (VD: `?sort_by=created_at&limit=10`).
**Code Naming Conventions:**
- **Python (Backend):** Variables & Functions dùng `snake_case` (`def get_user()`); Classes dùng `PascalCase` (`class DatabaseConfig`).
- **TypeScript (Frontend):** Variables & Hooks dùng `camelCase` (`useZeroSync()`); React Components dùng `PascalCase` (`DocumentUploader.tsx`).
- **File Names:** Component là `PascalCase.tsx`, các file helper/util là `kebab-case.ts`.
### Structure Patterns
**Project Organization:**
- Monorepo structure ảo: Tất cả code backend nằm trong thư mục gốc `backend/`, code frontend nằm trong thư mục gốc `web/`.
- Frontend Components: Chia theo feature-based (`web/src/components/features/auth/`), thay vì type-based.
### Format Patterns
**API Response Formats:**
- **Standard Wrapper:** Mọi FastAPI Response trả về REST đều phải được bọc trong cấu trúc chuẩn:
```json
{
"data": { ... }, // Payload chính (null nếu lỗi)
"error": null, // Object lỗi nếu có { "code": 400, "message": "..." }
"meta": { "page": 1 } // Dành cho pagination
}
```
- Streaming API (SSE): Phải trả về chuẩn Server-Sent Event format `data: {"chunk": "..."}\n\n`.
**Data Exchange Formats:**
- FastAPI Pydantic Models **phải alias** các trường `snake_case` thành `camelCase` khi dump ra JSON để Client TypeScript sử dụng.
### Communication Patterns
**State Management Patterns:**
- **Zero-first approach:** Mọi Data state cho entity phải được lấy ra từ hook `useQuery(zero.query...)`. Hạn chế cache local dư thừa.
- **UI State:** Dùng `Zustand` cho các state giao diện.
### Process Patterns
**Error Handling Patterns:**
- **Backend:** Phải ném `HTTPException` và có Global Exception Handler túm lại trả về format lỗi chuẩn.
- **Frontend Error Boundary:** React Error Boundaries phải bọc quanh từng Feature Widget để tránh sập toàn trang.
### Enforcement Guidelines
**All AI Agents MUST:**
- LUÔN kiểm tra Schema Postgres (nếu là Dev Agent) trước khi viết Model Python.
- LUÔN validate Pydantic output dùng `by_alias=True` để convert sang camelCase.
### Pattern Examples
**Good Examples:**
`const { data: userData } = useQuery(zero.query.users.where('is_active', true));`
**Anti-Patterns:**
`def GetUserData(): pass` (Python hàm viết hoa là sai).
Dùng `Fetch()` gọi API ngoài luồng Zero-sync cho các đối tượng đã sync qua Zero.
## Project Structure & Boundaries
### Complete Project Directory Structure
```text
surfsense/
├── .github/ # CI/CD workflows & PR templates
├── surfsense_backend/ # FastAPI Backend (Python)
│ ├── pyproject.toml
│ └── app/
│ ├── main.py # Application entry point
│ ├── api/routes/ # API Routers
│ ├── db.py # SQLAlchemy & PgVector definitions
│ ├── etl_pipeline/ # Text extraction (Docling/Unstructured/Llamacloud)
│ ├── indexing_pipeline/# Chunking, hashing & deduplication
│ ├── retriever/ # Hybrid Search (Full-text + PgVector RRF)
│ ├── schemas/ # Pydantic validation
│ └── tasks/ # Celery workers & beat (Redis)
├── surfsense_web/ # Next.js Frontend (TypeScript)
│ ├── package.json
│ ├── tailwind.config.ts
│ ├── tsconfig.json
│ ├── app/ # App Router
│ ├── components/ # UI and Feature Components
│ ├── lib/ # Generic utilities
│ ├── hooks/ # Custom hooks (Zero-sync wrappers)
│ └── store/ # UI State
├── surfsense_browser_extension/ # Trình duyệt mở rộng
├── surfsense_desktop/ # App Desktop (TBD)
├── docker/ # Cấu hình Docker & Infrastructure
│ └── docker-compose.yml # Orchestration (DB, Redis, Zero Cache, Backend, SearXNG)
├── docs/ # Documentation files
└── README.md
```
### Architectural Boundaries
**API Boundaries:**
- **FastAPI Endpoint Boundaries:** Chỉ phục vụ các tác vụ backend, AI Streaming RAG (Server-Sent Events), ETL, và Celery queueing.
- **Next.js Route Handlers (`surfsense_web/app/api/`):** Chỉ đóng vai trò Proxy an toàn hoặc xử lý Zero-Sync mutators (`/api/zero/mutate`) & query.
**Component Boundaries:**
- **UI vs Feature Components:** Component được định hình rõ ràng giữa các khối giao diện UI thông thường và smart components kết nối trực tiếp với Zero queries.
**Zero-Sync Boundaries (Data):**
- Mọi thao tác Read và Create/Update cho entity cơ bản (như hiển thị Documents list) đều thông qua Zero-Sync (`useQuery` / `zero.mutate`). Trạng thái Offline từ browser sẽ đẩy ngầm về DB Postgres (`zero-cache` process, port 4848).
### Requirements to Structure Mapping
**Epic/Feature Mapping (Agentic RAG & Streaming):**
- *Tính năng:* AI Search Streaming & Semantic Retreival
- **Backend Components:** `surfsense_backend/app/retriever/chunks_hybrid_search.py` (chứa Postgres RRF queries kết hợp vector).
- **Frontend Components:** `surfsense_web/app/...` và các hook chat streaming.
**Cross-Cutting Concerns (Local-First Experience):**
- *Tính năng:* Đồng bộ siêu trễ, UI luôn mượt dù mạng chậm.
- **Zero Configuration:** Quản lý trong `docker/docker-compose.yml` image `rocicorp/zero`.
- **Tương tác Interface:** Dùng hooks gọi Zero client để UI render tức thì.
### Integration Points
**Internal Communication:**
- Frontend giao tiếp với Backend qua 2 đường:
1. Cổng SSE trực tiếp `[Web] ----(SSE)----> [FastAPI]` cho AI Streaming & RAG.
2. Cổng Đồng bộ Dữ liệu Cục bộ: `[Web] <---(WebSockets)---> [Zero Cache] <---(Logical Replication)---> [Postgres]`.
**Data Flow:**
Luồng Upload tài liệu & RAG:
1. User upload file. API FastAPI nhận phản hồi lập tức nhờ `create_placeholder_documents()` (để trạng thái `pending` của tài liệu hiện ngay trên UI via Zero-Sync).
2. Tác vụ đẩy vào Pipeline `IndexingPipelineService` (Có thể process ở Background via Celery hoặc Parallel Batch).
3. `EtlPipelineService` trích xuất text (Plaintext/Docling/Vision_LLM). Chunks được hash và deduplicate.
4. Pgvector lưu Vectors thành công và đổi status => `ready`. Zero Server bắt được thay đổi qua Replication từ Postgres và push qua Web Socket về giao diện, UI tự động cập nhật mà không cần tải lại trang.
## Architecture Validation Results
### Coherence Validation ✅
**Decision Compatibility:**
- Tuyệt đối tương thích: Việc chia tách trách nhiệm rõ ràng (Web Client quản lý state bằng Zero Sync; FastAPI chỉ xử lý các tác vụ nặng & Streaming RAG) giúp tránh conflict về source of truth. Zero-Sync tương thích hoàn hảo với Postgres Logical Replication.
- Celery + Redis là combo battle-tested cho Async task, không có rủi ro về stack.
**Pattern Consistency:**
- Quy ước Naming Conventions (TypeScript: `camelCase`, DB & Python: `snake_case`) cùng nguyên tắc tự chuyển đổi (Alias `by_alias=True` trong Pydantic) giải quyết triệt để rủi ro lệch chuẩn dữ liệu khi các AI Agents Gen code tự động.
**Structure Alignment:**
- Cấu trúc "Monorepo ảo tĩnh" chia đôi `web/``backend/` tách biệt hoàn toàn Development Environment (uv cho Python, pnpm cho Node) nên không lấn cấn cấu hình.
### Requirements Coverage Validation ✅
**Epic/Feature Coverage:**
- **Local-first (FR9):** Covered 100% nhờ `@rocicorp/zero` và cấu hình IndexedDB cached.
- **DeepRAG & Streaming (FR4):** Covered 100% nhờ sự kết hợp giữa FastAPI Server-Sent Events (SSE) và Postgres `pgvector`.
**Non-Functional Requirements Coverage:**
- **Latency (TTFT < 1.5s):** Fast API async router và Streaming trực tiếp nén TTFT cực tốt.
- **Scalability:** Scale Backend độc lập với Frontend. Khâu process văn bản được tách riêng ra worker nodes qua Celery tránh sập web server.
### Implementation Readiness Validation ✅
**Decision Completeness:**
- Stack rõ ràng, version cụ thể (`Next.js 14+`, `FastAPI 0.100+`, `pgvector 0.8+, Postgres 16`, `@rocicorp/zero 1.1.1`).
- Đã quy định rõ AI Error Boundaries.
### Architecture Completeness Checklist
**✅ Requirements Analysis**
- [x] Đã phân tích toàn diện 14 FRs và 7 NFRs.
- [x] Đã xác định được "Local-first" và "Fast AI Streaming" là yêu cầu cốt lõi.
**✅ Architectural Decisions**
- [x] Quyết định 4 trụ cột công nghệ (Next.js, FastAPI, Postgres+Zero, Redis+Celery).
- [x] Các Quyết định bảo mật RLS và JWT tích hợp Zero.
**✅ Implementation Patterns**
- [x] Thiết lập Rule đặt tên rõ ràng chéo ngôn ngữ (TS & Python).
- [x] Chốt cấu trúc Request/Response bọc Standard Error Handler.
**✅ Project Structure**
- [x] Lên cây thư mục (Directory Tree) độc lập Backend - Web - Zero Config.
### Architecture Readiness Assessment
**Overall Status:** READY FOR IMPLEMENTATION
**Confidence Level:** HIGH (Cao)
- Kiến trúc giải quyết được bài toán khó nhất là: "Làm sao vừa chạy Local-first nhanh chóng lại vừa chạy Tác vụ AI siêu nặng".
**Implementation Handoff**
**Implementation Handoff**
- **First Implementation Priority:** Dùng hệ thống sẵn có (đã khởi tạo Next.js `surfsense_web` và FastAPI `surfsense_backend`). Môi trường local chạy qua `docker compose -f docker/docker-compose.dev.yml up -d` với đầy đủ Postgres (pgvector), Redis, Zero-Cache và SearXNG.

View file

@ -0,0 +1,91 @@
# SurfSense: Sơ đồ Macro User Flow Toàn Hệ Thống
Sau khi đào thật sâu vào toàn bộ source code của dự án, em phát hiện ra SurfSense không chỉ là một Web App đơn thuần. Đây là một **Hệ sinh thái đa nền tảng (Macro Ecosystem)** bao gồm 4 khối lớn làm việc chặt chẽ với nhau: `surfsense_web`, `surfsense_desktop`, `surfsense_browser_extension`, và `surfsense_backend`.
Đây là sự liên kết luồng thao tác của người dùng xuyên suốt toàn bộ các nền tảng của hệ thống:
```mermaid
graph TD
classDef web fill:#09090b,stroke:#a5b4fc,stroke-width:2px,color:#fff;
classDef desk fill:#1e1b4b,stroke:#8b5cf6,stroke-width:2px,color:#fff;
classDef ext fill:#18181b,stroke:#f472b6,stroke-width:2px,color:#fff;
classDef back fill:#27272a,stroke:#34d399,stroke-width:2px,color:#fff,stroke-dasharray: 5 5;
%% -------------------
%% 1. Web Flow (Surfsense_web)
%% -------------------
subgraph WebApp ["1. SurfSense Web (Next.js)"]
Login["Identity Provider (Auth/Callback)"]:::web
Dashboard["Dashboard & Search Spaces"]:::web
Connectors["Cloud Connectors (OAuth)"]:::web
Billing["Billing & Settings"]:::web
end
%% -------------------
%% 2. Desktop App Flow (Surfsense_desktop)
%% -------------------
subgraph DesktopApp ["2. SurfSense Desktop (Electron)"]
DLogin["Deep Link Login (Qua Web)"]:::desk
FolderWatcher["Folder Watcher (Dong bo file local)"]:::desk
QuickAsk["Quick Ask (Hoi nhanh kieu Spotlight)"]:::desk
Tray["System Tray & Phim Tat"]:::desk
end
%% -------------------
%% 3. Browser Extension Flow
%% -------------------
subgraph BrowserExt ["3. SurfSense Extension"]
ExtPopup["Popup UI & Auth"]:::ext
ExtCapture["Web Content Capture (Doc trang web)"]:::ext
end
%% -------------------
%% 4. Backend Core Flow
%% -------------------
subgraph Backend ["4. SurfSense Backend (FastAPI, Celery)"]
API["Core API Routes"]:::back
ETL["ETL & Indexing Pipeline (Xu ly Data)"]:::back
Agents["AI Agents (LLMs)"]:::back
Retriever["Vector Search / RAG"]:::back
end
%% --- Giao thiep Auth ---
DLogin -->|"Goi URL trinh duyet"| Login
ExtPopup -->|"Xac thuc session"| Login
Login --> Dashboard
%% --- Giao thiep Data (Ingestion) ---
FolderWatcher -->|"Lang nghe & ban file PDF/Doc"| API
ExtCapture -->|"Gửi the Tabs/HTML"| API
Connectors -->|"Trigger Cloud Sync"| API
API -->|"Jobs"| ETL
%% --- Giao thiep hoi dap (Chat) ---
Dashboard -->|"Gui Chat"| API
QuickAsk -->|"Spotlight Search"| API
API -->|"Retrieve Context"| Retriever
Retriever -->|"Context"| Agents
Agents -->|"Streaming Tra loi"| API
```
## Các phám phá cốt lõi (Deep Dive Findings)
1. **Local-First Synchronization với Desktop App (`surfsense_desktop`)**
- Ứng dụng Desktop không chỉ để dùng web. Nó chứa module `folder-watcher.ts` liên tục quét thư mục trên máy tính người dùng và tự động đẩy dữ liệu (PDF, Docs) lên hệ thống để AI đọc. Đây là luồng ingest data hoàn toàn ngầm mà user không cần thao tác upload thủ công trên giao diện web.
- Nó cũng chứa module `quick-ask.ts`, cho phép user dùng tổ hợp phím gợi Spotlight Bar để hỏi đáp AI nhanh mà không cần mở app.
2. **Cánh tay nối dài Browser Extension (`surfsense_browser_extension`)**
- Luồng lưu trữ nội dung web: User đọc bài báo ở các tab, bấm vào extension để Capture và đưa thẳng nội dung đó vào "Search Space".
3. **Backend Pipeline khổng lồ (`surfsense_backend`)**
- Đằng sau API là một dây chuyền công nghiệp: Nhận file -> `celery` chia việc -> `etl_pipeline` xử lý văn bản -> `indexing_pipeline` tự động cắt đoạn và lưu vector DB.
- Phần trả lời là do module `agents``retriever` đảm nhiệm (chuẩn RAG).
**Phân tích UX:**
Nhờ việc kiểm tra chéo này, em nhận ra UX của Web App không cần quá nhấn mạnh vào nút "Upload File" khổng lồ như các app khác, vì SurfSense đã giải quyết vấn đề nhập liệu ngầm thông qua **Desktop Folder Watcher****Browser Extension/Cloud Connectors**.
Do đó, UI Web app (`The Scholar` direction) chỉ cần tối tưu cho việc **Hiển thị, Tra cứu và Trí tuệ (Chat Layout)**.
Anh thấy sự móc nối sinh thái đa nền tảng này đã mô tả đúng tầm nhìn kiến trúc của SurfSense chưa ạ?

View file

@ -0,0 +1,143 @@
# SurfSense: Sơ đồ chi tiết các Luồng Ẩn (Triển khai Sâu)
Dựa trên việc kiểm tra sâu cấu trúc database (`db.py`) và kiến trúc API, đây là các Luồng Vi mô (Micro Flows) diễn ra bên dưới bề nổi bổ sung thêm cho 4 luồng cơ bản ban đầu. Đây là các Flow cấu thành sức mạnh hệ sinh thái nền tảng của SurfSense.
---
## 5. Luồng Đồng bộ Thời gian thực & Local-first (RociCorp Zero)
Giao diện của SurfSense đạt được tốc độ phản hồi tính bằng mili-giây (Instant UI) nhờ vào công nghệ Local-first từ Zero.
```mermaid
sequenceDiagram
participant User as Nguoi Dung
participant NextJS as NextJS Client (Z-Store)
participant Zero as Zero Cache Server
participant Postgres as PostgreSQL DB
%% Trang thai offline hoac low-latency
User->>NextJS: Tao Search Space moi
activate NextJS
NextJS->>NextJS: Ghi vao IndexedDB (Local)
NextJS-->>User: [UI] Cap nhat ngay lap tuc (0 latency)
%% Dong bo background
NextJS->>Zero: Day Mutator (Sync)
deactivate NextJS
activate Zero
Zero->>Postgres: Luu thay đoi vao DB trung tam
Postgres-->>Zero: Xac nhan luu thanh cong
%% Nguoi dung khac trong cung Search Space
Zero->>NextJS: Ban Replication Subscriptions (Socket)
deactivate Zero
activate NextJS
NextJS->>NextJS: Cap nhat Z-Store cho User B
deactivate NextJS
```
---
## 6. Luồng Uỷ quyền và Nuốt Dữ liệu từ App Thứ 3 (Third-Party Connectors)
Quy trình nhập liệu từ các nền tảng SaaS (Notion, Google Drive, Jira...) sử dụng Composio và Custom Extractors.
```mermaid
sequenceDiagram
participant User as Nguoi Dung
participant Web as Web UI
participant Backend as FastAPI
participant Auth as Composio OAuth
participant 3rdParty as Notion/Drive/Jira
participant Celery as ETL Celery Workers
User->>Web: Bam ket noi "Notion"
Web->>Backend: Yeu cau Authorization URL
Backend->>Auth: Tao Phien ung dung (Session)
Auth-->>User: Chuyen huong sang trang OAuth cua Notion
User->>3rdParty: Dong y cap quyen đoc
3rdParty-->>Backend: Callback Redirect voi Auth Code
activate Backend
Backend->>Auth: Đoi Code lay Access Token
Auth-->>Backend: Tra ve Token
Backend->>Backend: Luu vao Search Space DB
deactivate Backend
%% Kich hoat Ingestion
Backend->>Celery: Giao nhiem vu Crawl API (Task)
activate Celery
Celery->>3rdParty: Pull hang loat Docs / Tickets
3rdParty-->>Celery: Tra ve JSON data
Celery->>Celery: Convert JSON -> Markdown -> Chunks
Celery->>Celery: Luu VectorDB
Celery-->>Web: Notification: "Dong bo Notion hoan tat"
deactivate Celery
```
---
## 7. Luồng Giao tiếp Cộng tác & Bình luận (Collaboration / Chat Comments)
Mỗi Search Space trong SurfSense là một "Phòng làm việc chung". Các đoạn Chat AI có thể được bình luận, chia sẻ.
```mermaid
sequenceDiagram
participant UserA as Nguoi Dung A
participant Zero as Zero (Realtime)
participant DB as Postgres (Chat_Comments)
participant UserB as Nguoi Dung B
UserA->>UserA: Mo đoan chat cua Assistant
UserA->>Zero: Them Comment "@UserB cậu xem đoan nay"
activate Zero
Zero->>DB: Luu Comment vao NewChatMessage
%% Tinh nang cap nhat tu đong cho UserB
DB-->>Zero: State Changed
Zero-->>UserB: Trigger Sync (Realtime) tang IndexedDB
deactivate Zero
activate UserB
UserB->>UserB: Thay notification Mention tren UI
UserB->>Zero: Reply lai Comment
deactivate UserB
```
---
## 8. Luồng Phát sinh Nội dung Đa phương tiện từ RAG (Podcast / Video)
Trình độ tổng hợp kiến thức của SurfSense không dừng ở đoạn text, mà còn mở rộng ra Audio, Podcasts, Video Presentation dựa trên DB Models.
```mermaid
sequenceDiagram
participant User as Nguoi Dung
participant Web as Web UI
participant API as FastAPI
participant Celery as Celery Tasks
participant GenAI as Audio/Video Gen AI
participant DB as Postgres
User->>Web: "Tao Podcast ve chu đe bao cao thang nay"
activate Web
Web->>API: POST /api/generate-podcast
deactivate Web
activate API
API->>DB: Tao ban ghi PodcastStatus = PENDING
API->>Celery: Send task `generate_podcast`
API-->>Web: Tra ve Job ID
deactivate API
activate Celery
Celery->>DB: Update PodcastStatus = GENERATING
Celery->>GenAI: Truyen RAG content & Yeu cau sinh giong noi
activate GenAI
GenAI-->>Celery: Tra ve Stream/File URL (Media)
deactivate GenAI
Celery->>DB: Update PodcastStatus = READY & Luu Media Path
deactivate Celery
%% Cap nhat UI qua Zero
DB-->>Zero: State Mutation
Zero-->>Web: Giao dien hien thi Audio Player
```

View file

@ -0,0 +1,154 @@
# SurfSense: Chi tiết Micro User Flows
Dưới đây là sơ đồ chi tiết (Micro Flows) phân tách sâu vào 4 tính năng lõi quan trọng nhất của hệ thống, bao phủ cả trải nghiệm người dùng lẫn luồng dữ liệu ngầm phía sau.
---
## 1. Luồng Tự động Nhập dữ liệu (Local-First Ingestion)
Đây là "vũ khí bí mật" của SurfSense. Thay vì bắt user bấm nút upload thủ công, hệ thống sử dụng Desktop App và Extension để tự động hóa việc đưa tài liệu vào ngữ cảnh của AI.
```mermaid
sequenceDiagram
participant User as Nguoi Dung
participant Desk as Desktop App (Watcher)
participant Ext as Browser Extension
participant API as Backend API
participant ETL as ETL & Indexing Pipeline
%% Desktop Sync
User->>Desk: Luu file PDF/Doc vao thu muc "SurfSense"
activate Desk
Desk->>Desk: Phat hien file moi (chokidar)
Desk->>API: Upload file background
deactivate Desk
%% Extension Sync
User->>Ext: Chon "Luu vao SurfSense" khi dang doc bao
activate Ext
Ext->>Ext: Dung content.ts trich xuat HTML/Text
Ext->>API: Gui data qua API
deactivate Ext
%% Processing
activate API
API->>ETL: Chuyen Job vao Hang doi Celery
deactivate API
activate ETL
ETL->>ETL: Parsing (Tach van ban)
ETL->>ETL: Chunking (Chia nho doan)
ETL->>ETL: Embedding (Vector hoa)
ETL-->>User: [UI notification] "Tai lieu da san sang đe hoi đap!"
deactivate ETL
```
---
## 2. Luồng Trò chuyện & Truy xuất (Core Analytical Chat - RAG)
Đây là tính năng tương tác chính trên Website, nơi người dùng đặt câu hỏi và AI tìm kiếm bối cảnh từ dữ liệu cá nhân của user.
```mermaid
sequenceDiagram
participant User as Nguoi Dung
participant Web as Web (surfsense_web)
participant API as FastAPI Backend
participant RAG as Retriever (Vector DB)
participant LLM as AI Agents
User->>Web: Nhap cau hoi: "Tom tat cho toi file Report"
activate Web
Web->>API: POST /api/chat
activate API
API->>RAG: Truy van Vector (Semantic Search)
activate RAG
RAG-->>API: Tra ve Top-K chunks & Metadata
deactivate RAG
API->>LLM: Chuyen Cau hoi + Context cho Agent
activate LLM
LLM-->>API: Stream tokens (Co danh dau Citation)
deactivate LLM
API-->>Web: SSE (Server-Sent Events) Stream
deactivate API
Web->>Web: Parse token & Hien thi tin nhan AI
Web->>Web: Thay Citation [1], [2] -> Hien thi tai lieu o Split-Pane
Web-->>User: Đoc tra loi va bam vao Citation đe xem source
deactivate Web
```
---
## 3. Luồng Hỏi Đáp Thần Tốc (Desktop Quick Ask)
Một tính năng nổi bật giúp SurfSense gắn chặt vào thói quen hàng ngày của User. Bất kể đang mở app nào, user chỉ cần bấm tổ hợp phím là có thể truy vấn mọi tài liệu.
```mermaid
sequenceDiagram
participant OS as He đieu hanh
participant Tray as Desktop Tray & Shortcuts
participant QA as Quick Ask Overlay
participant API as Backend API
User->>OS: Bam to hop (VD: Cmd/Ctrl + Shift + Space)
OS->>Tray: Kich hoat Global Shortcut
activate Tray
Tray->>QA: Hien thi khung tim kiem noi (Spotlight)
deactivate Tray
activate QA
QA-->>User: San sang nhan Text
User->>QA: Nhap nhanh: "Tai lieu doanh thu nam ngoai đe o đau?"
QA->>API: Goi API chat nhanh
activate API
API-->>QA: Stream cau tra loi + ten file
deactivate API
QA-->>User: Tra ket qua tuc thi
%% Tuy chon
User->>QA: Click Open in App
QA->>OS: Mo Surfsense Web hoac App chinh tung ung
deactivate QA
```
---
## 4. Luồng Chuyển giao Xác thực (Cross-Platform Auth)
Vì Web đóng vai trò là Hub chính, Desktop App cần cơ chế mượn xác thực từ Web một cách mượt mà và an toàn.
```mermaid
sequenceDiagram
participant User as Nguoi Dung
participant Desk as Desktop App
participant Web as Web App
participant API as Backend API
User->>Desk: Mo App lan đau
activate Desk
Desk-->>User: Hien "Login with Browser"
User->>Desk: Bấm Login
Desk->>Web: Mo trinh duyet voi Deep Link (schema: surfsense://)
deactivate Desk
activate Web
Web->>Web: Kiem tra Session/Cookies
alt Neu chua login
Web-->>User: Mo trang /login > Nhap tai khoan > Thanh cong
end
Web->>API: Tao Token phien lam viec
API-->>Web: Tra ve Token an toan
Web->>Desk: Chuyen huong ve surfsense://auth?token=...
deactivate Web
activate Desk
Desk->>Desk: Luu Token vao Keychain/Secure Storage
Desk-->>User: Chua san sang, chuyen sang man hinh Permissions
User->>Desk: Cap quyen đoc thu muc (Mac/Win)
Desk-->>User: "San sang đong bo!"
deactivate Desk
```
---
*Ghi chú: Toàn bộ biểu đồ đã được biên dịch không chứa dấu tiếng Việt bên trong logic sơ đồ để đảm bảo khả năng tương thích hiển thị tuyệt đối.*

View file

@ -0,0 +1,314 @@
---
stepsCompleted:
- step-01-validate-prerequisites.md
- step-02-design-epics.md
inputDocuments:
- _bmad-output/planning-artifacts/prd.md
- _bmad-output/planning-artifacts/architecture.md
- _bmad-output/planning-artifacts/ux-design-specification.md
---
# SurfSense - Epic Breakdown
## Overview
This document provides the complete epic and story breakdown for SurfSense, decomposing the requirements from the PRD, UX Design if it exists, and Architecture requirements into implementable stories.
## Requirements Inventory
### Functional Requirements
FR1: Người dùng có thể tải lên các tệp tài liệu (PDF, TXT) vào không gian làm việc của họ.
FR2: Người dùng có thể xem lại danh sách các tài liệu đã tải lên trước đó.
FR3: Người dùng có thể xem được trạng thái tiến trình trích xuất (Đang đợi, Đang xử lý, Hoàn thành, Lỗi) của một tài liệu.
FR4: Người dùng có thể xóa một tài liệu khỏi không gian làm việc của họ.
FR5: Người dùng có thể tạo một phiên hỏi đáp (Chat Session) mới.
FR6: Người dùng có thể gửi câu hỏi dạng văn bản vào một phiên chat.
FR7: Người dùng có thể nhận được các luồng phản hồi trực tiếp (Streaming responses) từ AI bot theo thời gian thực.
FR8: Người dùng có thể xem lại danh sách các phiên trò chuyện trong quá khứ.
FR9: Người dùng có thể đọc lại toàn bộ nội dung tin nhắn của một phiên trò chuyện cụ thể.
FR10: Người dùng có thể đọc danh sách tài liệu và nội dung các khung chat cũ ngay cả khi ngắt kết nối hoàn toàn với internet.
FR11: Người dùng có thể nhận biết được trạng thái đồng bộ dữ liệu hiện tại của hệ thống (Ví dụ: Offline, Đang đồng bộ, Đã cập nhật xong).
FR12: Hệ thống có khả năng tự động bóc tách văn bản và tạo Vector Embeddings một cách bất đồng bộ ngầm khi tài liệu mới được tải lên.
FR13: Hệ thống có khả năng chặn yêu cầu (Rate Limit) nếu người dùng sử dụng vượt mức Token cho phép hoặc tải file quá quy định.
FR14: Người dùng có thể xác thực (Authentication) để đăng nhập và bảo vệ dữ liệu thuộc private workspace của họ.
### NonFunctional Requirements
NFR-P1 (Time to First Token - TTFT): Hệ thống bắt buộc phải phản hồi ký tự đầu tiên từ AI Agent thông qua SSE dưới 1.5 giây kể từ khi user nhấn Submit.
NFR-P2 (Sync Latency): Thời gian bộ nhớ đệm Zero-cache đồng bộ thay đổi trạng thái từ Remote DB về Local IndexedDB không được vượt quá 3 giây.
NFR-P3 (Background Processing): Tác vụ bóc tách văn bản và tạo Vector Embeddings cho file <5MB phải xong trên Celery Queue dưới 30 giây.
NFR-S1 (Data Segregation): RLS bắt buộc áp dụng. User ID không có quyền truy vấn dữ liệu tài khoản khác.
NFR-S2 (Local Storage Security): Dữ liệu Zero-cache bị xóa hoàn toàn khi "Log Out".
NFR-SC1 (Worker Scalability): Celery Worker phải "Stateless", có thể add thêm n-Workers mà code không can thiệp.
NFR-R1 (Offline Tolerance): Giao diện không trắng xoá khi mất mạng, đọc cache mượt như đang online.
### Additional Requirements
- Tận dụng Starter Template đã chọn: Official Next.js CLI & Custom Fast-Modern Async API (Cần lưu ý cho Epic 1 Story 1).
- Cấu trúc hệ thống Monorepo dùng Docker-compose để boot Postgres, Redis, Zero Server và Backend.
- Database Postgres sử dụng extension pgvector 0.8.2. Backend Python dùng SQLModel.
- Đồng bộ Realtime Local-first với rocicorp/zero 1.1.1 (truyền JWT từ API gateway sang bộ zero-client).
- Backend FastAPI phải trả về các REST API được bọc response chuẩn: `{ "data": ..., "error": ..., "meta": ... }`.
- Naming convention: FastAPI dùng snake_case nhưng output Pydantic phải set `by_alias=True` để convert ra camelCase phục vụ cho TypeScript Client. Database strictly snake_case.
- State Management: Sử dụng Zustand cho Global UI state, form xử lý với react-hook-form. Mọi fetch data chính từ Zero hook thay vì REST API.
- API Streaming: Thực thi Server-Sent Events cho luồng trả lời Chatbot RAG.
### UX Design Requirements
UX-DR1: Triển khai Design System từ shadcn/ui & Tailwind CSS. Base color là Zinc/Slate (Dark mode #09090b); màu nhấn Accent là Indigo/Teal chuyên dùng cho button và thẻ citation. Typography với font Inter/Geist Sans và JetBrains Mono.
UX-DR2: Ràng buộc Transition/Animation thời gian đáp ứng cực ngắn (<150ms) đáp ứng trải nghiệm Khởi tác Tức thì trên toàn ứng dụng.
UX-DR3: Cấu trúc Layout đặc thù Tách viền (Dynamic Split-Pane) phân bổ màn hình hiển thị cả khu vực dòng Chat và Trình đọc/view Document đồng thời; cần implement thư viện như `react-resizable-panels`.
UX-DR4: Action "Interactive Citation" Khi người dùng click hoặc tương tác thẻ citation, hệ thống phải liên kết điều khiển panel Document auto-scroll hoặc highlight sang đúng vị trí đoạn text gốc mà không cần refresh.
UX-DR5: Xây dựng System Indicators mượt mà (Micro-Sync Indicator) - chấm vàng góc màn hình thể hiện Syncing, thanh process bar nhỏ đính kèm các file list đang được upload (Index ẩn). Không dùng blocking modal spinners chặn màn hình.
UX-DR6: Hiển thị giao diện "Graceful Degradation" linh hoạt khi Offline: tự chuyển các nút/icon qua xám muted, duy trì trải nghiệm đọc danh sách và chat history trong trạng thái mất kết nối mạng.
### FR Coverage Map
FR1: Epic 2 - Tải tài liệu lên workspace
FR2: Epic 2 - Xem danh sách tài liệu đã tải
FR3: Epic 2 - Theo dõi trạng thái tiến trình trích xuất
FR4: Epic 2 - Xoá tài liệu khỏi workspace
FR5: Epic 3 - Tạo phiên chat mới
FR6: Epic 3 - Gửi câu hỏi vào chat
FR7: Epic 3 - Nhận phản hồi Streaming tức thì
FR8: Epic 4 - Xem danh sách phiên chat cũ
FR9: Epic 4 - Đọc nội dung tin nhắn cũ
FR10: Epic 4 - Đọc tài liệu/chat khi ngắt mạng (Offline mode)
FR11: Epic 4 - Nhận biết trạng thái đồng bộ Zero-sync (Online/Offline/Syncing)
FR12: Epic 2 - Tiến trình nhúng Vector bất đồng bộ ngầm
FR13: Epic 2 - Chặn yêu cầu nếu vượt mức cho phép (Rate Limit)
FR14: Epic 1 - Xác thực và bảo vệ dữ liệu (Workspace)
## Epic List
### Epic 1: Thiết lập Không gian riêng tư & Xác thực người dùng (User Workspace & Authentication)
Người dùng có thể đăng ký, đăng nhập và sở hữu một vùng không gian thao tác hoàn toàn tách biệt, bảo mật tuyệt đối cho dữ liệu cá nhân của họ. Epic này đặt nền móng hạ tầng (Next.js, FastAPI, Database) cho các tính năng tiếp theo.
**FRs covered:** FR14
#### Story 1.1: Khởi tạo Hạ tầng Dự án & Cơ sở Dữ liệu (Project Infrastructure & Database Init)
As a Kỹ sư Hệ thống,
I want thiết lập bộ khung Next.js, FastAPI, và cấu hình Docker-compose cho Postgres/Redis/ZeroServer,
So that toàn bộ nền tảng có thể khởi chạy môi trường phát triển (Dev Environment) một cách nhất quán cho tất cả các team.
**Acceptance Criteria:**
**Given** môi trường dự án mới
**When** chạy lệnh `docker-compose -f docker/docker-compose.dev.yml up -d`
**Then** các containers Postgres 16 (với pgvector), Redis, Zero-Server, FastAPI, và Next.js khởi tạo thành công
**And** database tự động migrate được schema ban đầu bao gồm bảng `users` với quy tắc `snake_case`.
#### Story 1.2: Triển khai Backend API Xác thực & JWT (Backend Auth API & JWT)
As a Người dùng,
I want gọi API an toàn để tạo tài khoản, đăng nhập và lấy mã Token (JWT),
So that hệ thống xác thực được danh tính của tôi và kích hoạt RLS (Row-level Security) bảo vệ dữ liệu trên Database Postgres.
**Acceptance Criteria:**
**Given** thông tin đăng nhập hợp lệ
**When** gửi request tới endpoint liên quan `/api/v1/auth/login`
**Then** hệ thống trả về mã JWT chứa userID hợp lệ, bọc trong cấu trúc Wrapper chuẩn `{ "data": {"token": "xxx"}, "error": null, "meta": null }`
**And** Cấu hình Row-Level Security (RLS) cơ bản cho bảng dữ liệu (người này không query được dữ liệu của người kia).
#### Story 1.3: Giao diện Đăng nhập & Tích hợp Token vào Zero-Client (Frontend Auth UI)
As a Người dùng,
I want sử dụng giao diện trơn tru để đăng ký/đăng nhập,
So that tôi nhận được Token và ngay lập tức kết nối tới hệ thống dữ liệu Local-first an toàn qua Zero Client.
**Acceptance Criteria:**
**Given** tôi đang ở trạng thái khách (Guest) trên UI
**When** tôi điền form đăng nhập thành công
**Then** giao diện lưu token vào cục bộ và tự động khởi tạo instance `ZeroClient` để bắt đầu mở cầu nối WebSockets.
**And** khi tôi nhấn nút "Đăng xuất" (Log Out), hàm `onLogout()` tự động thực thi dọn dẹp sạch (purge) toàn bộ IndexedDB, chặn bảo mật.
**And** Giao diện (Form đăng nhập, nút bấm) ứng dụng quy chuẩn UX-DR1 (Màu Base Zinc/Accent Indigo, font Inter).
### Epic 2: Quản lý Kho kiến thức & Trích xuất tự động (Knowledge Base Management & Ingestion)
Người dùng dễ dàng kéo thả các tệp PDF/TXT lên hệ thống; hệ thống tự động bóc tách dữ liệu mượt mà trong nền mà không làm gián đoạn công việc. Họ nắm rõ tiến độ nạp file và làm chủ khối lượng tài liệu của mình.
**FRs covered:** FR1, FR2, FR3, FR4, FR12, FR13
#### Story 2.1: Khởi tạo Kiến trúc Tác vụ nền & Xử lý PDF (Celery Worker & PDF Parser)
As a Kỹ sư Hệ thống,
I want xây dựng hệ thống worker bất đồng bộ (Celery + Redis) để bóc tách văn bản và tạo Vector Embeddings,
So that hệ thống API chính không bị nghẽn khi người dùng upload file, và có thể scale linh hoạt số lượng worker.
**Acceptance Criteria:**
**Given** phần mềm nhận một file PDF/TXT được đẩy vào hàng đợi (Queue)
**When** worker được phân công thực thi tác vụ
**Then** tiến trình phân giải text và nạp Vector qua pgvector hoàn thành dưới 30s (đối với file <5MB)
**And** trạng thái bản ghi tài liệu trên Database được cập nhật tuần tự (Processing -> Completed hoặc Error).
#### Story 2.2: Triển khai API Tải lên & Giới hạn Rate Limit (Upload API & Rate Limiting)
As a Kỹ sư Backend,
I want xây dựng endpoint FastAPI cho việc upload tài liệu kèm cơ chế Rate Limit,
So that server tiếp nhận an toàn và ngăn chặn upload spam quá mức hệ thống cho phép.
**Acceptance Criteria:**
**Given** người dùng đăng nhập hợp lệ
**When** đính kèm file và gửi POST tới `/api/v1/documents`
**Then** hệ thống check user token, lưu file vô Storage, tạo record ở DB với status 'Queue', và trigger đẩy task vào Celery
**And** nếu user push liên tục quá mức quy định (token/hạn mức tải), API sẽ trả về lỗi `429 Too Many Requests` bọc trong error format chuẩn.
#### Story 2.3: Giao diện Quản lý Tài liệu & Chỉ báo Syncing Khớp nối (Knowledge Base UI & Micro-Sync Indicators)
As a Người dùng,
I want thấy ngay lập tức danh sách tài liệu đang có và dễ dàng tải file mới lên,
So that tôi biết file nào đã sẵn sàng để chat, file nào đang chạy nền mà không bị gián đoạn thao tác chuột.
**Acceptance Criteria:**
**Given** người dùng ở giao diện không gian làm việc (Workspace)
**When** có một tài liệu đang được tải lên hoặc xử lý (Processing)
**Then** UX hiển thị thanh tiến trình nhỏ ở góc trên màn hình / cạnh danh sách (Micro-Sync Indicator) và không được chặn màn hình (UX-DR5)
**And** danh sách tài liệu được lấy thông qua Zero-client tự động update state realtime khi worker xử lý xong (FR2, FR3).
#### Story 2.4: API và Giao diện Xóa tài liệu khỏi Workspace (Delete Document Flow)
As a Người dùng,
I want chọn một tài liệu cũ và xóa hoàn toàn,
So that không gian lưu trữ được dọn dẹp và AI sẽ không bao giờ truy cập nội dung đó nữa.
**Acceptance Criteria:**
**Given** người dùng đang có tài liệu hiển thị trên danh sách
**When** người dùng click icon "Xoá" file
**Then** dữ liệu tài liệu lập tức bị loại bỏ khỏi giao diện UI do cơ chế optimism update của Zero
**And** trên Database, bản ghi bị xoá hoặc mark deleted, kèm theo việc dọn dẹp các Vectors rác liên quan trong background.
### Epic 3: Trò chuyện AI Hiện đại & Nguồn trích dẫn (AI Interactive Chat & Streaming Responses)
Người dùng có trải nghiệm truy vấn kho tài liệu "không độ trễ" (Instant Action) thông qua chat. Kết quả được stream về theo thời gian thực như một trợ lý xịn, tích hợp hệ thống Split-pane tinh tế để đối chiếu thẳng với Nguồn trích dẫn.
**FRs covered:** FR5, FR6, FR7
#### Story 3.1: API Tạo & Quản lý Phiên Chat (Chat Session API)
As a Người dùng,
I want tạo một phiên trò chuyện (chat session) mới với AI,
So that tôi có thể bắt đầu một định mức hội thoại mới, tách bạch hoàn toàn với các chủ đề cũ.
**Acceptance Criteria:**
**Given** cửa sổ Chat
**When** tôi chọn lệnh "New Chat" hoặc nhập thẳng vào input đầu tiên
**Then** hệ thống tạo một "Session" ID mới trên Database và lưu tin nhắn đầu tiên của user (FR5, FR6)
**And** trả về data qua REST API theo wrapper chuẩn để client chốt phiên làm việc.
#### Story 3.2: Khối RAG Engine & Cổng trả Streaming SSE (RAG Engine & SSE Endpoint)
As a Kỹ sư Backend,
I want xây dựng khối RAG query bằng pgvector và đẩy dữ liệu về dạng Server-Sent Events (SSE),
So that AI có thể phản hồi từng chữ một (streaming) ngay khi lấy được ngữ cảnh, và đảm bảo chuẩn NFR-P1 (< 1.5s).
**Acceptance Criteria:**
**Given** backend nhận một câu hỏi của user và Session ID
**When** gọi tới Model AI (ví dụ OpenAI/Gemini) với ngữ cảnh lấy từ VectorDB
**Then** API `/api/v1/chat/stream` trả dòng response trả về dưới định dạng sự kiện SSE (text/event-stream) (FR7)
**And** ký tự đầu tiên (First token) về tới client dưới 1.5s
**And** ở cuối luồng stream trả về đính kèm bộ Metadata (Array các id/đoạn trích dẫn được dùng).
#### Story 3.3: Giao diện Khung Chat & Tiếp nhận Streaming (Chat UI & SSE Client)
As a Người dùng,
I want thấy AI gõ từng chữ một vào màn hình chat kèm format Markdown đàng hoàng,
So that tôi không phải mòn mỏi nhìn biểu tượng Loading như các web đời cũ.
**Acceptance Criteria:**
**Given** tôi vừa bấm gửi câu hỏi "Ping"
**When** Next.js client mở luồng SSE kết nối về FastAPI
**Then** tin nhắn được append dần lên UI mượt mà với hoạt ảnh <150ms
**And** render được định dạng Markdown cơ bản (Bold, List, Code block) một cách trơn tru, không xộc xệch nhảy dòng khó chịu.
#### Story 3.4: Kiến trúc Split-Pane & Tương tác Trích dẫn (Split-Pane Layout & Interactive Citation)
As a Người dùng,
I want đọc khung chat ở một bên và văn bản gốc ở bên cạnh trên cùng 1 màn hình, bấm vào thẻ [1] ở chat là bên kia nhảy text tương ứng,
So that tôi có thể đối chiếu thông tin AI "bịa" hay "thật" ngay lập tức mà không phải tìm mỏi mắt.
**Acceptance Criteria:**
**Given** UI chia 2 bên (Split-Pane - bằng react-resizable-panels) - Chat trái, Doc phải (UX-DR3)
**When** AI trả lời xong có đính kèm cite `[1]`, tôi click vào `[1]`
**Then** bảng Document tự động đổi sang file tương ứng và auto-scroll + highlight dải vàng đúng dòng text đó (UX-DR4).
#### Story 3.5: Lựa chọn Mô hình LLM dựa trên Subscription (Model Selection via Quota)
As a Người dùng,
I want chọn cấu hình mô hình trí tuệ nhân tạo (VD: Claude 3.5 Sonnet, GPT-4) được cung cấp sẵn mà không cần điền API key cá nhân,
So that tôi có thể dùng trực tiếp và chi phí sử dụng được trừ thẳng vào số Token thuộc gói cước của tôi.
**Acceptance Criteria:**
**Given** tôi đang trong giao diện Chat
**When** tôi bấm vào Dropdown "LLM Model"
**Then** hệ thống liệt kê các tùy chọn model do SurfSense hỗ trợ kèm chi phí token mỗi lần gọi
**And** tuyệt đối không hiển thị ô nhập "Your API Key"
**And** nếu user dùng hết quota của Subscription khi gọi model cao cấp, hệ thống tự động chặn và bật thông báo Upgrade.
### Epic 4: Trải nghiệm Truy xuất Offline & Đồng bộ Local-First (Local-First & Offline Experience)
Người dùng tự do lướt xem danh sách tài liệu và đọc lịch sử chat ngay cả khi nằm ngoài vùng phủ sóng internet. Hệ thống cung cấp chỉ báo trạng thái rõ ràng (Syncing, Offline) giúp họ luôn an tâm về dữ liệu.
**FRs covered:** FR8, FR9, FR10, FR11
#### Story 4.1: Đồng bộ Danh sách Phiên Chat & Lịch sử Tin nhắn (Chat History Sync)
As a Người dùng,
I want danh sách lịch sử các phiên chat và tin nhắn bên trong tự động đồng bộ xuống máy tôi qua Zero-client,
So that tôi mở app lên là thấy ngay lập tức lịch sử cũ (FR8, FR9) và đọc liên tiếp không cần chờ load từ internet (FR10).
**Acceptance Criteria:**
**Given** thiết bị của tôi đã từng kết nối mạng trước đó
**When** tôi chọn một Session cũ (như hôm qua) trong Sidebar
**Then** hệ thống query trực tiếp từ IndexedDB cục bộ qua thư viện `@rocicorp/zero` và móc lên UI
**And** thời gian data mới từ server đẩy cập nhật xuống dưới Local Storage luôn đảm bảo dưới 3s (NFR-P2).
#### Story 4.2: Giao diện Phân rã Ân hạn khi ngắt mạng (Graceful Degradation Offline UI)
As a Người dùng,
I want hệ thống tự động khóa các tính năng cần internet như "Chat/Gửi tin/Upload" khi tôi mất wifi,
So that tôi không bị văng lỗi hay hiện màn hình đơ cứng, thay vào đó vẫn thong dong đọc nội dung cũ (NFR-R1).
**Acceptance Criteria:**
**Given** người dùng cấu hình ngắt mạng cố ý hoặc đột ngột mất wifi
**When** họ đang mở app
**Then** giao diện tự động bật mode Graceful Degradation: Input chat bị disable, nút Upload file bị mờ (muted xám)
**And** người dùng vẫn có thể click đọc văn bản trên màn Split-Pane thoăn thoắt không trễ (UX-DR6).
#### Story 4.3: Tích hợp Chỉ báo Trạng thái Mạng Toàn Cục (Global Network & Sync Indicators)
As a Người dùng,
I want thấy một icon nhỏ hoặc dải màu trực quan cho biết App đang Online, Offline, hay Syncing,
So that tôi chủ động biết ứng dụng có đang "sống" và "khớp nối" dữ liệu với đám mây hay không (FR11).
**Acceptance Criteria:**
**Given** app đang khởi chạy bình thường
**When** trạng thái kết nối mạng của Zero Client hoặc Browser thay đổi
**Then** Header hoặc góc dưới màn hình cập nhật icon (Xanh: Connected / Vàng: Syncing / Đỏ/Xám: Offline)
**And** thiết kế phải hòa hợp với bộ màu ZinC/Slate đã chọn, tuyệt đối không dùng thông báo (alert) nhảy ập vào mặt người dùng.
### Epic 5: Quản lý Gói cước, Thanh toán & Hạn mức Sử dụng (Subscription, Billing & Usage Management)
Hệ thống biến từ một ứng dụng tĩnh thành một nền tảng SaaS thương mại thông qua tích hợp thanh toán Stripe. Người dùng có thể xem bảng giá, chọn gói cước phù hợp, thanh toán an toàn và hệ thống tự động kiểm soát quota sử dụng dựa trên gói đăng ký, đảm bảo mô hình kinh doanh bền vững.
**FRs covered:** FR15, FR16, FR17
#### Story 5.1: Giao diện Bảng giá & Lựa chọn Gói Cước (Pricing & Plan Selection UI)
As a Khách hàng tiềm năng,
I want xem một bảng giá rõ ràng về các gói cước (ví dụ: Free, Pro, Team) với quyền lợi tương ứng,
So that tôi biết chính xác số lượng file/tin nhắn mình nhận được trước khi quyết định nâng cấp.
**Acceptance Criteria:**
**Given** tôi đang ở trang Pricing hoặc Modal nâng cấp tài khoản
**When** tôi lướt xem các tùy chọn gói cước
**Then** UI hiển thị các mức giá (monthly/yearly) rõ ràng cùng các bullets tính năng (FR15)
**And** thiết kế áp dụng chuẩn UX-DR1 (Dark mode, Accent Indigo) và có hiệu ứng hover mượt mà cho các pricing cards (<150ms).
#### Story 5.2: Tích hợp Stripe Checkout (Stripe Payment Integration)
As a Người dùng,
I want bấm "Nâng cấp" và được chuyển tới trang thanh toán an toàn,
So that tôi có thể điền thông tin thẻ tín dụng mà không sợ bị lộ dữ liệu trên máy chủ của SurfSense.
**Acceptance Criteria:**
**Given** tôi chọn một gói cước trả phí ở Story 5.1
**When** tôi click nút "Nâng cấp qua Stripe"
**Then** hệ thống gọi API backend lấy `sessionId` của Stripe Checkout
**And** tôi được điều hướng (redirect) an toàn sang trang thanh toán chính thức do Stripe cung cấp (FR16, NFR-S3).
#### Story 5.3: Webhook & Cập nhật Trạng thái Gói cước (Stripe Webhook Sync)
As a Kỹ sư Hệ thống,
I want backend tự động hứng Webhook từ Stripe mỗi khi có thanh toán thành công, gia hạn, hoặc hủy gói,
So that database được cập nhật trạng thái Subscription của user (Active/Canceled) mà không cần can thiệp thủ công.
**Acceptance Criteria:**
**Given** hệ thống Stripe bắn ra một event (ví dụ `checkout.session.completed` hoặc `customer.subscription.updated`)
**When** endpoint `/api/v1/stripe/webhook` tiếp nhận sự kiện
**Then** hệ thống verify chữ ký bảo mật từ Stripe (Stripe-Signature) để đảm bảo không bị giả mạo
**And** cập nhật trường `subscription_status``plan_id` tương ứng của User trong Database (FR17).
#### Story 5.4: Hệ thống Khóa Tác vụ dựa trên Hạn Mức (Usage Tracking & Rate Limit Enforcement)
As a Kỹ sư Hệ thống,
I want những người dùng hết quota (vượt quá file upload hoặc số lượng tin nhắn) bị từ chối dịch vụ cho đến khi nâng cấp,
So that mô hình kinh doanh không bị lỗ do chi phí LLM và Storage, áp dụng theo FR13.
**Acceptance Criteria:**
**Given** người dùng ở gói miễn phí (Ví dụ: giới hạn 5 file)
**When** họ cố gắng upload file thứ 6
**Then** API `/api/v1/documents` từ chối xử lý và trả về lỗi `403/429` (Quota Exceeded)
**And** UI nhận phản hồi từ API và hiển thị một thông báo / Modal nhỏ để up-sell giới thiệu họ lên gói Pro để tải file tiếp.

View file

@ -0,0 +1,173 @@
---
stepsCompleted:
- step-01-document-discovery.md
- step-02-prd-analysis.md
- step-03-epic-coverage-validation.md
- step-04-ux-alignment.md
- step-05-epic-quality-review.md
- step-06-final-assessment.md
filesAssessed:
- _bmad-output/planning-artifacts/prd.md
- _bmad-output/planning-artifacts/architecture.md
- _bmad-output/planning-artifacts/ux-design-specification.md
- _bmad-output/planning-artifacts/epics.md
---
# Implementation Readiness Assessment Report
**Date:** 2026-04-13
**Project:** SurfSense
## Document Discovery Files Found
**Whole Documents:**
- prd.md
- architecture.md
- epics.md
- ux-design-specification.md
- ux-design-directions.html
- current-user-flow-diagram.md
- detailed-feature-flows.md
- detailed-feature-flows-extended.md
**Sharded Documents:**
None
## PRD Analysis
### Functional Requirements
FR1: Người dùng có thể tải lên các tệp tài liệu (PDF, TXT) vào không gian làm việc của họ.
FR2: Người dùng có thể xem lại danh sách các tài liệu đã tải lên trước đó.
FR3: Người dùng có thể xem được trạng thái tiến trình trích xuất (Đang đợi, Đang xử lý, Hoàn thành, Lỗi) của một tài liệu.
FR4: Người dùng có thể xóa một tài liệu khỏi không gian làm việc của họ.
FR5: Người dùng có thể tạo một phiên hỏi đáp (Chat Session) mới.
FR6: Người dùng có thể gửi câu hỏi dạng văn bản vào một phiên chat.
FR7: Người dùng có thể nhận được các luồng phản hồi trực tiếp (Streaming responses) từ AI bot theo thời gian thực.
FR8: Người dùng có thể xem lại danh sách các phiên trò chuyện trong quá khứ.
FR9: Người dùng có thể đọc lại toàn bộ nội dung tin nhắn của một phiên trò chuyện cụ thể.
FR10: Người dùng có thể đọc danh sách tài liệu và nội dung các khung chat cũ ngay cả khi ngắt kết nối hoàn toàn với internet.
FR11: Người dùng có thể nhận biết được trạng thái đồng bộ dữ liệu hiện tại của hệ thống (Ví dụ: Offline, Đang đồng bộ, Đã cập nhật xong).
FR12: Hệ thống có khả năng tự động bóc tách văn bản và tạo Vector Embeddings một cách bất đồng bộ ngầm khi tài liệu mới được tải lên.
FR13: Hệ thống có khả năng chặn yêu cầu (Rate Limit) nếu người dùng sử dụng vượt mức Token cho phép hoặc tải file quá quy định.
FR14: Người dùng có thể xác thực (Authentication) để đăng nhập và bảo vệ dữ liệu thuộc private workspace của họ.
FR15: Hệ thống hiển thị bảng giá (Pricing) cho các gói cước với những đặc quyền về giới hạn tải file/nhắn tin khác nhau.
FR16: Người dùng có thể đăng ký gói cước và thanh toán an toàn thông qua cổng Stripe.com.
FR17: Hệ thống tự động theo dõi lượng sử dụng (Usage Tracking) và cập nhật trạng thái gói cước (Active/Canceled) qua Stripe Webhook.
Total FRs: 17
### Non-Functional Requirements
NFR-P1 (Time to First Token - TTFT): Hệ thống bắt buộc phải phản hồi ký tự đầu tiên từ AI Agent thông qua SSE dưới 1.5 giây kể từ khi user nhấn Submit.
NFR-P2 (Sync Latency): Thời gian bộ nhớ đệm Zero-cache đồng bộ thay đổi trạng thái (ví dụ một message mới) từ Remote DB về Local IndexedDB không được vượt quá 3 giây.
NFR-P3 (Background Processing): Tác vụ bóc tách văn bản và tạo Vector Embeddings cho một file chuẩn (dưới 5MB) phải được giải quyết xong trên Celery Queue trong vòng dưới 30 giây.
NFR-S1 (Data Segregation): Row-level Security (RLS) bắt buộc được áp dụng trên cấu trúc Database. Một User ID tuyệt đối không có quyền truy vấn chéo Document List hay Messages của tài khoản khác.
NFR-S2 (Local Storage Security): Toàn bộ dữ liệu Zero-cache lưu ở IndexedDB phía Client sẽ bị xóa hoàn toàn (purged) ngay khi người dùng nhấn "Log Out".
NFR-SC1 (Worker Scalability): Kiến trúc Celery Worker phải được giữ ở trạng thái "Stateless". Hệ thống phải đảm bảo việc thêm n-Workers vào hạ tầng Docker khi hàng đợi đang quá tải sẽ chạy lập tức mà không phải cấu hình lại mã nguồn.
NFR-R1 (Offline Tolerance - Chống chịu rớt mạng): Website phải chịu đựng được việc mất mạng vô thời hạn. Giao diện không được "Trắng màn hình" (White Screen of Death), mà phải cho phép User đọc dữ liệu đã cache mượt mà như đang online.
Total NFRs: 7
### Additional Requirements
- Giao diện Client: Đòi hỏi kiến trúc Frontend (Next.js) kết hợp quản trị State và Local Offline Syncing `@rocicorp/zero`. Phải cung cấp tín hiệu tiến trình đồng bộ dữ liệu (Indicator).
- Kiến trúc Server: Cần được REST/SSE tối ưu; chuẩn Open-API contracts; cách ly nghiêm ngặt giữa luồng Embedding Worker process cùng Data sync.
- Quyền bảo mật dữ liệu: Bảo vệ quyền riêng tư tuyệt đối cho tài liệu độc quyền của người dùng nhờ Local-first.
- Kiểm soát tính chính xác (Accuracy): LLM phải tuân thủ chặt Context Grounding, chống Hallucinations.
- Integration Requirements: Lựa chọn mô hình ngôn ngữ (OpenAI, Anthropic) do SurfSense cung cấp, chi phí token trừ tự động vào gói subscription. Tuyệt đối không hỗ trợ chức năng User tự nhập LLM API Key riêng.
- Risk Mitigations: Cơ chế fallback với file không trích xuất được text. Giám sát kích cỡ IndexedDB/Local DB.
- Validation Approach: Đo lường TTFT, kiểm thử Offline-to-Online.
- Web App & API Backend: Next.js + FastAPI + `@rocicorp/zero` + Postgres/pgvector.
- State Management: Sử dụng Zustand cho Global UI state, form xử lý với react-hook-form.
- MVP Strategy: Problem-solving MVP, chạy 1 worker tập trung.
### PRD Completeness Assessment
The PRD is comprehensive, with clearly enumerated and grouped FRs and NFRs mapping to the local-first, agentic RAG core value proposition. The distinction between MVP features and Future (Phase 2/3) features is well-defined. Constraints regarding the usage of specific models, subscription quota instead of actual user API keys, offline syncing constraints, and background ingestion have all been explicitly extracted and covered. The document forms a solid basis for full epic traceability mapping.
## Epic Coverage Validation
### Coverage Matrix
| FR Number | PRD Requirement | Epic Coverage | Status |
| --------- | --------------- | -------------- | --------- |
| FR1 | Người dùng có thể tải lên các tệp tài liệu (PDF, TXT) vào không gian làm việc của họ. | Epic 2 | ✓ Covered |
| FR2 | Người dùng có thể xem lại danh sách các tài liệu đã tải lên trước đó. | Epic 2 | ✓ Covered |
| FR3 | Người dùng có thể xem được trạng thái tiến trình trích xuất (Đang đợi, Đang xử lý, Hoàn thành, Lỗi) của một tài liệu. | Epic 2 | ✓ Covered |
| FR4 | Người dùng có thể xóa một tài liệu khỏi không gian làm việc của họ. | Epic 2 | ✓ Covered |
| FR5 | Người dùng có thể tạo một phiên hỏi đáp (Chat Session) mới. | Epic 3 | ✓ Covered |
| FR6 | Người dùng có thể gửi câu hỏi dạng văn bản vào một phiên chat. | Epic 3 | ✓ Covered |
| FR7 | Người dùng có thể nhận được các luồng phản hồi trực tiếp (Streaming responses) từ AI bot theo thời gian thực. | Epic 3 | ✓ Covered |
| FR8 | Người dùng có thể xem lại danh sách các phiên trò chuyện trong quá khứ. | Epic 4 | ✓ Covered |
| FR9 | Người dùng có thể đọc lại toàn bộ nội dung tin nhắn của một phiên trò chuyện cụ thể. | Epic 4 | ✓ Covered |
| FR10 | Người dùng có thể đọc danh sách tài liệu và nội dung các khung chat cũ ngay cả khi ngắt kết nối hoàn toàn với internet. | Epic 4 | ✓ Covered |
| FR11 | Người dùng có thể nhận biết được trạng thái đồng bộ dữ liệu hiện tại của hệ thống (Ví dụ: Offline, Đang đồng bộ, Đã cập nhật xong). | Epic 4 | ✓ Covered |
| FR12 | Hệ thống có khả năng tự động bóc tách văn bản và tạo Vector Embeddings một cách bất đồng bộ ngầm khi tài liệu mới được tải lên. | Epic 2 | ✓ Covered |
| FR13 | Hệ thống có khả năng chặn yêu cầu (Rate Limit) nếu người dùng sử dụng vượt mức Token cho phép hoặc tải file quá quy định. | Epic 2 | ✓ Covered |
| FR14 | Người dùng có thể xác thực (Authentication) để đăng nhập và bảo vệ dữ liệu thuộc private workspace của họ. | Epic 1 | ✓ Covered |
| FR15 | Hệ thống hiển thị bảng giá (Pricing) cho các gói cước với những đặc quyền về giới hạn tải file/nhắn tin khác nhau. | Epic 5 | ✓ Covered |
| FR16 | Người dùng có thể đăng ký gói cước và thanh toán an toàn thông qua cổng Stripe.com. | Epic 5 | ✓ Covered |
| FR17 | Hệ thống tự động theo dõi lượng sử dụng (Usage Tracking) và cập nhật trạng thái gói cước (Active/Canceled) qua Stripe Webhook. | Epic 5 | ✓ Covered |
### Missing Requirements
None. All 17 Functional Requirements are accurately represented and mapped successfully out of the 5 epics.
### Coverage Statistics
- Total PRD FRs: 17
- FRs covered in epics: 17
- Coverage percentage: 100%
## UX Alignment Assessment
### UX Document Status
Found: `ux-design-specification.md`, `ux-design-directions.html`, `current-user-flow-diagram.md`.
### Alignment Issues
None.
- **UX ↔ PRD Alignment:** UX specification aligns perfectly with PRD requirements, highlighting instant action (<1.5s TTFT), graceful degradation (Offline mode), interactive citations, and dynamic split-pane layout to support FRs and NFRs (such as NFR-P1, NFR-R1, and NFR-P2).
- **UX ↔ Architecture Alignment:** The architecture deeply supports UX needs. Rocicorp ZERO is employed for optimistic UI and <3s sync latency. FastAPI SSE is utilized for real-time text streaming. Local-first IndexedDB supports offline actions seamlessly. TailwindCSS and shadcn/ui give developers absolute control over <150ms animation constraints.
### Warnings
None. All UX and Architecture aspects align with the product's vision.
## Epic Quality Review
### Epic Structure Validation
- **User Value Focus:** All 5 epics are primarily user value-centric (Authentication, Document Management, Realtime Chat, Offline Experience, Billing/Subscription). Epic 1 establishes the workspace, Epic 5 monetizes the value.
- **Independence:** The epics are designed incrementally. Epic 1 sets the security constraints. Epic 2 allows uploading documents. Epic 3 enables chatting with them. Each epic provides clear functionality that depends only on immediately preceding epics.
### Story Quality Assessment
- **Sizing:** The stories are atomic and cover thin vertical slices (e.g., API creation -> UI handling for upload).
- **Acceptance Criteria:** Every story features a firm and testable BDD (Given/When/Then) format capturing success scenarios and failure/rate-limit conditions strictly.
- **Database/Entity Timing:** Tables are generated incrementally as their corresponding stories execute. E.g., `users` table via Story 1.1 schema migration, and sessions via Story 3.1.
### Special Implementation Checks
- Epic 1 Story 1 specifically satisfies the `bmad` best practice requirement: *"Set up initial project from starter template"* as defined by the Architecture document (Next.js + FastAPI + Postgres/pgvector via docker-compose).
### Finding Documentation
- 🔴 Critical Violations: None
- 🟠 Major Issues: None
- 🟡 Minor Concerns: Some roles represent "System Engineer" (e.g., Story 1.1, Story 2.1) focused on background tasks or infra, but they have directly verifiable Given-When-Then outputs that block nothing forward and have strict boundaries. These are accepted as they fulfill foundational technical requirements (like Celery/Worker instantiation).
## Summary and Recommendations
### Overall Readiness Status
**READY**
### Critical Issues Requiring Immediate Action
None. Hệ thống tài liệu phân tích (PRD, Architecture, UX, Epics) đã hoàn toàn đồng nhất, có khả năng truy xuất độc lập (fully traceable), thoả mãn toàn bộ quy tắc về yêu cầu hệ thống chức năng và phi chức năng.
### Recommended Next Steps
1. Chuẩn bị cho **Sprint Planning**: Ưu tiên bắt đầu ngay với Epic 1 (Authentication & Workspace Setup).
2. Triển khai infrastructure nền tảng bằng Docker Compose với các core services (Postgres + pgvector, Redis, Zero).
3. Initialization dự án theo kiến trúc chuẩn (Next.js App Router mảng Frontend, FastAPI cho Backend API).
### Final Note
This assessment identified 0 critical issues across all categories. Yêu cầu Subscription/Pricing đã được đưa vào luồng kiểm toán thành công. Dự án đã ở trạng thái **READY** để bước sang giai đoạn hiện thực hoá mã nguồn (Implementation).

View file

@ -0,0 +1,267 @@
---
stepsCompleted:
- step-01-init.md
- step-02-discovery.md
- step-02b-vision.md
- step-02c-executive-summary.md
- step-03-success.md
- step-04-journeys.md
- step-05-domain.md
- step-06-innovation.md
- step-07-project-type.md
- step-08-scoping.md
- step-09-functional.md
- step-10-nonfunctional.md
- step-11-polish.md
- step-12-complete.md
classification:
projectType: web_app/api_backend
domain: scientific
complexity: medium
projectContext: brownfield
inputDocuments:
- docs/index.md
- docs/project-overview.md
- docs/architecture-backend.md
- docs/architecture-web.md
- docs/data-models.md
- docs/api-contracts.md
- docs/source-tree-analysis.md
- docs/component-inventory.md
- docs/development-guide.md
- docs/deployment-guide.md
- docs/integration-architecture.md
- docs/project-scan-report.json
- _bmad-output/project-context.md
documentCounts:
briefCount: 0
researchCount: 0
brainstormingCount: 0
projectDocsCount: 13
workflowType: 'prd'
---
# Product Requirements Document - SurfSense
**Author:** luisphan
**Date:** 2026-04-13
## Executive Summary
SurfSense là nền tảng tìm kiếm và trích xuất ngữ cảnh (Context Extraction & Agentic RAG) AI-native, được thiết kế để giải quyết triệt để bài toán độ trễ và phân mảnh thông tin. Hệ thống cho phép người dùng và hạ tầng doanh nghiệp truy vấn dữ liệu theo thời gian thực một cách liền mạch, biến kho dữ liệu phức tạp thành các câu trả lời chính xác, an toàn và có thể hành động ngay lập tức. Thông qua kiến trúc Web App & Backend linh hoạt (Next.js & FastAPI), SurfSense đảm bảo trải nghiệm người dùng tối ưu với cơ chế xử lý dữ liệu song song và quy trình lập luận AI chuyên sâu.
### What Makes This Special
Điểm khác biệt cốt lõi của SurfSense nằm ở kiến trúc **Local-first** kết hợp cùng mô hình **Multi-agent Graph**. Bằng việc tích hợp công nghệ đồng bộ `@rocicorp/zero` (Zero-cache), nền tảng hỗ trợ đồng bộ dữ liệu tức thì và hoạt động hoàn hảo ngay cả khi offline (mất kết nối internet). Điều này khắc phục được điểm yếu cố hữu của các hệ thống RAG truyền thống: sự phụ thuộc vào kết nối mạng và độ trễ truy vấn cao. Đặc biệt, việc triển khai FastAPI & LangGraph cho phép hệ thống triển khai các luồng tác vụ Agentic linh hoạt đa bước, streaming kết quả về phía người dùng với tốc độ cao đồng thời bảo vệ nghiêm ngặt tính riêng tư của dữ liệu.
## Project Classification
- **Project Type:** Web App & API Backend
- **Domain:** Scientific / General (AI, Thông tin mạng, Retrieval-Augmented Generation)
- **Complexity:** Medium (Tích hợp Local-first Data Sync, Background Workers với Celery, Multi-agent orchestration)
- **Project Context:** Brownfield (Nền tảng kiến trúc đã thiết lập với Postgres/pgvector, Redis, Docker Stack và quy trình CI/CD hoàn thiện)
## Success Criteria
### User Success
Người dùng trải nghiệm được khoảnh khắc "Aha!" khi nhận được luồng phản hồi (streaming response) từ Agentic RAG ngay lập tức (dưới 1 giây kể từ khi submit) và có thể truy vấn ngữ cảnh/kho tài liệu ở dạng offline mượt mà không khác gì khi có mạng nhờ Zero-cache.
### Business Success
Hệ thống đạt tỷ lệ giữ chân (Retention rate) cao với tệp người dùng nghiên cứu chuyên sâu, đồng thời kiến trúc module hóa đủ linh hoạt để mở rộng quy mô (Scalability) và sẵn sàng đóng gói license nhắm tới thị trường B2B.
### Technical Success
Cơ chế Local-first (Zero-cache) đồng bộ hàng nghìn vector và bản ghi dữ liệu ngầm mà không gây tác động hay đóng băng (freeze) UI client. Ở backend, các Celery workers xử lý pipeline nhúng dữ liệu (background embeddings) hoàn toàn cách ly, duy trì độ ổn định và trơn tru cho API phục vụ.
### Measurable Outcomes
- Độ trễ Time-to-First-Token (TTFT) < 1 giây kể cả với các truy vấn sử dụng đa AI Agent.
- Web Client truy cập bình thường toàn bộ thông tin đã lưu trữ khi offline.
- Tác vụ Embedding không gây nghẽn (bottleneck) hệ thống Chat.
## Product Scope
### MVP - Minimum Viable Product
- Tích hợp framework `@rocicorp/zero` cung cấp Local-first caching và realtime sync.
- Hỗ trợ khai thác truy vấn văn bản, lưu trữ lịch sử offline.
- Triển khai LangGraph Agents cơ bản (tìm, đọc, tổng hợp nội dung).
### Growth Features (Post-MVP)
- Hỗ trợ RAG đa định dạng (đọc file PDF, hình ảnh).
- Tích hợp tài liệu nội bộ, Chatbot riêng cá nhân hóa.
- Filter thông minh và tagging đa dạng để quản lý vector.
### Vision (Future)
- Autonomous Proactive Agents: AI chạy nền thu thập nguồn thông tin hữu ích theo sở thích của người dùng để liên tục cập nhật kho ngữ cảnh cá nhân.
## User Journeys
### 1. Primary User - Success Path
- **Người dùng:** Alex - Chuyên viên Nghiên cứu Dữ liệu.
- **Tình huống:** Có hàng chục tài liệu phân mảnh và cần tổng hợp nhanh.
- **Hành trình:** Cài đặt và mở SurfSense Web App -> Nạp hàng loạt tài liệu -> Hệ thống tự động phân tích và nhúng dữ liệu qua Celery workers/LangGraph API đồng bộ bằng Zero-cache trong nền -> Gõ truy vấn -> SurfSense streaming câu trả lời tức thì kèm trích dẫn.
### 2. Primary User - Edge Case (Offline Mode)
- **Người dùng:** Alex (Trường hợp mất kết nối mạng).
- **Tình huống:** Cần tra cứu gấp dữ liệu đã nạp mà không có Internet.
- **Hành trình:** Mở Web App offline -> Toàn bộ dữ liệu ngữ cảnh đều khả dụng nhờ Zero-cache -> Truy vấn Local DB -> Giao diện phản hồi mượt mà không độ trễ, không lỗi "No Internet".
### 3. Admin / Operations User
- **Người dùng:** Jamie - Kỹ sư DevOps nội bộ.
- **Tình huống:** Quản lý tài nguyên, theo dõi tính ổn định khi traffic tăng cao.
- **Hành trình:** Giám sát hệ thống qua Docker Logs -> Nhận biết hàng đợi Celery có lượng công việc lớn -> Can thiệp/Scale up node không làm luồng chat của người dùng bị gián đoạn.
### 4. API Consumer / Developer
- **Người dùng:** Sam - Kỹ sư phần mềm.
- **Tình huống:** Xây dựng ứng dụng bên thứ ba tích hợp AI Agent của SurfSense.
- **Hành trình:** Tham khảo API -> Gửi cấu trúc truy vấn vào endpoint FastAPI `/api/rag/stream` -> Nhận lại chuỗi sự kiện Server-Sent Events (SSE) theo thời gian thực -> Tích hợp dễ dàng nội dung streaming vào ứng dụng của mình.
### Journey Requirements Summary
- **Giao diện Client (Journey 1 & 2):** Đòi hỏi kiến trúc Frontend (Next.js) kết hợp chặt chẽ việc quản trị State và Local Offline Syncing `@rocicorp/zero`. Phải cung cấp tín hiệu (Indicator) về tiến trình đồng bộ dữ liệu tới file bộ nhớ cục bộ mà không gây khóa luồng chính (Main Thread).
- **Kiến trúc Server & DevOps (Journey 3 & 4):** Backend APIs cần được REST/SSE tối ưu; chuẩn Open-API contracts; và cách ly nghiêm ngặt giữa luồng Embedding Worker process cùng Data sync để không gây tắc nghẽn khả năng trả lời query.
## Domain-Specific Requirements
### Compliance & Regulatory
- **Quyền bảo mật dữ liệu:** Bảo vệ quyền riêng tư tuyệt đối cho tài liệu độc quyền của người dùng nhờ tận dụng kiến trúc Local-first (giảm thiểu luồng dữ liệu thô đẩy lên hạ tầng cloud không cần thiết).
### Technical Constraints
- **Kiểm soát tính chính xác (Accuracy):** Hệ thống LLM phải tuân thủ chặt chẽ ngữ cảnh được nạp (Strict Context Grounding), chống lại hiện tượng ảo giác (Hallucinations).
- **Phân bổ tài nguyên (Computational Resources):** Duy trì sự cô lập hoàn toàn giữa Celery workers (dành cho embed) và FastAPI server (dành cho API endpoints) để loại bỏ rủi ro nghẽn cổ chai.
### Integration Requirements
- Kiến trúc mở cho phép người dùng tự do lựa chọn các mô hình ngôn ngữ (OpenAI, Anthropic) do SurfSense quản lý. Chi phí sử dụng Token sẽ được tự động trừ vào gói cước Subscription của người dùng (Tuyệt đối không hỗ trợ chức năng User tự nhập LLM API Key riêng nhằm kiểm soát chất lượng và doanh thu).
### Risk Mitigations
- **Phòng ngừa lỗi đọc file:** Cơ chế fallback thông minh phát hiện, báo lỗi cụ thể và tiếp tục với các file không trích xuất được text.
- **Giám sát dung lượng phía biên (Client):** Kiểm soát kích cỡ của IndexedDB hay Local DB để phòng ngừa Zero-cache làm ngốn bộ nhớ thiết bị của Client.
## Innovation & Novel Patterns
### Detected Innovation Areas
**Local-First Agentic RAG:** Sự kết hợp mới mẻ giữa RAG nhiều tác tử điều phối (Multi-Agent) cùng kiến trúc Local-first (thông qua `@rocicorp/zero`). Các hệ thống RAG truyền thống dựa hoàn toàn vào Cloud Database nên thường gặp độ trễ lớn và giới hạn về bộ nhớ cục bộ. SurfSense đảo ngược mô hình này, đồng bộ ngữ cảnh (Context) trực tiếp về IndexedDB/SQLite ở biên (Client). Điều này mang lại cảm giác phản hồi tức thì (Instant) mà vẫn sở hữu khả năng suy luận đa tầng ở phía Backend (thông qua LangGraph).
### Market Context & Competitive Landscape
Đa số các công cụ RAG SaaS hiện tại phụ thuộc hoàn toàn vào Cloud (gây lo ngại về bảo mật tài liệu và phụ thuộc internet). Ngược lại, các công cụ Local (chạy LLM trên máy cá nhân) lại thiếu tính liên thông giữa nhiều thiết bị và giới hạn bởi phần cứng nội bộ. SurfSense đánh vào khoảng trống ở giữa (Sweet Spot): Nắm giữ độ bảo mật và tốc độ của "Local", đồng thời khai thác sức mạnh khổng lồ của "Cloud LLM/Agents".
### Validation Approach
- **Đo lường TTFT:** Đo đạc "Time-to-First-Token", đặt mục tiêu luôn phản hồi dưới 1 giây nhờ việc bớt đi một bước gọi Database trung gian.
- **Kiểm thử Offline-to-Online:** Đánh giá khả năng hoạt động (đọc Context/State) bất chấp việc mất mạng và tự động phục hồi sự kiện khi có wifi trở lại.
### Risk Mitigation
- **Vấn đề đồng bộ dung lượng lớn:** Cấu trúc Local-first mang tới rủi ro là nếu kho dữ liệu người dùng lên tới hàng Gigabytes, việc tải Zero-cache ban đầu sẽ quá chậm.
- **Fallback (Giải pháp dự phòng):** Sử dụng cơ chế Partial Sync (Đồng bộ một phần) theo Filter/Tag, hoặc phân trang để tối ưu băng thông.
## Web App & API Backend Specific Requirements
### Project-Type Overview
SurfSense kết hợp giữa kiến trúc Single Page Application (SPA) cực kỳ mượt mà trên Next.js và một Backend API vững chắc chuyên trị các tác vụ AI (FastAPI). Hai lớp này giao tiếp qua chuẩn REST/SSE và đặc biệt là hệ thống đồng bộ Local-first từ `@rocicorp/zero`.
### Technical Architecture Considerations
- **Kiến trúc SPA & Real-time:** Next.js sẽ đóng vai trò SPA cung cấp trải nghiệm liền mạch. Trạng thái ứng dụng được đồng bộ real-time mà không cần tải lại trang.
- **Browser Matrix (Hỗ trợ trình duyệt):** Yêu cầu bắt buộc trên trình duyệt hiện đại (Chrome 90+, Safari 15+, Edge 90+) vì dữ liệu Zero-cache nội bộ phụ thuộc vào WebAssembly và IndexedDB.
- **Performance Targets:** Giới hạn Time-to-First-Token (TTFT) ở mức dưới 1 giây. Tốc độ đồng bộ Local-DB dưới 2 giây cho một chunk dữ liệu mới.
### Endpoint Specifications
Cấu trúc API (FastAPI) bao gồm:
- `/api/v1/documents` (REST): Upload files, trích xuất text, đưa vào Celery tasks queuing.
- `/api/v1/chat` (SSE): Trả về luồng streaming answers từ các mô hình học máy theo thời gian thực.
- `/api/zero/sync` (WebSocket/Sync): Endpoint kết nối Rocicorp Zero Client để chia sẻ state.
### Authentication & Rate Limits
- **Auth Model:** Định danh qua token (JWt/Supabase Auth) để phân lập không gian làm việc (Workspace) của mỗi User.
- **Rate Limits:** Giới hạn số Token tải lên và Token trả lời để tránh nguy cơ phá vỡ hệ thống bằng cách lạm dụng Celery Worker.
### Data Schemas & Local Sync
- Cấu trúc Local Schema (phía Client) mô phỏng lại một tập con tối giản (Sub-set) của Remote Schema nhằm phục vụ riêng cho các thao tác Offline (Xem danh sách tài liệu, đọc và truy vấn lịch sử chat).
## Project Scoping & Phased Development
### MVP Strategy & Philosophy
**MVP Approach:** Problem-solving MVP (Tập trung giải quyết cốt lõi vấn đề: RAG cực nhanh nhờ sự hỗ trợ của Rocicorp Zero). Chứng minh được dữ liệu trích xuất thành công và LLM có thể trả lời tức thì (Streaming).
**Resource Requirements:** Nhóm nhỏ (1-2 kỹ sư Full-stack am hiểu kiến trúc Agent và Web Real-time).
### MVP Feature Set (Phase 1)
**Core User Journeys Supported:**
- User Tải File & Chờ trích xuất nền (Background extraction).
- User Hỏi đáp (Chat) dựa trên nội dung file đó với độ trễ (TTFT) < 1 giây.
- Tính năng xem lại lịch sử Chat ngay khi Offline (Zero-cache).
- Đăng ký và thanh toán gói cước Subscription thông qua Stripe để nâng cấp/quản lý hạn mức sử dụng.
**Must-Have Capabilities:**
- Giao diện thao tác Upload File (PDF/TXT cơ bản).
- Pipeline xử lý nền (Celery queue cho Embedding).
- Chức năng Chatbot gọi Stream API từ Agent.
- Local Database (Zero-cache) lưu được `Documents``Messages` cơ bản.
- Hỗ trợ duy nhất 1 LLM Provider mạnh mẽ ở giai đoạn đầu (Ví dụ: OpenAI / gpt-4o) để đảm bảo không bị phân tán.
- Tích hợp cổng thanh toán Stripe xử lý Subscriptions và giao diện Pricing/Usage Tracking.
### Post-MVP Features
**Phase 2 (Growth):**
- Đăng nhập nhiều Workspaces (Làm việc nhóm).
- Phân luồng quyền File (RBAC).
- Cho phép người dùng chuyển đổi linh hoạt giữa các mô hình LLM (như Claude 3.5 Sonnet, GPT-4) được cung cấp sẵn, tích hợp thẳng với hệ thống tính phí quota.
**Phase 3 (Expansion):**
- Tích hợp thêm Data Sources (Google Drive, Notion, Slack).
- Mở rộng Agent System: Agent tự biên tập bài viết dài, Agent tổng hợp nghiên cứu (Research Agent).
- API Keys cho bên thứ ba tích hợp (Consumer API access).
### Risk Mitigation Strategy
- **Technical Risks:** Ở MVP, chỉ chạy 1 Worker tập trung với logic Queue đơn giản nhất để giảm rủi ro về Scale.
- **Market Risks:** Đặt một bộ định tuyến trạng thái UI rõ ràng hiển thị "Offline", "Syncing", "Online" để giải tỏa sự khó hiểu của User về Local-first.
- **Resource Risks:** Tận dụng tối đa bộ Docker-compose dựng sẵn và component UI mở. Hạn chế thiết kế lại từ đầu.
## Functional Requirements
### Document Management
- **FR1:** Người dùng có thể tải lên các tệp tài liệu (PDF, TXT) vào không gian làm việc của họ.
- **FR2:** Người dùng có thể xem lại danh sách các tài liệu đã tải lên trước đó.
- **FR3:** Người dùng có thể xem được trạng thái tiến trình trích xuất (Đang đợi, Đang xử lý, Hoàn thành, Lỗi) của một tài liệu.
- **FR4:** Người dùng có thể xóa một tài liệu khỏi không gian làm việc của họ.
### Chat & AI Interaction
- **FR5:** Người dùng có thể tạo một phiên hỏi đáp (Chat Session) mới.
- **FR6:** Người dùng có thể gửi câu hỏi dạng văn bản vào một phiên chat.
- **FR7:** Người dùng có thể nhận được các luồng phản hồi trực tiếp (Streaming responses) từ AI bot theo thời gian thực.
- **FR8:** Người dùng có thể xem lại danh sách các phiên trò chuyện trong quá khứ.
- **FR9:** Người dùng có thể đọc lại toàn bộ nội dung tin nhắn của một phiên trò chuyện cụ thể.
### Offline & Synchronization Capabilities
- **FR10:** Người dùng có thể đọc danh sách tài liệu và nội dung các khung chat cũ ngay cả khi ngắt kết nối hoàn toàn với internet.
- **FR11:** Người dùng có thể nhận biết được trạng thái đồng bộ dữ liệu hiện tại của hệ thống (Ví dụ: Offline, Đang đồng bộ, Đã cập nhật xong).
### Background Processing & System Limits
- **FR12:** Hệ thống có khả năng tự động bóc tách văn bản và tạo Vector Embeddings một cách bất đồng bộ ngầm khi tài liệu mới được tải lên.
- **FR13:** Hệ thống có khả năng chặn yêu cầu (Rate Limit) nếu người dùng sử dụng vượt mức Token cho phép hoặc tải file quá quy định.
- **FR14:** Người dùng có thể xác thực (Authentication) để đăng nhập và bảo vệ dữ liệu thuộc private workspace của họ.
### Pricing & Subscription
- **FR15:** Hệ thống hiển thị bảng giá (Pricing) cho các gói cước với những đặc quyền về giới hạn tải file/nhắn tin khác nhau.
- **FR16:** Người dùng có thể đăng ký gói cước và thanh toán an toàn thông qua cổng Stripe.com.
- **FR17:** Hệ thống tự động theo dõi lượng sử dụng (Usage Tracking) và cập nhật trạng thái gói cước (Active/Canceled) qua Stripe Webhook.
## Non-Functional Requirements
### Performance
- **NFR-P1 (Time to First Token - TTFT):** Hệ thống bắt buộc phải phản hồi ký tự đầu tiên từ AI Agent thông qua SSE dưới 1.5 giây kể từ khi user nhấn Submit.
- **NFR-P2 (Sync Latency):** Thời gian bộ nhớ đệm Zero-cache đồng bộ thay đổi trạng thái (ví dụ một message mới) từ Remote DB về Local IndexedDB không được vượt quá 3 giây.
- **NFR-P3 (Background Processing):** Tác vụ bóc tách văn bản và tạo Vector Embeddings cho một file chuẩn (dưới 5MB) phải được giải quyết xong trên Celery Queue trong vòng dưới 30 giây.
### Security
- **NFR-S1 (Data Segregation):** Row-level Security (RLS) bắt buộc được áp dụng trên cấu trúc Database. Một User ID tuyệt đối không có quyền truy vấn chéo Document List hay Messages của tài khoản khác.
- **NFR-S2 (Local Storage Security):** Toàn bộ dữ liệu Zero-cache lưu ở IndexedDB phía Client sẽ bị xóa hoàn toàn (purged) ngay khi người dùng nhấn "Log Out".
### Scalability
- **NFR-SC1 (Worker Scalability):** Kiến trúc Celery Worker phải được giữ ở trạng thái "Stateless". Hệ thống phải đảm bảo việc thêm n-Workers vào hạ tầng Docker khi hàng đợi đang quá tải sẽ chạy lập tức mà không phải cấu hình lại mã nguồn.
### Reliability
- **NFR-R1 (Offline Tolerance - Chống chịu rớt mạng):** Website phải chịu đựng được việc mất mạng vô thời hạn. Giao diện không được "Trắng màn hình" (White Screen of Death), mà phải cho phép User đọc dữ liệu đã cache mượt mà như đang online.

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html class="dark">
<head>
<title>SurfSense Design Directions</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = { darkMode: 'class', theme: { extend: { colors: { zinc: { 900: '#18181b', 800: '#27272a', 950: '#09090b' }, indigo: { 500: '#6366f1', 400: '#818cf8', 300: '#a5b4fc' } } } } }
</script>
</head>
<body class="bg-zinc-900 text-slate-300 font-sans p-8 max-w-5xl mx-auto">
<h1 class="text-3xl font-bold text-white mb-2">SurfSense Design Directions</h1>
<p class="text-zinc-400 mb-10">Mô phỏng thiết kế dựa trên phong cách Monochrome & Indigo Focus.</p>
<div class="mb-16">
<h2 class="text-xl font-semibold text-indigo-400 mb-2">Direction 1: "The Scholar" (Split-Pane Layout)</h2>
<p class="mb-6 text-sm text-zinc-400">Giao diện chia đôi màn hình chuẩn mực. Khung Chat bên trái, Tài liệu cuộn bên phải. Tối ưu cho việc đối chiếu và nghiên cứu sâu.</p>
<div class="border border-zinc-700 rounded-xl overflow-hidden flex h-[500px] bg-zinc-950 shadow-2xl">
<!-- Sidebar / Chat -->
<div class="w-1/3 border-r border-zinc-800 p-4 flex flex-col justify-between relative bg-zinc-900">
<div class="space-y-4">
<div class="bg-zinc-800 p-4 rounded-lg text-sm shadow-sm"><span class="text-indigo-400 font-semibold text-xs border border-indigo-500/50 px-1.5 py-0.5 rounded mr-2 uppercase tracking-wider">You</span>Nguyên nhân chính là gì?</div>
<div class="p-2 text-sm leading-relaxed"><span class="font-bold text-white mb-2 block flex items-center"><div class="w-2 h-2 bg-indigo-500 rounded-full mr-2 glow"></div> SurfSense AI</span>Nguyên nhân chính được báo cáo nhắc đến chủ yếu do sự thay đổi biểu đồ nhiệt độ toàn cầu <span class="bg-indigo-500/20 text-indigo-300 px-1.5 py-0.5 rounded cursor-pointer hover:ring-1 hover:ring-indigo-500 transition-all">[1]</span>.</div>
</div>
<div class="mt-4"><input type="text" class="w-full bg-zinc-800 border border-zinc-700 rounded-lg p-3 text-sm text-white focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-all placeholder-zinc-500" placeholder="Ask a question..."></div>
</div>
<!-- Document Pane -->
<div class="w-2/3 p-10 overflow-y-auto bg-zinc-950 relative">
<div class="absolute top-4 right-4 text-xs font-mono text-zinc-500 border border-zinc-800 px-2 rounded">SYNCED</div>
<h3 class="text-xl font-bold text-white mb-6">Climate_Report_2024.pdf</h3>
<p class="text-base leading-8 text-zinc-400 mb-4">... Mặc dù có nhiều giả thuyết, các hiện tượng quan sát được cho thấy <span class="bg-indigo-500/20 text-indigo-100 font-medium px-1 rounded ring-1 ring-indigo-500/50 shadow-[0_0_10px_rgba(99,102,241,0.2)]">thay đổi biểu đồ nhiệt độ toàn cầu</span> là tác nhân định hướng chính yếu của sự kiện này ...</p>
<p class="text-base leading-8 text-zinc-400">Các nhà khoa học cũng đồng thuận rằng...</p>
</div>
</div>
</div>
<div class="mb-12">
<h2 class="text-xl font-semibold text-indigo-400 mb-2">Direction 2: "Focus Mode" (Floating Overlay)</h2>
<p class="mb-6 text-sm text-zinc-400">Tài liệu chiếm trọn không gian, Chat là một Floating Widget nổi bên dưới tựa như Spotlight. Tối ưu cho việc đọc liền mạch, thỉnh thoảng mới hỏi AI.</p>
<div class="border border-zinc-700 rounded-xl overflow-hidden relative h-[500px] bg-zinc-950 shadow-2xl p-10 text-center flex flex-col items-center pt-20">
<h3 class="text-2xl font-bold text-white mb-6">Climate_Report_2024.pdf</h3>
<p class="text-lg leading-8 text-zinc-400 max-w-2xl mx-auto text-left">... Mặc dù có nhiều giả thuyết, các hiện tượng quan sát được cho thấy thay đổi biểu đồ nhiệt độ toàn cầu là tác nhân định hướng chính yếu của sự kiện này ... Các nhà khoa học cũng đồng thuận rằng mức độ nghiêm trọng cần được đánh giá lại...</p>
<!-- Floating Hover Chat -->
<div class="absolute bottom-8 left-1/2 transform -translate-x-1/2 w-3/4 max-w-2xl bg-zinc-800/90 backdrop-blur-md border border-zinc-700/50 rounded-2xl shadow-[0_20px_50px_rgba(0,0,0,0.5)] p-5">
<div class="mb-4 text-sm text-zinc-300 text-left flex items-start"><div class="w-1.5 h-1.5 rounded-full bg-indigo-500 mt-1.5 mr-3"></div><div class="leading-relaxed">Nguyên nhân chính được báo cáo nhắc đến chủ yếu do sự thay đổi biểu đồ nhiệt độ toàn cầu <span class="text-indigo-400 font-medium cursor-pointer hover:underline">[1]</span>.</div></div>
<div class="relative">
<input type="text" class="w-full bg-zinc-900 border border-zinc-700 rounded-xl p-3 pl-4 pr-10 text-sm text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/50 shadow-inner" placeholder="Follow up...">
<div class="absolute right-3 top-3 w-5 h-5 bg-indigo-500 text-white rounded text-xs flex items-center justify-center font-bold font-mono shadow"></div>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,198 @@
---
stepsCompleted:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
inputDocuments:
- _bmad-output/planning-artifacts/prd.md
- _bmad-output/planning-artifacts/architecture.md
- docs/project-overview.md
---
# UX Design Specification SurfSense
**Author:** Luisphan
**Date:** 2026-04-13
---
## Executive Summary
### Project Vision
SurfSense là nền tảng tìm kiếm và trích xuất ngữ cảnh (Agentic RAG) được thiết kế đặc biệt với kiến trúc Local-first. Sứ mệnh cốt lõi của ứng dụng là mang tới trải nghiệm truy vấn siêu tốc (Time-to-First-Token < 1 giây) khả năng hoạt động liền mạch ngay cả khi mất kết nối mạng. Hệ thống phá bỏ rào cản về độ trễ của các ứng dụng RAG truyền thống dựa trên cloud nhờ việc đồng bộ hoá ngầm kho dữ liệu trực tiếp về thiết bị người dùng (Zero-cache).
### Target Users
1. **Người dùng chính (Alex - Data Researcher):** Làm việc với lượng lớn tài liệu phân mảnh, có yêu cầu khắt khe về việc tổng hợp thông tin, trích dẫn chính xác và không có thời gian chờ đợi web load (loading spinners).
2. **Kỹ sư vận hành (Jamie - DevOps) & Nhóm dev tích hợp (Sam - Developer):** Cần giám sát hệ thống phân tán minh bạch, tích hợp AI streaming qua SSE một cách dể hiểu, đảm bảo background workers không làm nghẽn luồng chat.
### Key Design Challenges
1. **Truyền đạt trạng thái kết nối mạng phức tạp (Local-first logic):** Cần chỉ báo UI (indicators) tinh tế thể hiện trạng thái `Syncing`, `Offline`, hoặc `Online` mà không gây rối rắm.
2. **Quản lý kỳ vọng thời gian thực:** Giao diện cần placeholder khéo léo để User an tâm chờ đợi tiến trình trích xuất tài liệu (Embedding) qua Celery.
3. **Hiển thị Streaming và Trích dẫn (Citations):** Giao diện AI chat phát sinh văn bản theo luồng SSE cực mượt, pop-up hiển thị nguồn tham khảo tự nhiên.
### Design Opportunities
1. **Trải nghiệm truy xuất không có 'Loading':** Biến việc chờ đợi thành dĩ vãng nhờ Rocicorp Zero. UI phản hồi tức thì cho các thao tác nội bộ.
2. **Tương tác Desktop-like trên Web:** Áp dụng tư duy tương tác layout mở đa khung giống một phần mềm biên tập nội dung, thay vì danh sách chat cuộn đơn tuyến.
## Core User Experience
### Defining Experience
- **Hành động nòng cốt:** Tiến hành "Trò chuyện mang tính Khám phá" (Exploratory Chat) với kho dữ liệu cá nhân.
- Mọi thao tác xoay quanh việc hỏi đáp cực kỳ tự nhiên, trong đó văn bản do người dùng tải lên sẽ đóng vai trò bệ đỡ (grounding) vô hình hỗ trợ đằng sau mà không bắt ép người dùng phải thao tác chọn file quá rườm rà.
### Platform Strategy
- **Chiến lược Nền tảng:** Môi trường Web (Browser-based) nhưng mang cảm giác của "Ứng dụng Hệ điều hành/Desktop App". Ưu tiên thiết kế trên Desktop và Tablet vì hành vi "Data Research" thường yêu cầu màn hình lớn để đọc tài liệu song song với khung Chat.
- Ứng dụng phải hoạt động mượt mà kể cả khi Refresh trang đột ngột nhờ lưu cache sâu.
### Effortless Interactions
- **Các tương tác "Không tốn sức" (Zero-friction):**
- Kéo và thả file là tệp sẽ lập tức xuất hiện trong danh sách ảo (Placeholder) mà không cần thấy thanh loading-bar của HTTP Upload.
- Lướt lại tin nhắn lịch sử của ngày hôm qua không tốn nổi 1ms - cảm giác cuộn mượt như đang scroll bộ nhớ offline.
### Critical Success Moments
- **"Khoảnh khắc Aha" làm nên sự khác biệt:**
1. Khi người dùng bấm nút [Gửi câu hỏi], chưa kịp rời tay khỏi chuột, chữ cái đầu tiên (First Token) của AI đã bắt đầu gõ lên màn hình.
2. Người dùng vô tình mất WiFi, nhưng họ vẫn có thể xem lại toàn bộ câu trả lời AI sinh ra trước đó và đọc tài liệu đính kèm mà không dính logo "Lỗi khủng long".
### Experience Principles
1. **Khởi tác Tức thì (Instant Action):** UI không bao giờ bị "đóng băng" kể cả khi đang có background work. Mọi click đều phải phản hồi state dưới 10ms.
2. **Lùi bước Âm thầm (Graceful Degradation):** Khi mất mạng, giao diện ngầm đổi màu sang trạng thái "Offline" tinh tế. Nút "Tạo Embedding" tự động disable nhẹ nhàng (chứ không báo lỗi popup) và khuyến khích họ đọc lịch sử.
3. **Hiển thị Rành mạch (Clear Provenance):** Không bao giờ để User phải tự đoán AI lấy câu trả lời từ đâu. Tính năng pop-up Trích dẫn (Citation) là trái tim của giao diện hiển thị câu trả lời AI.
## Desired Emotional Response
### Primary Emotional Goals
- **Quyền năng & Tự chủ (Empowered & In Control):** Người dùng cảm thấy họ đang nắm giữ một "bộ não thứ hai" (second brain) có khả năng đọc hiểu khối lượng kiến thức khổng lồ ngay lập tức.
- **Tin tưởng tuyệt đối (Absolute Trust):** Hoàn toàn yên tâm về tính bảo mật (dữ liệu nằm trên máy) và độ tin cậy của câu trả lời (luôn có trích dẫn minh bạch).
- **Kinh ngạc vì sự êm ái (Delightfully Frictionless):** Cảm giác ngạc nhiên, thích thú khi không phải chờ đợi các vòng quay "Loading" nhàm chán như môi trường web truyền thống.
### Emotional Journey Mapping
- **Tiếp xúc ban đầu (First Discovery):** Tò mò và ngỡ ngàng trước tốc độ phản hồi tức thì khi thả file vào (dữ liệu được sync ngầm bằng Rocicorp Zero).
- **Trong quá trình Chat (Core Action):** Cảm giác trôi chảy (Flow state). Suy nghĩ không bị đứt đoạn nhờ AI gõ trả lời không độ trễ.
- **Sau khi hoàn thành (Task Completion):** Thoả mãn và minh mẫn, lấy được câu trả lời kèm nguồn tham chiếu rõ ràng.
- **Sự cố mất mạng/Vào vùng lõm (Disruption/Offline):** Cảm giác an tâm, thở phào nhẹ nhõm vì giao diện chỉ nhẹ nhàng chuyển sang màu "Offline" nhưng mọi dữ liệu chat hay tài liệu vẫn hiện diện để đọc tiếp.
### Micro-Emotions
- **Tự tin (Confidence) > Bối rối (Confusion):** Người dùng luôn biết câu trả lời này được trích xuất từ văn bản gốc nào nhờ cơ chế Highlight Citation.
- **Thư giãn (Relaxed) > Căng thẳng (Anxiety):** Không lo sợ ấn nhầm nút làm mất đi đoạn chat dài, vì mọi state được lưu xuống IndexedDB (PGLite) liên tục.
### Design Implications
- *Nếu muốn tạo sự Tự chủ:* Giấu đi các thiết lập Agent rườm rà, nhường chỗ cho giao diện chat/đọc tài liệu rộng rãi; chỉ hiển thị trạng thái "Đang đồng bộ (Syncing)" là một icon nhỏ gọn không chặn thao tác (Non-blocking UI).
- *Nếu muốn tạo sự Tin tưởng:* Giao diện hiển thị Nguồn trích dẫn (Citations) phải cực kỳ nổi bật, có thể click thẳng vào để nhảy đến đúng trang PDF/đoạn text bên sidebar.
- *Nếu muốn tạo Delight:* Áp dụng các micro-animations (ví dụ: nút "Gửi" biến đổi mượt mà khi AI đang type), nhưng phải giữ cho mọi animation có thời lượng cực ngắn (<150ms).
### Emotional Design Principles
1. **Thiết kế vì trạng thái Dòng chảy (Design for Flow):** Loại bỏ mọi pop-up chặn màn hình.
2. **Minh bạch là Đáng tin (Transparency is Trust):** AI phải luôn "thừa nhận" nguồn gốc kiến thức của nó, nếu không biết thì thể hiện giao diện trung lập thay vì bịa (hallucinate).
3. **Im lặng là Vàng (Quiet Background):** Trạng thái Embeddings hay Syncing để làm việc với dữ liệu lớn phải diễn ra như một nhịp thở nhẹ ở dưới đáy UI, không đòi hỏi sự chú ý.
## UX Pattern Analysis & Inspiration
### Inspiring Products Analysis
1. **Linear:**
- *Điểm xuất sắc:* Tốc độ tuyệt đối nhờ kiến trúc Local-first (sync ngầm). Cảm giác mượt mà, phản hồi lập tức (zero-latency).
- *Bài học xử lý:* Không bao giờ dùng thanh Loading (Spinner) chặn luồng làm việc. Sử dụng phím tắt (Cmd+K) để tăng tốc thao tác.
2. **Obsidian / Logseq:**
- *Điểm xuất sắc:* Quản lý kiến thức mạnh mẽ, cảm giác dữ liệu hoàn toàn thuộc về mình (nằm trên máy tính local). Khả năng chia đa màn hình (Split-pane) để vừa đọc nội dung vừa ghi chú.
3. **Perplexity / Cursor (Tính năng Composer/Chat):**
- *Điểm xuất sắc:* Minh bạch về nguồn dữ liệu (Sources). Cách trích dẫn (Citations) nhỏ gọn `[1]` nhưng có thể click để tra cứu ngược nguồn gốc câu trả lời rất thuyết phục.
### Transferable UX Patterns
- **Kiểu bố cục Tách viền (Split-Pane Layout):** Góc Chat một bên, góc Đọc/Tra cứu tài liệu (PDF/Text Viewer) một bên. Người dùng không phải chuyển tab để kiểm chứng độ chính xác của câu trả lời.
- **Trích dẫn có tính tương tác (Interactive Citations):** Khi di chuột hoặc click vào số trích dẫn trong câu trả lời báo cáo, đoạn văn bản gốc tương ứng trong file PDF/Text ở pane bên cạnh sẽ tự động scroll tới và highlight.
- **Micro-Sync Indicator (Hiển thị đồng bộ tinh tế):** Học từ Linear - sử dụng một chấm nhỏ hoặc icon xoay góc màn hình để báo hiệu "Đang đồng bộ" (Syncing lên PGlite/Local) thay vì khoá màn hình.
### Anti-Patterns to Avoid
- **The Chatbot Island (Chatbot đơn độc):** Chỉ thiết kế một khung chat ở giữa màn hình mà giấu nhẹm đi khu vực hiển thị tài liệu gốc. Điều này tước mất công cụ đối chiếu của người dùng.
- **Blocking Spinners (Vòng lặp chờ đợi):** Bắt người dùng nhìn Icon xoay màn hình trong 10-15 giây để chờ AI tạo Embedding hoặc khi mạng chậm.
- **Blackbox AI (AI Hộp đen):** Trả lời một câu dài nhưng không có bất kỳ dòng trích dẫn nào, khiến người dùng mất niềm tin nếu phát hiện ra ảo giác (hallucination).
### Design Inspiration Strategy
- **Điều sẽ Áp dụng (Adopt):**
- Mô hình UI phản hồi tức thời (Optimistic UI) cho các thao tác nội bộ và thêm file.
- Card/Badge hiển thị rõ ràng Nguồn (Sources) được dùng cho mỗi response.
- **Điều sẽ Biến tấu (Adapt):**
- Đưa Layout Split-pane vào Web truyền thống (Dùng cơ chế kéo thanh chia hoặc tự động bật mở ngăn tài liệu khi người dùng click vào trích dẫn).
- **Điều sẽ Tránh xa (Avoid):**
- Ẩn quá trình Index dữ liệu. Chúng ta phải "cho thấy âm thầm" việc tài liệu đang được học (Indexed) thông qua một thanh tiến trình nhỏ gắn liền với từng file cụ thể, không ảnh hưởng chat chính.
## Design System Foundation
### 1.1 Design System Choice
**shadcn/ui + Tailwind CSS (Themeable/Custom Hybrid)**
### Rationale for Selection
- **Kiểm soát tuyệt đối (Total Control):** Khác với các thư viện đóng gói sẵn (như Ant Design hay MUI), `shadcn/ui` cho phép chúng ta cài đặt thẳng mã nguồn component (với Tailwind) vào dự án. Điều này tối quan trọng để Frontend Dev có thể can thiệp sâu vào các micro-animation, đáp ứng tiêu chí "Khởi tác Tức thì" (Instant Action) dưới 150ms mà không bị xung đột thư viện.
- **Tốc độ và Hiệu suất:** Dựa trên nền tảng Radix UI Primitives, các logic phức tạp như Focus, Keyboard Navigation đều được xử lý chuẩn mực. Điều này hoàn toàn thích hợp với mục tiêu theo đuổi kiến trúc Local-first (Rocicorp Zero), nơi mọi tương tác UI đều được phản hồi lập tức.
- **Phong cách Hiện đại:** Mặc định `shadcn/ui` mang hơi hướng thẩm mỹ "sạch", trung tính và hiện đại, rất tương đồng với trải nghiệm "Desktop-like" của Linear hay Notion mà chúng ta đang nhắm tới.
### Implementation Approach
- Các component cơ bản (Button, Dialog, Toast, Tooltip) sẽ được khởi tạo qua shadcn CLI để tái sử dụng chuẩn kiến trúc.
- Riêng hệ thống **Tách viền (Split-Pane)** kết hợp không gian Chat và Đọc Tài liệu sẽ được custom chuyên sâu bằng thư viện chuyên dụng cho resizable panel (ví dụ `react-resizable-panels`) kết hợp Tailwind để chịu tải tốt nhất khi nội dung AI đang streaming thay đổi DOM liên tục.
### Customization Strategy
- **Design Tokens:** Tinh chỉnh `tailwind.config.ts` để gán màu sắc trực quan cho các trạng thái mạng (Online/Syncing/Offline) dưới dạng Non-blocking UI.
- **Typography:** Sử dụng Font chữ tối ưu cho việc "Nghiên cứu/Đọc" (ví dụ: Inter, hoặc các font phổ biến cho tài liệu học thuật) kết hợp với phông Monospace riêng cho các đoạn Code / Raw text.
- **Animation Constraints:** Tạo quy tắc khắt khe về thời lượng chuyển động (VD: Khai báo `@layer utilities` các class `duration-fast` < 150ms) để giữ cho cảm giác mọi thứ thao tác đều lập tức ngay dưới tay người dùng, không bao giờ bắt họ phải chờ một cái Dialog mất 0.5s để hiện lên.
## 2. Core User Experience
### 2.1 The Defining Experience
**Trò chuyện Phân tích Định hướng Nguồn (Source-grounded Analytical Chat)**
Mọi thứ trong SurfSense xoay quanh một tương tác vàng: *Hỏi một câu phức tạp dựa trên bộ tài liệu cá nhân, và ngay lập tức nhận về luồng văn bản trả lời đi kèm các trích dẫn (citations) trực quan.* Nếu làm đúng tương tác này, người dùng sẽ cảm thấy họ đang nắm trong tay một đội ngũ trợ lý nghiên cứu làm việc song song không mệt mỏi.
### 2.2 User Mental Model
- **Thói quen hiện tại (Status Quo):** Người dùng phải mở hàng chục tab PDF, dùng Ctrl+F tìm từ khoá, copy-paste từng đoạn sang ChatGPT/Claude để hỏi, và sau đó hoang mang vì AI có thể tóm tắt dông dài hoặc bịa đặt (hallucinate). Trải nghiệm rất chắp vá.
- **Kỳ vọng đối với SurfSense:** "Tôi gom 10 file báo cáo thả vào app, tôi hỏi một câu, hệ thống đọc cả 10 file đó và trả cho tôi câu trả lời được đúc kết lại, đồng thời **chỉ rõ luôn là lấy từ dòng nào của file nào**."
### 2.3 Success Criteria
1. **Khẳng định Bản sắc:** Người dùng ngay lập tức nhận ra đây là công cụ "Nghiên cứu tài liệu" (Research), chứ không phải công cụ tán gẫu (General Chat) như ChatGPT.
2. **Speed-to-First-Token:** Kéo thả tệp xong, click hỏi, phản hồi (Token) đầu tiên của AI xuất hiện tức thì nhờ cơ chế cache/sync tối ưu.
3. **Citations == Trust (Trích dẫn là Niềm tin):** Trích dẫn không chỉ ghi dạng text `[Source: document.pdf]`, mà phải là một Badge tương tác. Click vào Badge, nguyên bản tài liệu bật lên đúng ở dòng đó.
### 2.4 Novel UX Patterns
- **Established (Kế thừa mẫu quen thuộc):** Ô nhập câu hỏi Chat kiểu bong bóng (giống ChatGPT) để người dùng không phải học cách dùng mới.
- **Novel (Sự đột phá khác biệt):** Layout động (Dynamic Split-pane). Khi chat bình thường là 1 khung trung tâm rộng rãi. Khi click vào 1 trích dẫn `[2]`, màn hình mượt mà trượt sang trái, mở ra nửa màn hình bên phải là trình đọc PDF (PDF Viewer) scroll sẵn tới đúng vùng được highlight.
### 2.5 Experience Mechanics
1. **Initiation (Bắt đầu):** Người dùng kéo/thả một tệp PDF vào khung chat. File lập tức bay vào mục "Current Collection" một cách ảo diệu (Syncing chạy ngầm, không có thanh loading tròn chặn màn hình).
2. **Interaction (Tương tác thao tác):** Người dùng gõ "Nguyên nhân chính là gì?" và Enter. Token được lưu tức thì xuống db local (PGLite) bằng Rocicorp Zero, giao diện đẩy bong bóng tin nhắn lên ngay lập tức mà không khựng 1 giây.
3. **Feedback (Phản hồi thị giác):** Response trả về dồn dập (streaming). Cứ mỗi lần AI rải xong một fact (sự kiện), một thẻ Badge `[1]` nhỏ nhắn hiện ra phía cuối câu.
4. **Completion (Khoảnh khắc Aha):** Người dùng click dứt khoát vào `[1]`. Giao diện tách đôi, file PDF/Text gốc hiện ra tô vàng đúng câu AI vừa trích dẫn. Người dùng gật gù tin tưởng và yên tâm gõ tiếp câu hỏi số 2.
## Visual Design Foundation
### Color System
**Chiến lược "Trung tính & Một điểm nhấn" (Monochrome with Accent)**
Khác với ứng dụng giải trí, SurfSense là công cụ phân tích tài liệu, mắt người dùng sẽ phải đọc chữ liên tục. Sự rườm rà về màu sắc sẽ làm người dùng phân tâm.
- **Base (Nền tảng):** Sử dụng dải màu `Zinc` hoặc `Slate` của Tailwind. Chế độ Dark Mode sẽ là chủ đạo (với nền `#09090b`), tạo cảm giác "hacker/researcher" bí ẩn nhưng sang trọng. Light Mode sử dụng nền trắng `#ffffff` tinh khiết.
- **Accent (Điểm nhấn):** `Indigo` (Tím xanh) hoặc `Teal` (Xanh cổ vịt). Màu Accent chỉ xuất hiện ở các vị trí: Nút thao tác chính (Call-to-Action), viền Focus, và đặc biệt là **Màu của Thẻ Trích dẫn (Citations)** để thu hút sự chú ý.
- **Semantic/Status Indicators:** Bỏ qua các khối màu to. Chỉ sử dụng glow (đốm sáng) hoặc viền mỏng:
- *Syncing:* Ánh sáng vàng cam (Amber glow) nhẹ nhàng ở góc màn hình.
- *Offline:* Các nút bị vô hiệu hoá chuyển sắc xám nhạt (Muted Gray).
- *Success:* Xanh ngọc (Emerald) vụt sáng rồi tắt khi file được Vector hoá thành công.
### Typography System
**Tập trung vào Tính Dễ Đọc (High Legibility)**
- **Primary Typeface (UI & Giao diện):** `Inter` hoặc `Geist Sans`. Font chữ không chân, trung tính, hiện đại, đảm bảo UI nhìn gọn gàng ở kích thước 12-14px.
- **Reading Typeface (Văn bản & Trả lời AI):** Có thể giữ nguyên `Inter` nhưng tăng `line-height` lên `1.6` (leading-relaxed) để tối ưu cho việc đọc đoạn văn dài.
- **Monospace Typeface:** `JetBrains Mono` hoặc `Fira Code`. Dành riêng cho giao diện hiển thị Raw Text, đoạn Code, hoặc Metadata của tài liệu, tạo sự phân biệt rõ ràng với văn bản văn xuôi.
### Spacing & Layout Foundation
**Hệ thống Lưới không gian (Airy vs Dense)**
- **Base Grid:** Dựa theo hệ số 8px mặc định của Tailwind (VD: 8, 16, 24, 32px).
- **Phân bổ không gian:**
- *Khu vực Chat:* Cần khoảng không thoáng đãng (Airy) giữa các tin nhắn (padding lớn, margin lớn) để làm chậm nhịp độ tiếp nhận thông tin, giúp người dùng "thở" khi xử lý dữ liệu phức tạp.
- *Khu vực Đọc PDF/Document (Bên phải):* Mật độ cao (Dense/Compact) để chứa được nhiều chữ nhất có thể trên một khung hình, tối ưu việc dò tìm.
- **Split-Pane Layout:** Trên màn hình Desktop (>1024px), giới hạn khung Chat ở mức maxWidth cố định (khoảng 800px), toàn bộ phần hẹp dư thừa rẽ băng nhường chỗ cho khung Document Panel.
### Accessibility Considerations
- **Contrast Ratios (Độ Tương phản):** Tất cả Text (đặc biệt là nội dung AI sinh ra) phải đạt chuẩn WCAG AA (nhịp tương phản 4.5:1). Chữ xám trên nền xám đen cần kiểm tra kỹ.
- **Focus States (Dành cho Pro Users):** Vì phần mềm đề cao phím tắt (Cmd+K), hiệu ứng Focus (ví dụ viền `ring-2 ring-indigo-500`) phải nổi bật rõ ràng khi người dùng dùng phím `Tab` duyệt qua các Citation.
<!-- UX design content will be appended sequentially through collaborative workflow steps -->