Architecture Overview
How chat routes, embedding jobs, credit ledger tables, and Stripe webhooks connect. Skim the stack table first, then jump to the sections you plan to change.
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Database | Supabase (PostgreSQL + pgvector) |
| Auth | Supabase Auth (Magic Link + OAuth) |
| Payments | Stripe (Subscriptions + One-time) |
| AI | Vercel AI SDK (OpenAI + Anthropic) |
| Styling | Tailwind CSS v4 |
| UI | shadcn/ui components |
Directory Structure
src/
├── app/ # Next.js App Router pages
│ ├── (auth)/ # Auth routes (login, callback)
│ ├── (dashboard)/ # Protected dashboard routes
│ ├── (marketing)/ # Public marketing pages
│ ├── api/ # API routes
│ └── docs/ # Documentation pages
├── components/ # React components
│ ├── ui/ # shadcn/ui base components
│ ├── chat/ # Chat-specific components
│ ├── dashboard/ # Dashboard components
│ └── billing/ # Billing components
├── config/ # Configuration files
│ ├── ai-models.ts # AI model definitions
│ ├── pricing.ts # Tier & pricing config
│ ├── features.ts # Feature flags
│ ├── rag.ts # RAG pipeline config
│ └── ui.ts # UI/branding config
├── lib/ # Utility libraries
│ ├── supabase/ # Supabase clients
│ ├── stripe/ # Stripe client
│ └── ai/ # AI utilities & RAG
├── db/ # Database schemas
└── types/ # TypeScript types
Request Flow
Authentication Flow
User → Login Page → Supabase Auth → OAuth/Magic Link
↓
Auth Callback
↓
Profile Creation (trigger)
↓
Dashboard Redirect
Chat Request Flow
User Input → Chat Interface → /api/chat
↓
Auth Check
↓
Credit Check
↓
Model Validation
↓
RAG Retrieval (if docs)
↓
streamText() → AI Provider
↓
onFinish: Credit Deduction
↓
Stream Response → Client
Payment Flow
User → Billing Page → generateCheckoutLink()
↓
Stripe Checkout
↓
Payment Complete
↓
Webhook: checkout.session.completed
↓
Update Profile (tier, credits)
Key Design Decisions
Config-Driven Architecture
All business logic is controlled via TypeScript config files:
ai-models.ts: Define models, costs, capabilitiespricing.ts: Define tiers, credits, allowed modelsfeatures.ts: Feature flags for different tiers
This allows changing business rules without modifying code.
Credit Economy
Every AI interaction costs credits based on token usage:
- Credits are checked before API calls (402 if insufficient)
- Credits are deducted AFTER successful completion (in
onFinish) - Different models have different costs per 1k tokens
Row Level Security (RLS)
All database tables use RLS policies:
- Users can only access their own data
- Pattern:
auth.uid() = user_id - Critical for multi-tenant security
Server Components by Default
Dashboard pages are Server Components:
- Data fetching happens on server
- Reduced client bundle size
- Better SEO and initial load
Client Components are used only when needed:
- Interactive features (chat input)
- Real-time updates (credit widget)
- Browser APIs (localStorage)
Component Architecture
Chat Interface
ChatInterface (client)
├── ModelSelector (client)
├── SuggestionCards (client)
├── Messages List
├── DocumentList (client)
└── Input Form
├── AttachmentButton (client)
├── Input
└── Submit Button
Dashboard Layout
DashboardLayout (server)
├── Header
│ └── Logout Button
└── Sidebar
├── ChatHistory (client)
├── CreditWidget (client)
└── Navigation Links
API Routes
| Route | Method | Description |
|---|---|---|
/api/chat | POST | AI chat with streaming |
/api/upload | POST | Document upload |
/api/rag | POST | Trigger vectorization |
/api/billing/invoices | GET | Fetch Stripe invoices |
/api/webhooks/stripe | POST | Stripe webhook handler |