mirror of
https://github.com/centminmod/my-claude-code-setup.git
synced 2025-12-17 07:26:23 +00:00
312 lines
11 KiB
Markdown
312 lines
11 KiB
Markdown
# CLAUDE.md - Cloudflare Quick Template
|
|
|
|
## Project: [NAME]
|
|
Auth: Clerk | Platform: Cloudflare Workers/Pages
|
|
|
|
---
|
|
|
|
## CRITICAL: Verify Before Coding
|
|
|
|
### Step 1: Detect Stack
|
|
Inspect project files:
|
|
- `package.json` -> Node/TS (check deps: hono, next, remix, astro)
|
|
- `requirements.txt` / `pyproject.toml` -> Python Workers
|
|
- `go.mod` -> Go | `Cargo.toml` -> Rust
|
|
- `index.html` (no package.json) -> Static HTML (use Pages Git Integration)
|
|
- No files? -> Run `npm create cloudflare@latest`
|
|
|
|
### Step 2: Fetch Documentation
|
|
Use MCP tools if available, otherwise web fetch these URLs:
|
|
|
|
**Cloudflare:**
|
|
| Service | URL |
|
|
|---------|-----|
|
|
| Workers | https://developers.cloudflare.com/workers/ |
|
|
| D1 Get Started | https://developers.cloudflare.com/d1/get-started/ |
|
|
| KV | https://developers.cloudflare.com/kv/ |
|
|
| R2 | https://developers.cloudflare.com/r2/ |
|
|
| Durable Objects | https://developers.cloudflare.com/durable-objects/ |
|
|
| Pages | https://developers.cloudflare.com/pages/ |
|
|
| Pages Git Integration | https://developers.cloudflare.com/pages/get-started/git-integration/ |
|
|
| Pages Functions | https://developers.cloudflare.com/pages/functions/ |
|
|
|
|
**Clerk:**
|
|
| Resource | URL |
|
|
|----------|-----|
|
|
| JS Backend SDK | https://clerk.com/docs/js-backend/getting-started/quickstart |
|
|
| authenticateRequest() | https://clerk.com/docs/reference/backend/authenticate-request |
|
|
| Hono Middleware | https://github.com/honojs/middleware/tree/main/packages/clerk-auth |
|
|
| Next.js | https://clerk.com/docs/reference/nextjs/overview |
|
|
|
|
**Frameworks:**
|
|
| Framework | URL |
|
|
|-----------|-----|
|
|
| Hono | https://hono.dev/docs/getting-started/cloudflare-workers |
|
|
| Next.js | https://developers.cloudflare.com/pages/framework-guides/nextjs/ |
|
|
| Drizzle+D1 | https://orm.drizzle.team/docs/get-started/d1-new |
|
|
|
|
---
|
|
|
|
## Wrangler Config Reference
|
|
|
|
```jsonc
|
|
{
|
|
"$schema": "./node_modules/wrangler/config-schema.json",
|
|
"name": "app",
|
|
"main": "src/index.ts",
|
|
"compatibility_date": "2024-12-01",
|
|
"compatibility_flags": ["nodejs_compat"],
|
|
"d1_databases": [{ "binding": "DB", "database_name": "x", "database_id": "x" }],
|
|
"kv_namespaces": [{ "binding": "KV", "id": "x" }],
|
|
"r2_buckets": [{ "binding": "BUCKET", "bucket_name": "x" }]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Cloudflare Pages: Static HTML via GitHub
|
|
|
|
For static HTML sites (no build step). Docs: https://developers.cloudflare.com/pages/get-started/git-integration/
|
|
|
|
### Setup (Dashboard)
|
|
1. **Dashboard > Workers & Pages > Create > Pages > Connect to Git**
|
|
2. Select GitHub repo
|
|
3. Build command: *(empty)* | Output directory: `/` or `/public`
|
|
4. Deploy
|
|
|
|
### Static Site Structure
|
|
```
|
|
/
|
|
├── index.html
|
|
├── about.html
|
|
├── css/style.css
|
|
├── js/app.js
|
|
├── _headers # Optional: caching/security headers
|
|
└── _redirects # Optional: redirect rules
|
|
```
|
|
|
|
### Adding API Routes (Pages Functions)
|
|
```
|
|
/
|
|
├── index.html
|
|
├── functions/
|
|
│ └── api/
|
|
│ └── hello.ts # -> /api/hello
|
|
```
|
|
|
|
**functions/api/hello.ts:**
|
|
```typescript
|
|
// Use PagesFunction<Env> when you have bindings (D1, KV, etc.)
|
|
export const onRequest: PagesFunction = async (context) => {
|
|
return Response.json({ message: 'Hello!' })
|
|
}
|
|
```
|
|
|
|
### CLI Commands
|
|
```bash
|
|
wrangler pages dev ./ # Local dev
|
|
wrangler pages deploy ./ --project-name=my-site # Deploy
|
|
```
|
|
|
|
---
|
|
|
|
## Clerk Patterns (VERIFY CURRENT API BEFORE USE)
|
|
|
|
**Hono (@hono/clerk-auth):**
|
|
```typescript
|
|
import { Hono } from 'hono'
|
|
import { clerkMiddleware, getAuth } from '@hono/clerk-auth'
|
|
|
|
const app = new Hono<{ Bindings: Env }>()
|
|
app.use('*', clerkMiddleware())
|
|
app.get('/api/*', (c) => {
|
|
const auth = getAuth(c)
|
|
if (!auth?.userId) return c.json({ error: 'Unauthorized' }, 401)
|
|
return c.json({ userId: auth.userId })
|
|
})
|
|
export default app
|
|
```
|
|
|
|
**Raw Workers (@clerk/backend):**
|
|
```typescript
|
|
import { createClerkClient } from '@clerk/backend'
|
|
|
|
export default {
|
|
async fetch(request: Request, env: Env): Promise<Response> {
|
|
// BOTH keys required!
|
|
const clerkClient = createClerkClient({
|
|
secretKey: env.CLERK_SECRET_KEY,
|
|
publishableKey: env.CLERK_PUBLISHABLE_KEY,
|
|
})
|
|
|
|
const { isAuthenticated, toAuth } = await clerkClient.authenticateRequest(request, {
|
|
authorizedParties: ['https://your-domain.com']
|
|
})
|
|
|
|
if (!isAuthenticated) {
|
|
return new Response('Unauthorized', { status: 401 })
|
|
}
|
|
|
|
const auth = toAuth()
|
|
return new Response(JSON.stringify({ userId: auth.userId }))
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Secrets
|
|
- `.dev.vars` for local (gitignore!)
|
|
- `wrangler secret put KEY` for prod
|
|
- **Required for Clerk:** `CLERK_SECRET_KEY` AND `CLERK_PUBLISHABLE_KEY`
|
|
|
|
---
|
|
|
|
## Commands Reference
|
|
|
|
### Wrangler CLI Documentation
|
|
Full reference: https://developers.cloudflare.com/workers/wrangler/commands/
|
|
|
|
```bash
|
|
# ============================================================================
|
|
# PROJECT SETUP
|
|
# Docs: https://developers.cloudflare.com/workers/get-started/guide/
|
|
# ============================================================================
|
|
npm create cloudflare@latest # Interactive project creation
|
|
npm create cloudflare@latest my-app # Named project
|
|
npm create cloudflare@latest -- --template hono # With template
|
|
|
|
# ============================================================================
|
|
# LOCAL DEVELOPMENT
|
|
# Workers: https://developers.cloudflare.com/workers/wrangler/commands/#dev
|
|
# Pages: https://developers.cloudflare.com/pages/functions/local-development/
|
|
# ============================================================================
|
|
wrangler dev # Workers dev server (localhost:8787)
|
|
wrangler dev --port 3000 # Custom port
|
|
wrangler dev --remote # Use REAL cloud resources (CAUTION!)
|
|
|
|
wrangler pages dev ./ # Pages dev server (localhost:8788)
|
|
wrangler pages dev ./dist # Pages with build output dir
|
|
wrangler pages dev ./ --d1=DB # Pages with D1 binding
|
|
|
|
# ============================================================================
|
|
# DEPLOYMENT
|
|
# Docs: https://developers.cloudflare.com/workers/wrangler/commands/#deploy
|
|
# ============================================================================
|
|
wrangler deploy # Deploy Worker to production
|
|
wrangler deploy --env staging # Deploy to environment
|
|
|
|
wrangler pages deploy ./dist --project-name=my-site # Deploy Pages
|
|
wrangler pages project create my-site # Create Pages project first
|
|
|
|
# ============================================================================
|
|
# D1 DATABASE (SQLite)
|
|
# Docs: https://developers.cloudflare.com/d1/wrangler-commands/
|
|
# ============================================================================
|
|
wrangler d1 create <db-name> # Create DB (returns database_id for config)
|
|
wrangler d1 list # List all databases
|
|
|
|
# Execute SQL (--local for dev, --remote for production)
|
|
wrangler d1 execute <db> --local --file=./schema.sql # Local
|
|
wrangler d1 execute <db> --remote --file=./schema.sql # PRODUCTION (careful!)
|
|
wrangler d1 execute <db> --local --command="SELECT * FROM users"
|
|
|
|
# Migrations (recommended for schema changes)
|
|
# Docs: https://developers.cloudflare.com/d1/reference/migrations/
|
|
wrangler d1 migrations create <db> <name> # Create migration file
|
|
wrangler d1 migrations apply <db> --local # Apply locally
|
|
wrangler d1 migrations apply <db> --remote # Apply to production
|
|
|
|
# ============================================================================
|
|
# KV STORAGE (Key-Value, eventually consistent)
|
|
# Docs: https://developers.cloudflare.com/kv/reference/kv-commands/
|
|
# ============================================================================
|
|
wrangler kv namespace create <name> # Create namespace (returns id)
|
|
wrangler kv namespace create <name> --preview # Create preview namespace
|
|
wrangler kv namespace list # List namespaces
|
|
|
|
wrangler kv key put --binding=KV "key" "value" --local # Put (local)
|
|
wrangler kv key put --binding=KV "key" "value" # Put (production)
|
|
wrangler kv key get --binding=KV "key" # Get value
|
|
wrangler kv key list --binding=KV # List keys
|
|
|
|
# ============================================================================
|
|
# R2 OBJECT STORAGE (S3-compatible)
|
|
# Docs: https://developers.cloudflare.com/r2/api/wrangler/
|
|
# ============================================================================
|
|
wrangler r2 bucket create <name> # Create bucket
|
|
wrangler r2 bucket list # List buckets
|
|
wrangler r2 object put <bucket>/<key> --file=./file.txt # Upload
|
|
wrangler r2 object get <bucket>/<key> # Download
|
|
|
|
# ============================================================================
|
|
# SECRETS (Encrypted env vars for production)
|
|
# Docs: https://developers.cloudflare.com/workers/wrangler/commands/#secret
|
|
# ============================================================================
|
|
wrangler secret put <NAME> # Add secret (prompts for value)
|
|
echo "value" | wrangler secret put <NAME> # Add from stdin (CI/CD)
|
|
wrangler secret list # List secret names
|
|
wrangler secret delete <NAME> # Delete secret
|
|
|
|
# ============================================================================
|
|
# TYPESCRIPT & DEBUGGING
|
|
# ============================================================================
|
|
wrangler types # Generate Env types from config
|
|
# Docs: https://developers.cloudflare.com/workers/wrangler/commands/#types
|
|
|
|
wrangler tail # Stream production logs
|
|
wrangler tail --status=error # Filter by status
|
|
wrangler tail --format=json # JSON output
|
|
# Docs: https://developers.cloudflare.com/workers/wrangler/commands/#tail
|
|
|
|
# ============================================================================
|
|
# AUTH
|
|
# ============================================================================
|
|
wrangler login # Login to Cloudflare (opens browser)
|
|
wrangler whoami # Check current user
|
|
wrangler logout # Logout
|
|
```
|
|
|
|
### Key Command Patterns for AI
|
|
|
|
```bash
|
|
# Pattern: Local vs Remote operations
|
|
# --local = Uses local simulation (safe for development)
|
|
# --remote = Uses PRODUCTION resources (be careful!)
|
|
|
|
# Pattern: Bindings in Pages dev
|
|
# Pass bindings via CLI when no wrangler.toml:
|
|
wrangler pages dev ./ --d1=DB --kv=CACHE --r2=STORAGE
|
|
|
|
# Pattern: Environment-specific operations
|
|
wrangler deploy --env staging
|
|
wrangler secret put API_KEY --env staging
|
|
wrangler tail --env staging
|
|
|
|
# Pattern: Get resource IDs for wrangler config
|
|
wrangler d1 create my-db # Output includes database_id
|
|
wrangler kv namespace create CACHE # Output includes namespace id
|
|
# Add these IDs to wrangler.toml/wrangler.jsonc bindings
|
|
```
|
|
|
|
---
|
|
|
|
## Key Constraints
|
|
| Limit | Value |
|
|
|-------|-------|
|
|
| D1 rows/query | 1000 (use pagination) |
|
|
| KV consistency | Eventually consistent |
|
|
| Workers CPU | 30s paid / 10ms free |
|
|
| R2 object size | 5TB max |
|
|
|
|
**Gotchas:**
|
|
- Clone request before reading body twice
|
|
- Use `nodejs_compat` flag for Node APIs
|
|
- Clerk `@clerk/backend` needs BOTH secretKey AND publishableKey
|
|
- D1 transactions: `await db.batch([stmt1, stmt2])`
|
|
- Set `authorizedParties` in Clerk to prevent CSRF
|
|
|
|
---
|
|
|
|
## Notes
|
|
<!-- Project-specific notes --> |