AgentSkillsCN

productpix-navigator

借助架构图与数据流追踪,导航 ProductPix 代码库。适用于搜索 src/lib/、src/app/api/、src/components/,或 prompt-bench/ 目录。涵盖 create_generation_job RPC、信用系统、迁移、EmptyState、Toast 组件。适用于“X 在哪里被定义?”、“Y 是如何工作的?”、数据库查询、API 路由,或组件位置的查询。可通过 lib/db、lib/ai、lib/r2、route.ts、page.tsx、supabase/migrations,或任何关于生成/上传/支付流程的探索来触发。(项目)

SKILL.md
--- frontmatter
name: productpix-navigator
description: Navigate ProductPix codebase with architecture maps and data flow traces. Use when searching src/lib/, src/app/api/, src/components/, or prompt-bench/. Covers create_generation_job RPC, credit system, migrations, EmptyState, Toast components. Use for "where is X defined", "how does Y work", database queries, API routes, or component locations. Triggers on lib/db, lib/ai, lib/r2, route.ts, page.tsx, supabase/migrations, or any exploration of generation/upload/payment flows. (project)

ProductPix Navigator

Stop opening files blindly. This skill provides comprehensive architecture and navigation context for the ProductPix codebase.

Quick Architecture Overview

code
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Browser       │────▶│   Next.js 16    │────▶│   Supabase      │
│   (Client)      │     │   App Router    │     │   PostgreSQL    │
└─────────────────┘     └─────────────────┘     └─────────────────┘
         │                      │                        │
         │ presigned            │ rawPrompt +            │ RPC calls
         │ URLs                 │ image-to-image         │ (create_job,
         ▼                      ▼                        │  add_credits)
┌─────────────────┐     ┌─────────────────┐             │
│  Cloudflare R2  │     │   Google        │             │
│  (Images)       │     │   Gemini        │             │
└─────────────────┘     └─────────────────┘             │
                                                         │
                    ┌────────────────────────────────────┘
                    ▼
            ┌─────────────────┐
            │  prompt-bench   │
            │  CLI Testing    │
            └─────────────────┘

System Components

LayerTechnologyLocationPurpose
FrontendNext.js 16 App Routersrc/app/UI, routing, server components
APINext.js Route Handlerssrc/app/api/Backend logic, validation
DatabaseSupabase (PostgreSQL)src/lib/supabase/Data persistence, RLS, RPC
StorageCloudflare R2src/lib/r2/Image uploads, presigned URLs
AIGoogle Geminisrc/lib/ai/Image generation (rawPrompt + i2i)
PaymentsStripesrc/lib/stripe/Credit purchases, webhooks
Testingprompt-bench CLIprompt-bench/Isolated prompt testing framework
PricingMulti-providersrc/lib/pricing/Cost calculation (Anthropic, OpenAI, Google)

Component Boundaries & Responsibilities

Frontend (src/app/)

  • Owns: UI rendering, client interactions, routing
  • Talks to: API routes via fetch/Server Actions
  • Never: Direct database access, direct R2 access, direct Gemini calls

API Layer (src/app/api/)

  • Owns: Business logic, validation, auth checks, RPC orchestration
  • Talks to: Supabase (via admin client), R2 (presigned URLs), Gemini
  • Never: UI concerns, client state

Database (Supabase)

  • Owns: Data persistence, RLS policies, RPC functions
  • Talks to: Only API layer (via client/server/admin clients)
  • RPC Functions: create_generation_job, add_credits, consume_credits, refund_credits, update_prompt_test_status

Storage (R2)

  • Owns: Image file storage
  • Access: Browser uploads directly via presigned URLs (NOT through server)
  • Confirmation: Server confirms upload after browser completes

prompt-bench (CLI)

  • Owns: Prompt template testing, evaluation, A/B comparison
  • Talks to: Supabase (templates, tests, evaluations), R2 (images), Gemini
  • Never: Web app concerns (isolated module with dual tsconfig)

Entry Points (User Action → File)

