docs: comprehensive documentation - README, specs, architecture, API reference, UI/UX flow, dev guide
This commit is contained in:
204
docs/api-reference.md
Normal file
204
docs/api-reference.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# ComparAIson — API Reference
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
Development: http://localhost:3000
|
||||
Production: https://comparaison.tophermayor.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All authenticated endpoints use Better Auth session cookies.
|
||||
|
||||
### POST `/api/auth/sign-up`
|
||||
Create a new account.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"name": "Alex Johnson",
|
||||
"email": "alex@example.com",
|
||||
"password": "securepassword123"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:** `200 OK` — Sets session cookie, returns user object
|
||||
|
||||
### POST `/api/auth/sign-in`
|
||||
Sign in to existing account.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"email": "alex@example.com",
|
||||
"password": "securepassword123"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:** `200 OK` — Sets session cookie, redirects to callbackUrl
|
||||
|
||||
### POST `/api/auth/sign-out`
|
||||
Sign out, clears session.
|
||||
|
||||
**Response:** `200 OK` — Redirects to `/`
|
||||
|
||||
---
|
||||
|
||||
## Comparison Endpoints
|
||||
|
||||
### POST `/api/compare`
|
||||
Start a new comparison research. Returns a Server-Sent Events stream.
|
||||
|
||||
**Authentication:** Required
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"query": "for modern web development",
|
||||
"items": ["React", "Vue", "Svelte"],
|
||||
"dimensions": ["Performance", "Developer Experience"]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `query` | string | No | Context/focus for the comparison |
|
||||
| `items` | string[] | Yes | Items to compare (2-10) |
|
||||
| `dimensions` | string[] | No | Optional dimension hints |
|
||||
|
||||
**Response:** `200 OK` — `text/event-stream`
|
||||
|
||||
SSE event format:
|
||||
```
|
||||
event: progress
|
||||
data: {"status":"researching","message":"Analyzing comparison request...","itemsCompleted":0,"totalItems":3,"currentStep":"Analyzing comparison request..."}
|
||||
|
||||
event: progress
|
||||
data: {"status":"researching","message":"Researching React...","itemsCompleted":1,"totalItems":3,"currentStep":"Analyzing React"}
|
||||
|
||||
event: progress
|
||||
data: {"status":"completed","message":"Research complete!","itemsCompleted":3,"totalItems":3,"currentStep":"Done"}
|
||||
|
||||
event: done
|
||||
data: {"id":"clx123abc","slug":"react-vs-vue-vs-svelte-clx123","data":{...full comparison data...}}
|
||||
```
|
||||
|
||||
**Error Response:** `400 Bad Request`
|
||||
```json
|
||||
{ "error": "At least 2 items are required" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Page Routes
|
||||
|
||||
### `GET /`
|
||||
Landing page. Public. Shows hero, example comparisons, features.
|
||||
|
||||
### `GET /sign-in`
|
||||
Sign in form. Public. Redirects to `/compare` on success.
|
||||
|
||||
### `GET /sign-up`
|
||||
Sign up form. Public. Redirects to `/compare` on success.
|
||||
|
||||
### `GET /compare`
|
||||
Comparison creation page. **Protected.** Shows item input form + streaming progress.
|
||||
|
||||
### `GET /compare/[slug]`
|
||||
Comparison results page. Public (if comparison is public). Shows tabbed visualization layout.
|
||||
|
||||
**URL format:** `/compare/react-vs-vue-vs-svelte-clx123a`
|
||||
|
||||
### `GET /explore`
|
||||
Public comparisons feed. Public. Grid layout with search + category filter.
|
||||
|
||||
### `GET /profile`
|
||||
User profile page. **Protected.** Shows user info, stats, and saved comparisons.
|
||||
|
||||
---
|
||||
|
||||
## TypeScript Types
|
||||
|
||||
### ComparisonRequest
|
||||
```typescript
|
||||
interface ComparisonRequest {
|
||||
query: string;
|
||||
items: string[];
|
||||
dimensions?: string[];
|
||||
}
|
||||
```
|
||||
|
||||
### ComparisonResult
|
||||
```typescript
|
||||
interface ComparisonResult {
|
||||
items: ItemResearch[];
|
||||
dimensions: string[];
|
||||
summary: string;
|
||||
recommendation: string;
|
||||
}
|
||||
```
|
||||
|
||||
### ItemResearch
|
||||
```typescript
|
||||
interface ItemResearch {
|
||||
name: string;
|
||||
description: string;
|
||||
overallScore: number;
|
||||
dimensions: Record<string, DimensionResult>;
|
||||
pros: string[];
|
||||
cons: string[];
|
||||
sources: { title: string; url: string; snippet: string }[];
|
||||
}
|
||||
```
|
||||
|
||||
### DimensionResult
|
||||
```typescript
|
||||
interface DimensionResult {
|
||||
score: number; // 1-10
|
||||
summary: string;
|
||||
details: string;
|
||||
pros: string[];
|
||||
cons: string[];
|
||||
}
|
||||
```
|
||||
|
||||
### ResearchProgress (SSE)
|
||||
```typescript
|
||||
type ResearchProgress =
|
||||
| { stage: "parsing"; message: string }
|
||||
| { stage: "searching"; item: string; results: number }
|
||||
| { stage: "researching"; item: string; progress: number }
|
||||
| { stage: "synthesizing"; message: string }
|
||||
| { stage: "complete"; result: ComparisonResult }
|
||||
| { stage: "error"; error: string };
|
||||
```
|
||||
|
||||
### ComparisonData (Frontend)
|
||||
```typescript
|
||||
interface ComparisonData {
|
||||
id: string;
|
||||
userId: string;
|
||||
title: string;
|
||||
query: string;
|
||||
slug: string;
|
||||
status: "researching" | "completed" | "failed";
|
||||
summary: string;
|
||||
items: {
|
||||
name: string;
|
||||
description: string;
|
||||
overallScore: number;
|
||||
dimensions: Record<string, DimensionResult>;
|
||||
pros: string[];
|
||||
cons: string[];
|
||||
}[];
|
||||
dimensions: string[];
|
||||
tags: string[];
|
||||
isPublic: boolean;
|
||||
viewCount: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user