Skip to content

fix(surveys): show a closed state instead of a generic error (Issue 1460) - #1471

Draft
leahpeker wants to merge 2 commits into
mainfrom
fix-survey-closed-state
Draft

fix(surveys): show a closed state instead of a generic error (Issue 1460)#1471
leahpeker wants to merge 2 commits into
mainfrom
fix-survey-closed-state

Conversation

@leahpeker

Copy link
Copy Markdown
Collaborator

Summary

  • get_survey_public no longer filters on is_active, so a closed survey resolves and returns is_active: false instead of 404ing into the generic "couldn't load the survey — try refreshing" error. The members-only visibility gate is unchanged — those still 404 for anonymous callers.
  • submit_survey_response rejects a closed survey with a new survey.closed code (400) rather than a bare 404, mapped in the frontend to "this survey is closed — responses are no longer accepted".
  • SurveyScreen renders a closed state (title, description, status message, no form or submit button) when isActive is false. Guarded on pollResult === null so a finalized datetime poll keeps its existing finalized view — finalize_poll also sets is_active = False, so without that guard finalized polls would have regressed into the closed state.
  • Generated mirrors regenerated via make dump-codes + make generate-codes; make agent-check-codes confirms validation_codes.json, validationCodes.gen.ts, and openapi_schema.json are all up to date.

Closes #1460

Test plan

  • 5 new backend tests in backend/tests/test_surveys_public.py::TestClosedSurvey — closed survey returns 200 with is_active: false; closed members-only survey 404s for anonymous and 200s for a member; submit to a closed survey returns 400 survey.closed and writes no response; submit to a closed members-only survey 404s for anonymous.
  • 3 new vitest cases in frontend/src/screens/surveys/SurveyScreen.test.tsx — closed render (no form/submit), active survey still renders the form, and an inactive survey with a poll result keeps the finalized view.
  • Visit a closed survey and confirm the closed state renders instead of the generic error.

CI note

make agent-ci passes except for 7 pre-existing failures unrelated to this change: tests/test_sse.py (5, needs pg_notify), tests/test_poll_finalize_race.py, and tests/test_rsvp_capacity_race.py (need real row locking). These fail locally because the agent targets run against per-worktree SQLite; the Makefile documents this above its ifdef CI block, and GitHub Actions runs them against Postgres. Baseline before this change was identical (7 failed / 2213 passed). Frontend CI, lint, typecheck, complexity and check-codes are all green.

🤖 Generated with Claude Code

get_survey_public no longer filters on is_active, so a closed survey
resolves and returns is_active=false rather than 404ing into a generic
"couldn't load" error. The members-only visibility gate still 404s for
anonymous callers. Submitting to a closed survey is rejected with a new
survey.closed code (400).

SurveyScreen renders a closed state for an inactive survey, guarded on
pollResult being null so a finalized datetime poll keeps its existing
finalized view (finalize_poll also sets is_active=False).
…ed gate

The finalized-poll path is newly reachable: before the is_active filter was
dropped, get_survey_public 404'd every finalized poll, so the readonly
finalized branch was dead code on that route.

- GET a finalized poll returns 200 with its poll_result
- submitting to a finalized poll is rejected with survey.closed
- the anonymous 404 on a closed members-only survey leaks no title,
  description or question label
- a submit rejected with survey.closed invalidates the survey query
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.

Closed surveys show a generic error instead of a closed state

1 participant