Skip to content

Toronto Voter Survey - #52

Open
mikaalnaik wants to merge 3 commits into
mainfrom
mikaal/toronto-issue-survey
Open

Toronto Voter Survey#52
mikaalnaik wants to merge 3 commits into
mainfrom
mikaal/toronto-issue-survey

Conversation

@mikaalnaik

Copy link
Copy Markdown
Contributor

No description provided.

mikaalnaik and others added 3 commits August 7, 2026 16:26
The questions lived here in surveyData.ts, which was a deliberate choice
while this was the only thing rendering them: rewording a question needed
no deploy on the API side. Candidates now answer surveys too, and a
candidate questionnaire is authored in York Factory's CMS — a question set
that only exists in the front end can't be rendered as an admin form. So
the database became the source of truth and this follows it.

The renderer is unchanged in spirit: it still derives step count, progress,
validation and the submitted payload from whatever steps it's given, only
now they arrive over the wire. Adding a question is a CMS edit with no
deploy here at all, which is more than the old arrangement managed.

Three things follow from the move:

- The submitted slug and version come from the survey that was actually
  rendered rather than constants, so answers can't be filed under a
  question set the respondent never saw.
- yesno options come from the API like any other choice list, so the
  values published results group by have one definition rather than a copy
  on each side.
- Ward choices are resolved from the election's councillor races when the
  survey is served, so the list can't drift from the ward pages the way a
  frozen copy in this repo did.

The page 404s when the definition can't be fetched and the ISR cache is
cold. A half-rendered form is worse than an honest miss, and keeping a
hard-coded fallback here is the drift this change exists to end.

Depends on york_factory#100: production has no /surveys endpoint until
that ships.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds a CMS-driven, multi-step Toronto voter survey and a proxy that records responses through York Factory. It also extracts shared postal-code normalization and introduces a main-site select primitive.

  • Fetches the Toronto 2026 survey definition with a five-minute revalidation interval.
  • Renders remote question steps with client-side validation, progress, submission, and analytics.
  • Adds a survey-response API proxy and reuses postal-code normalization across election endpoints.
  • Adds survey transition styling and a Base UI dropdown.

Confidence Score: 4/5

The PR should not merge until the York Factory survey-definition and response endpoints it requires are available, because the current backend leaves the new page and submission flow unusable.

Both mandatory network boundaries in the new survey flow target routes absent from the current York Factory repository, causing the page to resolve to a 404 and preventing responses from being recorded.

Files Needing Attention: src/lib/elections/survey.ts and src/app/api/elections/survey/route.ts

Important Files Changed

Filename Overview
src/lib/elections/survey.ts Defines the remote survey contract and fetches it from a York Factory endpoint that is absent from the current backend.
src/app/api/elections/survey/route.ts Validates and forwards survey responses, but targets an unregistered York Factory endpoint.
src/app/toronto/elections/2026/survey/page.tsx Loads the remote survey and deliberately converts upstream fetch failures into a page-level 404.
src/app/toronto/elections/2026/survey/SurveyClient.tsx Implements the dynamic multi-step renderer, validation, navigation, and retry-preserving submission flow.
src/app/toronto/elections/2026/survey/submitSurvey.ts Builds the survey payload from rendered answers and records successful submissions in PostHog.
src/components/ui/select.tsx Adds a controlled Base UI select styled for the main site.
src/lib/elections/postal-code.ts Extracts the existing Canadian postal-code validation and normalization behavior for reuse.

Sequence Diagram

sequenceDiagram
    participant V as Voter
    participant T as Tradingpost Survey Page
    participant P as Tradingpost API Proxy
    participant Y as York Factory
    V->>T: Open Toronto survey
    T->>Y: "GET /elections/{election}/surveys/{slug}"
    Y-->>T: 404 (route not registered)
    T-->>V: Not Found
    V->>P: Submit completed answers
    P->>Y: "POST /elections/{election}/survey_responses"
    Y-->>P: 404 (route not registered)
    P-->>V: Survey submission failed
Loading

Fix All in Codex Fix All in Claude Code

Prompt To Fix All With AI
### Issue 1
src/lib/elections/survey.ts:108-111
**Backend survey routes are missing**

The survey page always requests `GET /elections/{election}/surveys/{survey}`, but the current York Factory election routes register only pledges, so the request returns 404 and `loadSurvey` turns the new page into a not-found response. The submission proxy likewise targets an unregistered `POST /elections/{election}/survey_responses` route, preventing responses from being recorded.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "survey context" | Re-trigger Greptile

Comment on lines +108 to +111
): Promise<Survey> {
const { data } = await apiFetch<{ data: Survey }>(
`/elections/${electionSlug}/surveys/${surveySlug}`,
{ revalidate: 300, tags: [`survey:${electionSlug}:${surveySlug}`] },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Backend survey routes are missing

The survey page always requests GET /elections/{election}/surveys/{survey}, but the current York Factory election routes register only pledges, so the request returns 404 and loadSurvey turns the new page into a not-found response. The submission proxy likewise targets an unregistered POST /elections/{election}/survey_responses route, preventing responses from being recorded.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/elections/survey.ts
Line: 108-111

Comment:
**Backend survey routes are missing**

The survey page always requests `GET /elections/{election}/surveys/{survey}`, but the current York Factory election routes register only pledges, so the request returns 404 and `loadSurvey` turns the new page into a not-found response. The submission proxy likewise targets an unregistered `POST /elections/{election}/survey_responses` route, preventing responses from being recorded.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code

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