Dentolize · Canary Build Fix (DHS Integration) Walkthrough
On this pageRequired functional checksAdditional edges worth checking, beyond the PR's own listNot in scope for this PR's testing

For 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

  1. **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.

  1. 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.

  1. 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.

  1. 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. canSubmitOperation now 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 .js files that pass user={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.

  • DHSStatusTag translation dependency. DHSStatusTag.tsx reads dhs.* 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.