Rate my Claude file

just /init no edits

@stoicma--2/27/2026

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-next
  • src/components/ - Client components with "use client" directive where needed
  • src/hooks/ - useSwipe (touch/mouse drag gestures), useLocalVotes (localStorage vote tracking)
  • src/lib/ - Utilities: supabase/server.ts and supabase/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 - Uses createServerClient with cookie store from next/headers. Used in server actions and server components.
  • src/lib/supabase/client.ts - Uses createBrowserClient. 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).

Share on X

Comments (0)