Skip to content

fix(phi): open the patient record when access justification is confirmed - #223

Merged
NeuroKoder3 merged 1 commit into
mainfrom
fix/phi-justification-confirm-access
Jul 31, 2026
Merged

fix(phi): open the patient record when access justification is confirmed#223
NeuroKoder3 merged 1 commit into
mainfrom
fix/phi-justification-confirm-access

Conversation

@NeuroKoder3

Copy link
Copy Markdown
Owner

The bug

In the Risk Intel dashboard, clicking View next to a patient (aHHQ, Lab Currency, Readiness Barriers tabs) opens the access-justification prompt. Selecting a reason and clicking Confirm Access returned the user to the dashboard without ever opening the record.

Root cause

Radix's AlertDialogAction closes the dialog itself, so pressing Confirm Access fired onOpenChange(false) in addition to the submit handler. The dialog treated any close as a cancellation:

<AlertDialog open={open} onOpenChange={(isOpen) => { if (!isOpen) onCancel(); }}>

That ran the cancel path while the access:authorizePhiAccess IPC was still in flight. handleCancel settled the request as cancelled first, and because a promise resolves only once, the real grant arriving moments later was discarded — so accessGranted stayed false and PatientDetails's onCancel had already called window.history.back().

This affected every route into a patient record, not just the two tabs reported.

A second defect: Cancel invoked onCancel twice (its own onClick plus the close event), so window.history.back() ran twice and skipped a page.

Changes

  • JustificationDialog records which button caused the close, so a confirm is no longer read as a cancellation. All non-confirm closes (Cancel, Escape, overlay) route through a single cancel path, emitting exactly one onCancel.
  • useJustifiedAccess ignores a cancellation while a confirm owns the outcome — defence in depth against the same race.
  • PatientDetails distinguishes denied from cancelled and shows the reason with a way back, instead of waiting forever on a dialog that already closed. This is what a viewer/user/regulator role (no patient:view_phi) would previously have hit.

Why CI missed it

tests/components/PatientDetails.test.jsx mocks both useJustifiedAccess and JustificationDialog, so their interaction was never exercised.

Testing

New tests/components/JustificationAccessFlow.test.jsx drives the real dialog and real hook through actual user events: confirm, slow IPC, custom text, empty justification, denial, thrown IPC error, Cancel, and Escape.

Verified the suite genuinely reproduces the bug — against the pre-fix code 7 of 10 fail, including the double-cancel; all 10 pass after.

  • 10/10 new tests pass
  • 137/137 component tests pass
  • 37/37 Electron suites pass
  • lint clean, production build clean

Epic Connection Hub

Not touched. The change is confined to three renderer files; no main-process, FHIR, HL7, or EHR code is modified.

Made with Cursor

Confirming the PHI access justification bounced the user back to the page
they came from without ever opening the record. Radix's AlertDialogAction
closes the dialog itself, so the resulting onOpenChange(false) ran the
cancel path while the authorization IPC was still in flight. handleCancel
settled the request as cancelled first, and because a promise resolves
once, the grant that arrived moments later was discarded. Every route into
a patient record was affected, including the Risk Intel aHHQ, Lab Currency,
and Readiness Barriers tabs.

The dialog now records which button caused the close so a confirm is not
read as a cancellation, and the hook ignores a cancel while a confirm owns
the outcome. Cancelling also emits exactly one onCancel instead of two,
which had made PatientDetails call window.history.back() twice and skip a
page.

A denied request (insufficient role, IPC failure) now shows the reason with
a way back rather than leaving the page waiting on a dialog that has
already closed.

The existing PatientDetails suite mocks both the dialog and the hook, so
their interaction was never exercised and this passed CI. The new suite
uses the real implementations and fails on the pre-fix code.

No Epic/FHIR/HL7 or main-process code is touched.

Co-authored-by: Cursor <cursoragent@cursor.com>
@strix-security

Copy link
Copy Markdown

Strix is installed on this repository, but we couldn't run this PR security review because this workspace's trial has ended. Add a card to resume code reviews here.

@NeuroKoder3
NeuroKoder3 merged commit 37cfc31 into main Jul 31, 2026
16 checks passed
@NeuroKoder3
NeuroKoder3 deleted the fix/phi-justification-confirm-access branch July 31, 2026 18:03
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.

1 participant