Skip to main content

Orders Service — Migration Plan

Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · SERVICE_OVERVIEW · DOMAIN_MODEL

1. Background

The orders-service consolidates two previously separate bounded contexts per ADR-0046:

Legacy moduleFR prefixStatus
orders-cpoeFR-CPOE-, FR-ORD-Retired as standalone; absorbed into orders-service
requisitions-referralsFR-REQ-, FR-REF-Retired per ADR-0046; RETIRED.md in _sources/requisitions-referrals/

FR mappings: all FR-REQ-* and FR-REF-* references are re-numbered as FR-ORDERS-* in this service's documentation. Legacy refs are preserved in the FR table for traceability.

2. Migration Scope

Migration concernDetail
Legacy CPOE order dataOrders created in the legacy CPOE module need migration to the unified orders schema
Legacy requisition dataAll lab and radiology requisitions created via requisitions-referrals-service migrate to orders schema as laboratory and radiology order types
Referral recordsLegacy referral records migrate as referral order type orders
Order set templatesCPOE legacy order set templates migrate with ords_ ID prefix
FHIR resourcesLegacy FHIR ServiceRequests re-issued with new resource IDs via interop-service

3. Migration Phases

Phase 0: Pre-Migration Preparation

  • Audit legacy CPOE database for record count, status distribution, and schema gaps.
  • Map legacy status values to new OrderStatus enum (draft / active / completed / cancelled / entered-in-error).
  • Map legacy requisition types to new orderType enum (laboratory, radiology, referral).
  • Identify legacy orders without an encounterId (encounter-bound is now required; assign to a synthetic encounter or flag as entered-in-error).
  • Identify any legacy controlled-substance orders requiring dual-sign audit records.

Phase 1: Schema Deployment

  • Deploy orders-service schema alongside legacy schema (blue-green; both active).
  • Run initial schema migration scripts — no data movement yet.
  • Validate RLS policies in staging with synthetic data.

Phase 2: Historical Data Migration (Batch)

Run migration scripts against a DB snapshot (not live):

-- Example: migrate legacy lab requisitions to orders
INSERT INTO orders.orders (
id, tenant_id, patient_id, encounter_id, order_type,
order_code, status, priority, ordered_by, ordered_at,
lab_detail, version, created_at, updated_at
)
SELECT
'ord_' || legacy_req.id,
legacy_req.tenant_id,
legacy_req.patient_id,
COALESCE(legacy_req.encounter_id, 'enc_legacy_synthetic'),
'laboratory',
jsonb_build_object('system', 'http://loinc.org', 'code', legacy_req.loinc_code, 'display', legacy_req.test_name),
CASE legacy_req.status
WHEN 'OPEN' THEN 'active'
WHEN 'COMPLETED' THEN 'completed'
WHEN 'CANCELLED' THEN 'cancelled'
ELSE 'entered-in-error'
END,
LOWER(legacy_req.priority),
legacy_req.created_by,
legacy_req.created_at,
jsonb_build_object('priority', LOWER(legacy_req.priority), 'fastingRequired', legacy_req.fasting_required),
1,
legacy_req.created_at,
legacy_req.updated_at
FROM legacy_schema.requisitions legacy_req
WHERE legacy_req.tenant_id = :tenant_id;

Migration script approach:

StepScriptIdempotency
1. Migrate CPOE ordersscripts/migrate-cpoe-orders.tsUpsert on id — safe to re-run
2. Migrate lab requisitionsscripts/migrate-lab-requisitions.tsUpsert on id
3. Migrate radiology requisitionsscripts/migrate-radiology-requisitions.tsUpsert on id
4. Migrate referralsscripts/migrate-referrals.tsUpsert on id
5. Migrate order setsscripts/migrate-order-sets.tsUpsert on id
6. Validate row countsscripts/validate-migration-counts.tsComparison report
7. Generate FHIR re-issue manifestscripts/generate-fhir-reissue-manifest.tsID mapping CSV

Phase 3: Cut-Over

StepAction
Stop writes to legacy CPOE and requisitions-referrals servicesFeature flag LEGACY_ORDERS_WRITE=false
Run final incremental sync (delta migration)Capture all records written after Phase 2 snapshot
Validate record counts matchAutomated count comparison script
Switch read traffic to new orders-serviceKong route weight: 0% → 100% new service
Enable FHIR re-issue via interop-servicePublish new ServiceRequest / MedicationRequest IDs
Archive legacy serviceSet legacy service replicas to 0; retain DB for 90 days read-only

Phase 4: FHIR ID Remapping

Legacy FHIR ServiceRequest and MedicationRequest IDs must be updated in consuming services (patient-chart-service, patient-portal-service). interop-service maintains a fhir_id_redirect table during the 90-day retention window:

Legacy FHIR ID → New FHIR ID (via orders-service)

External clients following legacy FHIR IDs receive a 301 Moved Permanently response pointing to the new ID for 90 days after cut-over.

4. Tenant Onboarding

For tenants onboarded after orders-service GA (no legacy data):

  1. No migration required — fresh schema, RLS policies applied automatically.
  2. Order set templates may be imported from system-global templates (flagged is_global=true).
  3. CDS rules are provisioned by terminology-service independently.

For tenants migrating from legacy CPOE systems:

  1. Tenant-specific migration run is scheduled during a maintenance window.
  2. Migration team provides count validation report before go-live.
  3. Tenant's active orders are validated by clinical team (sample check: 10% of active orders).

5. Rollback Plan

TriggerRollback action
Migration count mismatch > 0.1%Halt migration; investigate delta; re-run from Phase 2
Post-cutover order creation failure rate > 0.5%Kong route weight back to legacy; investigate
FHIR ID mismatch in patient-chart-serviceRe-run FHIR re-issue manifest; extend redirect window
Data integrity failure in RLS validationEmergency: set legacy service back to 100% weight; page on-call

Legacy DB is preserved read-only for 90 days post-cutover. All rollback actions are documented in the operations runbook at infra/runbooks/orders-migration-rollback.md.

6. Legacy FR Mapping

New FRLegacy FRSource module
FR-ORDERS-001FR-CPOE-001orders-cpoe
FR-ORDERS-002FR-CPOE-002orders-cpoe
FR-ORDERS-010FR-REQ-001requisitions-referrals
FR-ORDERS-011FR-REQ-002requisitions-referrals
FR-ORDERS-020FR-REF-001requisitions-referrals
FR-ORDERS-021FR-REF-002requisitions-referrals

Full mapping table maintained in services/orders-service/_sources/orders-cpoe/TRACEABILITY_MATRIX.md.

7. Open Questions

  • Confirm legacy encounter-less orders handling with clinical informatics team.
  • Agree on FHIR ID redirect window duration with interop-service team (90 days proposed).