# 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; 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; pros: string[]; cons: string[]; }[]; dimensions: string[]; tags: string[]; isPublic: boolean; viewCount: number; createdAt: string; updatedAt: string; } ```