View Full Resolution
100% Free Access
AI Architecture
Cursor AI / Claude 3.5
Category
AI Agents
Best Use Case
Commercial & Cinematic
AI Agents
Verified Blueprint
Cloudflare Workers Hono Angular Saas Agent Rule
Cursor rules for full-stack SaaS applications on Cloudflare Workers with Hono APIs, Angular frontends, typed RPC, D1/Neon, and production observability.
Ready-to-Run Prompt
100% Free Copy
# 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;
```
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;
```
Structured JSON Schema
Use with automated API pipelines, LangChain, or custom image generators
{
"system_prompt": "# Cloudflare Workers + Hono + Angular SaaS\n\nFull-stack SaaS on Cloudflare Workers with Hono API, Angular frontend, and enterprise integrations.\n\n## Stack\nCF 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\n\n## TypeScript\n- Strict mode, never `any` (use `unknown`), prefer `interface` over `type`\n- `readonly` when not reassigned, `undefined` over `null`\n- Zod as source of truth for validation\n- ESLint flat config (`eslint.config.ts`) + typescript-eslint + Prettier\n\n## Hono API\n- Inline handlers for RPC type inference (never separate controller files)\n- Method chaining: `app.use().get().post()` preserves types\n- `hc<AppType>(BASE_URL)` for typed client\n- `@hono/zod-validator` on ALL request bodies\n- `app.onError()` + `app.notFound()` centralized\n- Split large apps: `app.route('/path', subApp)`\n- Error envelope: `{ error: string, code?: string, details?: unknown }`\n- `createFactory<{ Bindings: Env }>()` for reusable middleware chains\n- `GET /health` returns `{ status, version, timestamp }`\n\n## Angular\n- Standalone only (no NgModules), Angular 21 zoneless by default\n- Signals stable: `signal()`, `computed()`, `effect()`, `linkedSignal()`, `resource()`\n- `HttpResource` for data fetching\n- Control flow: `@if`/`@for`/`@switch`/`@defer` (not `*ngIf`/`*ngFor`)\n- kebab-case files, one component per file, `providedIn: 'root'`\n- PrimeNG for UI components\n\n## Drizzle v1\n- `sqliteTable` for D1, plural snake_case tables\n- `$inferSelect`/`$inferInsert` for types\n- `createInsertSchema`/`createSelectSchema` from `drizzle-orm/zod`\n- Batch API (not `BEGIN` — D1 doesn't support transactions)\n- Prepared statements for repeated queries\n\n## CF Workers\n- CPU limit: 10ms free / 30s paid\n- `ctx.waitUntil()` for async post-response work\n- `ctx.passThroughOnException()` for graceful degradation\n- Bindings typed via `Env` interface\n- D1 global read replication for latency reduction\n- Workers Builds for native CI/CD (preview URLs per branch)\n\n## Inngest v4 (Background Jobs)\n- `eventType('name', { schema: z.object({...}) })` per-event (v4 breaking)\n- `inngest/cloudflare` adapter + `inngest.setEnvVars(c.env)` for Workers\n- Step functions: `step.run()`, `step.sleep()`, `step.waitForEvent()`, `step.sendEvent()`\n- `step.ai.infer()` offloads inference (zero compute during wait)\n- `step.realtime.publish()` for durable pub/sub\n- Each step idempotent, retried independently\n\n## Testing (TDD)\n- Failing test FIRST, then implement\n- Playwright for E2E: 6 breakpoints (375, 390, 768, 1024, 1280, 1920)\n- Vitest for unit tests\n- No sleeps — use `waitFor`/`toBeVisible()`\n- Selectors: `data-testid` > role > text\n- axe-core 0 violations\n- `PROD_URL` env var for production testing\n\n## Security (OWASP Top 10:2025)\n- Must: HSTS, CSP (nonce-based strict), X-Content-Type-Options, X-Frame-Options\n- Must: Referrer-Policy, Permissions-Policy, COOP, COEP, CORP\n- Remove: X-XSS-Protection, Expect-CT, Server, X-Powered-By\n- Turnstile on all forms, Zod validation on all inputs\n- Stripe webhooks: verify signature, deduplicate via KV\n\n## Auth (Clerk)\n- JWT verified per-request (no session store)\n- Webhook sync: Clerk → D1 for user data\n- RBAC: Clerk org roles for org-scoped, D1 for app-level\n- Route layers: public → auth-only → role-gated → owner-only\n\n## Quality\n- Lighthouse: a11y ≥95, perf ≥75\n- WCAG 2.2 AA compliance\n- LCP ≤2.5s, CLS ≤0.1, INP ≤200ms\n- JS ≤200KB gz, CSS ≤50KB gz\n- Functions ≤50 lines, cyclomatic complexity ≤10\n\n## Deploy\n```bash\nnpx wrangler deploy && curl -sX POST \\\n \"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache\" \\\n -H \"Authorization: Bearer ${CF_API_TOKEN}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"purge_everything\":true}'\n```\n\n## Hono Worker Starter\n```typescript\nimport { Hono } from 'hono';\nimport { secureHeaders } from 'hono/secure-headers';\nimport { cors } from 'hono/cors';\n\ninterface Env {\n DB: D1Database;\n KV: KVNamespace;\n AI: Ai;\n TURNSTILE_SECRET: string;\n}\n\nconst app = new Hono<{ Bindings: Env }>();\napp.use('*', secureHeaders());\napp.use('/api/*', cors({ origin: ['https://yourdomain.com'] }));\napp.get('/health', (c) => c.json({ status: 'ok', timestamp: new Date().toISOString() }));\nexport default app;\n```",
"prompt_type": "agent_rule",
"framework": "cursor",
"globs": "**/*",
"compatible_models": [
"Claude 3.5 Sonnet",
"GPT-4o",
"Cursor AI",
"Gemini 2.5 Flash"
],
"download_filename": "cloudflare-workers-hono-angular-saas.cursorrules",
"tags": [
"cursor",
"cursorrules",
"agent",
"coding",
"cloudflare"
]
}
Internal Discovery
View All →