Kulcare Docs
DeveloperHospital surgery center

Hospital Recovery U2 Execution

Shared capacity constraints, Recovery persistence, schema verification and release limits.

Boundary

Source checkpoint: dc9cc344bae85e9cb4f7f3e523e490719e1efeed on feat/hospital-nursing-discharge-u6-u8. Local U2 follows the Recovery plan in draft PR 2757. Clinical owns the source records. Hospital coordinates care within Clinical. Current patterns are canonical MAR composite foreign keys, immutable history, tenant RLS and enforced-role tests.

U2 adds persistence and database safeguards. It adds no public Recovery route, clinical permission grant, policy activation or live page. Local U3-U8 still own resource commands, stays, nursing care, HTTP/UI integration and acceptance. Programme U8 signed discharge remains separate.

Stored Records

  • Canonical beds gain care_area, current_recovery_stay_id and lock_version.
  • Existing resources default to unclassified. No preset, name or planning count supplies a classification.
  • Recovery stays preserve case, registration, patient and the exact nullable encounter. They do not create an admission.
  • Immutable commands, movements, observation links, escalation events and assessments hold workflow history.
  • Measurements remain in canonical observations. Links bind observation identity, observed time and recording user/staff or practitioner provenance.
  • Changes to occupancy require matching immutable movement and command evidence. Current owner and bed pointers must agree at commit.

RLS isolates tenants. Same-facility composite references also reject foreign-facility links within one tenant. Action permissions and current clinical authority remain later command/API requirements. A valid database row does not prove authorized nursing care.

Shared Writer Safety

The bed remains the physical arbitration point. Admission and Recovery writes lock that same row. Recovery locks the case before capacity. Capacity checks lock ward, room and then sorted beds; they reject a changed parent chain. Parent changes cannot detach occupied care. Generic bed edits cannot remove its active owner or change its occupied structure. Deferred checks permit an atomic move/discharge transaction but reject a partial committed release. Ordinary unlinked observations remain editable. Linked Recovery observations require append-only corrections; generic update/delete and category replacement cannot remove them.

This does not complete the later U4 service lock-order changes or clinical handoff checks. The migration does not enable a new caller that could exercise an unfinished workflow.

The existing canonical bed API returns HTTP 409 with STALE_WRITE for an optimistic-lock conflict. Bed, room and ward endpoints return CAPACITY_CONFLICT for a protected capacity write. Both codes use the shared error envelope. Responses contain no database exception text. Authorization still runs before a write. This does not add a public Recovery command API or enable IPD gates for Hospital.

Deployment And Forward Recovery

Migration: 20261020150001_add_hospital_recovery_integrity.rb. It takes bounded source-table locks, checks legacy capacity/care identities, and applies the new constraints in one transaction. The lock wait limit is five seconds; the statement limit is 60 seconds. It sets transaction-local row_security = off so a role that cannot inspect all protected source rows fails instead of reporting a false clean preflight. This does not disable table RLS or grant the role a bypass.

The preflight reports aggregate counts only. It does not log patient details or change source rows. Invalid scope, conflicting active care, missing current owners or inactive occupied parent chains block migration. Reconcile affected records privately with the facility and clinical owner. Preserve the original care identity. Do not classify, discharge, move or reseed patients to make a migration pass.

On lock/preflight failure, the transaction rolls back. Resolve the cause before retry. After successful deployment, use a reviewed forward migration for repairs. Rollback refuses to delete care history. Verify runtime-role grants and actual constraints/RLS in the target environment before intake is enabled. Schema delivery is not a D4 nursing or D5 capacity approval.

Verification

Full review completed. Its findings have fixes and focused test evidence below. The final external follow-up and full-suite verification passed. This record is not a release approval. The first source tests failed because care_area did not exist. A separate regression proved that an admission could claim a different registration from its encounter; the source guard now rejects that identity mismatch. An early schema-dump command lacked pg_dump in its path. The migration had committed only in its disposable database. Later verification uses explicit Ruby 3.4.9 and PostgreSQL 17 tool paths. The additive SQL is captured from the new migration DDL, not a full regeneration of an existing database.

The isolated SQL-path database requires the standard db:rls_test_role:provision task after schema load. The initial unprovisioned run failed the mandatory RLS-role assertions; those failures were not accepted as skipped proof. No shared development, staging or production database was reset or changed.

The reviewed focused set passed on two independent disposable databases: 196 tests and 1,918 assertions on each path, with no failures, errors or skips. The full schema-only dumps match after removal of random pg_dump delimiter nonces. Migration-path tests disabled Rails schema maintenance in that verification process only. The repository test harness did not change. Earlier runs that allowed Rails to reload the schema are not migration-path evidence.

The bed API regressions first reproduced an unhandled capacity error and a nonstandard stale response. All five request tests now pass. An inactive-parent admission regression also failed before its guard correction and passes on both final schema paths. The admission/Recovery race reloads and locks the canonical bed so an optimistic-lock exception cannot substitute for the database ownership check.

An additional owned pre-U2 database held a valid active admission before migration. Migration, supported bed transfer and supported discharge all committed successfully. The check passed one test with 14 assertions. It preserved the patient/care identity and the legacy encounter's null registration pointer. No shared source record was changed.

Review Findings And Corrections

