feat(compliance): implement FRS S-01 Compliance Standards Administration#3500
feat(compliance): implement FRS S-01 Compliance Standards Administration#3500mherman22 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Implements the FRS S-01 Compliance Standards Administration module, including backend domain model + APIs and frontend admin/editor UIs for managing compliance standards, parameter groups, and per-test thresholds (including select-list value mappings).
Changes:
- Added compliance domain entities/enums, DAO/service layers, CSV seed/import logging, and operational utilities.
- Implemented REST endpoints for standards/thresholds/test-threshold management and supporting DTO wrappers to avoid lazy-graph serialization issues.
- Integrated compliance admin UI entry points and embedded per-test “Compliance Thresholds” tab into the Test Editor.
Reviewed changes
Copilot reviewed 75 out of 124 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main/java/org/openelisglobal/compliance/valueholder/ComplianceThresholdValueMap.java | New entity for SELECT_MAP value→status mappings |
| src/main/java/org/openelisglobal/compliance/valueholder/ComplianceStatus.java | New enum for COMPLIANT/BORDERLINE/NON_COMPLIANT |
| src/main/java/org/openelisglobal/compliance/valueholder/ComplianceStandardStatus.java | New lifecycle enum for standards |
| src/main/java/org/openelisglobal/compliance/valueholder/ComplianceImportLog.java | New entity to persist CSV import/seed audit logs |
| src/main/java/org/openelisglobal/compliance/valueholder/BulkProcessResult.java | Helper model for bulk operation outcomes |
| src/main/java/org/openelisglobal/compliance/util/ComplianceConstants.java | Centralized constants + export cap config |
| src/main/java/org/openelisglobal/compliance/service/TestComplianceStandardServiceImpl.java | Service for linking tests↔standards |
| src/main/java/org/openelisglobal/compliance/service/TestComplianceStandardService.java | Interface for tests↔standards operations |
| src/main/java/org/openelisglobal/compliance/service/ParameterGroupServiceImpl.java | Parameter group CRUD + delete guard (BR-003) |
| src/main/java/org/openelisglobal/compliance/service/ParameterGroupService.java | Parameter group service API + bulk count |
| src/main/java/org/openelisglobal/compliance/service/EvaluationStatusServiceImpl.java | Status transition rules + lifecycle actions |
| src/main/java/org/openelisglobal/compliance/service/EvaluationStatusService.java | Status lifecycle service interface |
| src/main/java/org/openelisglobal/compliance/service/EvaluationServiceImpl.java | Core evaluation logic + manual review flags |
| src/main/java/org/openelisglobal/compliance/service/EvaluationService.java | Core evaluation service interface |
| src/main/java/org/openelisglobal/compliance/service/EvaluationResultServiceImpl.java | Result CRUD + validation + recalc support |
| src/main/java/org/openelisglobal/compliance/service/EvaluationResultService.java | Result service API |
| src/main/java/org/openelisglobal/compliance/service/ComplianceThresholdValueMapConfigurationHandler.java | CSV seed loader for SELECT_MAP mappings |
| src/main/java/org/openelisglobal/compliance/service/ComplianceThresholdServiceImpl.java | Threshold CRUD, validation, uniqueness, mapping sysUser propagation |
| src/main/java/org/openelisglobal/compliance/service/ComplianceThresholdService.java | Threshold service API |
| src/main/java/org/openelisglobal/compliance/service/ComplianceStandardService.java | Standards service API (search, lifecycle, copy, FHIR hooks) |
| src/main/java/org/openelisglobal/compliance/service/ComplianceReportingService.java | Reporting service interface for compliance reports/exports |
| src/main/java/org/openelisglobal/compliance/service/ComplianceParameterGroupConfigurationHandler.java | CSV seed loader for parameter groups |
| src/main/java/org/openelisglobal/compliance/service/ComplianceMessages.java | Centralized i18n-backed error messages |
| src/main/java/org/openelisglobal/compliance/service/ComplianceImportLogServiceImpl.java | Service to record/retrieve import logs |
| src/main/java/org/openelisglobal/compliance/service/ComplianceImportLogService.java | Import log service API |
| src/main/java/org/openelisglobal/compliance/service/ComplianceEvaluationService.java | Compliance evaluation service API (broad) |
| src/main/java/org/openelisglobal/compliance/service/ComplianceCsvUtil.java | Shared CSV parsing helpers |
| src/main/java/org/openelisglobal/compliance/service/CSVImportService.java | CSV import service interface (upload path) |
| src/main/java/org/openelisglobal/compliance/service/BulkEvaluationServiceImpl.java | Batch/bulk evaluation operations |
| src/main/java/org/openelisglobal/compliance/service/BulkEvaluationService.java | Bulk evaluation service API |
| src/main/java/org/openelisglobal/compliance/form/ComplianceStandardConfigMenuForm.java | MVC form for (legacy) compliance standard config menu |
| src/main/java/org/openelisglobal/compliance/daoimpl/TestComplianceStandardDAOImpl.java | DAO queries for tests↔standards associations |
| src/main/java/org/openelisglobal/compliance/daoimpl/ParameterGroupDAOImpl.java | DAO for groups + reorder + bulk counts |
| src/main/java/org/openelisglobal/compliance/daoimpl/EvaluationResultDAOImpl.java | DAO queries for evaluation results |
| src/main/java/org/openelisglobal/compliance/daoimpl/ComplianceThresholdDAOImpl.java | DAO queries for thresholds + summary aggregates |
| src/main/java/org/openelisglobal/compliance/daoimpl/ComplianceImportLogDAOImpl.java | DAO for import log listing |
| src/main/java/org/openelisglobal/compliance/dao/TestComplianceStandardDAO.java | DAO interface for tests↔standards data access |
| src/main/java/org/openelisglobal/compliance/dao/ParameterGroupDAO.java | DAO interface for parameter groups |
| src/main/java/org/openelisglobal/compliance/dao/EvaluationResultDAO.java | DAO interface for evaluation results |
| src/main/java/org/openelisglobal/compliance/dao/ComplianceThresholdDAO.java | DAO interface for thresholds |
| src/main/java/org/openelisglobal/compliance/dao/ComplianceStandardDAO.java | DAO interface for standards |
| src/main/java/org/openelisglobal/compliance/dao/ComplianceImportLogDAO.java | DAO interface for import logs |
| src/main/java/org/openelisglobal/compliance/dao/ComplianceEvaluationDAO.java | DAO interface for evaluations + bulk save/update |
| src/main/java/org/openelisglobal/compliance/controller/rest/TestComplianceThresholdRestController.java | Test-scoped threshold CRUD endpoints |
| src/main/java/org/openelisglobal/compliance/controller/rest/ParameterGroupListItem.java | DTO wrapper for parameter groups list |
| src/main/java/org/openelisglobal/compliance/controller/rest/ComplianceThresholdRestController.java | Group-scoped threshold CRUD + test summary endpoint |
| src/main/java/org/openelisglobal/compliance/controller/rest/ComplianceThresholdListItem.java | Slim DTO for threshold responses incl. flattened group/standard |
| src/main/java/org/openelisglobal/compliance/controller/rest/ComplianceTestCatalogRestController.java | Compliance-oriented test catalog endpoint (+ select options + counts) |
| src/main/java/org/openelisglobal/compliance/controller/rest/ComplianceStandardListItem.java | Standards list wrapper adding parameterGroupCount |
| src/main/java/org/openelisglobal/compliance/controller/rest/ComplianceReportingController.java | REST endpoints for compliance reporting/export |
| src/main/java/org/openelisglobal/compliance/controller/ComplianceStandardConfigMenuController.java | MVC controller for (legacy) compliance config menu |
| frontend/src/components/admin/testManagementConfigMenu/TestModifyEntry.jsx | Adds Compliance Thresholds tab into Test Editor |
| frontend/src/components/admin/testManagementConfigMenu/TestManagementConfigMenu.jsx | Adds admin tile linking to ComplianceStandardsAdmin |
| frontend/src/components/admin/complianceStandards/SelectMapForm.jsx | UI to map select-list options → compliance status |
| frontend/src/components/admin/Admin.jsx | Wires ComplianceStandardsAdmin route into Admin app |
cab97f4 to
b3153d5
Compare
|
👋 Hi, @mherman22, This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there. |
9d00b60 to
49bb1f0
Compare
56345c0 to
3ff8bc5
Compare
|
👋 Hi, @mherman22, This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there. |
bf355e3 to
800f8be
Compare
|
👋 Hi, @mherman22, This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there. |
138d1b2 to
5ba04dd
Compare
|
👋 Hi, @mherman22, This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there. |
Implements the FRS S-01 v2.0 admin/data-model/seed-loader scope of the
Compliance Standards Administration feature. S-05 (evaluation engine)
is a separate FRS and is NOT in this commit.
Two admin surfaces:
* Compliance Standards admin (/MasterListsPage/ComplianceStandardsAdmin)
with list/search/filter/archive/copy + parameter-group accordion +
Tab 2 per-test thresholds editor.
* FR-3-001 Compliance Thresholds tab inside Modify Test, embedded as
a horizontal Carbon Tab peer to the existing 7-step wizard until
the Test Catalog Management v2.1 vertical-sidebar refactor lands.
Data model: ComplianceStandard, ParameterGroup, ComplianceThreshold,
ComplianceThresholdValueMap with Liquibase changesets 018-027.
Threshold types HIGH/LOW/RANGE/BORDERLINE/DESCRIPTIVE/SELECT_MAP.
Per-test multi-limit numeric form + select-list value-mapping form
(FR-3-013/014/015). Threshold count badge on the Modify Test tab
label per v2.1 spec. ACTIVE-only standard ComboBox per FR-3-008.
REST: /rest/compliance/standards (CRUD + copy + archive +
parameter-groups + linked-tests), /rest/compliance/thresholds
(group-scoped + summary), /rest/tests/{testId}/compliance-thresholds
(test-scoped). Standard mutations gated by GLOBAL_ADMIN.
Seed loader (FR-6): four DomainConfigurationHandler subclasses load
*-standards.csv, *-parameter-groups.csv, *-thresholds.csv,
*-threshold-value-maps.csv from
volume/configuration/backend/compliance-standards/ on startup.
Idempotent by natural key. Ships PP No. 22/2021 (Baku Mutu) seed
with water-quality tests.
Deferred:
* FR-4-001 standard auto-suggest at registration (blocked on S-02)
* FR-7-003 result version-lock (blocked on S-05)
* compliance.threshold.view permission gate (blocked on Section 11
permissions framework)
* FR-6-008 compliance.seed.directory config-key override
* Test Editor 14-tab vertical sidebar refactor (Test Catalog
Management v2.1, separate effort)
f95eedb to
7748176
Compare
|
👋 Hi, @mherman22, This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there. |
There was a problem hiding this comment.
Hey @mherman22 — clear PR write-up and the architecture is sound (clean DAO / Service / Controller layering, @PreAuthorize overrides on mutations, JPQL with bind params, service-level @Transactional). A few things I'd want before merge:
1. Test quality.
ComplianceThresholdDAOImplTestmocksEntityManager/TypedQueryand asserts the result equals what the mock was stubbed to return — that's testing Mockito, not the DAO. I'd drop the file (the service-level integration tests already cover the DAO path) or rewrite as a real-DBBaseWebContextSensitiveTest.- Nine pagination tests in
ComplianceStandardRestControllerIntegrationTestend with onlyassertNotNullonArrays.asList(...), which can never be null — so a regression to broken pagination still passes. Tightening tohasSizeLessThanOrEqualTo(1000)/hasSize(0)etc. would catch real failures. setUp()widens auth toROLE_GLOBAL_ADMIN + ROLE_ADMIN + ROLE_RESULTSfor every test, so there's no negative auth coverage. OneROLE_RESULTS-only POST expecting 403 would close that.
2. Carbon in LinkTestForm.jsx. Sample-type filter chips and search-result rows render as raw <button> + inline-styled hex colors. Button is already imported on line 2 but unused. Same file has ~20 inline style={{...}} sites — worth one pass to align with the rest of the admin surface.
3. Component size. TestComplianceThresholds.jsx is 1573 lines and ComplianceStandardsAdmin.jsx is 1057. The embeddedTestId branching in TestComplianceThresholds is a natural seam for splitting into standalone + embedded + editor. Not blocking, but every follow-up touching this surface will be harder.
Smaller stuff worth a glance:
023-compliance-threshold-test-fk.xmlcollides on filename prefix with develop's new023-add-patient-madagascar-address-fields.xml. Both load fine (distinct changeset IDs inside) but renaming yours to028-would clear the recurringbase.xmlmerge conflicts.GET /rest/compliance/standards/activereturns raw entities whileGET /rest/compliance/standardsreturnsComplianceStandardListItemDTOs. Works in practice via OSIV, but worth normalizing both endpoints to DTOs.- Latest push's
Authoritative E2E Executor / Cypress / Adminjob is failing — worth a quick triage to confirm it's not a regression from the new admin tile changing the admin landing page.
Architecture and FRS coverage look solid overall — happy to do another pass once the test-quality and Carbon items land.
Pull Requests Requirements
Issue number if applicable.
Styleguide and Design
documentation.
Summary
Implements FRS S-01 Compliance Standards Administration — a configurable regulatory-standards framework so non-clinical test results can be evaluated against externally published thresholds (Indonesia's PP No. 22/2021 / Baku Mutu, WHO drinking-water guidelines, etc.).
This PR is scoped to S-01 only (admin / data model / seed loader). The S-05 Compliance Evaluation Engine is a separate FRS and is not in this PR.
Two admin surfaces:
/MasterListsPage/ComplianceStandardsAdmin) — list / search / filter / archive / copy standards; manage parameter groups + linked tests inline.Data model
Four JPA entities form the standard → group → threshold → option-mapping hierarchy. All persist via Liquibase changesets
018→027(no XML mappings, ORM annotations on the value holders).compliance_standardThe top-level regulation. Natural key is
(name, regulation_number, version).idfhir_uuidname,display_nameissuing_bodyregulation_numberversion" - Copy"on copy-cloneeffective_date,expiry_datecountry_regionstatusDRAFT/ACTIVE/SUPERSEDED/ARCHIVEDsuperseded_by_iddescription,regulatory_contextenforcement_authorityis_pre_seededcreated_date,created_by,archived,archived_date,sys_user_id,last_updatedPlus a
compliance_standard_sample_typejoin table (FR-1-007a sample-type set).parameter_groupLogical grouping of parameters within a standard. Per-standard uniqueness on
(standard_id, name).idstandard_idname,description,sort_order,is_mandatorysort_ordercompliance_thresholdThe actual numeric/categorical constraint. Per-(group, parameter, type) uniqueness so multi-limit saves (HIGH + BORDERLINE on the same parameter) don't collide.
idgroup_idtest_idparameter_code,display_namethreshold_typeMINIMUM/MAXIMUM/RANGE/BORDERLINE/EXACT/DESCRIPTIVE/SELECT_MAPmin_value,max_value,target_valuevalue_descriptiveunits,method_referencedetection_limitis_mandatory,is_active,sort_orderis_activeis the FR-3-010 archive flagvalidation_rules,notes(test_id, group_id, threshold_type)compliance_threshold_value_mapMaps select-list result options to a
ComplianceStatus. Required for FR-3-013 / FR-3-014.idthreshold_idoption_valuecompliance_statusCOMPLIANT/BORDERLINE/NON_COMPLIANTLiquibase migrations
018-compliance-standards-complete-feature.xml019-compliance-threshold-add-descriptive.xmlDESCRIPTIVEto threshold-type CHECK020-compliance-threshold-add-select-map.xmlSELECT_MAPto threshold-type CHECK023-compliance-threshold-test-fk.xmltest_idfrom String → real FK024-compliance-standard-sample-types.xml025-compliance-rename-lastupdated-column.xmllastupdated→last_updatedto match BaseObject mapping026-compliance-threshold-value-map.xml027-compliance-frs-data-model-alignment.xml(name, regulationNumber, version),is_activeon threshold,(test_id, group_id, threshold_type)uniqueness. Drop/add steps split + guarded by<sqlCheck>againstinformation_schema.table_constraintsso reruns on partly-migrated DBs are no-ops.REST API
All endpoints under
/rest/compliance/...and/rest/tests/{testId}/compliance-thresholds. View endpoints accept any authenticated lab role; mutations areGLOBAL_ADMIN-only.Slim DTOs (
ComplianceThresholdListItem,TestCatalogEntry, etc.) are built inside service-level transactions so the controllers stay thin and Jackson never traverses a lazy graph.Frontend
frontend/src/components/admin/complianceStandards/:ComplianceStandardsAdmin.jsx— list page with filters (status / region / sample-type / text), inline-row add+edit, archive flow with destructive modal, Copy Standard action (just landed), View Linked Tests panel, clickable linked-tests count, parameter-group accordion.StandardForm.jsx— inline editor, ComboBox typeahead for Country/Region, applicable sample-types panel, Description TextArea, Save Standard.ParameterGroupAccordionItem.jsx— per-group editor with Move Up / Move Down (individual PUTs), threshold child rows.LinkTestForm.jsx— sample-type chip filters, typeahead capped at 12, excludes already-linked tests.MultiLimitForm.jsx— single form rendering all 5 numeric limit types as checkable rows.SelectMapForm.jsx— option × ComplianceStatus matrix with live row tinting + per-row a11y label.TestComplianceThresholds.jsx— Tab 2: overview table → per-test editor with vertical sidebar, Limit Types Legend, Group-by toggle, superseded warning banner. Also runs in embedded mode (embeddedTestIdprop) when mounted inside Modify Test → it suppresses its own header strip and placeholder sidebar so the parent Test Editor owns those affordances.frontend/src/components/admin/testManagementConfigMenu/TestModifyEntry.jsx— when a test is selected for editing, the editor surface is now wrapped in CarbonTabs: Tab 1 "Configuration" hosts the existing 7-stepTestStepFormwizard (untouched); Tab 2 "Compliance Thresholds" hosts<TestComplianceThresholds embeddedTestId={...} />. Toasts from both tabs flow through the existingNotificationContext+AlertDialogalready mounted on the page.React Intl throughout — no hardcoded user-facing strings.
Seed loader (FR-6)
Four sibling
DomainConfigurationHandlers underorg.openelisglobal.compliance.serviceload CSVs fromvolume/configuration/backend/compliance-standards/at app startup. Idempotent — each row is upserted by natural key.*-standards.csv*-parameter-groups.csv*-thresholds.csv*-threshold-value-maps.csvShips with the Baku Mutu PP No. 22/2021 default seed. CSV authoring rules in
volume/configuration/backend/compliance-standards/README.md.Hardening done:
""decodes to literal").#comment lines.ThresholdType.fromImportTokenaccepts FRS-aliased tokens (HIGH,LOW,MAX,MIN,QUALITATIVE,select-map, etc.) instead of silently dropping rows that don't match the canonical enum constant.ComplianceStatus.parseacceptsNON_COMPLIANT,Non-Compliant,NON-COMPLIANT, etc.nullso re-imports can clear stale values.testNamecolumn on threshold rows resolves to a realTestviaTestService.getTestByName, populatingcompliance_threshold.test_idso seeded data shows up in the Tests column on the Standards list and inside Modify Test.FRS Section 12 — Acceptance Criteria
/active); S-02 caller wiring is cross-modulePragmatic deviations from the FRS literal text
label.complianceStandard.*,button.complianceStandard.*. The codebase mostly uses its owncompliance.*namespace; the FRS-literal keys (button.complianceStandard.copy) are added where the spec is explicit. Functionally equivalent, doesn't match the literal key strings.compliance.standard.view/.add/.modify/.archiveetc. This PR maps onto existing OpenELIS roles (GLOBAL_ADMIN/RECEPTION/RESULTS) — the FRS-named permission keys are deferred until the broader OpenELIS roles/permissions cleanup.Deferred to follow-up PRs
compliance.threshold.view)ComplianceEvaluation,EvaluationResult, evaluation/bulk/reporting REST + service tierComplianceImportLogcompliance.seed.directoryconfig wiring (FR-6-008)Test plan
mvn clean compile— backend compilesmvn test -Dtest='ComplianceStandardServiceTest,ComplianceThresholdServiceImplTest,ComplianceThresholdServiceTest,ParameterGroupServiceTest,ComplianceThresholdDAOImplTest'— service / DAO suites passmvn spotless:check— backend formatting cleancd frontend && npx prettier --check "src/**/*.{js,jsx,ts,tsx,css}"— frontend formatting clean018→027apply against a clean PostgreSQL database; rerunning on a partly-migrated DB succeeds (the 027 split is a no-op on the new shape)volume/configuration/backend/compliance-standards/load on startup; PP No. 22/2021 standard appears with parameter groups + thresholds + value mappingsSUPERSEDEDcomplianceStatus="Non-Compliant"andthresholdType="HIGH"loads correctly (lenient parsers)