Kulcare Docs
DeveloperHospital surgery center

Hospital Recovery

Live Recovery APIs, shared capacity, clinical evidence, retry safety and release gates.

Delivery Boundary

Programme U7 is governed by the focused Recovery plan. Local U1-U7 implement source protection, named resources, stays, observations, escalation, current readiness, secured HTTP APIs and the live workbench in both presets. See U6 API evidence, U7 UI evidence and U8 acceptance. Development mock mode remains separate; live failures do not return mock care. Programme U8 signed discharge and full ward operations remain later work. The ABDM discharge contract is a hard requirement for that signed-discharge phase, not a claim that this work exports a report. Production policy approval, explicit nursing grants, D4/D5, deployed QA and pilot acceptance remain separate gates. An empty production policy registry must keep policy-controlled assessment/handoff unavailable.

Use the manual QA guide and U1 execution record for evidence, limits, and the next implementation boundary. No green characterization test grants clinical release approval.

Current Source Evidence

TestObserved behaviorRequired later action
RC01Case-linked MAR enrollment preserves a null encounter without creating an admission. The obligations query does not assert clearance.Carry the same identity through the Recovery stay. Do not auto-create an encounter.
RC02The canonical assignable scope includes inactive/reserved beds and does not check parent activity.Recovery must require an approved active resource chain and an available bed.
RC03U1 exposed occupied-bed deactivation/reparenting. U2 changes this test to prove database rejection.Keep the guard through every supported writer.
RC04U1 exposed bed release without closing an active admission. U2 changes this test to prove commit rejection.Release must coordinate the actual care owner in one transaction, not call this helper alone.
RC05The canonical state machine rejects occupied-to-available and requires cleaning.Preserve this lifecycle in commands and UI.
RC06A second active admission for one bed fails at the database index.Keep this protection and add cross-workflow ownership checks. It does not protect a future Recovery stay by itself.
RC07Canonical observations store structured values, units, observed time and optional practitioner without an encounter.Reuse these records; add protected Recovery linkage and authenticated user/staff provenance.
RC08Encounter category replacement deletes old vital observation identities.Exclude protected Recovery evidence or reject the managed mutation atomically.
RC09Generic observation update/delete has no Recovery correction lineage.Protect linked records and route corrections through the managed command.

The tests are in backend/domains/clinical/test/services/hospital/recovery_characterization_test.rb. Tests named GAP capture a known unsafe source behavior, not a desired invariant. When the relevant local U2-U5 fix lands, replace that gap expectation with a rejection/preservation regression in the same delivery. Do not keep unsafe behavior to preserve a characterization assertion.

The isolated U1 source database reported, before the U2 forward repair:

TableRLS enabledRLS forcedOwned foreign keys
clinical.facility_bedsNoNo0
clinical.facility_roomsYesYes3
clinical.facility_wardsYesYes2
clinical.admissionsYesYes8

This is metadata evidence from the isolated candidate database, not an audit of staging or production. The original bed migration declares protections that the SQL dump does not contain. U2 adds the forward repair. Actual-object checks, SQL/migration parity, enforced-role tests and facility acceptance remain required before Recovery intake.

Source And Writer Inventory

All paths in this table are under backend/domains/clinical/.

