- Document production URL (comparaison.local.tophermayor.com) - Detail host (ubuntu/192.168.50.61), Traefik ingress, shared Postgres - Add Docker label routing, proxy-net network info - List recent fixes: userId in comparison inserts, OpenAI getClient(), BETTER_AUTH_SECRET
6.4 KiB
ComparAIson
AI-Powered Deep Research Comparison Platform
Compare anything with intelligent, multi-dimensional analysis. ComparAIson uses LLM-powered research to generate comprehensive, visual comparisons — then saves them as shareable posts on your profile.
Features
- Deep Research Engine — Multi-provider LLM pipeline (Tavily search → Perplexity/OpenAI synthesis) with automatic fallback
- Interactive Visualizations — Radar charts, grouped bar charts, feature comparison tables, score cards, pros/cons breakdowns
- Real-Time Streaming — Watch research progress live via Server-Sent Events
- User Profiles — Save comparisons to your profile, browse a public feed
- Self-Hosted — Docker Compose deployment, runs on a Raspberry Pi
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router, Server Components, Server Actions) |
| Language | TypeScript |
| Database | PostgreSQL 16 |
| ORM | Drizzle ORM |
| Auth | Better Auth (email + password) |
| UI | Tailwind CSS + shadcn/ui |
| Charts | Recharts |
| LLM | OpenAI GPT-4o-mini + Tavily Search + Perplexity Sonar |
| Deployment | Docker Compose + Traefik reverse proxy |
Quick Start
Prerequisites
- Node.js 20+
- PostgreSQL 16+ (or Docker)
- At least one LLM API key
1. Clone & Install
git clone https://gitea.tophermayor.com/TopherMayor/comparaison.git
cd comparaison
npm install
2. Configure Environment
cp .env.example .env.local
# Edit .env.local with your API keys and database URL
Required environment variables:
| Variable | Description | Required |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | Yes |
BETTER_AUTH_SECRET |
Random secret for session signing | Yes |
OPENAI_API_KEY |
OpenAI API key (GPT-4o-mini) | Yes* |
TAVILY_API_KEY |
Tavily search API key | Recommended |
PERPLEXITY_API_KEY |
Perplexity Sonar API key | Optional |
NEXT_PUBLIC_APP_URL |
Public URL of the app | Yes |
*At minimum, one LLM provider key is required. OpenAI works standalone; Tavily adds web search; Perplexity adds cheaper synthesis.
3. Database Setup
# Generate migration
npx drizzle-kit generate
# Run migration
npx drizzle-kit migrate
4. Development
npm run dev
# App runs at http://localhost:3000
5. Docker Deployment
docker compose up -d
Deployment
Production URL: https://comparaison.local.tophermayor.com
| Detail | Value |
|---|---|
| Host | ubuntu (192.168.50.61) |
| Compose file | /srv/compose/comparaison/docker-compose.yml |
| Reverse proxy | Traefik (shared instance on proxy-net) |
| Database | Shared PostgreSQL (postgres-shared container on proxy-net) |
| Routing | Docker labels on the app container (Traefik router/rules) |
Production Setup
-
Traefik Ingress — A shared Traefik instance handles TLS termination and routes traffic to the app container via Docker labels. The app joins the
proxy-netnetwork so Traefik can reach it. -
Shared PostgreSQL — A standalone
postgres-sharedcontainer provides the database. The comparaison app connects to it overproxy-net. No separate DB container is defined in the app's compose file. -
Environment — The following are configured in the production environment:
DATABASE_URL— Points to the shared Postgres instanceBETTER_AUTH_SECRET— Random secret for session signingOPENAI_API_KEY,TAVILY_API_KEY,PERPLEXITY_API_KEY— LLM provider keysNEXT_PUBLIC_APP_URL—https://comparaison.local.tophermayor.com
Deploying Updates
# On ubuntu (192.168.50.61)
cd /srv/compose/comparaison
docker compose pull && docker compose up -d
Recent Fixes
- Added
userIdto comparison inserts so saved comparisons are properly associated with authenticated users - Fixed OpenAI provider
getClient()to correctly initialize the OpenAI client - Added
BETTER_AUTH_SECRETto production environment for proper session management
Project Structure
src/
├── app/
│ ├── (auth)/ # Auth route group
│ │ ├── sign-in/ # Sign in page
│ │ └── sign-up/ # Sign up page
│ ├── (main)/ # Main app route group (with nav)
│ │ ├── compare/ # Comparison input + results
│ │ ├── explore/ # Public comparisons feed
│ │ └── profile/ # User profile + saved comparisons
│ ├── api/
│ │ ├── auth/[...all]/ # Better Auth catch-all
│ │ └── compare/ # SSE streaming research endpoint
│ ├── layout.tsx # Root layout
│ └── page.tsx # Landing page
├── components/
│ ├── comparison/ # Visualization components
│ │ ├── radar-chart.tsx
│ │ ├── bar-chart.tsx
│ │ ├── comparison-table.tsx
│ │ ├── score-card.tsx
│ │ └── pros-cons-card.tsx
│ └── ui/ # shadcn/ui components
├── hooks/
│ └── use-comparison-stream.ts # SSE streaming hook
├── lib/
│ ├── auth.ts # Better Auth server config
│ ├── auth-client.ts # Better Auth client
│ ├── db/
│ │ ├── index.ts # Drizzle client
│ │ └── schema.ts # Database schema
│ ├── llm/
│ │ ├── index.ts # Research pipeline orchestrator
│ │ ├── types.ts # LLM type definitions
│ │ └── providers/
│ │ ├── index.ts # Provider fallback chain
│ │ ├── openai.ts # OpenAI GPT-4o-mini provider
│ │ ├── tavily.ts # Tavily search provider
│ │ └── perplexity.ts # Perplexity Sonar provider
│ ├── types.ts # Shared type definitions
│ └── utils.ts # Utility functions
└── middleware.ts # Auth middleware + route protection
Architecture
See docs/architecture.md for detailed architecture documentation.
API Reference
See docs/api-reference.md for endpoint documentation.
UI/UX Flow
See docs/ui-ux-flow.md for user journey and wireframe descriptions.
License
MIT