Skip to content

Add a "report incorrect information" form to activity pages#23

Open
GreerBK wants to merge 1 commit into
claude/zealous-hugle-2aaccbfrom
claude/report-inaccurate-info
Open

Add a "report incorrect information" form to activity pages#23
GreerBK wants to merge 1 commit into
claude/zealous-hugle-2aaccbfrom
claude/report-inaccurate-info

Conversation

@GreerBK

@GreerBK GreerBK commented Jun 10, 2026

Copy link
Copy Markdown
Owner

What this adds

Every activity page now has a quiet "See something incorrect or out of date? Let us know." button at the bottom. It expands into a short form — what's wrong plus an optional email for a reply — and submissions are filed straight into a new Reports table in Airtable, linked to the activity, with Status = New.

The Reports table already exists in your base (created during this session, with a linked "Reports" column visible on Activities rows). Your review loop: open Reports → read the New rows → fix the linked activity (and bump its Last Verified date) → set the report to Fixed.

Safety & abuse protection

  • Writes use a separate, write-capable Airtable token (AIRTABLE_WRITE_PAT). The site's main token stays read-only. Until you add the new token, the form degrades gracefully ("Reporting is not set up yet").
  • Hidden honeypot field — bots that fill it get a fake success and nothing is saved.
  • 2,000-character message cap, 10 KB request cap, control characters stripped, email format checked, non-POST requests rejected.
  • The endpoint verifies the reported activity exists and is Active before saving, so junk IDs and unlisted records are rejected.

Verified locally against the real stack

Validation paths (bad ID, short message, bad email, oversized body) all return friendly 400s; honeypot returns a decoy success; with no write token the endpoint returns its graceful 503; with a read-only token the upstream rejection maps to a clean 502. A record with the exact payload shape was created in the live Reports table and deleted again — every field (linked activity, Status choice, timestamp) accepted. The form was exercised in a real browser: focus management, error state (visitor's text preserved), and success state all work; console is clean; npm run build passes.

To make it live (after merging) — two things only you can do

  1. Create the write token and add it to Cloudflare.
    • Airtable → your account icon → Developer HubPersonal access tokensCreate token. Name it e.g. mnparkinsons-reports-write, add scopes data.records:read and data.records:write, and under Access pick only your MN Parkinson's base. Copy the token.
    • Cloudflare → Workers & PagesmnparkinsonsSettingsVariables and Secrets → add AIRTABLE_WRITE_PAT with that value, for Production and Preview (same dance as before).
    • Redeploy (Deployments → ⋯ → Retry deployment, or just push/merge anything).
  2. Email notifications (optional but recommended): in Airtable → Automations → create → trigger "When a record is created" in Reports → action "Send email" to yourself → turn it on. About four clicks, same idea as your geocode automation.

Branch note

This PR is based on claude/zealous-hugle-2aaccb (PR #22), so it shows only the report feature. Merge #22 first; once its branch is deleted, GitHub automatically points this PR at main.

🤖 Generated with Claude Code

Each activity page gets a quiet "See something incorrect or out of date?"
disclosure that expands into a short form (what's wrong + optional reply
email). Submissions POST to the new /api/report function, which validates
the input, confirms the activity exists and is Active, and files a row in
the new Reports table in Airtable — linked to the activity, Status=New,
with page URL and timestamp. Greer's workflow: review New reports, fix the
linked activity, bump its Last Verified date, mark the report Fixed.

Safety/abuse posture:
- Writes use a separate AIRTABLE_WRITE_PAT (to be configured); the main
  token stays read-only. Until the write token exists the endpoint
  degrades to a friendly "not set up yet" message.
- Hidden honeypot field (bots get a fake success), 2000-char message cap,
  10KB body cap, control characters stripped, email validated, non-POST
  methods 405.

UI details: focus moves into the form on open and back to the toggle on
cancel, errors keep the visitor's text for retry, success is announced via
a live region, and the section is hidden in print.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant