On this page
Required functional checksAdditional edges worth checking, beyond the PR's own listNot in scope for this PR's testingFor Quality
This PR's own description lists required manual testing before merge — reproduced and expanded below with the reasoning for each, since several of these failure modes are silent: no error, no crash, just a missing UI element or a stale cache.
Required functional checks
- **All six DHS surfaces, with a full-permission user, on a DHS-enabled tenant with a
DHS-mapped branch.** Confirm each screen renders and functions: Integration Settings, Check Insurance, Check Eligibility, Approval Submission, Approval Detail, Manual Update. This is the direct test of the fix — before this PR the production bundle didn't contain this code at all.
- The nested render specifically:
ReviewStep (inside the Check Insurance modal) → DHSCheckEligibility. This is the deepest prop-injection chain in the PR (3 explicit hops) and its guard is user?.permissions?.checkDhsEligibility at ReviewStep.tsx:196. If user is ever undefined at this hop, the eligibility section simply doesn't render — no error, no placeholder, nothing to indicate something is missing. This is the single hardest failure mode in this PR to catch by accident; it needs a deliberate click-through.
- Permission removal sweep. For each of
viewDhsIntegration,checkDhsInsurance,
checkDhsEligibility, createDhsApproval, createManualDhsApproval, viewDhsApprovals: remove it from the test user's group and confirm the corresponding screen/button disappears cleanly, with no crash and no partially-rendered state.
- Apollo refetch after eligibility save. After saving patient details inside the
eligibility modal, open Apollo DevTools (or otherwise confirm) that PATIENT_DETAILS actually refetches. This PR changed the refetch target from an imported query object to the literal string 'PATIENT_DETAILS' (useDHSApprovalSubmission.tsx:32) — Apollo matches refetch-by-name against the query document's declared operation name, so this works only as long as the host's query keeps that exact name. A silent mismatch here looks like: the mutation succeeds, no error appears, but the UI shows stale data until a manual reload.
Additional edges worth checking, beyond the PR's own list
- Watch for a silent cache-refetch no-op: the same refetch-by-string-name pattern is
used elsewhere in this PR (useDHSApprovalSubmission.tsx:32 also refetches 'GET_PATIENT_OPERATIONS'). Any future rename of either host query, without a matching update to these strings, reintroduces the exact class of stale-badge bug the code comment in the pre-PR version described fixing (the chart operations badge not updating until a manual reload).
canSubmitOperation's strict-equality check. In
packages/clinic-web-canary/src/features/DHS/shared/dhsApprovalStatus.ts:19-20, an operation is resubmittable only if op.dhsApproval.approvalNumber === null (strict, not loose). If a GraphQL query for this feature ever changes to omit the approvalNumber field (making it undefined rather than null), a genuinely-failed approval with no number would stop being offered for resubmission, silently. Confirm any query touching canSubmitOperation always selects approvalNumber explicitly.
- The three-way copy of DHS approval-status logic.
canSubmitOperationnow exists in
three places: packages/server/src/utils/dhsApprovalStatus.js (authoritative), packages/clinic-mobile/src/shared/utils/dhsApprovalStatus.js, and the new packages/clinic-web-canary/src/features/DHS/shared/dhsApprovalStatus.ts. Nothing in CI currently enforces these three stay identical. If a future change to the server's eligibility rule doesn't get mirrored into all three, canary and clinic-web could disagree with the server about which operations are submittable — worth a regression test or a lint rule if this recurs.
- Untyped host call sites. The five
.jsfiles that passuser={user}into a canary
component (ChartTable.js, ChartTableFooter.js, PatientProfile.js, PatientCommonFields.js, SettingsIntegrations.js) have no TypeScript checking. A future refactor of any of these files that drops the user prop produces no build error, no runtime error, and no console warning — just a DHS feature that silently stops appearing. If this module gets a linting pass in the future, flagging canary component usages missing a required prop from a .js call site would catch this class of regression before it ships.
DHSStatusTagtranslation dependency.DHSStatusTag.tsxreadsdhs.*translation
keys that are the host's, populated into the shared i18next instance from clinic-mobile's translation JSON, not duplicated into canary. If canary is ever loaded in a context where the host hasn't populated those keys yet (e.g. a future standalone canary entry point), the status tag would render raw translation keys instead of labels — worth a quick check if canary's mounting/lifecycle ever changes.
Not in scope for this PR's testing
- Any DHS business/eligibility logic itself (unchanged).
- NPHIES (Saudi) integration — a separate, untouched code path.