docs: comprehensive documentation - README, specs, architecture, API reference, UI/UX flow, dev guide
This commit is contained in:
129
docs/architecture.md
Normal file
129
docs/architecture.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# ComparAIson — Architecture
|
||||
|
||||
## System Overview
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
||||
│ Browser │────▶│ Traefik │────▶│ Next.js │
|
||||
│ (React SPA) │◀────│ (Reverse │◀────│ (Port 3000)│
|
||||
│ │ │ Proxy) │ │ │
|
||||
└─────────────┘ └──────────────┘ └──────┬──────┘
|
||||
│
|
||||
┌─────────────┼─────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│PostgreSQL│ │ Tavily │ │ OpenAI │
|
||||
│ (DB) │ │ (Search) │ │ (LLM) │
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
┌──────────┐
|
||||
│Perplexity│
|
||||
│ (LLM) │
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
## Component Architecture
|
||||
|
||||
### Frontend (Next.js App Router)
|
||||
|
||||
```
|
||||
Route Groups:
|
||||
├── (auth)/ — Unauthenticated pages (sign-in, sign-up)
|
||||
├── (main)/ — Authenticated pages with shared nav layout
|
||||
│ ├── compare/ — Comparison creation + results viewing
|
||||
│ ├── explore/ — Public feed browsing
|
||||
│ └── profile/ — User profile + comparison history
|
||||
└── api/ — Server-side API routes
|
||||
├── auth/ — Better Auth endpoints
|
||||
└── compare/ — SSE research streaming endpoint
|
||||
```
|
||||
|
||||
**Key patterns:**
|
||||
- **Server Components** for data-fetching pages (profile, explore)
|
||||
- **Client Components** for interactive UI (compare input, charts, streaming)
|
||||
- **Server Actions** for mutations (save comparison, update profile)
|
||||
- **SSE streaming** for real-time research progress
|
||||
|
||||
### Backend Services
|
||||
|
||||
#### Research Pipeline (`src/lib/llm/`)
|
||||
Orchestrates the multi-stage research process:
|
||||
1. **Input parsing** — Validate items, extract dimensions
|
||||
2. **Provider detection** — Check available API keys, select best provider chain
|
||||
3. **Web search** — Tavily API searches per item
|
||||
4. **LLM synthesis** — Structured JSON generation via Perplexity or OpenAI
|
||||
5. **Validation** — Runtime type checking of LLM output
|
||||
6. **Persistence** — Store results in PostgreSQL via Drizzle ORM
|
||||
|
||||
#### Auth System (`src/lib/auth.ts`)
|
||||
- Better Auth with Drizzle adapter
|
||||
- Email + password authentication
|
||||
- 7-day session expiry
|
||||
- Middleware-based route protection
|
||||
|
||||
#### Database (`src/lib/db/`)
|
||||
- Drizzle ORM with PostgreSQL
|
||||
- 5 tables: users, sessions, comparisons, comparison_items, comparison_dimensions
|
||||
- JSONB columns for flexible research data storage
|
||||
- Indexed on userId, slug, status for query performance
|
||||
|
||||
## Data Flow
|
||||
|
||||
### Comparison Creation Flow
|
||||
|
||||
```
|
||||
1. User enters items + query on /compare
|
||||
2. Client calls POST /api/compare with { items, query, dimensions }
|
||||
3. Server creates comparison record (status: "researching")
|
||||
4. Server opens SSE stream to client
|
||||
5. Research pipeline runs:
|
||||
a. Parsing → emits SSE "parsing" event
|
||||
b. For each item:
|
||||
- Tavily search → emits SSE "searching" event
|
||||
- Process results → emits SSE "researching" event with progress %
|
||||
c. Synthesize all data → emits SSE "synthesizing" event
|
||||
d. Validate + structure → emits SSE "complete" event with full data
|
||||
6. Server persists results to comparisons + comparison_items tables
|
||||
7. Client renders visualization components with result data
|
||||
8. User redirected to /compare/[slug] with full results
|
||||
```
|
||||
|
||||
### Comparison Viewing Flow
|
||||
|
||||
```
|
||||
1. User navigates to /compare/[slug]
|
||||
2. Server component fetches comparison from DB by slug
|
||||
3. If status === "researching": show streaming progress UI
|
||||
4. If status === "completed": render full results with all viz components
|
||||
5. If status === "failed": show error with retry option
|
||||
6. Increment viewCount on each visit
|
||||
```
|
||||
|
||||
## Deployment Architecture
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app: # Next.js standalone (~150-300MB RAM)
|
||||
db: # PostgreSQL 16 Alpine (~200-400MB RAM)
|
||||
```
|
||||
|
||||
Total estimated RAM: **400-800MB** — fits comfortably on an 8GB Raspberry Pi.
|
||||
|
||||
### Traefik Integration
|
||||
|
||||
The app is exposed via Traefik reverse proxy with:
|
||||
- HTTPS termination
|
||||
- Domain routing (e.g., `comparaison.tophermayor.com`)
|
||||
- Automatic SSL certificate management
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Layer | Strategy |
|
||||
|---|---|
|
||||
| LLM API failures | 3x retry with exponential backoff |
|
||||
| Provider unavailable | Automatic fallback to next provider in chain |
|
||||
| Invalid LLM output | Runtime validation + retry with new prompt |
|
||||
| Database errors | Transaction rollback, error logged, user sees "failed" status |
|
||||
| SSE connection lost | Client auto-reconnects, polls comparison status from DB |
|
||||
| Auth failures | Redirect to sign-in with callback URL |
|
||||
Reference in New Issue
Block a user