Supported pathCurrent write and lockingRecovery obligation
services/ipd/admit_service.rb, createU4 creates canonical care and a bedless admission in one savepoint, then locks parents/beds and claims capacity.One owner; losing intake leaves no orphan care. No Recovery dependency on the IPD gate.
Same service, assignU4 reloads and locks admission before checking active/bedless state, then locks parents and bed.Retain the admission recheck and cross-workflow owner guard.
Same service, transferU4 locks admission, all sorted parents and beds, then changes owner and releases source to cleaning.Preserve one current owner and no partial release.
services/discharges/create_service.rbU4 locks related cases, current admission, stays and capacity. Active Recovery blocks discharge of the source encounter.Receive after discharge must reject terminal source care. Never use this admission-only path as day-care discharge.
controllers/facility_beds_controller.rbUpdate permits room/active changes. Transition locks the bed and changes status.Structure/state endpoints must not detach or release active care. A model validation alone does not protect raw writes.
controllers/facility_rooms_controller.rb, facility_wards_controller.rbParent edits and ward deactivation affect child resources.Reject an occupied parent's unsafe deactivation/reparenting and serialize against intake.
models/facility_bed.rbrelease!, transition_to! and direct updates are additional entry points.Apply shared invariants below the controller. Preserve cleaning and occupant scope.
services/hospital/surgical_cases/transition_service.rbLocks case, then booking where applicable; readiness takes the Inventory source lock.Ready/completed/cancelled changes cannot bypass or lose active Recovery care.
services/medication_mar/order_command.rbCase, registration for create, then request; nursing commands lock case, request, occurrence.Keep case-first order and exact nullable encounter linkage. Recovery must not create a second medication writer.
services/hospital/readiness/command.rb and services/hospital/case_stock/command.rbCase lock precedes source changes/locks.Keep source gates in the existing case-owned transaction and do not introduce reverse bed-to-case locking.
controllers/observations_controller.rbGeneric create/update/delete and transactional bulk vital recording.Add source-owner protection and retain ordinary unlinked observation behavior.
services/encounters/save_clinical_data_service.rbReplaces included categories with delete_all; patient-level history spans encounters.Do not delete Recovery-owned evidence, unlink its history or silently recreate it under a new ID.

Shared Occupancy And Lock Contract

This is the target protocol for local U2-U5, not a claim that existing writers follow it. Use one transaction for state, receipt, immutable events and required mutation audit.

  1. Resolve current membership, selected facility and action authority. Recheck current authorization before replaying a receipt.
  2. Lock applicable case rows in stable ID order, then existing admission rows, then stay rows. Re-read the current care owner and references under those locks.
  3. For operations that depend on parent activity or change structure, lock affected wards, then rooms, each in stable ID order. Lock all affected bed rows in stable ID order after the parents.
  4. When the action requires current clinical evidence, follow existing case-first source order. Lock medication requests and occurrences in stable ID order. Acquire any required Inventory source lock through its owning service. No source command may acquire a case or capacity lock in reverse order.
  5. Recheck expected versions, active resource chain, current owner, exact care identity and current source obligations. Commit one effect or return a conflict with no partial state.

A resource-only writer does not acquire a care-owner lock after a bed lock. It rejects an active-care mutation or enters the owner-first command path before taking bed locks. Database guards arbitrate on the same parent bed row and validate scope/owner agreement; they must not introduce bed-to-owner lock acquisition. U2/U4 must prove the full graph with independent connections. This protocol is not a runtime race-test receipt.

Required database invariants:

  • One canonical physical identity per bed; purpose classification is separate from category.
  • At most one active Recovery stay per case and one current physical owner across active admissions/stays.
  • Bed, room, ward, case and registration references belong to the same tenant/facility.
  • Bed pointers and active-owner references agree at transaction completion. A null encounter is valid for day care, not permission to omit the case/patient owner.
  • Occupied resources and their parent chain cannot be deleted, deactivated, reclassified or moved out from under care.
  • Immutable movement, observation-link, assessment and receipt history cannot be rewritten by generic CRUD.

Do not add a parallel physical-resource ledger. Do not infer a Recovery purpose or license count from a preset.

Proposed HTTP Contract

The original anchor is retained for existing links. Local U6 now implements these routes and U7 uses them through the typed hospitalRecoveryApi. Paths are relative to /clinical/facilities/:facility_id. The facility ID is a selector, not authorization. A request does not supply a tenant as authority.

