Surveys System - Create, Participate & Analyze Surveys#74
Surveys System - Create, Participate & Analyze Surveys#74ghanshyam2005singh wants to merge 3 commits into
Conversation
|
Warning Review limit reached
Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
WalkthroughAdds a full survey system: backend survey storage and analytics, API handlers and routing, four client pages for creating, taking, listing, and reviewing surveys, navbar navigation updates, and API coverage tests. ChangesSurvey feature implementation
Estimated code review effort: 4 (Complex) | ~75 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant Worker
participant SurveysAPI
participant SurveysCore
participant D1
User->>Worker: Request /api/surveys/*
Worker->>SurveysAPI: Dispatch api_* handler
SurveysAPI->>SurveysCore: Call core survey function
SurveysCore->>D1: Read or write survey data
D1-->>SurveysCore: Rows or write result
SurveysCore-->>SurveysAPI: JSON payload or CSV text
SurveysAPI-->>User: HTTP response
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 18
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@public/survey-create.html`:
- Line 123: The toast container used by showToast is missing an accessibility
live region, so screen readers won’t announce success/error messages. Update the
`#toast-container` in survey-create.html to use an appropriate aria-live setting
(and related accessible attributes if needed) so dynamic toast updates are
announced. Make the same accessibility fix anywhere else the same toast
container pattern appears in the template.
- Around line 125-141: The confirm modal is missing accessible dialog behavior
in the modal markup and its open/close helpers. Update `#confirm-modal` with
dialog semantics such as `role="dialog"`, `aria-modal="true"`, and
`aria-labelledby` tied to the title, then adjust `showConfirmModal` and
`closeConfirmModal` to manage focus properly. Move focus to the confirm button
when opening, restore focus to the trigger when closing, and add an Escape key
handler that calls `closeConfirmModal()`. Keep the same behavior consistent for
the other confirm modal instance referenced in the template.
- Around line 261-321: The question reordering UI in questionCardHtml/onDrop
only supports mouse drag-and-drop and leaves keyboard-only users with no way to
change order. Add an accessible fallback in the same question card, such as
“move up” and “move down” buttons near the drag handle, and wire them to the
same splice-based reorder logic used by onDrop/renderQuestions/saveDraft so the
behavior stays consistent. Ensure the controls are focusable, labeled, and work
for each question key in questions.
- Around line 85-88: Add accessible names and state semantics to the icon-only
controls in the survey template: update the public survey toggle in the
togglePublic/public-toggle markup to expose an explicit accessible label plus
switch semantics (aria-label, role="switch", and aria-checked reflecting state),
and add an aria-label (or equivalent accessible name) to the remove-option
button and the remove-question trash button so screen reader users can identify
each action even without visible text; use the existing public-toggle,
remove-option, and remove-question button elements as the targets for these
changes.
- Around line 137-138: Add type="button" to the confirm modal buttons in the
markup handled by the modal actions so they do not default to submit behavior.
Update the Cancel button with onclick="closeConfirmModal()" and the confirm
button with id="confirm-modal-confirm-btn" to match the other buttons in this
file that already set type="button", keeping the change localized to the modal
button elements in the survey creation page.
- Around line 72-79: Associate the “Survey Title” and “Description” labels with
their respective inputs by wiring each label’s for attribute to the matching id
on the input/textarea in the survey create template. Update the existing
label/input pairs in the survey form so the labels point to survey-title and
survey-description, preserving the current field structure while making the
accessibility relationship explicit.
- Around line 373-383: clearDraft() resets the isPublic flag but leaves the
public toggle UI out of sync, so the switch can still दिख as private after the
draft is cleared. In the clearDraft confirm callback, update the same
knob/button classes used by togglePublic() and loadDraft() for
`#public-toggle-knob` and `#public-toggle` so the visual state matches the new
isPublic = true value before rendering the toast.
In `@public/survey-results.html`:
- Around line 8-10: Pin the external assets in public/survey-results.html to
exact CDN versions and add SRI plus crossorigin attributes. Update the existing
Tailwind, Font Awesome, and Chart.js tags so they no longer use floating aliases
like Chart.js `@4`, and ensure each tag includes a matching integrity hash and
crossorigin="anonymous". Use the current script/link tags in survey-results.html
as the locations to update.
- Around line 199-211: The Pie/Bar toggle buttons in questionCardHtml currently
expose state only through the active class, so update the rendered buttons to
include aria-pressed and make toggleChartType() keep that attribute synced with
the selected chart type. Use the existing data-chart-toggle, data-type, and
chart-toggle-btn hooks to find and update the active/inactive buttons whenever
the chart mode changes.
In `@public/survey.html`:
- Around line 296-308: Duplicate-submission handling in the survey submit flow
is tied to backend wording instead of a stable signal. Update the response
handling in the survey submission logic (the fetch/res.json path that checks
res.ok) to branch on a backend-provided error code rather than testing
data.error text. Have the API return a consistent code such as
already_submitted, and in the survey UI use that code to show the
duplicate-state view while keeping the generic error path for all other
failures.
- Around line 154-201: The survey question renderer in questionHtml is
interpolating q.id raw into inline onclick/onchange handlers and data-*
attributes, so it needs the same escaping used for q.text and o.text. Update
every q.id insertion in the multiple_choice, checkbox, true_false, scale,
textarea, and wrapper attributes to pass through esc() before concatenation,
keeping the handler strings and attributes safe if the identifier shape ever
changes.
- Around line 170-188: Add aria-pressed support to the true/false and scale
toggle buttons so screen readers can detect the selected state. Update
setToggleAnswer to keep aria-pressed="true" on the active button and "false" on
the others while still applying the selected class, and make sure the button
markup in the true_false and scale render branches includes the attribute.
In `@public/surveys.html`:
- Around line 56-60: The search field in the `id="search"` input is missing an
accessible label, so add an `aria-label` to that input in `public/surveys.html`;
the magnifying-glass icon should remain decorative and not be used as the label.
Update the existing search input markup so assistive technologies announce it
properly, using the `search` input element as the target.
- Around line 95-111: The confirm modal in confirm-modal should be made
accessible by exposing it as a real dialog and handling keyboard dismissal.
Update the modal container and related open/close logic around
closeConfirmModal() and the confirm button to add dialog semantics (role and
aria-modal), focus the primary action when opened, trap focus inside the modal,
and close it on Escape. Also add explicit type attributes to both buttons in the
modal so the Cancel and Delete actions are unambiguous.
- Around line 168-200: The search is currently limited to the first 50 items
because `loadSurveys()` always fetches a fixed `limit=50` and `renderList()`
only filters the in-memory `allSurveys` array. Update `loadSurveys`/`renderList`
so the search box drives server-backed queries using the existing `GET
/api/surveys` parameters (`q`, `limit`, `offset`) instead of only client-side
filtering. Add debounced input handling to re-fetch on search text changes, and
wire pagination or “load more” via `offset` so all surveys remain reachable.
In `@src/api/surveys.py`:
- Around line 94-109: The CSV export response is reaching into the private
core._CORS constant from api_export_survey, which couples another module to an
internal detail. Expose the CORS headers through a public API in core (for
example a CORS_HEADERS constant or a helper like csv_response), and update
api_export_survey to use that public symbol instead of spreading core._CORS
directly. Keep the response construction consistent with the existing
json_resp/ok/err pattern.
In `@src/surveys.py`:
- Around line 546-577: The delete_survey cascade is not atomic, so a failure in
the middle can leave partial/orphaned survey data behind. Update delete_survey
to execute the DELETE statements through env.DB.batch([...]) instead of running
each prepare(...).run() separately, and keep the existing survey_id/user_id
checks in place before the batch. Use the delete_survey function and its current
DELETE queries as the main place to refactor the cascade.
- Around line 605-624: The CSV export in the survey answers flow writes
untrusted user input directly into cells, which can trigger spreadsheet
formulas. Update the export logic around answers_by_response and the
writer.writerow calls to sanitize any text value before writing it to CSV,
especially answer_text and other free-form fields. Neutralize values that begin
with formula-triggering prefixes such as =, +, -, or @ so they are treated as
plain text when opened in Excel or Sheets.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: be583b21-1aee-4ed4-b82f-7b6a9cb32f1c
⛔ Files ignored due to path filters (1)
migrations/0010_add_surveys.sqlis excluded by!**/migrations/**
📒 Files selected for processing (9)
public/partials/navbar.htmlpublic/survey-create.htmlpublic/survey-results.htmlpublic/survey.htmlpublic/surveys.htmlsrc/api/surveys.pysrc/surveys.pysrc/worker.pytests/test_api_surveys.py
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
public/survey-create.html (1)
256-265: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
moveQuestionis dead code — keyboard reorder fallback still not wired up.This adds the splice-based reorder logic previously suggested as a keyboard-accessible alternative to drag-and-drop, but per the summary it's unused — no "move up"/"move down" button in
questionCardHtmlcalls it. The underlying accessibility gap (keyboard-only users can't reorder questions) remains unresolved; only the helper skeleton was added.Wire
moveQuestion(q._key, -1)/moveQuestion(q._key, 1)to two small buttons inquestionCardHtmlalongside the drag handle.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@public/survey-create.html` around lines 256 - 265, The reorder helper moveQuestion is currently unused, so keyboard-only reordering still does not work. Update questionCardHtml to add two small “move up” and “move down” buttons that call moveQuestion(q._key, -1) and moveQuestion(q._key, 1) respectively, and place them alongside the existing drag handle so the splice-based fallback is actually reachable.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@public/survey-create.html`:
- Line 404: The clearDraft flow is calling an undefined syncPublicToggle()
helper, which causes a ReferenceError before the rest of the reset logic runs.
Update clearDraft to reuse the existing public-toggle state update logic already
used elsewhere in the survey creation flow, or extract that logic into a shared
helper and call it here. Make sure the reset continues through questions
re-rendering and the success toast after the toggle state is updated.
- Around line 155-156: The HTML in the survey-create page has duplicate IDs for
site-footer and toast-container, which makes DOM lookups ambiguous. Update the
markup so each ID is unique across the document, and ensure showToast() targets
the intended toast container by using the single canonical toast-container
element. Verify any related footer or toast initialization code still references
the corrected IDs.
In `@public/surveys.html`:
- Around line 78-84: The new Load more button in the surveys page is missing an
explicit button type and currently defaults to submit, so update the button
element in the surveys markup to use type="button" while keeping the existing id
and onclick behavior on load-more-btn.
In `@src/surveys.py`:
- Around line 36-38: The CSV formula-injection guard in _CSV_FORMULA_PREFIXES is
incomplete because it only covers =, +, -, and @; extend the check in the survey
export sanitizer to also treat tab, carriage return, and line feed as dangerous
leading characters. Update the logic that uses _CSV_FORMULA_PREFIXES so values
starting with those whitespace/control characters are rejected or escaped
consistently with the existing spreadsheet formula protections.
- Around line 103-107: The err helper currently uses an implicitly optional code
parameter, which should be made explicit to match the codebase and satisfy Ruff.
Update the err function signature to use Optional[str] for code, and add the
corresponding Optional import in src/surveys.py so the type annotation is clear
and consistent.
---
Duplicate comments:
In `@public/survey-create.html`:
- Around line 256-265: The reorder helper moveQuestion is currently unused, so
keyboard-only reordering still does not work. Update questionCardHtml to add two
small “move up” and “move down” buttons that call moveQuestion(q._key, -1) and
moveQuestion(q._key, 1) respectively, and place them alongside the existing drag
handle so the splice-based fallback is actually reachable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: e26708b1-dfc0-408b-a4da-a8b13cf74b32
📒 Files selected for processing (6)
public/survey-create.htmlpublic/survey-results.htmlpublic/survey.htmlpublic/surveys.htmlsrc/api/surveys.pysrc/surveys.py
This PR introduces a complete Surveys System that allows community members to create surveys, collect responses, and analyze results through an interactive dashboard.
Features
Survey Directory
Survey Creation
Survey Participation
Survey Results & Analytics
Export Functionality
Database
Added migration:
New tables:
All relationships use appropriate cascading deletes.
Backend
Added modular survey implementation:
New endpoints:
Frontend
Added pages:
Security
Testing
Added comprehensive API coverage for:
Added an end-to-end Surveys system for browsing public surveys, creating surveys with validation, taking surveys with required-question enforcement and progress tracking, and viewing analytics/results with CSV export.
Key updates:
/api/surveysendpoints for listing, creating, viewing, submitting responses, fetching results/analytics, exporting to CSV, and deleting surveys, with authentication/ownership/visibility checks and standardized error handling.surveys,survey_questions,survey_options,survey_responses, andsurvey_answerstables (with cascading deletes and supporting indexes).Impact: