Why Review Relay starts with GattyWorks
We are tuning the first tenant against our own services. The second step is a client intake, not copied code.
One GattyWorks tenant, a reusable client intake, and no model call behind the review drafts.
On 27 July 2026, we built and provisioned the first Review Relay tenant for GattyWorks. The Worker, D1 database, Turnstile widget, and confirmed Google review link are connected. The next tenant will come from a reviewed client intake instead of a fork.
The old Debrief screen hid the hard part
The first prototype was called Debrief. It asked for a star rating, a service, a few positive attributes, and then produced short, medium, and detailed review drafts. It worked as a UI demo, but it looked separate from the GattyWorks site. Its single-choice and multiple-choice pills also looked the same.
The harder problems were outside the screen: honest input, Google policy, bot traffic, template reuse, copy tracking, private feedback, data retention, and a safe way to add another business without cloning the app.
GattyWorks is the first tenant on purpose
The first route is `/reviews/gattyworks`. Its service choices match work we actually sell: a 24-hour marketing site, a 48-hour web MVP, AI workflows, custom agents, and three audit depths. Neutral memory cues cover delivery timing, communication, technical depth, pricing, handover, and how issues were handled.
tenant: gattyworks
services:
- 24-hour marketing site
- 48-hour web MVP
- AI workflow
- Surface, Deep, or Full audit
memory_cues:
- Delivery timing
- Communication
- Handover quality
public_draft_tokens:
- business_name
- customer_own_wordsNothing is preselected. The customer chooses the service and checks only the statements that match what happened. Those explicit choices become the factual sentence inside the editable draft, so no typing is required.
The controls now show their meaning. Stars are native radio inputs. Services are round single-choice controls. Memory cues are square checkboxes, with a five-choice cap. The page also uses the GattyWorks header, footer, palette, and responsive layout.
The reusable part is a client intake
A second business should not need a fork of the component. We will send the business a short intake, review the answers, and create one tenant record plus its public URL.
business_name: ""
url_slug: ""
google_review_url: ""
services:
- id: ""
label: ""
neutral_memory_cues:
- id: ""
label: ""
private_feedback_owner: ""
daily_session_limit: 250
feedback_retention_days: 90The intake is deliberately narrow. We need the public business name, a URL slug, the direct Google review link, service labels, neutral memory cues, the person who owns private feedback, and sensible traffic and retention limits. We do not ask the business to supply praise that customers must repeat.
The first client URLs can live at `/reviews/<business>`. If the product later moves to `reviews.gattyworks.com`, those paths can redirect without changing the tenant data. The page, Worker, security rules, and database schema stay shared.
Why there is no model call
Review Relay does not call an AI model when a customer asks for a draft. D1 holds a small pool of prewritten patterns for each length. The Worker chooses among the least-used patterns, inserts the sentence built from the customer's explicit choices, and returns three editable drafts.
This removes model cost and latency, but cost was not the only reason. A model could turn a vague prompt into praise the customer never gave. The template renderer has two allowed tokens and rejects any unsupported token.
short: {own}
medium: I am sharing my own experience with {business}. {own}
detailed: My review is based on my own experience with {business}. {own} I chose this rating based on that experience.When somebody copies a draft, D1 records the template ID, length, copy time, and a SHA-256 hash. It does not store the rendered review text. Copy counts move used templates toward the back of the pool.
The compliant path is less clever
Google Maps policy allows businesses to ask for reviews that represent a genuine experience. It prohibits discouraging negative reviews, selectively asking only happy customers, and requesting specific content.
That changed the product. Every star rating gets the same choices: open Google, send private feedback, do both, or do neither. A low rating never hides the Google link. Private feedback is optional, separate, and stored only after explicit consent.
Google can give a business a direct review link. The Places API exposes it as `googleMapsLinks.writeAReviewUri`. That interface does not include fields for prefilling review text or stars, so Review Relay copies the draft and opens Google. The customer still chooses the rating, pastes, edits, and submits.
One static page, one small backend
The production footprint is one Worker custom domain, one D1 database, one Turnstile widget, two rate-limit bindings, two encrypted secrets, and one daily cleanup trigger. It does not need Workers AI, KV, R2, Durable Objects, Queues, or a paid model API.
A new session requires a Turnstile token checked by the Worker. Cloudflare documents that these tokens last five minutes and can be validated once. Review Relay then issues a 30-minute opaque session. The public creation path and later session calls have separate rate limits.
Request bodies are capped at 8 KB and origins are allowlisted. Raw IP addresses are not stored. A keyed IP hash is kept on the short-lived session for abuse investigation. Optional private feedback is deleted after 90 days by the daily job.
What exists, and what comes next
The implementation branch has the `/reviews/gattyworks` route, tenant configuration, the Worker, D1 migration, Turnstile validation, rate limits, copy tracking, retention cleanup, and a noindex redirect from `/debrief`. Six Worker unit tests, the type check, the Wrangler dry run, the full static export, and desktop and mobile browser checks passed.
The GattyWorks tenant is now provisioned on `reviews-api.gattyworks.com` with the confirmed Business Profile review link. The remaining production check is one human review run from rating through Google's submit screen.