Skip to main content

Facility Service — Migration Plan

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: SERVICE_TEMPLATE §17

1. Context

facility-service consolidates two legacy modules (facility-management and hierarchy) into one bounded context. Migration addresses:

  1. Code & ownership migration from apps/services/facility-management and apps/services/hierarchy into services/facility-service.
  2. Database merge of facility_db and hierarchy_db into facility schema inside the unified service DB.
  3. Event renaming from legacy subjects to canonical facility.* subjects.
  4. Existing tenants' hierarchies preserved unchanged.

2. Migration tracks

TrackDescriptionPhase
T1Code merge: copy aggregates, ports, handlers; re-wire importsM0
T2Schema merge: ETL hierarchy_db.*facility.hierarchy_*; preserve IDsM0
T3Event bridge: dual-publish legacy (hierarchy.node.created) + canonical (facility.hierarchy_node.created.v1) for 30 daysM0 → M1
T4Consumer cutover: every consumer switches to canonical subjectsM1
T5Legacy retirement: drop dual-publish, drop legacy DBsM1 end

3. Data mapping

Legacy tableLegacy DBNew tableNotes
hierarchy_nodeshierarchy_dbfacility.hierarchy_nodesPreserve id; map profile_id; tenant_id unchanged
hierarchy_edgeshierarchy_dbfacility.hierarchy_edgesPreserve id
hierarchy_profileshierarchy_dbfacility.hierarchy_profilesSeed platform profiles if missing
provider_node_membershipshierarchy_dbfacility.provider_node_membershipsPreserve id
locationsfacility_dbfacility.locationsRequire hierarchy_node_id; backfill from joined record
location_hoursfacility_dbfacility.location_hours1:1 copy
bedsfacility_dbfacility.bedsPreserve IDs; ensure unique (location_id, bed_number)
resource_catalog_itemsfacility_dbfacility.resource_catalog_items1:1

4. Event renaming

Legacy subjectNew subjectStrategy
hierarchy.node.createdfacility.hierarchy_node.created.v1Dual-publish 30d
hierarchy.node.updatedfacility.hierarchy_node.updated.v1Dual-publish 30d
hierarchy.node.deactivatedfacility.hierarchy_node.deactivated.v1Dual-publish 30d
hierarchy.edge.createdfacility.hierarchy_edge.created.v1Dual-publish 30d
facility.node-config.createdfacility.location.created.v1Dual-publish 30d
facility.node-config.updatedfacility.location.updated.v1Dual-publish 30d
facility.bed.status-changedfacility.bed.status_changed.v1Dual-publish 30d
facility.resource.createdfacility.resource.created.v1Dual-publish 30d
facility.resource.updatedfacility.resource.updated.v1Dual-publish 30d

5. Procedure (per tenant)

  1. Freeze window (announced 72h ahead): no hierarchy changes for 15min.
  2. Snapshot legacy DBs.
  3. Run ETL into new facility schema, preserving IDs.
  4. Smoke-test read APIs; compare counts per tenant.
  5. Unfreeze; enable writes on new service with dual-publish.
  6. Monitor for 30 days; consumer cutover.
  7. Retire legacy DB; drop topics.

6. Rollback

  • Retain legacy DBs read-only for 90 days.
  • If regression detected: disable new service writes, route all traffic to legacy (events re-subscribed via inverse-bridge), investigate, redo ETL.

7. Client impact

SurfaceImpactMitigation
Admin UIEndpoint URL moves from /hierarchy/* to /api/v1/hierarchy/*UI config update
scheduling-serviceSubject renameListener updated in same release train
LicensingresolveEffectiveLicenses(nodeId) preservedNone — Licensing switches to RPC against new service
FHIR/fhir/R4/Location URL unchangedNone