You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build the shared Cloudflare Worker that receives feedback submissions from any app, validates and enriches them with Claude, enforces rate limits, and files a structured GitHub issue in the correct repo.
User story
As a developer, I want a single centralized worker to handle all feedback submissions so that I don't maintain identical backend code in every app repo.
Context
This is the backend backbone of the feedback system. All app UI widgets POST to this worker. It mirrors the architecture of the existing cloudflare/openai-policy-worker/ (see cloudflare/openai-policy-worker/src/index.js and wrangler.toml for patterns to follow).
Rate limiting enforced: max 5 submissions per IP per 10 minutes (uses Cloudflare KV or Durable Objects)
Claude API call validates content — rejects submissions classified as spam, abuse, or hate speech (returns 422 with reason)
Claude API call enriches accepted submissions: adds headers, acceptance-criteria stub (for feature requests) or reproduction-steps stub (for bugs), while preserving the verbatim original user text in a quoted block
Session logs (if provided) are appended as a collapsed <details> block in the issue body
Screenshot (if provided) is uploaded to a GitHub Gist or attached as a comment — issue body includes the link
GitHub issue created in the correct repo based on appId (mapping configured in worker env, e.g. APP_REPO_MAP=gaming_app:wcmchenry3-stack/gaming_app,...)
Labels applied: bug or enhancement based on type, plus user-feedback (create this label in target repos if absent)
Worker returns { issueNumber, issueUrl } on success
CORS headers set to only allow requests from known app origins (configured via env var ALLOWED_ORIGINS)
All secrets (ANTHROPIC_API_KEY, GITHUB_TOKEN, ALLOWED_ORIGINS, APP_REPO_MAP) managed via wrangler secret put — none hardcoded
Issue body builder: original text appears verbatim in blockquote, enriched sections present
appId → repo mapping: unknown appId returns 400
E2E tests
Not required: worker E2E covered by integration test against Cloudflare Workers dev environment
Performance
p95 response time < 5 seconds (Claude API is the bottleneck — acceptable for a feedback form)
Regression
Resubmitting same content within rate-limit window returns 429, not duplicate issue
Documentation to update
CLAUDE.md — add cloudflare/feedback-worker/ section describing the worker, its env vars, and how to add a new app
Unknowns / needs investigation
Cloudflare KV vs Durable Objects for rate limiting — KV has eventual consistency; Durable Objects are strongly consistent but add cost. Decide before implementation.
Screenshot storage: GitHub Gist upload vs. issue comment attachment — evaluate GitHub API limits for base64 image size.
Out of scope
Admin UI for reviewing submissions
Webhook retries / dead-letter queue (can add in a follow-up)
Localization suggestion type handled in separate story (#localization-story)
In plain English
Build the shared Cloudflare Worker that receives feedback submissions from any app, validates and enriches them with Claude, enforces rate limits, and files a structured GitHub issue in the correct repo.
User story
As a developer, I want a single centralized worker to handle all feedback submissions so that I don't maintain identical backend code in every app repo.
Context
This is the backend backbone of the feedback system. All app UI widgets POST to this worker. It mirrors the architecture of the existing
cloudflare/openai-policy-worker/(seecloudflare/openai-policy-worker/src/index.jsandwrangler.tomlfor patterns to follow).Part of: #46
Acceptance criteria
cloudflare/feedback-worker/in this repo with its ownwrangler.tomlPOST /feedbackendpoint accepts JSON:{ appId, title, description, type, screenshotBase64?, sessionLogs? }<details>block in the issue bodyappId(mapping configured in worker env, e.g.APP_REPO_MAP=gaming_app:wcmchenry3-stack/gaming_app,...)bugorenhancementbased on type, plususer-feedback(create this label in target repos if absent){ issueNumber, issueUrl }on successALLOWED_ORIGINS)ANTHROPIC_API_KEY,GITHUB_TOKEN,ALLOWED_ORIGINS,APP_REPO_MAP) managed viawrangler secret put— none hardcodedTechnical notes
cloudflare/openai-policy-worker/structure:src/index.js,wrangler.toml,package.jsonworkers_dev = truefor this worker (HTTP, not email)ratelimit:{ip}stored in Cloudflare KV bindingRATE_LIMIT_KVclaude-3-haiku-3-5for fast, cheap classification;claude-3-5-sonnetfor enrichment (or combine in one call)createGitHubIssue()pattern from openai-policy-workerappIdvalues:gaming_app,book_app(expandable)> blockquotesection titled "Original submission (verbatim)"Test coverage
Unit tests
appId→ repo mapping: unknown appId returns 400E2E tests
Performance
Regression
Documentation to update
CLAUDE.md— addcloudflare/feedback-worker/section describing the worker, its env vars, and how to add a new appUnknowns / needs investigation
Out of scope
Dependencies
Definition of done