130 lines
5.4 KiB
Markdown
130 lines
5.4 KiB
Markdown
# 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 |
|