Skip to content

Add a community survey API that stores answers - #6624

Open
brsbl wants to merge 9 commits into
mainfrom
web/community-survey-api
Open

brsbl wants to merge 9 commits into
mainfrom
web/community-survey-api

Conversation

@brsbl

@brsbl brsbl commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Human comments

What was wrong

getbb.app had no way to collect community survey answers. Layer 1 of 4.

What changed

  • POST /api/community/survey takes JSON answers and stores them in community_survey_response (migration 0011).
  • Migration 0011 also creates the sticker-claim tables and emailed_at that Give survey finishers a free sticker claim link #6608 and Email survey finishers their answers and claim link #6609 use, so the stack adds one migration.
  • One set of rules in survey.ts decides which questions apply, and hidden answers are dropped.
  • Students and people not working skip the work questions.
  • Checkbox questions accept any number of listed choices.
  • Every shown question is required, and choices must come from the list.
  • A retried send with the same submission ID is saved once.
  • Bodies are capped at 16 KiB, counted in bytes while they stream.
  • Rate limits key IPv6 clients by their /64 network.

Collection stays off (COMMUNITY_FORMS_ENABLED=false) until launch.

How you verified

  • Handler tests against a real D1 database cover saving, duplicates, validation, the body cap and rate-limit keys.
  • An endless streamed body is rejected after a few chunks.
  • Manual API checks covered saving once per ID, 400s for bad bodies, 503 when collection is off, and 429 on the rate limit.
  • Remote CI: passed. Run

BB-Thread-ID: thr_yz6t8hi7s8

AGENT GENERATED

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T04:26:35.884800Z d79bd23 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d79bd23e94

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/src/community/handler.ts Outdated
Comment on lines +61 to +62
const body = await request.text();
if (body.length > MAX_BODY_BYTES) return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce the byte limit while reading the request stream

When collection is enabled, a request without Content-Length is buffered completely by request.text() before the size check runs. A large streamed request can therefore exhaust worker memory rather than receive the intended controlled rejection; the per-client rate limiter does not bound the size of an individual request. Additionally, body.length counts UTF-16 code units, so multibyte JSON exceeding 16 KiB can pass this check. Read the stream with a running byte count and cancel it as soon as it exceeds MAX_BODY_BYTES, before decoding and parsing.

Useful? React with 👍 / 👎.

@brsbl
brsbl added this pull request to stack #6625 October 30, 2026 04:38
POST /api/community/survey takes JSON answers, applies the survey's
show/hide and validation rules, rate limits by client, and stores visible
answers once per submission ID in D1. Collection stays off until launch
review.

BB-Thread-ID: thr_yz6t8hi7s8

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brsbl
brsbl force-pushed the web/community-survey-api branch from d79bd23 to 2ff2623 Compare October 30, 2026 04:43
brsbl and others added 7 commits October 30, 2026 05:20
Reading the whole body before checking its size let a request without a
Content-Length header buffer far past 16 KiB, and the check counted UTF-16
units instead of bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Finishers whose coworkers use bb now say how plugins move between them,
and the role question gains Marketing or operations and Freelancer,
consultant or agency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Marketing or operations falls back to the Other write-in, and the work
question now offers 2–5, 6–10 and more than 10 people.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brsbl
brsbl force-pushed the web/community-survey-api branch 2 times, most recently from abdaf09 to ab548a2 Compare October 30, 2026 11:38
Product data and research calls answer it better than a community survey.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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