Rate my Claude file
just /init no edits
Vote to see the stats!
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
npm run dev # Start dev server
npm run build # Production build
npm run lint # ESLint check
npm start # Serve production build
Deployment: npx vercel --prod --yes (auto-deploy from GitHub is NOT enabled).
Architecture
Next.js 16 App Router with TypeScript, Tailwind CSS v4, Supabase (Postgres + Auth), and Claude Haiku for AI moderation. Deployed on Vercel.
Key Directories
src/actions/- Server actions ("use server"): submit, vote, comment, fetch-nextsrc/components/- Client components with "use client" directive where neededsrc/hooks/-useSwipe(touch/mouse drag gestures),useLocalVotes(localStorage vote tracking)src/lib/- Utilities:supabase/server.tsandsupabase/client.ts(separate SSR vs browser clients),moderate.ts(Haiku moderation),scoring.ts(Wilson + hot ranking),queue.ts(recency-weighted random selection)supabase/migrations/- SQL schema and seed data
Data Flow
Home page fetches a random submission (recency-weighted, excluding localStorage-tracked seen IDs) via server action. User votes via swipe gesture or button click, which triggers castVote() server action that inserts a vote record and calls increment_vote() Postgres RPC. Client then fetches next card.
Supabase Client Pattern
Two separate clients following @supabase/ssr conventions:
src/lib/supabase/server.ts- UsescreateServerClientwith cookie store fromnext/headers. Used in server actions and server components.src/lib/supabase/client.ts- UsescreateBrowserClient. Used in client components.src/middleware.ts- Refreshes Supabase auth session on every request. Gracefully skips if env vars missing.
Database
Three tables with RLS enabled: submissions, votes, comments. All allow public read and insert. Submissions are updatable only by owner (auth.uid() = user_id). The increment_vote PL/pgSQL function uses security definer with explicit search_path = public.
Ranking
- Hot tab:
(upvotes - downvotes) / (hours_since + 2)^1.5 - All Time tab: Wilson score lower bound (95% confidence interval)
Design System: Neo-Brutalist
Tailwind v4 theme variables defined in src/app/globals.css under @theme:
- Colors:
brutal-yellow(#FFD700),brutal-red(#FF6B6B),brutal-green(#4ADE80),brutal-blue(#60A5FA),brutal-black,brutal-white,brutal-offwhite(#FAFAF5) - Reusable CSS classes:
.brutal-card(3px black border, 4px offset shadow),.brutal-btn(same border/shadow with hover translate effect) - Typography: JetBrains Mono (Google Fonts import) for code/monospace content, system font stack for UI
- No purple hues
Environment Variables
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
ANTHROPIC_API_KEY
NEXT_PUBLIC_SITE_URL
AI Moderation
src/lib/moderate.ts calls Claude Haiku on every submission. Validates content is a plausible CLAUDE.md, rejects offensive/spam/secrets. Returns { approved: boolean, reason: string }. Falls back to approved on API failure.
Path Alias
@/* maps to ./src/* (configured in tsconfig.json).