Repository navigation
feat(forms): response management, member response edits, and safe user deletion - #100
Merged
Merged
Conversation
…ts and credits survive as history
…dense list row actions
…heir answers prefilled
…it behind ?edit=true
…s on the overview
… No access to members
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
🚅 Deployed to the nexus-pr-100 environment in nexus
|
ethnjs
marked this pull request as ready for review
October 2, 2026 23:44
This branch was successfully deployed
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 free
to 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.
Summary
What changed
Backend
Models and migrations
tournaments.owner_id,forms.created_by,join_codes.created_byandaudit_log_entries.actor_idbecome nullable withON DELETE SET NULL. (b4e8d2f1a7c3)User.form_responsesandUser.chapter_membershipcascade withpassive_deletes. The ORM used to null their NOT NULLuser_idinstead, which is why that delete failed.forms.allow_response_edits; existing forms default to off. (c5f1a9e3d2b7)Schemas and routes
GET /admin/users/{id}/returnsowned_tournaments.POST /tournaments/{id}/transfer-ownership/now also allows admins, which is how an ownerless tournament gets an owner. Its audit entry now records the previous owner, not the actor.PersonRef) returnuser_id: nullfor a deleted user;TournamentRead.owner_idandFormRead.created_byare nullable.GET /forms/{id}/responses/returnsFormResponseManagerRead, addingrespondent(name, email, membership id)./responses/me/is unchanged.DELETE /forms/{id}/responses/{response_id}/permanently removes one response and its answers; manage access, 409 on an archived form or tournament.allow_response_editsonFormRead,FormListRead,MemberFormRead, and settable throughPATCH /forms/{id}/.PATCH /forms/{id}/responses/me/accepts any live question when the form allows edits; otherwise only flagged questions, as before.GET /forms/{id}/?raw=truenow requires manage access. PlainGET /forms/{id}/is unchanged.Logic
form_response_deleted, storing the form and the respondent's name.Frontend
Responses tab
/forms/[id]/responses, reached from Questions / Responses tabs in the form header; the tab row is sticky.ResponseAnswers, which unwraps stored option snapshots, shows options removed since as "Removed", and shows "Not answered" for blanks.Member view and edit
/forms/[id]/viewserves every state: fill a new response, view your submitted one read-only, or edit it with?edit=true.FormFillFlowone question at a time with previous answers prefilled; only changed answers are sent.FormUpdateFlowis removed.?edit=truewhen editing is locked falls back to the read-only view and drops the param.Managers
ranks.Admin
Shared UI
RadioList,CheckboxList,ButtonGroup,RankedListandDropdownoptions take an optionalbadge.QuestionRenderertakesremovedOptionsandanswerNote.BulkDeleteModaltakes an optionalconfirmPhraseandnotReady.Out of scope
GET /forms/{id}/still returns manager-only details (field_key, custom option values,response_count,prerequisites). That needs a member schema of its own.Test plan
pytestpasses locallyAutomated
test_users.py: admin delete with responses, owned tournament survives ownerless, deleted actor in the audit log,owned_tournaments, admin re-owning an ownerless tournament, self-delete as an owner.test_forms.py: respondent on the manager list, response delete (archived form blocked, wrong form 404, audit entry, write-through kept, onboarding recomputed),allow_response_edits(toggle, free edits, merged validation, onboarding access),raw=truegated,forms/mefield.