User ActionEntry FileFlow Link
Visit homepagesrc/app/page.tsxLanding page
Sign upsrc/app/signup/page.tsxAuth flow
Loginsrc/app/login/page.tsxAuth flow
Generate single imagesrc/app/generate/page.tsxGeneration flow
Create batchsrc/app/batch/new/page.tsxBatch flow
View batchsrc/app/batch/[batchId]/page.tsxBatch flow
Purchase creditssrc/app/pricing/page.tsxPayment flow
View dashboardsrc/app/dashboard/page.tsxDashboard
Manage settingssrc/app/settings/page.tsxSettings

API Entry Points

EndpointFilePurpose
POST /api/generatesrc/app/api/generate/route.tsSingle image generation
POST /api/batchsrc/app/api/batch/route.tsBatch creation
GET /api/batch/[id]src/app/api/batch/[id]/route.tsBatch status
POST /api/uploadsrc/app/api/upload/route.tsPresigned URL generation
POST /api/stripe/checkoutsrc/app/api/stripe/checkout/route.tsCreate checkout session
POST /api/webhooks/stripesrc/app/api/webhooks/stripe/route.tsStripe webhook handler
GET /api/templatessrc/app/api/templates/route.tsList prompt templates
GET /api/imagessrc/app/api/images/route.tsList generated images

Database Queries (src/lib/db/)

Each file contains domain-specific queries using Supabase client:

FilePurposeKey Functions
users.tsUser managementgetUserById, getUserByEmail
credits.tsCredit balancegetUserCredits, addCredits (via RPC)
jobs.tsGeneration jobscreateJob (via RPC), getJobById, updateJobStatus
generated-images.tsImage recordssaveGeneratedImage, getImagesByUser
uploads.tsSource imagescreateUpload, getUploadById
batch.tsBatch operationscreateBatch, getBatchById, getBatchJobs
templates.tsPrompt templatesgetTemplates, getTemplateBySlug, saveTemplate
billing.tsStripe billinggetCustomerBilling, createCheckout
cost-queries.tsCost trackinggetGenerationCosts, getCostsByModel

Supabase Client Variants (src/lib/supabase/)

Critical: Use the right client for the context!

typescript
// Browser client - RLS enforced, uses cookies
import { createClient } from '@/lib/supabase/client'

// Server client - SSR, RLS enforced, uses headers
import { createClient } from '@/lib/supabase/server'

// Admin client - BYPASSES RLS, for system operations
import { getAdminClient } from '@/lib/supabase/admin'

Generation Flow

code
1. User clicks "Generate" in UI
   └─▶ src/app/generate/page.tsx (form submission)

2. Form submits to API
   └─▶ POST /api/generate (src/app/api/generate/route.ts)

3. API validates & creates job
   └─▶ createJob() RPC call (src/lib/db/jobs.ts)
   └─▶ consume_credits RPC (checks balance, deducts)

4. API calls Gemini
   └─▶ geminiProvider.rawPrompt() (src/lib/ai/providers/gemini.ts)
   └─▶ Google Gemini API

5. Image generated
   └─▶ Base64 response from Gemini

6. Store image in R2
   └─▶ uploadToR2() (src/lib/r2/index.ts)
   └─▶ Cloudflare R2 bucket

7. Save record to database
   └─▶ saveGeneratedImage() (src/lib/db/generated-images.ts)

8. Update job status
   └─▶ updateJobStatus() (src/lib/db/jobs.ts)

9. Return response
   └─▶ { imageUrl, creditsRemaining, jobId }

Upload Flow (Browser → R2)

