Kulcare Docs

Hospital MAR QA

Synthetic live API journeys, manual checks and clinical release gates.

This guide verifies local MAR U8. It does not approve clinical activation, Recovery or signed discharge. Use synthetic patients only. The production policy registry remains empty. Never enable a policy on staging to complete a checklist without clinical approval.

Local Automated Journey

Use a fresh PostgreSQL database with this exact name pattern: kulcare_hospital_mar_u8_<digits>_<preset>_browser. The preset is surgery_center or hospital_50. Never use a development, staging or production database. The fixture refuses any existing business data before the test harness can seed records. Do not reset a used fixture.

From backend, load the schema and provision test grants:

export DATABASE_URL=postgresql:///kulcare_hospital_mar_u8_2026101906_surgery_center_browser
export RAILS_ENV=test
createdb kulcare_hospital_mar_u8_2026101906_surgery_center_browser
mise exec ruby@3.4.9 -- bin/rails db:schema:load db:environment:set db:test:prepare
mise exec ruby@3.4.9 -- bin/rails db:rls_test_role:provision
export HOSPITAL_MAR_BROWSER_SESSION=/private/tmp/hospital-mar-qa-session.json
HOSPITAL_MAR_BROWSER_FIXTURE=true HOSPITAL_MAR_PRESET=surgery_center \
  mise exec ruby@3.4.9 -- bin/rails runner domains/clinical/test/support/hospital_mar_journey_fixture.rb
HOSPITAL_MAR_BROWSER_SERVER=true HOSPITAL_MAR_BACKEND_PORT=4026 \
  mise exec ruby@3.4.9 -- bin/rails runner domains/clinical/test/support/hospital_mar_browser_server.rb

The session path must be new, owned, mode 0600 and inside a canonical temporary directory. Symlinks and paths that escape that directory are rejected. It contains synthetic credentials. Do not commit, share or send it to a review service. The backend binds to the assigned local port. Every fresh pool connection must use the existing non-bypass kulcare_rls_test role. It uses a fixed test clock and a facility-scoped test policy, not deployed configuration.

In another terminal, from frontend:

VITE_API_URL=http://127.0.0.1:4026 VITE_HOSPITAL_MOCK_MODE=false \
  pnpm --filter @kulcare/shell exec vite --host 127.0.0.1 --port 3026 --strictPort

Then run the browser script from frontend:

HOSPITAL_MAR_BROWSER_SESSION=/private/tmp/hospital-mar-qa-session.json \
  HOSPITAL_MAR_EVIDENCE=/private/tmp/hospital-mar-qa-evidence \
  node scripts/hospital-mar-journey.mjs

Chrome must be installed. The script uses a new browser context for each actor. Finish dependency builds and full frontend CI before starting this journey. Do not rebuild workspace packages while the acceptance frontend is running. Those writes trigger hot reloads and can replace provider instances during care. If that happens, restart the isolated frontend and rerun on a fresh database; do not ignore JavaScript errors or delete already recorded care to reuse a fixture. It validates the facility and preset before care. It creates an order, records one dose, corrects its documented quantity, and reloads both history values. It checks view-only history and case context, and checks 1440px and 390px layouts. An encounter-linked case loses the POST response after the server commits. Recovery must find the original receipt with one POST.

Stop both isolated servers before testing the other preset. Use a fresh database and a different session path. Do not rerun this write journey against used data. After testing, stop the test servers and remove private session/evidence files under your normal local data-retention procedure. Leave the demo server alone.

Manual Candidate QA

