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
| Area | FULL (default) | ERP |
|---|---|---|
| Clinical SPI beans | Registered (FormEncounterTypeSupport, …) | Absent — form/workflow still boot |
| Observation forms | Require encounter type validation | Rejected with a clear error |
| Visit-type workflow health | Lists gaps per visit type | Returns empty (no clinical catalog) |
| Module manifest | All activated modules | Clinical domain modules forced inactive |
| Frontend navigation | All permitted routes | Imaging, 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@ConditionalOnPropertyadapter in the clinical engine instead.