Cloudflare Workers + Hono + Angular SaaS

"Cursor rules for full-stack SaaS applications on Cloudflare Workers with Hono APIs, Angular frontends, typed RPC, D1/Neon, and production observability."

更新:2026-07-14

说明

# Cloudflare Workers + Hono + Angular SaaS

Full-stack SaaS on Cloudflare Workers with Hono API, Angular frontend, and enterprise integrations.

## Stack CF Workers+Hono v4.12+ | Angular 21+Ionic 8+PrimeNG 21 | D1/Neon | Drizzle v1 | Zod | Clerk Core 3 | Stripe | Inngest v4 | Resend | Bun 1.3 | Playwright v1.59+ | Vitest | ESLint+Prettier | PostHog | Sentry

## TypeScript - Strict mode, never `any` (use `unknown`), prefer `interface` over `type` - `readonly` when not reassigned, `undefined` over `null` - Zod as source of truth for validation - ESLint flat config (`eslint.config.ts`) + typescript-eslint + Prettier

## Hono API - Inline handlers for RPC type inference (never separate controller files) - Method chaining: `app.use().get().post()` preserves types - `hc<AppType>(BASE_URL)` for typed client - `@hono/zod-validator` on ALL request bodies - `app.onError()` + `app.notFound()` centralized - Split large apps: `app.route('/path', subApp)` - Error envelope: `{ error: string, code?: string, details?: unknown }` - `createFactory<{ Bindings: Env }>()` for reusable middleware chains - `GET /health` returns `{ status, version, timestamp }`

## Angular - Standalone only (no NgModules), Angular 21 zoneless by default - Signals stable: `signal()`, `computed()`, `effect()`, `linkedSignal()`, `resource()` - `HttpResource` for data fetching - Control flow: `@if`/`@for`/`@switch`/`@defer` (not `*ngIf`/`*ngFor`) - kebab-case files, one component per file, `providedIn: 'root'` - PrimeNG for UI components

## Drizzle v1 - `sqliteTable` for D1, plural snake_case tables - `$inferSelect`/`$inferInsert` for types - `createInsertSchema`/`createSelectSchema` from `drizzle-orm/zod` - Batch API (not `BEGIN` — D1 doesn't support transactions) - Prepared statements for repeated queries

## CF Workers - CPU limit: 10ms free / 30s paid - `ctx.waitUntil()` for async post-response work - `ctx.passThroughOnException()` for graceful degradation - Bindings typed via `Env` interface - D1 global read replication for latency reduction - Workers Builds for native CI/CD (preview URLs per branch)

## Inngest v4 (Background Jobs) - `eventType('name', { schema: z.object({...}) })` per-event (v4 breaking) - `inngest/cloudflare` adapter + `inngest.setEnvVars(c.env)` for Workers - Step functions: `step.run()`, `step.sleep()`, `step.waitForEvent()`, `step.sendEvent()` - `step.ai.infer()` offloads inference (zero compute during wait) - `step.realtime.publish()` for durable pub/sub - Each step idempotent, retried independently

## Testing (TDD) - Failing test FIRST, then implement - Playwright for E2E: 6 breakpoints (375, 390, 768, 1024, 1280, 1920) - Vitest for unit tests - No sleeps — use `waitFor`/`toBeVisible()` - Selectors: `data-testid` > role > text - axe-core 0 violations - `PROD_URL` env var for production testing

## Security (OWASP Top 10:2025) - Must: HSTS, CSP (nonce-based strict), X-Content-Type-Options, X-Frame-Options - Must: Referrer-Policy, Permissions-Policy, COOP, COEP, CORP - Remove: X-XSS-Protection, Expect-CT, Server, X-Powered-By - Turnstile on all forms, Zod validation on all inputs - Stripe webhooks: verify signature, deduplicate via KV

## Auth (Clerk) - JWT verified per-request (no session store) - Webhook sync: Clerk → D1 for user data - RBAC: Clerk org roles for org-scoped, D1 for app-level - Route layers: public → auth-only → role-gated → owner-only

## Quality - Lighthouse: a11y ≥95, perf ≥75 - WCAG 2.2 AA compliance - LCP ≤2.5s, CLS ≤0.1, INP ≤200ms - JS ≤200KB gz, CSS ≤50KB gz - Functions ≤50 lines, cyclomatic complexity ≤10

## Deploy ```bash npx wrangler deploy && curl -sX POST \ "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache" \ -H "Authorization: Bearer ${CF_API_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"purge_everything":true}' ```

## Hono Worker Starter ```typescript import { Hono } from 'hono'; import { secureHeaders } from 'hono/secure-headers'; import { cors } from 'hono/cors';

interface Env { DB: D1Database; KV: KVNamespace; AI: Ai; TURNSTILE_SECRET: string; }

const app = new Hono<{ Bindings: Env }>(); app.use('*', secureHeaders()); app.use('/api/*', cors({ origin: ['https://yourdomain.com'] })); app.get('/health', (c) => c.json({ status: 'ok', timestamp: new Date().toISOString() })); export default app; ```

来源

https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/cloudflare-workers-hono-angular-saas-cursorrules-prompt-file.mdc

← 返回全部 Skill