# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

PRIME is a Next.js 14 web application that generates AI-powered avatar transformations. Users upload a photo to transform into the "PRIME" dark noir aesthetic.

## Commands

```bash
npm run dev    # Start development server (localhost:3000)
npm run build  # Production build
npm run start  # Start production server
```

## Architecture

### API Routes (`app/api/`)

**Image Transformation:**

- **`/api/prime`** - Advanced transformation endpoint with full control. Accepts `FormData` with file upload, `tier` (subtle/core/apex), `grain` (clean/gritty/filthy), `rain` (none/light/storm), `aura_color`, and `archetype` parameters. Returns raw PNG binary. Uses centralized prompt system from `lib/primePrompt.ts`.
- **`/api/transform`** - Simple transformation endpoint. Accepts base64 JSON, uses default `core` tier and `obsidian` aura. Returns base64 data URL.
- **`/api/share`** - Uploads a generated image for sharing (returns public URL, does not add to gallery).

**Community Features:**

- **`/api/gallery`** - GET: Fetch up to 50 recent gallery images. POST: Submit image to gallery (with SSRF protection and content validation).
- **`/api/vote`** - GET: Retrieve PRIME declaration count. POST: Cast vote (IP-hashed for privacy, one vote per IP).

### Key Components (`components/`)
- **Generator.tsx** - Main interactive component:
  - Upload photo → send to `/api/prime` with tier/archetype/grain/rain controls → display before/after comparison
  - Features: Aura intensity (subtle/core/apex), grain (clean/gritty/filthy), rain (none/light/storm), archetype selection, gallery submission button
- **SoundProvider.tsx** - Global React context provider for sound state
- **CompareSlider.tsx** - Before/after image comparison slider
- **TransformLoader.tsx** - Loading animation during transformation

### Library Functions (`lib/`)

- **primePrompt.ts** - Centralized PRIME prompt system:
  - `buildPrimePrompt({ tier, auraColor, archetypeModifier, grain, rain })` - Constructs transformation prompts
  - `PRIME_TIERS` - Type-safe tier definitions: subtle, core, apex
  - `PRIME_GRAINS` - Type-safe grain definitions: clean, gritty, filthy
  - `PRIME_RAINS` - Type-safe rain definitions: none, light, storm
  - `DEFAULT_AURA_COLOR` - Default "obsidian" color
  - Tier/grain/rain modifiers and negative prompt template
- **validation.ts** - Security validation utilities:
  - `isValidImageUrl(url)` - SSRF prevention (blocks internal IPs)
  - `sanitizePrompt(input)` - Removes quotes, limits length, prevents injection
  - `validateContentLength(request, maxMB)` - Request size validation
  - `validateImageContentType(contentType)` - Content-type verification
- **ratelimit.ts** - Rate limiting with in-memory fallback:
  - `InMemoryRateLimiter` class - Sliding window algorithm
  - `aiRatelimit` - 5 requests/hour for AI operations
  - `galleryRatelimit` - 10 requests/hour for gallery/votes
  - `getClientIp(request)` - Extract IP from headers
  - `checkRateLimit(limiter, ip)` - Unified rate check with error responses
- **supabase.ts** - Supabase client initialization

### Data Structures (`data/`)

- **archetypes.ts** - Six PRIME archetypes with personality and visual traits:
  - `Archetype` interface: id, image, title, name, line, description, traits, forgedBy, promptModifier
  - `archetypes` array - All six archetypes (Forged, Silent, Storm, Noir King, Calculator, Wraith)
  - `getArchetypeById(id)` - Lookup archetype by ID
  - `getArchetypePromptModifier(id)` - Get visual modifier string

### Hooks (`hooks/`)

- **useSound.ts** - Web Audio API-based sound effects (hover, click, success, error, ambient). Also exports `SoundContext` and `useSoundContext` for global sound state.
- **useScrollReveal.ts** - Intersection Observer-based scroll reveal animations

### Styling
- CSS Modules pattern: each component has a corresponding `.module.css` file
- Global styles in `app/globals.css`
- Uses `text-gradient` utility class for branded gradient text

## Environment Variables

Required in `.env.local` (see `.env.example`):

- `NEXT_PUBLIC_SITE_URL` - Site URL for metadata (e.g., https://primenow.ltd)
- `OPENAI_API_KEY` - OpenAI API key for GPT-4o image generation (gpt-image-1 model)
- `NEXT_PUBLIC_SUPABASE_URL` - Supabase project URL
- `NEXT_PUBLIC_SUPABASE_ANON_KEY` - Supabase anonymous key for client-side access

Optional:

- `REPLICATE_API_TOKEN` - Replicate API token (legacy, may be removed)
- `UPSTASH_REDIS_REST_URL` - Upstash Redis URL for distributed rate limiting
- `UPSTASH_REDIS_REST_TOKEN` - Upstash Redis token

## External Services

- **OpenAI API** - GPT-4o Image Generation (gpt-image-1) and Image Editing for transformations
- **Supabase** - PostgreSQL database and storage:
  - `gallery` table - Community image gallery
  - `prime_declarations` table - Vote tracking (IP-hashed for privacy)
  - `gallery` storage bucket - Uploaded images
- **Upstash Redis** (optional) - Distributed rate limiting (falls back to in-memory if not configured)

## Database Schema

### `prime_declarations` Table

```sql
CREATE TABLE prime_declarations (
  id SERIAL PRIMARY KEY,
  ip_hash VARCHAR(16) NOT NULL UNIQUE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```

Used for voting system. IP addresses are hashed (SHA-256 + salt) for privacy while preventing duplicate votes.

## Path Aliases

`@/*` maps to project root (configured in `tsconfig.json`)
