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

7.7 KiB

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

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


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:

npx vitest run test/index.spec.ts

Run a single test by name:

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:

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

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.
} 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.