@@ -4,9 +4,26 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44
55## Project Overview
66
7- DebateLab is an AI-powered debate preparation suite. It uses ** Supabase Edge Functions** as the backend for all AI calls ( keys are never exposed to the browser) . Authentication is via Supabase Auth with Google OAuth.
7+ DebateLab is an AI-powered debate preparation suite for competitive debaters . It combines multiple AI providers (OpenAI, Google Gemini, Anthropic) with real-time web research via Jina AI. Uses ** Supabase Edge Functions** as the backend so API keys are never exposed to the browser. Authentication is via Supabase Auth with Google OAuth.
88
99** Live URL:** https://debate.pi-stack.org
10+ ** Hosting:** Raspberry Pi + Docker + Cloudflare Tunnel
11+
12+ ## Tech Stack
13+
14+ | Layer | Technology |
15+ | -------| ------------|
16+ | Frontend | React 18, TypeScript, Vite 5 |
17+ | Styling | TailwindCSS + shadcn/ui (51+ components) |
18+ | State | Zustand with localStorage persistence |
19+ | Forms | React Hook Form + Zod validation |
20+ | Routing | React Router v6 |
21+ | Backend | Supabase Edge Functions (Deno runtime) |
22+ | Auth | Supabase Auth (Google OAuth) |
23+ | Database | Supabase PostgreSQL (15 tables, RLS enabled) |
24+ | AI Providers | OpenAI, Google Gemini, Anthropic Claude |
25+ | Web Search | Jina AI (Search + Reader) |
26+ | CI/CD | GitHub Actions + Docker Hub + Watchtower |
1027
1128## Common Commands
1229
@@ -15,79 +32,203 @@ DebateLab is an AI-powered debate preparation suite. It uses **Supabase Edge Fun
1532npm install # Install dependencies
1633npm run dev # Start dev server on port 8080
1734npm run build # Production build to dist/
35+ npm run build:dev # Dev build with source maps
36+ npm run preview # Preview production build
1837
1938# Quality
2039npm run lint # Run ESLint
21- npm test # Run tests with Vitest
40+ npm test # Run tests with Vitest (39 tests)
41+ npm run test:watch # Run tests in watch mode
2242
2343# Docker
2444docker build -t debate-trainer .
2545docker run -d -p 3001:80 --name debate-app debate-trainer
46+
47+ # Supabase
48+ npx supabase functions deploy ai # Deploy AI function
49+ npx supabase functions deploy admin # Deploy admin function
50+ npx supabase functions deploy share # Deploy share function
2651```
2752
2853## Architecture
2954
30- ### Backend: Supabase Edge Functions
55+ ### Backend: 3 Supabase Edge Functions
56+
57+ 1 . ** ` supabase/functions/ai/index.ts ` ** (~ 888 lines) - Main AI proxy
58+ - JWT authentication required
59+ - API keys stored as Supabase secrets (OPENAI_API_KEY, GOOGLE_API_KEY, ANTHROPIC_API_KEY, JINA_API_KEY)
60+ - Input sanitization with prompt injection pattern detection
61+ - Deep research with Jina AI (multi-round search, content reading, URL verification)
62+ - Rate limiting per authenticated user
63+ - Multi-provider routing (OpenAI, Google, Anthropic)
3164
32- All AI calls go through ` supabase/functions/ai/index.ts ` :
33- - JWT authentication required
34- - API keys stored as Supabase secrets
35- - Input sanitization for prompt injection
36- - Deep research with Jina AI (multi-search, URL verification)
65+ 2 . ** ` supabase/functions/admin/index.ts ` ** (~ 329 lines) - Admin API
66+ - Admin role verification
67+ - User management, usage stats
68+
69+ 3 . ** ` supabase/functions/share/index.ts ` ** (~ 131 lines) - Share link creation
70+ - Unique share code generation with collision detection
3771
3872### Frontend: React + Zustand
3973
74+ ** AI Client** (` src/lib/ai/client.ts ` ):
75+ - Calls Edge Function via ` fetch ` with JWT Bearer token
76+ - Custom error hierarchy: ` AIError ` , ` AIAuthError ` , ` AIRateLimitError ` , ` AIProviderError ` , ` AIResponseError ` , ` TimeoutError `
77+ - Type guards for error handling
78+
4079** Session Store** (` src/lib/stores/session-store.ts ` ):
41- - Active results for each feature
42- - History arrays (savedCases, savedAttacks, etc. )
80+ - Active results for each feature (generateResult, attackResult, etc.)
81+ - History arrays (savedCases, savedAttacks, savedBrainstorms, savedFactoids, savedChats )
4382- Source Library for knowledge base grounding
83+ - Persistence key: ` debate-trainer-storage `
4484
4585** Settings Store** (` src/lib/stores/settings-store.ts ` ):
46- - Per-feature AI provider configuration
47- - Theme, language, admin mode
86+ - Per-feature AI provider configuration (provider, model, temperature)
87+ - Theme (light/dark/system), language (en/es)
88+ - Admin mode, custom system prompt
89+ - Persistence key: ` debate-settings `
4890
4991### State Persistence
5092- All data stored in browser localStorage via Zustand persist
5193- Auth state in Supabase session
5294
95+ ## Project Structure
96+
97+ ```
98+ src/
99+ ├── components/
100+ │ ├── auth/ # Auth-related components
101+ │ ├── features/ # Feature-specific components (9 folders)
102+ │ ├── landing/ # Landing page components (11 files)
103+ │ ├── layout/ # AppLayout, Sidebar, MobileNav
104+ │ └── ui/ # shadcn/ui components (51 files)
105+ ├── hooks/ # use-mobile, use-speech-to-text, use-toast
106+ ├── lib/
107+ │ ├── ai/
108+ │ │ ├── client.ts # AI integration (Edge Function calls)
109+ │ │ └── schemas/ # Zod validation (ask, attack, brainstorm, factoids, generate)
110+ │ ├── stores/ # Zustand stores
111+ │ ├── supabase/ # Client + AuthProvider
112+ │ └── validation/ # URL validation
113+ ├── pages/ # 14 route pages
114+ └── test/ # Tests (39 passing across 8 files)
115+
116+ supabase/functions/ # Edge Functions (ai, admin, share)
117+ ```
118+
53119## Feature Organization
54120
55- Five main features under ` src/components/features/ ` :
56- - ** generate/** : Case generation
57- - ** attack/** : Critical analysis
58- - ** brainstorm/** : Idea generation
59- - ** factoids/** : Evidence research with web search
60- - ** ask/** : Coach chat
121+ Main features under ` src/components/features/ ` :
122+ - ** generate/** : Case generation (4-6-6-3 tournament format, contentions with CWI structure)
123+ - ** attack/** : Critical analysis with fallacy detection and severity ratings
124+ - ** brainstorm/** : Multi-mode ideation (mindmap, buckets, top-5)
125+ - ** factoids/** : Deep research with multi-round Jina search, URL verification, content reading
126+ - ** ask/** : Coach chat with conversation memory, source grounding, voice input
127+
128+ Each follows: ` FeatureForm.tsx ` -> ` FeatureResults.tsx ` pattern.
129+
130+ Additional features:
131+ - ** Source Library** (` /library ` ): Persistent knowledge base (URL reading, manual text, response saving)
132+ - ** Debate Timer** (` /timer ` ): Presets for constructive (4m), rebuttal (6m), cross-ex (6m), summary (3m)
133+ - ** Word/PDF Export** : Download cases as .docx or formatted PDF
134+ - ** Google Docs Export** : Direct export via Google Docs API
135+ - ** Argument Flowcharts** : Visual debate flow with React Flow
136+
137+ ## Routes
138+
139+ | Path | Page | Description |
140+ | ------| ------| -------------|
141+ | ` / ` | GeneratePage | Case generation |
142+ | ` /attack ` | AttackPage | Case critique |
143+ | ` /brainstorm ` | BrainstormPage | Idea generation |
144+ | ` /factoids ` | FactoidsPage | Research |
145+ | ` /ask ` | AskPage | Chat coaching |
146+ | ` /library ` | LibraryPage | Source library |
147+ | ` /history ` | HistoryPage | Saved items |
148+ | ` /timer ` | TimerPage | Debate stopwatch |
149+ | ` /settings ` | SettingsPage | Configuration |
150+ | ` /login ` | LoginPage | Authentication |
151+
152+ ## Database Schema (15 tables)
61153
62- Each follows: ` FeatureForm.tsx ` → ` FeatureResults.tsx ` pattern.
154+ Tables with RLS enabled: ` user_settings ` , ` cases ` , ` attacks ` , ` brainstorms ` , ` factoids ` , ` chats ` , ` messages ` , ` sources ` , ` source_files ` , ` ai_requests ` , ` api_keys ` , ` shared_items ` , ` user_roles ` , ` rate_limits ` , ` global_prompts `
155+
156+ All RLS policies use optimized ` (SELECT auth.uid()) ` pattern.
63157
64158## Security
65159
66160| Layer | Implementation |
67161| -------| ----------------|
68- | API Keys | Supabase Edge Function secrets |
69- | Auth | Supabase Auth + JWT |
70- | Input Validation | Prompt injection sanitization |
71- | Nginx | CSP headers, block sensitive files |
72-
73- ## Critical Files
74-
75- - ** Edge Function** : ` supabase/functions/ai/index.ts ` - All AI logic
76- - ** Supabase Client** : ` src/lib/supabase/client.ts `
77- - ** State** : ` src/lib/stores/session-store.ts ` , ` settings-store.ts `
78- - ** Schemas** : ` src/lib/ai/schemas/ ` - Zod validation
79- - ** Deployment** : ` Dockerfile ` , ` nginx.conf `
162+ | API Keys | Supabase Edge Function secrets (never in browser) |
163+ | Auth | Supabase Auth + JWT verification |
164+ | Input Validation | Prompt injection regex patterns, MAX_INPUT_LENGTH=50000 |
165+ | CORS | Strict allowlist (debate.pi-stack.org + localhost) |
166+ | Nginx | CSP headers, HSTS, X-Frame-Options, block sensitive files |
167+ | URL Validation | Block javascript:, data:, vbscript:, file: protocols |
168+ | File Validation | 10MB limit, allowed extensions only |
169+ | RLS | All 15 tables protected with row-level security |
170+
171+ ## Environment Variables
172+
173+ | Variable | Location | Description |
174+ | ----------| ----------| -------------|
175+ | ` VITE_SUPABASE_URL ` | Frontend (.env) | Supabase project URL |
176+ | ` VITE_SUPABASE_ANON_KEY ` | Frontend (.env) | Supabase anonymous key |
177+ | ` OPENAI_API_KEY ` | Supabase secrets | OpenAI API key |
178+ | ` GOOGLE_API_KEY ` | Supabase secrets | Google AI API key |
179+ | ` ANTHROPIC_API_KEY ` | Supabase secrets | Anthropic API key |
180+ | ` JINA_API_KEY ` | Supabase secrets | Jina AI API key |
181+ | ` AI_DEFAULT_PROVIDER ` | Supabase secrets | Default provider (google) |
182+ | ` AI_DEFAULT_MODEL ` | Supabase secrets | Default model (gemini-2.0-flash) |
80183
81184## Deployment
82185
83186Docker two-stage build:
84- 1 . Node builder: ` npm ci → npm run build `
85- 2 . nginx runtime: serves static files
187+ 1 . Node builder (` node:20-alpine ` ): ` npm ci ` -> ` npm run build `
188+ 2 . Nginx runtime (` nginx:alpine ` ): serves static files from ` dist/ `
189+
190+ Production: Raspberry Pi + Watchtower for auto-updates from Docker Hub + Cloudflare Tunnel.
191+
192+ CI/CD: GitHub Actions on push to main -> build + push multi-arch Docker image.
193+
194+ ## Adding a New Feature
86195
87- Production uses Watchtower for auto-updates from Docker Hub.
196+ 1 . Create Zod schema: ` src/lib/ai/schemas/newfeature.ts `
197+ 2 . Update Edge Function: ` supabase/functions/ai/index.ts ` (add feature case)
198+ 3 . Create form component: ` src/components/features/newfeature/NewFeatureForm.tsx `
199+ 4 . Create results component: ` src/components/features/newfeature/NewFeatureResults.tsx `
200+ 5 . Create page: ` src/pages/NewFeaturePage.tsx `
201+ 6 . Add route: ` src/App.tsx `
202+ 7 . Update stores: ` src/lib/stores/session-store.ts `
203+
204+ ## Coding Conventions
205+
206+ - 2-space indentation
207+ - Named exports preferred
208+ - ` @/ ` alias for ` src/ ` imports
209+ - PascalCase.tsx for components, kebab-case.ts for utilities
210+ - Functional components with hooks
211+ - React Hook Form for forms, Zod for runtime validation
212+ - shadcn/ui for UI components, TailwindCSS for styling
88213
89214## Admin Mode
90215
91216Code ` debate2026 ` in Settings unlocks:
92217- Global custom system prompt
93- - Database reset
218+ - Database reset functionality
219+ - Advanced configuration options
220+
221+ ## Known Technical Debt
222+
223+ - TypeScript strict mode disabled in ` tsconfig.app.json ` (TD-01, high priority)
224+ - Bundle size warnings: GeneratePage (360KB), vendor-charts/Recharts (400KB)
225+ - Test coverage measurement blocked by peer dep conflict (@vitest/coverage-v8 )
226+ - Deep research may approach Edge Function timeout limits
227+
228+ ## Upcoming Features (Roadmap)
229+
230+ ** Next up:**
231+ - Practice Mode / Sparring Partner (AI plays opponent, turn-based with timer)
232+ - Debate Wiki integration (WikiDebate, NDCA caselist)
233+ - Stripe payments (free trial -> $5/mo Pro tier, promo code system)
234+ - Native mobile apps (Capacitor or React Native)
0 commit comments