The app runs on Cloudflare Workers, with or without static assets.
Unlock the rest of the checks
Two checks in each section are open, including why they matter, how to check them, and the prompt. Every other check keeps its title on the page. The reason, the steps and the prompt for those checks are omitted until you pay. One payment of £10 opens every stack. Access does not expire.
Or pay £15 once for the same access and the AI-Ready Pack. That price is the checklist price plus the pack price. The pack does not change your ranking.
Card details go to Stripe, not to this form. After payment, this browser gets a cookie. Restore access sends a one-hour link if you need another device. Error fixes stay free.
0 of 22 done
Ticks are saved in this browser only.
Security
Critical
wrangler.jsonc is committed. Vars in that file are not secret. API keys, webhook secrets and database passwords belong in Wrangler secrets, or in .dev.vars locally, which stays out of git.
You are working in this repository. Do not add features.
Goal: secrets are read from the Worker env and are not written in wrangler.jsonc or source.
Steps:
1. Search for keys and passwords in the repo and in wrangler config.
2. Move public values to vars. Leave secret names out of the file.
3. Read secrets from env in the Worker. Document the names in the README and in .dev.vars.example with empty values.
4. If a real secret was committed, tell me to rotate it and to set the new value with wrangler secret put. Do not print it.
5. Confirm .dev.vars is gitignored.
High
A binding is not a public database. It becomes public if a route runs a query from the request with no auth check. Agents sometimes add /api/debug or pass the SQL string from the client.
You are working in this repository. Do not add features.
Goal: D1 and KV are only touched by server code that checks the caller, and no route accepts raw SQL.
Steps:
1. Find every env.DB and env.KV use, or the binding names this project actually has.
2. Remove any debug route that dumps a table.
3. Use bound parameters (?1) rather than string concatenation.
4. Check auth before returning private rows.
5. Tell me which routes still read the database and what they require.
High
The reason, the checks and the prompt for this item are paid.
A Worker route that marks an order paid on any JSON body will be found. Verify the provider's signature on the raw body, with the endpoint secret stored as a Wrangler secret, and only then fulfil.
You are working in this repository. Do not add features.
Goal: payment webhooks are verified before any order is fulfilled.
Steps:
1. Find the webhook handler.
2. Verify the signature on the raw body using the provider's library and a secret from env.
3. Return 400 when verification fails, and do not write.
4. On success, update the order once. Make a second delivery of the same event id a no-op if you already store event ids.
5. Do not print the secret. Name the Wrangler secret I must set.
Deploy
Medium
A workers.dev URL is a fine test. Customers and sign-in cookies should use the domain you own, on HTTPS, which Cloudflare terminates for you. Update auth redirects to that host before you announce it.
You are working in this repository. Do not add features.
Goal: the app uses a single canonical origin from an environment variable, so auth redirects and links are not stuck on a workers.dev host.
Steps:
1. Find hard-coded workers.dev or localhost origins used in redirects.
2. Read the public site URL from env.
3. Document the custom domain step in the README: route the Worker, then set the var.
4. Do not run wrangler deploy.
5. List the values I still need to set.
SEO and AI visibility
The AI-Ready Pack is a paid download of llms.txt templates, robots rules, schema and a short guide. Publishing those files does not, by itself, change your ranking.
Medium
If robots.txt is missing, you have not decided what may be crawled. If it blocks GPTBot, ClaudeBot and similar agents by habit, chat tools cannot read the public pages you want them to cite. Public marketing pages should be allowed. Signed-in app URLs should not be listed in the sitemap.
You are working in this repository. Do not add features.
Goal: /robots.txt allows general crawling and named AI crawlers, and /sitemap.xml lists public pages only.
Steps:
1. Add robots.txt with Allow rules and a Sitemap line using the production origin.
2. Explicitly allow GPTBot, ChatGPT-User, OAI-SearchBot, Google-Extended, PerplexityBot, ClaudeBot, anthropic-ai and Applebot-Extended.
3. Add a sitemap of public URLs. Leave out account pages.
4. Do not invent traffic numbers in the copy.
5. Show me the files.
A SoftwareApplication block in JSON-LD gives search engines the product name, URL and description in a structured form. It does not replace a clear page. The type is published by schema.org.
You are working in this repository. Do not add features.
Goal: The public homepage includes valid SoftwareApplication JSON-LD.
Work in the Worker site, in the public folder or the HTML layout that ships to Cloudflare.
Steps:
1. Add one application/ld+json script with @context https://schema.org and @type SoftwareApplication.
2. Set name, url and description from the real product. Do not add aggregateRating, review, or offers unless I have given you those facts.
3. Keep the JSON valid.
4. Do not invent traffic numbers, reviews, or testimonials.
5. Show me the files you changed.
D1 rows, KV rate limits and request logs are still personal data when they contain emails or IP addresses. The privacy page should match the bindings you use, and it needs a contact address before you collect signups.
You are working in this repository. Do not add features.
Goal: add /privacy that describes the D1 tables, KV keys and logs this Worker writes.
Steps:
1. Read the queries and list fields you store.
2. Write the page with placeholders [TRADING NAME], [REGISTERED ADDRESS] and [CONTACT EMAIL].
3. If you store an IP, say so. If you store only a hash with a TTL, say that instead. Do not claim either unless the code does it.
4. Link the page from the footer.
5. Tell me what is still a placeholder.
Monitoring
High
A Worker that throws shows the visitor a Cloudflare error code and shows you nothing unless logs are enabled. Error 1101 means the script threw. Error 1102 means it ran too long. Both are much easier to fix if the stack trace is in the log.
You are working in this repository. Do not add features.
Goal: Workers logs and traces are enabled, and handlers log structured JSON on failure.
Steps:
1. In wrangler.jsonc set observability.enabled to true, and set both logs and traces enabled. Use a trace head_sampling_rate below 1 if you want to limit volume, and keep logs at 1 while you launch.
2. On caught errors, console.error a JSON object with the path and message, not the request headers.
3. Do not log env values.
4. Do not deploy.
5. Tell me how to tail logs with wrangler tail once I have an account.