Uh oh!
There was an error while loading. Please reload this page.
Instrument the Toronto voter survey for PostHog - #80
Merged
Conversation
Completion and stage drop-off were both invisible: the only event the survey sent was `survey_submitted`, which says how many finished and nothing about how many started or where the rest went. Adds useSurveyAnalytics, which holds every event in one place so they carry the same identity — survey, version, election — plus elapsed seconds. A funnel is only as good as that consistency: a step event missing survey_version pools answers to two question sets into one drop-off number. `survey_step_completed` fires on clearing a step rather than on being shown one, so a respondent who lands on a step and leaves emits nothing for it — which is the drop we want counted. Repeat it as successive funnel steps filtered on step_index to read stage drop-off. `survey_step_blocked` separates "couldn't get past validation" from "gave up", and `survey_results_viewed` separates completions shown a real candidate comparison from wards with no published answers. `survey_submitted` moves out of submitSurvey into the hook, keeping its name and properties, so it carries the step and timing properties the completion funnel is built on. posthog.identify stays where the email is known to have been accepted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Greptile SummaryThe PR centralizes Toronto voter-survey analytics in a new hook and instruments views, starts, step transitions, submission outcomes, abandonment, and result rendering.
Confidence Score: 5/5The PR appears safe to merge; no concrete blocking or independently actionable non-blocking defect remains. The instrumentation follows the existing survey lifecycle, successful submissions are captured after API acceptance, and result reporting waits for the comparison data state that controls what the voter sees.
|
| Filename | Overview |
|---|---|
| src/app/toronto/vote/2026/survey/SurveyClient.tsx | Integrates lifecycle, step, submission, and comparison-result analytics without changing the survey’s user-facing control flow. |
| src/app/toronto/vote/2026/survey/analytics.ts | Introduces a centralized PostHog hook with consistent event properties and documented best-effort abandonment semantics. |
| src/app/toronto/vote/2026/survey/submitSurvey.ts | Removes duplicate submission capture while preserving PostHog identification after the API accepts the response. |
Sequence Diagram
sequenceDiagram
participant V as Voter
participant S as SurveyClient
participant A as Survey analytics
participant API as Survey API
participant PH as PostHog
V->>S: Open questionnaire
S->>A: Mount
A->>PH: survey_viewed
V->>S: Enter first answer
S->>A: started(progress)
A->>PH: survey_started
V->>S: Complete or fail validation
S->>A: stepCompleted / stepBlocked
A->>PH: Step event
V->>S: Submit
S->>API: submitSurvey
API-->>S: Accepted response
S->>A: submitted(progress, response)
A->>PH: survey_submitted
S->>A: resultsViewed(comparison)
A->>PH: survey_results_viewed
Reviews (1): Last reviewed commit: "Instrument the Toronto voter survey for ..." | Re-trigger Greptile
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Completion and stage drop-off for the Toronto voter survey were both invisible: the only event the survey sent was
survey_submitted, which says how many finished and nothing about how many started or where the rest went.Adds
useSurveyAnalytics(src/app/toronto/vote/2026/survey/analytics.ts), which holds every event in one place so each carries the same identity —survey,survey_version,election,step_count— plusseconds_elapsed.Events
survey_viewedsurvey_startedsurvey_step_completedstep_index,step_id,answered_on_stepsurvey_step_blockedfields,field_countsurvey_step_backsurvey_submittedwardsurvey_submit_failedsurvey_abandonedsurvey_results_viewedhas_comparison,ward,racesHow to read it in PostHog
survey_viewed→survey_started→survey_submitted.survey_step_completedrepeated per step, filtered onstep_index0, 1, 2… It fires on clearing a step rather than on being shown one, so someone who lands on step 3 and leaves never emits it — that is the drop.survey_step_blockedseparates "couldn't get past validation" from "gave up" on the same step.survey_results_viewedseparates completions shown a real candidate comparison from wards whose candidates have not answered.Notes for review
survey_submittedmoves out ofsubmitSurvey.tsinto the hook, keeping its name and existing properties, so one place emits it with the step and timing properties the funnel is built on.posthog.identifystays insubmitSurvey, where the email is known to have been accepted.survey_abandonedis a best-effort last-seen marker, not a verdict: someone who backgrounds the tab and returns to finish emits both it andsurvey_submitted. It is capped at one per run and sent viasendBeacon. Read completion fromsurvey_submitted, not as the inverse of this.Testing
tsc --noEmitandeslintpass. The events themselves are not verified against a live project — there is noNEXT_PUBLIC_POSTHOG_TOKENlocally, soposthog.initnever runs and captures are no-ops in dev. Worth a look at the PostHog live event feed on the preview deploy before relying on the funnel.🤖 Generated with Claude Code