code
1. User selects file
   └─▶ src/components/forms/* (file input)

2. Request presigned URL
   └─▶ POST /api/upload (src/app/api/upload/route.ts)
   └─▶ getPresignedUrl() (src/lib/r2/index.ts)

3. Browser uploads directly to R2
   └─▶ PUT request to presigned URL
   └─▶ Cloudflare R2 (NOT through server)

4. Confirm upload
   └─▶ createUpload() (src/lib/db/uploads.ts)
   └─▶ Save upload record in Supabase

Key Gotcha: Browser uploads DIRECTLY to R2 via presigned URL. Server only generates URL and confirms after upload completes.

Payment Flow

code
1. User clicks "Buy Credits"
   └─▶ src/app/pricing/page.tsx

2. Create Stripe checkout session
   └─▶ POST /api/stripe/checkout (src/app/api/stripe/checkout/route.ts)
   └─▶ stripe.checkout.sessions.create()

3. User completes payment on Stripe
   └─▶ Redirects to Stripe hosted checkout

4. Stripe sends webhook
   └─▶ POST /api/webhooks/stripe (src/app/api/webhooks/stripe/route.ts)
   └─▶ Verify signature, handle event

5. Add credits to user account
   └─▶ add_credits RPC (src/lib/db/credits.ts)
   └─▶ Updates users.credits, creates credit_transaction record

6. Redirect to success page
   └─▶ src/app/success/page.tsx

Batch Flow

code
1. User creates batch
   └─▶ src/app/batch/new/page.tsx (batch form)

2. Submit batch
   └─▶ POST /api/batch (src/app/api/batch/route.ts)
   └─▶ createBatch() (src/lib/db/batch.ts)

3. Create jobs for each item
   └─▶ Loop: createJob() RPC for each batch item

4. Process jobs
   └─▶ Background processing (same as generation flow)

5. View batch status
   └─▶ src/app/batch/[batchId]/page.tsx
   └─▶ GET /api/batch/[id] (src/app/api/batch/[id]/route.ts)
   └─▶ getBatchJobs() (src/lib/db/batch.ts)

prompt-bench Testing Framework

Isolated CLI for prompt template testing (see prompt-bench.toml for config).

Directory Structure

code
prompt-bench/
├── cli.ts                    # Entry point
├── core/                     # Core types, errors, compiler
│   ├── types.ts              # Template, Test, Evaluation types
│   ├── errors.ts             # Result<T> type
│   ├── compiler.ts           # Template variable compilation
│   ├── evaluator.ts          # AI-powered evaluation
│   └── statistics.ts         # Score analysis
├── commands/                 # CLI commands
│   ├── run.ts                # Generate images
│   ├── evaluate.ts           # Score images
│   ├── compare.ts            # A/B testing
│   ├── report.ts             # HTML reports
│   ├── test.ts               # Full pipeline
│   ├── sync.ts               # Sync templates to DB
│   └── improve.ts            # AI-powered iteration
├── templates/                # Template definitions
│   ├── registry.ts           # Template registry
│   └── *.ts                  # Template files
└── db/                       # Database helpers
    └── client.ts             # Supabase admin client

prompt-bench Commands

CommandPurposeExample
bun bench runGenerate imagesbun bench run --template ecommerce-base
bun bench evaluateScore imagesbun bench evaluate --label batch-1
bun bench compareA/B testingbun bench compare --baseline v1 --candidate v2
bun bench reportHTML reportbun bench report --label batch-1
bun bench testFull pipelinebun bench test --template ecommerce-base
bun bench syncSync templatesbun bench sync
bun bench improveAI iterationbun bench improve --template ecommerce-base
bun bench open-last-reportOpen last reportbun bench open-last-report

prompt-bench Key Concepts

  • Templates: Prompt templates with variables (stored in prompt-bench/templates/)
  • Batch files: JSON test cases with variable values (fixtures/images-batch.json)
  • Idempotency: Tests tracked by hash keys to prevent duplicate evaluations
  • Result type: Explicit error handling (no exceptions), uses ok()/err()
  • R2 evaluation: Evaluator fetches images directly from R2 URLs (not local files)
  • Dual tsconfig: tsconfig.json (CLI + tests) vs tsconfig.build.json (Next.js build, excludes prompt-bench/)

Finding Things (Grep Patterns)

By Feature

bash
# Generation-related code
grep -rl "generation\|generate" --include="*.ts" src/app src/lib

# Credit system
grep -rl "credit\|balance" --include="*.ts" src/lib/db src/app/api

# R2 storage
grep -rl "r2\|presigned\|upload" --include="*.ts" src/lib src/app/api

# Gemini AI
grep -rl "gemini\|rawPrompt" --include="*.ts" src/lib/ai

# Stripe payments
grep -rl "stripe\|checkout\|webhook" --include="*.ts" src/lib/stripe src/app/api

By Component Type

bash
# Find all API routes
find src/app/api -name "route.ts"

# Find all page components
find src/app -name "page.tsx"

# Find all Server Actions
grep -rn "use server" --include="*.ts" src/

# Find all Client Components
grep -rn "use client" --include="*.tsx" src/

# Find all database queries
ls src/lib/db/*.ts

# Find all Supabase RPC calls
grep -rn "\.rpc(" --include="*.ts" src/

By Error/Issue

bash
# Find where specific error is thrown
grep -rn "CreditError\|InsufficientCredits" --include="*.ts" src/

# Find error handling patterns
grep -rn "try.*catch\|\.catch(" --include="*.ts" src/

# Find where jobs fail
grep -rn "status.*failed\|error" --include="*.ts" src/lib/db/jobs.ts

# Find R2 upload errors
grep -rn "UploadError\|presigned.*error" --include="*.ts" src/lib/r2

Common Gotchas

From CLAUDE.md and project experience:

R2 Uploads

  • Gotcha: Browser uploads DIRECTLY to R2 via presigned URL (NOT through server)
  • Why: Reduces server load, faster uploads
  • Flow: Request presigned URL → Browser PUT to R2 → Confirm upload in DB

Source Images (prompt-bench)

  • Gotcha: Images resolved relative to batch file, hash-deduplicated in R2
  • Why: Avoid duplicate uploads, consistent references
  • Impact: Same source image = same R2 key across tests

Idempotency (prompt-bench)

  • Gotcha: Tests use hash keys to prevent duplicate evaluations on re-runs
  • Why: Re-running tests shouldn't create duplicate database records
  • Impact: Same template + batch = same test record

Environment Variables

  • Gotcha: Load .env BEFORE .env.local in prompt-bench (see cli.ts:17-18)
  • Why: Base config first, then local overrides
  • Impact: Ensures correct config precedence

R2 Evaluation (prompt-bench)

  • Gotcha: Evaluator fetches images from R2 URLs, not local files
  • Why: Consistent evaluation environment
  • Impact: Images must be uploaded to R2 before evaluation

Dual TypeScript Configs

  • Gotcha: tsconfig.json includes prompt-bench/, tsconfig.build.json excludes it
  • Why: CLI/tests need prompt-bench, Next.js build doesn't
  • Impact: Use correct config for context (Next.js uses tsconfig.build.json)

Model Matching (pricing)

  • Gotcha: Exact match → prefix match → error (NEVER guess provider)
  • Why: Incorrect provider = wrong pricing
  • Impact: Unknown models throw error, user must update prompt-bench.toml

Key Tables (Supabase Schema)

TablePurposeKey Columns
usersUser accountsid, email, credits
uploadsSource imagesid, user_id, r2_key, r2_url
jobsGeneration jobsid, user_id, status, template_id
generated_imagesOutput imagesid, job_id, r2_url, cost
credit_transactionsCredit historyid, user_id, amount, type
prompt_templatesTemplate definitionsid, slug, template, variables
prompt_testsTest runsid, template_id, batch_label, status
prompt_evaluationsEvaluation scoresid, test_id, image_id, score

Deep Dives

For detailed documentation on specific subsystems, see:

Commands Quick Reference

See CLAUDE.md for full command list. Most common:

bash
# Development
bun dev                    # Start dev server
bun build                  # Production build
bun test                   # Run tests

# prompt-bench
bun bench test --template <slug> --batch <file>    # Full pipeline
bun bench evaluate --label <batch-label>           # Score images
bun bench compare --baseline <l1> --candidate <l2> # A/B testing
bun bench open-last-report                         # Open report

# Supabase
npx supabase db push       # Push schema changes
npx supabase gen types ts  # Generate TypeScript types