Method and routeMeaning
GET /recovery/capabilityRead/write availability, source/policy status, supported actions and precise unavailable reasons.
GET /recovery_boardAuthorized resource totals, paginated active stays, awaiting-assignment cases and one evaluation time/timezone.
GET/POST /recovery_resourcesList or provision canonical named Recovery resources; return permitted parent-group choices.
GET /recovery_resource_commands/:operation_keyRecover a provisioning receipt with current configuration authority, without knowing the created resource ID.
POST /recovery_resources/:id/commandsVersioned structure, activation and cleaning/maintenance commands.
GET /recovery_resources/:id/commands/:operation_keyAuthorized resource-command receipt lookup.
GET /surgical_cases/:case_id/recoveryCurrent stay, assessment/obligations and source-safe case projection.
POST /surgical_cases/:case_id/recovery_commandsStay, observation, escalation, assessment and continuing-care handoff commands.
GET /surgical_cases/:case_id/recovery_commandsPaginated command history, or exact operation_key lookup.
GET /recovery_stays/:id/historyPaginated protected clinical/movement history.
GET /recovery_stays/:id/handoff_targetsOnly currently eligible existing continuing-care destinations and acknowledgement actions.

Use current Hospital response envelopes and structured errors. Use runtime validation and snake-case mapping in hospitalRecoveryApi/recoveryTypes, not component HTTP calls. Opaque versions are strings. Operation keys are UUIDs, scoped to tenant/facility and protected resource/action context. Command history must not disclose another case's receipt through a matching key.

Command Matrix

Every command has action, operation_key, relevant expected versions and any required reason. Reject unrecognized fields and actor/tenant/patient overrides. Resolve resource and patient identities from authorized records, not text entered by the caller.

Action groupRequired preconditions/payloadCurrent result and effect
Provision resourceExisting authorized canonical group/room, unique local name/code, recovery purpose and current configuration versionOne resource and receipt; no planning-count side effect.
Rename/activate/classifyResource version and permitted new valuesNew version, or occupied-parent/owner conflict. No implicit move.
Clean/maintenanceResource version and allowed state transition; reason where requiredState/event change only. Cannot discharge or free occupied care.
ReceiveCase version, available resource and its version; case is awaiting Recovery assignmentOne active stay/occupant. An already-received case conflicts or replays its exact receipt.
MoveStay version, target bed version and expected current resource/versionSame stay at target, source cleaning and immutable movement.
Record/correct observationsStay version; structured coded values/units, observed time, note; correction target/current evidence version and reasonCanonical observations, protected links and author/time history. No client-ready flag.
Raise/acknowledge/resolve escalationStay/escalation version, reason and current evidence reference where requiredSeparate immutable lifecycle events. Acknowledgement is not resolution.
Assess readinessStay version, expected policy hash and current evidence revision preconditionsServer-evaluated result, current blockers and bound evidence snapshot.
Accept continuing-care handoffStay/current-target versions, server-eligible target and receiving actor's authenticated acknowledgement, reasonExplicit accepted context/obligations, closed stay and source cleaning once. No patient discharge.

The accepting actor must have current authority for the target context and supply their own authenticated acknowledgement. The producer cannot submit another actor's identity as proof of acceptance. U1 does not assert that a supported receiving workflow exists for every facility. If there is no eligible target, handoff is unavailable. Bed moves and ongoing care remain distinct. The later U8 signed-discharge service calls the guarded release boundary inside its own transaction. No public discharged flag, arbitrary destination, home label or browser-supplied proof can invoke it.

Read And Error Semantics

Base view requires view_hospital and view_surgical_cases, current facility scope and the relevant module/capability. Clinical values require observation-source read authority. MAR data retains its own policy. Structural resource changes use manage_hospital_configuration. U1 did not seed manage_recovery. The U4 candidate pulls its migration and catalog/default/snapshot/key-behavior coverage forward from U6, with no default role grant. It checks real stay operations and current facility assignment. The shell remains the role/permission administration surface. Clinical writes additionally require canonical observation authority, current staff/practitioner assignment and the approved action policy. An admin role is not nursing authority.