Run the U7 actor and workflow checklist on the deployed candidate, in both presets. Record the source revision, facility, actor grants, policy reference/hash and result. Local browser results are not a staging sign-off.

  • Confirm the candidate revision and approved test policy before any write.
  • Create care without an encounter. Confirm no ward admission is created.
  • Repeat with an encounter-linked case and compare canonical history.
  • Confirm the decimal dose and route stay unchanged after reload.
  • Record hold, resume, refusal, omission and confirmed missed outcomes.
  • Check PRN limits, source revision conflicts and source stop behavior.
  • Correct time only. Confirm a refusal and documented dose remain unchanged.
  • Correct an outcome just before its original correction window ends. After that original window ends, confirm a second correction is rejected and its control is unavailable. A correction must not restart the window.
  • Hold a dose, then hold its source order. Confirm resume requires review of the older hold and cannot bypass its resolution. Repeat revisions with an older unresolved slot and confirm every open obligation appears in the prescriber review.
  • Hold and resume a PRN request. Confirm it stays visible as pending even on the next day, without a replacement availability row. Resolving the request must preserve its hold history.
  • Let held and resumed PRN instructions expire. Confirm queue and detail retain the obligation but do not offer administer, hold or resume. Keep resolution and authorized historical-care paths available.
  • Compare a wide date window across pages. Confirm totals include the full filtered result, stable order and PRN availability. Search must still match case and patient context.
  • Search by case number in a facility with more than 250 current orders, including PRN orders. Confirm page order and full counts remain correct across both row types.
  • Lose a response after commit. Reconcile the original key without another POST.
  • Confirm a write or its receipt, then fail current reads. Confirm no success message and no new command. Reload, restore reads and reconcile. Confirm the old key clears only after refresh, with no second POST.
  • Reject a stale source write and fail its refresh. Reload and confirm the rejection remains pending. Restore reads and reconcile. Confirm the key clears without an absent-receipt retry or another POST.
  • Interrupt a command before execution, revise its source elsewhere, and reload. Reconcile the absent receipt. Use original-command re-entry even if the action disappeared. Confirm an edited clinical field cannot send. Re-enter the original fields and confirm the POST uses the old key and preconditions. A definitive stale rejection must release recovery after fresh reads.
  • Inspect session storage with synthetic care only. Confirm it contains no medication, dose, indication, event time or reason values. Field structure and concurrency IDs are permitted.
  • Recover scheduled and PRN source orders, PRN administration and corrections. Keep original array entries, numeric limits, correction selectors and nullable fields. Coding version and user-selected values must survive re-entry without storage of their values.
  • Fail exact re-entry, then lose the response to a correct retry. Confirm one visible error in the dialog first, then one page error after the dialog closes. Keep the old key and reconcile; do not start a replacement.
  • Change profile/facility during a request. Confirm private data and drafts reset.
  • Leave an unresolved command as user A. Log out and sign in as user B with the same role, tenant and facility. Confirm B sees no A intent or case draft. Return as A and confirm its original key remains.
  • Repeat user changes during reads, writes and receipt lookup. Deliver each old response late. Confirm no old data, success message or key cleanup appears in the new user scope.
  • Return a mismatched receipt actor. Confirm recovery stays unresolved. Preserve an old unowned storage entry for supervised recovery; do not attach it to the current user.
  • Read an empty or out-of-range page with nonzero summary counts. Disable required audit and expect unavailable, not counts. Restore audit and confirm disclosure evidence.
  • Enroll an eligible order whose canonical dosage is an object, then repeat with an array. Preserve each shape and require explicit structured instructions.
  • Stop or revise an order, record an allowed non-dose outcome, then correct it to another non-dose outcome at the retained time. Confirm a physical-dose correction outside historical authority stays denied.
  • Confirm view-only controls are absent and direct writes are denied.
  • As a view-only clinical user, read original and correction history. Confirm dose, unit, outcome, performer and correction actor. Revoke view access or facility assignment and confirm reads are denied. Audit failure must return unavailable, not private data.
  • Correct dose only, then reload. Confirm both original and corrected documented quantities remain visible. The prescribed quantity must have its own label.
  • Read a valid code-only medication with no display label. Confirm the unavailable-label text appears in sources, concurrent orders, setup gaps and the worklist without hiding the whole response.
  • Confirm failed refresh keeps recovery blocked; no false success appears.
  • Confirm obligation summaries distinguish missing sources from resolved care.
  • Check keyboard focus, date/time controls, dialogs and narrow layouts.
  • Obtain clinical and nursing acceptance. Record approval separately.

Evidence Boundary

See the U8 execution record. Request tests use the enforced non-bypass database role. The isolated browser server now also verifies a non-bypass kulcare_rls_test request pool. Historical owner-role browser runs are not RLS evidence. A browser journey does not replace the enforced-role security tests. No automated test approves a clinical policy.

On this page