feat(microbiology): capture culture purpose for WHONET - #4117
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1dfbf6cf58
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
6de40d0 to
9dffde4
Compare
9dffde4 to
54363bc
Compare
54363bc to
3d39343
Compare
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds an explicit “culture purpose” classification to microbiology order details and uses it to control WHONET population inclusion (default clinical-only; screening/unspecified opt-in), including auditability and read-only behavior for final cases.
Changes:
- Adds nullable
culture_purposeDB column via Liquibase and wires it through backend valueholders/services with audited corrections and final-case locking. - Extends WHONET query/selection to include screening + unspecified inclusion flags and updates preview metrics accordingly.
- Updates frontend order entry, case views, timeline rendering, and WHONET export UI/routes to display and persist culture purpose behavior; expands backend/frontend/Playwright test coverage.
Reviewed changes
Copilot reviewed 51 out of 51 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/test/resources/liquibase/microbiology-r11-culture-purpose-rollback.xml | Test changelog to apply/rollback/reapply culture purpose migration |
| src/test/java/org/openelisglobal/microbiology/service/MicroWhonetDatasetServiceTest.java | Adds WHONET filtering tests for purpose inclusion flags |
| src/test/java/org/openelisglobal/microbiology/service/MicroOrderRoutingServiceTest.java | Updates routing tests to require culture purpose; adds missing-purpose test |
| src/test/java/org/openelisglobal/microbiology/service/MicroCaseOrderDetailServiceTest.java | Adds order-detail persistence/audit/final-locking tests for culture purpose |
| src/test/java/org/openelisglobal/microbiology/MicrobiologyOrderSaveIntegrationTest.java | Ensures integration saves/loads culture purpose |
| src/test/java/org/openelisglobal/microbiology/MicrobiologyCulturePurposeLiquibaseTest.java | Testcontainers-based migration rollback/reapply verification |
| src/test/java/org/openelisglobal/microbiology/MicroWhonetPersistenceIntegrationTest.java | Updates WHONET persisted selection integration for new flags |
| src/test/java/org/openelisglobal/microbiology/MicroOrderRoutingIntegrationTest.java | Ensures routing persists/round-trips culture purpose |
| src/main/resources/liquibase/3.5.x.x/base.xml | Includes new Liquibase changeset in base pipeline |
| src/main/resources/liquibase/3.5.x.x/088-microbiology-culture-purpose.xml | Adds nullable culture_purpose column + rollback |
| src/main/java/org/openelisglobal/microbiology/valueholder/MicroWhonetExportSelection.java | Persists WHONET includeScreening/includeUnspecified booleans |
| src/main/java/org/openelisglobal/microbiology/valueholder/MicroCulturePurpose.java | Defines canonical culture purpose enum values |
| src/main/java/org/openelisglobal/microbiology/valueholder/MicroCaseOrderDetail.java | Adds persisted culturePurpose property |
| src/main/java/org/openelisglobal/microbiology/valueholder/MicroCaseActivityType.java | Adds CULTURE_PURPOSE_CHANGED timeline activity type |
| src/main/java/org/openelisglobal/microbiology/service/MicroWhonetDatasetServiceImpl.java | Filters WHONET candidates by culture purpose + adds preview counts |
| src/main/java/org/openelisglobal/microbiology/service/MicroOrderRoutingServiceImpl.java | Validates submitted culture purpose for new orders |
| src/main/java/org/openelisglobal/microbiology/service/MicroCaseServiceImpl.java | Includes culture purpose in compiled case detail form |
| src/main/java/org/openelisglobal/microbiology/service/MicroCaseOrderDetailServiceImpl.java | Normalizes/persists purpose, audits corrections, enforces final-case lock |
| src/main/java/org/openelisglobal/microbiology/form/MicroWhonetPreviewForm.java | Adds WHONET preview fields for purpose counts and filter stage |
| src/main/java/org/openelisglobal/microbiology/form/MicroWhonetExportQueryForm.java | Adds includeScreening/includeUnspecified query flags |
| src/main/java/org/openelisglobal/microbiology/form/MicroCaseOrderDetailRequestForm.java | Adds culturePurpose request field + validation pattern |
| src/main/java/org/openelisglobal/microbiology/form/MicroCaseOrderDetailForm.java | Adds culturePurpose field to case order detail form |
| specs/782-ogc-782-microbiology-mvp-spec/tasks.md | Updates roadmap task status/ordering for R11 slice |
| specs/782-ogc-782-microbiology-mvp-spec/evidence/code-qa-r11-2026-08-22.md | Adds R11 code-QA evidence writeup |
| specs/782-ogc-782-microbiology-mvp-spec/contracts/microbiology-openapi.yaml | Documents new order-detail correction endpoint + WHONET flags/schema |
| frontend/src/languages/en.json | Adds i18n strings for culture purpose UI + WHONET controls/metrics |
| frontend/src/components/order/orderDataUtils.test.js | Updates loaded-order shaping expectations to include culturePurpose |
| frontend/src/components/order/orderDataUtils.js | Applies explicit culturePurpose shaping during order load |
| frontend/src/components/microbiology/tests/WhonetExport.test.jsx | Updates WHONET export tests for new controls, url state, metrics |
| frontend/src/components/microbiology/tests/OrderDetailPanel.test.jsx | Adds tests for purpose edit + final read-only behavior |
| frontend/src/components/microbiology/tests/MicrobiologyOrderEntrySection.test.jsx | Ensures new orders default to clinical purpose and can toggle |
| frontend/src/components/microbiology/tests/CaseTimelinePanel.test.jsx | Tests rendering of audited purpose change from structuredData |
| frontend/src/components/microbiology/tests/CaseInfoSummary.test.jsx | Ensures case summary displays purpose + Unspecified handling |
| frontend/src/components/microbiology/WhonetService.test.js | Updates preview request serialization tests for new flags |
| frontend/src/components/microbiology/WhonetService.js | Serializes includeScreening/includeUnspecified query params |
| frontend/src/components/microbiology/WhonetRoutes.test.js | Ensures URL parse/build round-trips new boolean flags |
| frontend/src/components/microbiology/WhonetRoutes.js | Parses/builds canonical WHONET routes including purpose flags |
| frontend/src/components/microbiology/WhonetExport.scss | Styles the new WHONET culture-purpose filter fieldset |
| frontend/src/components/microbiology/WhonetExport.jsx | Adds WHONET purpose inclusion checkboxes + metrics |
| frontend/src/components/microbiology/OrderDetailPanel.jsx | Adds read-only support and hides save button when locked |
| frontend/src/components/microbiology/MicrobiologyOrderEntrySection.jsx | Ensures culturePurpose participates in form change detection |
| frontend/src/components/microbiology/MicrobiologyOrderDetailFields.jsx | Adds culture purpose radio group + Unspecified tag |
| frontend/src/components/microbiology/MicrobiologyLabels.js | Adds formatter for culture purpose labels |
| frontend/src/components/microbiology/MicrobiologyCaseView.jsx | Passes final-release read-only state down to order detail panel |
| frontend/src/components/microbiology/CaseTimelinePanel.jsx | Renders CULTURE_PURPOSE_CHANGED with structured audit data |
| frontend/src/components/microbiology/CaseInfoSummary.jsx | Displays culture purpose in case info summaries |
| frontend/src/components/formModel/innitialValues/OrderEntryFormValues.js | Defaults new microbiology orders to CLINICAL_DIAGNOSTIC |
| frontend/playwright/tests/foundational/core/microbiology-order-entry.spec.ts | Asserts default clinical purpose on order entry/reload |
| frontend/playwright/tests/foundational/core/microbiology-culture-purpose.spec.ts | New end-to-end journey covering audit + WHONET purpose inclusion |
| frontend/playwright/helpers/whonet-export.ts | Adds purpose flags to canonical WHONET export query builder |
| frontend/playwright/helpers/seed-microbiology-data.ts | Seeds fixtures with culture purpose and updates scenario keys |
Suppressed comments (2)
src/main/java/org/openelisglobal/microbiology/service/MicroCaseOrderDetailServiceImpl.java:1
- The Spring-wired constructor always creates a fresh
new ObjectMapper(), bypassing any app-wide Jackson configuration (modules, naming, features) and making serialization behavior less consistent across the service layer. Prefer injecting the sharedObjectMapperbean (e.g., make theObjectMappera required constructor parameter and annotate that constructor for Spring), and avoid creating a new mapper in production code.
src/main/java/org/openelisglobal/microbiology/service/MicroCaseOrderDetailServiceImpl.java:1 - There are now multiple different error messages for the same missing-purpose condition (e.g., this throws
\"Culture purpose is required\"while routing validation throws\"Culture purpose is required for a new microbiology order\"). Aligning these messages (or making them consistently endpoint-scoped) would make the API easier to consume and reduce brittle client/test expectations.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
3d39343 to
ecdc855
Compare
ecdc855 to
d81508b
Compare
d81508b to
884a570
Compare
884a570 to
58c67cf
Compare
58c67cf to
d21b4e6
Compare
d21b4e6 to
90cf85a
Compare
90cf85a to
1eac9ad
Compare
1eac9ad to
55ecc4b
Compare
8da1701 to
88f16d6
Compare
88f16d6 to
a785b3f
Compare
a785b3f to
7144ce0
Compare
7144ce0 to
9d4561e
Compare
9d4561e to
684c90d
Compare
684c90d to
c6d9283
Compare
c6d9283 to
9346fe4
Compare
9346fe4 to
e43fc39
Compare
e43fc39 to
28200b3
Compare
28200b3 to
7708ad7
Compare
7708ad7 to
30400a7
Compare
Summary
Completes the OGC-782 R11 Culture purpose slice on top of R10 PR #4116.
The implementation does not infer culture purpose from program names, specimen, organism, origin, or location.
Implementation
culture_purposeorder-detail column through Liquibase changeset088-microbiology-culture-purpose.xml, including rollback.Validation
core-appPlaywright journey passes locally and against the exact current PR head deployed at amr.openelis-global.org./and/Microbiology/worklist.UAT
Live Grist story
AMR-S32, R11 - Classify culture purpose and control WHONET populations, is published separately with six required steps in the AMR Review overlay. It uses service-created editable accessionUATMICROEDF2766FE0and final accessionUATMICRO584CA24AF3.The public checklist is available at uat-amr.json. Human Pass/Fail/N/A review remains pending; the roadmap therefore uses
[x], not the human-validated[✓].The official seeder update is in openelis-review-tooling PR #15.
Alignment And Evidence
OpenELIS Work requires explicit screening inclusion for M-09 but does not prescribe where classification is stored. The feature specification ruling is an explicit order-level Culture purpose.
Known Separate Issues