ConditionRequired transport meaning
Missing authentication or denied current authorityExisting 401/403 contract; no receipt existence or restricted clinical data.
Foreign/missing selected resourceExisting non-disclosing 404 contract.
Invalid shape, unknown field or bad typed value422 validation details with field names; no write.
Stale resource/source version or changed payload under a used key409 conflict with a safe code and reload/recovery instruction.
Inactive bed or parent resource409 RESOURCE_UNAVAILABLE; no occupancy change or receipt.
Occupied resource, invalid state or current readiness blockerStructured conflict/validation result, with authorized source links where applicable.
Missing capability, policy or required sourceExplicit unavailable reason; never empty/ready success.
Required audit unavailable503; no clinical read result or committed clinical mutation.
Authorized exact lookup has no committed receipt200 with receipt: null; do not equate timeout/denial with absence.

An exact-key replay is authorized before lookup and returns the committed receipt before testing the old versions again. A replay does not assert that the present source state still equals the original result. Refetch current state. After a lost response, look up the same key; never silently generate a new mutation intent. For provisioning, use the facility-scoped /recovery_resource_commands/:operation_key lookup because the created ID may be unknown. Require current configuration authority and return the created resource ID in the committed receipt, or receipt: null for authorized absence. The instance-scoped lookup remains valid for commands against an already known resource. Keep only private identity-scoped retry metadata, not observation notes, patient search or clinical payloads in browser storage.

Board counts cover the authorized filtered population, not only the current page. Active overnight stays remain visible across the facility-local date boundary. An observation/MAR reader without source authority sees unavailable/forbidden source state, not fabricated normal values. Query keys include tenant, facility, profile, authenticated user and filters. Cancel or isolate old responses and clear drafts/selectors on identity changes; preserve initial deep links during first identity hydration.

Resource drafts retain the version captured when selected. A refetch cannot replace that token under unsent fields. A changed version blocks save until the user explicitly loads the current resource. Readiness review also starts unchecked. It records the evidence the user reviewed, not merely the evidence that loaded. Changed evidence requires another explicit review.

A direct RESOURCE_UNAVAILABLE rejection permits a new target only after fresh reads succeed. Failed refresh keeps the original key. Timeouts and 503 results remain uncertain. A case with a closed Recovery stay cannot start another stay through receive; exact-key replay still returns the original receipt.

Read-Only Capacity Audit Specification

Run the future audit against the selected facility with current read authority. Local U1 supplies this specification, not an executable production repair tool. Use aggregated, non-PHI output in the release record. Keep any authorized row-level reconciliation material private.

CheckReportCutover rule
Actual schemaRLS/force/policy, scoped FKs, uniqueness, grants, schema pathMissing required protection blocks new Recovery intake.
Resource chainOrphan or cross-tenant/facility room/ward/bed referencesResolve with approved forward corrections; no automatic reassignment.
Physical ownerActive admissions, bed pointers/status, duplicate or missing ownerPreserve active care and investigate discrepancies before validation.
AvailabilityInactive occupied bed/parent, reserved/cleaning/maintenance resourcesNever count as free because a planning field or preset says so.
Purpose/countingUnclassified existing resources and deduplicated recovery/inpatient totalsD5 facility approval supplies the mapping; never infer from names or presets.
Care continuityExact nullable case/encounter/registration, MAR links, required document/source statusNo fabricated admission/encounter, no silent resolution of obligations.

The audit must be read-only and repeatable. Re-running it must not change rows, counters, classifications or migration state. Record selected facility, evaluated time, deployed commit, object-check outcome, aggregate counts and reviewer decision. An audit failure is not permission to reset or reseed a shared database.

Settings And Release

Planning capacity remains metadata. Real resource commands determine capacity. Disabling intake must preserve the authorized continuation/reconciliation path for active care and exact-key recovery. Code/schema delivery does not approve clinical policy or production resource classification. Use the release acceptance record for D4/D5 decisions and actual deployed QA.

On this page