Skip to content

PRD: Cloudflare standards, deploy readiness, AI-readiness & maintainability improvements (2026-08 audit) #21

Description

@tkowalczyk

PRD: Bring tstack-on-cf to current Cloudflare standards (deploy readiness, AI-readiness, maintainability)

Audit date: 2026-08-07 · Baseline: Cloudflare Workers Best Practices guide (2026-02-15), Wrangler v4 standards, Workers Logs/Traces/Source Maps, Smart Placement, Hyperdrive, versioned deployments, vitest-pool-workers, llms.txt/AGENTS.md agent conventions.

Background

tstack-on-cf is the TanStack Start + Hono template on Cloudflare Workers (@cloudflare/vite-plugin, Neon Postgres via drizzle neon-http, three wrangler envs, Biome 2 + GritQL plugins, Vitest 4, semantic-release). The audit found a strong base — observability logs (100%) + traces (1%) enabled, compat-date auto-bump bot, weekly taze bumps, clean secrets hygiene, accurate llms.txt with a symlinked AGENTS.md, meta-tests that keep config/docs honest, and a completed workers-best-practices issue series (#5#16) that must not be re-proposed. This PRD covers what remains.

Goals

  1. Close the remaining Cloudflare-standards gaps (source maps, placement, Hyperdrive decision, env routing posture, CI-safe typegen).
  2. Gate and automate the path to production (PR CI, CD, migration story, rollback guidance).
  3. Keep agent-facing docs truthful (dead /docs pointer, README drift, missing LICENSE) and extend agent tooling (.mcp.json, Codex parity).
  4. Make tests exercise the real runtime and clean up masked dead dependencies.

Non-goals

  • New product features or UI work.
  • Replacing Neon/Drizzle or the TanStack/Hono architecture.
  • Re-doing anything from the closed workers-best-practices series (secrets out of vars, observability, env blocks, onError, structured logging, /api routing, DB singleton, cf-typegen pre-push).

Workstream 1 — Cloudflare standards conformance

  • Enable source map upload. No upload_source_maps in wrangler.jsonc — production stack traces are minified in Workers Logs despite logs+traces being on. Add "upload_source_maps": true (top-level, inherited by envs).
  • Enable Smart Placement for staging/production. The Worker makes sequential round-trips to Neon pinned in eu-central-1 (src/db/setup.ts) — the canonical Smart Placement case. Add placement: { "mode": "smart" } and measure.
  • Decide Hyperdrive vs neon-http, and record it. Cloudflare's standard for external Postgres is a Hyperdrive binding (pooling + edge caching); the repo uses the neon-http fetch driver directly. Evaluate Hyperdrive (drizzle-orm/node-postgres) against neon-http and document the decision either way.
  • Give staging/production a routing posture. wrangler.jsonc:15-24 env blocks are name+vars only — no routes/custom_domain, no explicit workers_dev/preview_urls, despite the repo's own .claude/rules/cloudflare-deployment.md recommending custom_domain: true. Add commented placeholders + explicit posture per env.
  • Make cf-typegen CI-safe. Typegen currently depends on gitignored .dev.vars for secret inference, forcing SKIP_SIMPLE_GIT_HOOKS=1 in all three workflows and a deliberate typegen skip in compat-date.yml:96-101. Type the secrets explicitly in committed service-bindings.d.ts (interface Env extends BaseEnv { DATABASE_HOST: string; … }) — then typegen runs anywhere and the workarounds get deleted. (Also evaluate the new secrets.required wrangler config property as the declared source of truth.)

Workstream 2 — Deployment readiness

  • Add PR CI. .github/workflows/ has only release.yml (post-merge), deps-update.yml, compat-date.yml; nothing validates pull requests, including the bots' own PRs. Add ci.yml on pull_request + push running lint:ci, types, test, knip, and vite build.
  • Add CD. Deploys run from a laptop with local wrangler auth (package.json:13-15). Add staged CD via cloudflare/wrangler-action (staging on main push, production on release tag, CLOUDFLARE_API_TOKEN secret) or Workers Builds; include the env-scoped build first.
  • Finish the per-env migration story. Only src/db/migrations/dev/ exists; .staging.vars/.production.vars are empty placeholders and migrations run manually via dotenvx. Wire db:migrate:<env> into the CD flow (migrate → deploy) or document the manual gate explicitly.
  • Document the auth/security posture of the API. src/hono/api/clients.ts is public unauthenticated CRUD with no rate limiting or CORS anywhere. For a template that's acceptable only if loud: add an auth middleware slot in src/hono/factory.ts (e.g. bearer/JWT) and a security-posture section in README.
  • Pin Node. No engines, no .nvmrc; CI floats on lts/*. Add both.
  • Add rollback/gradual-rollout guidance. Nothing in README about wrangler versions upload, gradual deployments, or wrangler rollback for incidents.

Workstream 3 — AI-readiness

  • Fix the dead /docs pointer. AGENTS.md:86-89 and README.md:437 declare /docs the single source of truth for business requirements; the directory doesn't exist. Create it with a stub or remove the claim.
  • Fix README drift (3 spots). README.md:155 shows compatibility_date: "2025-09-02" vs actual 2026-05-25; README.md:112 claims migrations/{dev,staging,production}/ but only dev/ exists; README.md:454 links a LICENSE file that doesn't exist despite the MIT claim. Fix all three, add the LICENSE, and consider extending the repo's meta-test pattern to enforce the wrangler snippet.
  • Add .mcp.json. Ship Cloudflare docs/bindings MCP servers (and optionally Neon MCP) as project-scoped config — the template already commits to agent-assisted workflows.
  • Close the Codex parity gap or declare it. .codex/agents/ has 1 of the 3 .claude/agents/ (only mvp-e); hooks are mirrored but agents aren't. Mirror them or state the supported-agent matrix (same for the absent .cursor/).

Workstream 4 — Maintainability

  • Make tests exercise the real runtime. 10 files / ~27 cases, all config-heavy: no @cloudflare/vitest-pool-workers (so src/server.ts dispatch, env wiring, and SSR never run in workerd) and zero component tests (vitest.config.ts doesn't even set jsdom). Add a Vitest workspace: workers-pool project for server/Hono + jsdom project for components — or delete the unused testing deps.
  • Remove dead devDependencies masked by knip config. web-vitals, @tanstack/react-form, @testing-library/dom, @testing-library/react have zero usages but are hidden via knip.json ignoreDependencies; knip also ignores all of src/db/** and src/core/errors.ts. Remove the deps and shrink the ignore list.
  • Create a major-upgrade cadence. Vite is exact-pinned at 7.1.2 with Vite 8.2.1 out; taze minor mode never proposes majors and nothing tracks them (also pending: Biome 2.5.x, TS 7/tsgo evaluation). Add a scheduled majors report that opens/updates an issue.
  • Explain pnpm-workspace.yaml. It exists solely for pnpm 10 allowBuilds with no packages: key — add a comment so humans and agents stop assuming a monorepo.
  • Minor: align .example.vars naming with wrangler's .dev.vars.example convention; enable verbatimModuleSyntax (Biome already enforces useImportType).

Prioritization

Priority Items
P0 PR CI; CD pipeline; CI-safe typegen (unblocks the bot workflows)
P1 upload_source_maps; Smart Placement; migration story; README drift + LICENSE; /docs pointer; workers-pool tests
P2 Hyperdrive decision record; routing posture; auth slot + security docs; .mcp.json; Codex parity; dead deps; majors cadence; Node pin

Acceptance criteria

  • PRs cannot merge without lint/types/test/build passing; staging deploys on main, production on release, both from CI.
  • pnpm run cf-typegen produces identical output with or without .dev.vars present; the SKIP_SIMPLE_GIT_HOOKS workarounds are gone from workflows.
  • wrangler.jsonc has upload_source_maps and Smart Placement on server envs; a written decision exists for Hyperdrive vs neon-http.
  • README contains no stale snippets or dead links; LICENSE exists; AGENTS.md pointers all resolve.
  • At least one test suite runs inside workerd via vitest-pool-workers; knip passes with a minimal ignore list.

Out of scope

Executing the Vite 8 / TS 7 majors (tracked by the new cadence), replacing Neon, building real auth (only the middleware slot + docs are in scope).

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestworkers-best-practicesCloudflare Workers best-practices audit finding

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions