Fix extraction placeholders, incidental parties, filing-type sync, and draft identity - #220
Merged
Merged
Conversation
The workflow screens stamp their own draft into the URL on load, via the replaceState in draft-scope.js, so a direct visit to /payment/ settles on /payment/?draft=1. routePattern anchored at end of string, so all nine screens in WORKFLOW_VIEWS failed the URL assertion before Axe ever ran -- which is why filing options, plans, and my drafts passed while the workflow steps did not. Match the path and ignore any query or fragment. A screen that redirects somewhere else is still caught. All nine screens audit clean at WCAG 2 A/AA with no findings at any impact. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BEU5k33H4u1aKT6bnzR1KG
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
Closes #217. Closes #218.
Four related data-integrity problems are fixed together because each one touches the same extraction-to-submission pipeline.
What changed
Filter extraction placeholders (#217)
The LLM sometimes returns
"unknown","none","N/A", and similar non-answers instead of leaving a field empty. These leaked through to the data extraction review page and were shown as if they were real case facts.clean_extracted_value()inextraction_fields.pyrecursively strips a configurable set of placeholder strings before normalization and before display, so older saved extractions are covered without a migration.N/A→na); meaningful values like"All Unknown Occupants"are preserved because the full phrase is not in the placeholder list.Keep incidental names as evidence only (#217)
Witnesses, guardians, children, and other people mentioned in passing were being auto-promoted to case parties. The filer then had to manually delete them from the party list.
review_rows()inextracted_parties.pynow only surfaces auto-party suggestions when the extracted side isINITIATINGorRESPONDING.other party nameskey is removed fromCONFIRMED_IN_FORM_KEYSso these names are never treated as form-confirmed data.Synchronize filing types (#218)
The draft's
filing_type_code/filing_type_namesummary fields could fall out of sync with the leadFilingDocumentafter uploads, reordering, or partial saves, causing the wrong filing type to appear on review and in the submission payload.FilingDocument.save()inmodels.pycalls the newsync_primary_filing_type()helper after every document save, keeping the draft in sync atomically.write_case_data()indrafts.pywrites explicit client edits through to the lead document before saving the draft summary, so legacy API calls cannot clobber the authoritative source.mark_submitted()callssync_primary_filing_type()once more just before the status flip as a final safety net.Preserve draft identity across redirects (#218)
When a view redirected to another URL (e.g., after saving or submitting), the draft PK query-parameter was silently dropped. The next page then resolved a different draft or created a new one, corrupting the filer's session.
DraftIdentityMiddlewareinmiddleware.py:process_viewresolves and validates the named draft before the view runs; raisesDraftIdentityError(409) on a mismatch.process_responsere-injects the draft PK intoLocationheaders andredirect_urlJSON keys so redirects carry the identity forward.draft_unavailable.htmlpage.MIDDLEWAREand wired up via thesignalsmodule imported inapps.py.get_current_draft()default changed toresume_latest=Falseso API calls cannot silently adopt a draft that belongs to a different browser tab.Validation
uv run pytest -q— 685 passed.npm run test:unit— 43 passed.