Files
tangfamily/AGENTS.md
2026-06-24 22:13:01 +08:00

181 lines
7.7 KiB
Markdown

# Cloudflare Workers
STOP. Your knowledge of Cloudflare Workers APIs and limits may be outdated. Always retrieve current documentation before any Workers, KV, R2, D1, Durable Objects, Queues, Vectorize, AI, or Agents SDK task.
## Docs
- https://developers.cloudflare.com/workers/
- MCP: `https://docs.mcp.cloudflare.com/mcp`
For all limits and quotas, retrieve from the product's `/platform/limits/` page. e.g. `/workers/platform/limits`
## Product Docs
Retrieve API references and limits from:
`/kv/` · `/r2/` · `/d1/` · `/durable-objects/` · `/queues/` · `/vectorize/` · `/workers-ai/` · `/agents/`
## Errors
- **Error 1102** (CPU/Memory exceeded): Retrieve limits from `/workers/platform/limits/`
- **All errors**: https://developers.cloudflare.com/workers/observability/errors/
---
# Project: tangfamily
A Cloudflare Workers full-stack family tree website. The single Worker at `src/index.ts` serves all API routes; static HTML pages in `public/` are served via Cloudflare's asset pipeline (`env.ASSETS`). Data is stored in a KV namespace (`FAMILY_DATA`). Deployed at https://tangfamily.shumengya666.workers.dev.
## Commands
| Command | Purpose |
|---------|---------|
| `npm run dev` | Start local dev server (http://127.0.0.1:8787) |
| `npm run deploy` | Deploy to Cloudflare |
| `npm test` | Run all tests (vitest watch mode) |
| `npm run cf-typegen` | Regenerate `worker-configuration.d.ts` from `wrangler.jsonc` |
**Run a single test file:**
```bash
npx vitest run test/index.spec.ts
```
**Run a single test by name:**
```bash
npx vitest run -t "test name here"
```
Always run `npm run cf-typegen` after changing any bindings in `wrangler.jsonc`.
There is no lint script. Format with Prettier manually if needed:
```bash
npx prettier --write "src/**/*.ts"
```
## Project Structure
```
src/index.ts # Single-file Worker: all API handlers + routing + CORS
public/index.html # Visitor login page
public/tree.html # Family tree viewer (authenticated visitors)
public/admin-login.html # Admin login
public/admin.html # Admin CRUD panel
test/index.spec.ts # Vitest integration tests (runs inside Workers runtime)
test/tsconfig.json # Extends root tsconfig; adds vitest-pool-workers types
test/env.d.ts # Merges Env into cloudflare:test module
vitest.config.mts # Vitest config — uses defineWorkersConfig + wrangler.jsonc
wrangler.jsonc # Worker config: entry, KV binding, assets, compat flags
worker-configuration.d.ts # Auto-generated by cf-typegen — do not edit manually
```
## Architecture
- All API logic lives in `src/index.ts`; there are no other Worker source files.
- `public/*.html` pages are pure HTML with inline CSS and inline `<script>` — no bundler, no frameworks.
- KV stores two kinds of keys:
- `members` → JSON-serialised `FamilyMember[]`
- `session:{uuid}` → JSON `{ isAdmin: boolean, createdAt: number }`, TTL 24h
- Auth is token-based: login returns a UUID token stored in KV; the client stores it in `localStorage`.
- CORS headers are applied in the main `fetch` dispatcher, not inside individual handlers.
- Static assets are served by `env.ASSETS.fetch(request)` as the default fallback.
## API Routes
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `POST` | `/api/login` | none | Returns session token |
| `GET` | `/api/members` | visitor+ | List all members |
| `POST` | `/api/members` | admin | Add or update a member |
| `POST` | `/api/members/delete` | admin | Delete a member by `id` |
## Data Shape
```typescript
interface FamilyMember {
id: string;
name: string;
birthYear: number;
gender: '男' | '女';
generation?: string;
fatherId?: string;
motherId?: string;
}
```
## Node.js Compatibility
https://developers.cloudflare.com/workers/runtime-apis/nodejs/
The `nodejs_compat` flag is enabled. The `global_fetch_strictly_public` flag is also active — `fetch()` cannot reach private/internal addresses.
## TypeScript
- **`strict: true`** — all strict checks are on; do not disable any of them.
- **`target/lib: es2024`** — use modern JS features freely.
- **`moduleResolution: "Bundler"`** — do not use Node-style `require()` or `.js` extensions in imports.
- **`noEmit: true`** — Wrangler compiles; `tsc` is for type-checking only.
- **`isolatedModules: true`** — every file must be independently transpilable; avoid type-only re-exports without the `type` keyword.
- Prefer `interface` over `type` for object shapes.
- Use `satisfies` instead of `as` for the default Worker export: `} satisfies ExportedHandler<Env>`.
- Cast JSON parse results with `as`: `await request.json() as MyType`.
- Use literal union types for constrained values: `gender: '男' | '女'`.
## Code Style
### Formatting (Prettier + EditorConfig)
- **Indentation:** tabs (not spaces), everywhere except YAML.
- **Line endings:** LF.
- **Quotes:** single quotes in TypeScript/JS.
- **Semicolons:** always.
- **Print width:** 140 characters.
- Trim trailing whitespace; always end files with a newline.
### Naming Conventions
- **Functions:** `camelCase`; request handlers prefixed with `handle` (`handleLogin`, `handleGetMembers`).
- **Interfaces/Types:** `PascalCase` (`FamilyMember`, `Env`).
- **Constants:** `SCREAMING_SNAKE_CASE` (`VISITOR_PASSWORD`, `ADMIN_PASSWORD`).
- **Variables:** `camelCase` (`membersJson`, `sessionData`, `corsHeaders`).
- **KV keys:** lowercase with colon-separated namespaces (`session:{uuid}`, `members`).
- **HTML element IDs:** `camelCase` (`membersList`, `memberBirthYear`).
- **CSS classes:** `kebab-case` (`member-card`, `btn-danger`).
### Imports
- Worker source (`src/`) has **no imports** — use Workers runtime globals only (`crypto`, `KVNamespace`, `Request`, `Response`, `Headers`, `URL`, `ExecutionContext`, `ExportedHandler`).
- In tests, import from `cloudflare:test` and `vitest` first, then local modules.
- No path aliases. Use relative paths (`../src`).
### Error Handling
- All async handlers use `try/catch`.
- The `catch` block returns a structured JSON error response with an appropriate HTTP status code.
- Do not log or inspect the caught `error` variable in Worker code — translate to a user-facing message in Chinese.
- Return `401` for unauthenticated, `403` for unauthorised (missing admin), `400` for bad input, `404` for unknown routes, `405` for wrong method.
```typescript
} catch (error) {
return new Response(JSON.stringify({ success: false, error: '操作失败' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
```
### Response Pattern
- Construct JSON responses with `new Response(JSON.stringify({...}), { headers: { 'Content-Type': 'application/json' } })`.
- Do not add CORS headers inside handlers — they are merged in the main dispatcher.
- Return `null` body with `{ headers: corsHeaders }` for `OPTIONS` preflight.
### Async/Await
- All handlers are `async function`, returning `Promise<Response>`.
- Use `async/await` exclusively — no `.then()/.catch()` chains.
- KV reads are awaited sequentially; use `Promise.all` only when operations are truly independent.
- Call `await verifyToken(...)` as the first gate in every protected handler.
## Testing
- Tests run inside the real Cloudflare Workers runtime via `@cloudflare/vitest-pool-workers` — not Node.js.
- `vitest.config.mts` uses `defineWorkersConfig` and points at `wrangler.jsonc` for bindings.
- The `test/` directory has its own `tsconfig.json` (extends root, adds `@cloudflare/vitest-pool-workers` types).
- Use `env` from `cloudflare:test` to access bindings directly; use `SELF.fetch()` for integration-style HTTP requests.
- Type-cast `.json()` results: `await res.json() as { token: string }`.
- Do not add test-only logic to `src/index.ts`.
- After adding new bindings to `wrangler.jsonc`, run `npm run cf-typegen` before writing tests.