Skip to main content

ERP deployment profile (M34-000)

The platform ships as a full EHR by default. Some facilities run another EMR for clinical work and want this instance for administrative function only — HRMS, procurement, finance, forms, workflows, documents — without patient-records surfaces.

Configuration

Set the deployment-wide profile:

UHP_DEPLOYMENT_PROFILE=ERP # administrative spine only
# UHP_DEPLOYMENT_PROFILE=FULL # default integrated EHR

The property binds as uhp.deployment.profile from core/src/main/resources/uhp-module-defaults.yml.

What changes in ERP mode

AreaFULL (default)ERP
Clinical SPI beansRegistered (FormEncounterTypeSupport, …)Absent — form/workflow still boot
Observation formsRequire encounter type validationRejected with a clear error
Visit-type workflow healthLists gaps per visit typeReturns empty (no clinical catalog)
Module manifestAll activated modulesClinical domain modules forced inactive
Frontend navigationAll permitted routesImaging, lab, pharmacy, programmes, scheduling, workspace, and clinical setup links hidden

Clinical domain module keys: clinical, program, billing, scheduling, lab, pharmacy, imaging, fhir, hl7, providerportal, patientportal, workspace.

Boundary enforcement

Three former direct imports from the form and workflow engines into clinical/demographic services were inverted to optional SPI beans (..service.spi..). An ArchUnit rule (erpSpineMustNotDependOnClinicalEngines) freezes the administrative spine against new clinical, program, billing, or scheduling imports. A small allowlist covers pre-existing couplings documented in EngineBoundaryRules — do not extend that list without a deliberate ticket.

Why it is this way

A Maven split between core-platform and core-clinical is deferred. ERP mode proves the boundary in the running monolith: the spine boots, DOMAIN and handler-backed forms work, and clinical engines remain in the jar but dormant until the profile is FULL.

Traps

  • ERP is not “modules turned off in the UI only”. The manifest marks clinical modules inactive and the frontend hides nav by profile — both layers must agree.
  • Do not add clinical imports to spine engines. Use an SPI under ..service.spi.. and a @ConditionalOnProperty adapter in the clinical engine instead.