The full CE review completed against source checkpoint dc9cc344ba and the stable U2 diff. Run ID: 20261020-163907-3266cb5d. Its initial verdict was Not ready with three confirmed findings.

  • Finding 1: a round trip could reuse an old movement receipt. The red test reproduced acceptance. Movements now have a same-stay predecessor, one origin and one successor per predecessor. A transition must name the former current event. The round-trip replay test now rejects reuse.
  • Finding 2: occupied room and ward edits exposed unhandled database errors. Request tests reproduced the server error. The affected endpoints now return rollback-safe shared conflict envelopes.
  • Finding 3: evidence bindings lacked negative tests. Enforced-role tests now cover different patient, registration/facility, exact-null encounter, observed time and author provenance. They also cover history receipt stay/actor/action, correction successors and escalation lineage.

Further tests force deferred checks after valid admission transfers/discharges and exercise a real non-transactional request commit. That request returns a conflict without a partial release or success audit. CodeRabbit's initial reviews also corrected the race fixture's bed lock and the observation fixture's staff-role lookup. The lookup now selects the recording actor's role, not an arbitrary facility role. The simplification pass reused the existing active/available scopes; no proof test was removed.

The full review used 11 bounded read-only lenses, followed by merge, validation and report steps. At most two workers ran at once. All workers were collected and closed. Hospital profiles requested gpt-6-astra/high for high-risk review and gpt-6.1-sol/high for the other read-only tasks and finish steps. Served-model, effort and token receipts were unavailable. The CE cross-model route did not run because its launcher requires forbidden npx. Local adversarial review covered that lens. The separately approved CodeRabbit reviews did run.

The prior full backend CI run reported 18,830 tests with one failure in the unchanged referral timestamp test. It computes 5.days.ago before and after work, so a second boundary changes its expected value. That run is not counted as a green gate. The final unchanged referral test passed in canonical four-shard CI: 18,839 domain tests, 87,385 assertions, no failures or errors, and eight existing skips. The separate pricing gate passed 20 tests and 26 assertions. No failure baseline was changed.

Changed-file lint passed all 24 Ruby source/test files. The migration passed Ruby syntax checks; the repository excludes migrations from normal RuboCop. The schema diff is additive: 649 additions, no deletions. The Fumadocs build passed and indexed 510 pages. Its existing unrelated Reports HTML warning remains. No frontend runtime changed, so frontend application CI/browser acceptance was not rerun.

CodeRabbit completed its final scoped review with zero findings. A fresh focused source review confirmed findings 1-3 resolved, with no remaining P1/P2/P3 issue in those corrections. The full CE receipt records the original Not ready verdict; the follow-up closes its findings rather than rewriting that historical review. All source tests above apply to the corrected candidate.

Worker Record

All listed workers were collected and closed. Profiles and receipt limits are stated above. The final follow-up is static source review, not a claim that its worker executed the parent checks.

TaskWorker ID
Simplification01a158f3-eefd-7121-9c7e-f6f2c0b23441
Correctness01a15900-cec8-75b0-93dd-1f7780d20978
Standards01a15900-d02d-7b52-9283-aa1e5aded26f
Testing01a15902-6b50-7eb3-b1af-69b59720553e
Maintainability01a15904-c975-7dc3-9d4c-20a4ca35fb72
Security01a15904-caa9-7ce3-aed7-941b8e644ae0
Performance01a15905-e77a-7a31-8a79-0cb6ea888f40
API contract01a15906-6cb7-74d3-9108-41339c6296e7
Migration01a15907-1064-7dd1-93d3-1bf1208d0334
Reliability01a15908-43a2-7703-b1f7-0ca06760fb16
Adversarial01a15908-ec61-7622-9e2a-b3dce8305124
Deployment checks01a15909-eb07-72a2-b92b-836a1848a17b
Review merge01a1590b-c28c-7722-8748-cab2ac1e1c9a
Finding validation01a1590f-7693-7323-8a21-03bcd6c6d587
Review report01a15911-8430-72a3-9d4a-67b9c86469cc
Correction follow-up01a1591d-3871-72e1-a213-25c825b394da

Target Deployment Checks

The release owner must approve the target role, write pause, restore evidence and lock window. Five-second lock and 60-second statement limits do not bound the entire migration transaction. Rehearse with approved representative volume. Run preflight under an identity that can inspect all tenants or fails under forced RLS. Do not grant bypass to make a check pass.

Before and after migration, compare aggregate bed statuses and active-admission counts while writers are paused. After migration, check the version row and actual constraints, triggers, RLS and runtime grants. Run this aggregate ownership check under the approved audit identity:

BEGIN READ ONLY;
SET LOCAL row_security = off;
DO $$ BEGIN
  PERFORM clinical.check_recovery_bed_owner(id) FROM clinical.facility_beds;
END $$;
COMMIT;

No exception is expected. A hidden-source privilege error is a stop signal, not a clean result. Monitor admission/discharge errors, capacity conflicts, lock waits and deadlocks after writers resume. Do not run db:rollback after successful deployment. Use reviewed forward recovery.

Manual QA

  • Compare migration-built and SQL-loaded capacity constraints, RLS, grants, immutability and owner checks.
  • Inspect a synthetic invalid-capacity preflight; confirm failure leaves source records unchanged.
  • Verify an existing admission can still be read, moved and discharged through supported paths.
  • Confirm legacy resources remain unclassified until D5 mapping is approved.
  • Confirm live Recovery remains unavailable and no clinical permission or production policy was enabled.

Use the per-unit QA guide for later manual acceptance.

On this page