2026-04-24 14:06:35 -07:00

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

  1. Traefik Ingress — A shared Traefik instance handles TLS termination and routes traffic to the app container via Docker labels. The app joins the proxy-net network so Traefik can reach it.

  2. Shared PostgreSQL — A standalone postgres-shared container provides the database. The comparaison app connects to it over proxy-net. No separate DB container is defined in the app's compose file.

  3. Environment — The following are configured in the production environment:

    • DATABASE_URL — Points to the shared Postgres instance
    • BETTER_AUTH_SECRET — Random secret for session signing
    • OPENAI_API_KEY, TAVILY_API_KEY, PERPLEXITY_API_KEY — LLM provider keys
    • NEXT_PUBLIC_APP_URLhttps://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 userId to comparison inserts so saved comparisons are properly associated with authenticated users
  • Fixed OpenAI provider getClient() to correctly initialize the OpenAI client
  • Added BETTER_AUTH_SECRET to 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

Description
AI-Powered Deep Research Comparison Platform
Readme 483 KiB
Languages
TypeScript 97%
CSS 2.4%
JavaScript 0.3%
Dockerfile 0.3%