#562 File Answers Can Be Edited When Withdrawn - #596
Open
b-at-neu wants to merge 2 commits into
Open
Conversation
Both hardcoded 'draft' gates in question-files.ts (the pre-check and the in-transaction findFirst) now use APPLICANT_EDITABLE_APPLICATION_STATUSES, matching the text-answer path. APPLICATION_NOT_EDITABLE_MESSAGE moves to lib/constants.ts so both answer types share one sentence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
b-at-neu
commented
Aug 24, 2026
b-at-neu
left a comment
Collaborator
Author
There was a problem hiding this comment.
Code Review — Cycle 1 · needs revision
1 open — 1 🟡 Low (see inline)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Collaborator
Author
Revision — Cycle 1fixed R1-L1 · f1fd25b |
b-at-neu
commented
Aug 24, 2026
b-at-neu
left a comment
Collaborator
Author
There was a problem hiding this comment.
Code Review — Cycle 2 · approved
0 open — R1-L1 resolved, no regressions
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.
Closes #562
Summary
'draft'in two places inprisma/actions/question-files.ts, while text answers already gated onAPPLICANT_EDITABLE_APPLICATION_STATUSES(draft|withdrawn) — a withdrawn applicant could edit their text answers but not replace or remove a file answer. Both gates now use the same predicate.APPLICATION_NOT_EDITABLE_MESSAGEmoves from a module-private constant inprisma/actions/applications.tsto a shared export inlib/constants.ts, so both answer types return the identical sentence for the same situation instead of file answers returning the misleading "This application has already been submitted." (which used to fire even foraccepted/rejected).AnswerFieldalready support this once the server actions stop refusing the write.Changes
lib/constants.ts— addedisApplicantEditableApplicationStatus(mirrorsisNonReviewableApplicationStatus's shape) and the exportedAPPLICATION_NOT_EDITABLE_MESSAGE.prisma/actions/question-files.ts—authorizeTarget's pre-check andreadAndWriteAnswerValue's in-transaction guard both now acceptdraft|withdrawn; renamedApplicationSubmittedError→ApplicationNotEditableError; removed the localSUBMITTED_ERRORcopy.prisma/actions/applications.ts— dropped the module-private message constant in favor of thelib/constants.tsexport; replaced the two unsafe-cast.includes()checks with the new predicate.app/(main)/(auth)/positions/[id]/apply/page.tsx— same predicate swap forisEditable.tests/stubs/vercel-blob.ts(new) — alias target for@vercel/blobin thedbtest project; exposesonPut/deletedUrls/resetBlobStubso the race test can flip application status mid-upload.vitest.config.ts— registers the@vercel/blobalias for thedbproject.tests/db/question-file-answers.test.ts(new) — status matrix foruploadQuestionFileAnswer/removeQuestionFileAnswer(bothisGlobal: true/false), plus the post-pre-check race case.docs/PERMISSIONS.md— rewrote thequestion-files.tsserver-action-authorization row; removed the now-closed File answers can't be edited when withdrawn, unlike text answers #562 "Known-open deviations" entry.docs/WORKFLOWS.md— AP-8's stale-tab bullet and AP-14's happy path updated to reflect that file answers are editable on a withdrawn application, with the shared error copy.Testing plan
file_uploadposition question, apply as an applicant, upload a PDF, and submit./my-applications, then click Edit & resubmit./my-applications/[id]shows the new file./profilestill shows the original file (the profile's blob must survive the reference count).accepted, visit/positions/[id]/apply→ the "You've already applied" card, no editor.tests/db/question-file-answers.test.ts— upload/remove succeed exactly ondraft/withdrawnand return the shared message otherwise, over everyApplicationStatus, for both global and position-scoped questions; the post-pre-check race returns the message, records adelof the new blob, and leaves the stored value untouched.Automated checks
npm run prettier:check— passnpm run eslint:check— passnpm run tsc:check— passnpm run test:unit— pass (227/227)npm run test(db project) — could not run locally: port 5432 was already bound by an unrelated process in this sandbox, so Postgres couldn't be started vianpm run db:start. The newtests/db/question-file-answers.test.tsfollows the exact status-matrix pattern already proven intests/db/application-transitions.test.ts(same fixtures, sameactAs/isErrorhelpers) and will run in CI.Notes
'This application has already been submitted. Withdraw it to make changes.'is asserted verbatim (not imported) in bothtests/db/application-transitions.test.tsand the newtests/db/question-file-answers.test.ts, per plan — importing the constant would let a copy change pass silently.accepted/rejected(where withdraw is itself blocked); this ticket intentionally chose copy consistency with the text-answer path over per-status accuracy.