Skip to content

feat(fhir): NASS-1868: Lab request rejected status#9128

Open
tcodling wants to merge 7 commits intomainfrom
cursor/NASS-1868-lab-request-rejected-status-94da
Open

feat(fhir): NASS-1868: Lab request rejected status#9128
tcodling wants to merge 7 commits intomainfrom
cursor/NASS-1868-lab-request-rejected-status-94da

Conversation

@tcodling
Copy link
Copy Markdown
Contributor

@tcodling tcodling commented Feb 8, 2026

Changes

This PR introduces a new REJECTED status for lab requests in Tamanu.

Previously, when a sample was rejected in SENAITE, the FHIR diagnostic report with cancelled status would map to CANCELLED in Tamanu. Now, this cancelled FHIR status will map to the new REJECTED status in Tamanu.

Key changes include:

  • Adding REJECTED to LAB_REQUEST_STATUSES with a red color.
  • Updating FhirDiagnosticReport to map FHIR cancelled status to Tamanu REJECTED.
  • Including REJECTED in the list of hidden statuses in the LabRequestView.
  • Preventing manual selection of REJECTED status in the LabRequestChangeStatusModal as it's an externally set status.
  • Updating relevant tests to reflect the new mapping.

Deploys

  • Deploy to Tamanu Internal

Tests

  • Run E2E Tests

Remember to...

  • ...write or update tests
  • ...add UI screenshots and testing notes to the Linear issue
  • ...add any manual upgrade steps to the Linear issue
  • ...update the config reference, settings reference, or any relevant runbook(s)
  • ...call out additions or changes to config files for the deployment team to take note of

Linear Issue: NASS-1868

Open in Cursor Open in Web


Note

Medium Risk
Introduces a new domain status and changes FHIR↔︎Tamanu status mapping, which can impact downstream workflows and UI filtering if any code paths still assume cancelled is the only terminal state. Coverage is improved via updated materialisation tests, reducing regression risk.

Overview
Introduces a new lab request terminal status REJECTED (label + red status config) alongside existing LAB_REQUEST_STATUSES.

FHIR materialisation logic now maps DiagnosticReport.status = cancelled to LAB_REQUEST_STATUSES.REJECTED (instead of CANCELLED), and REJECTED is treated as ServiceRequest.status = revoked when exposing lab requests as FHIR ServiceRequest.

Web UI updates hide REJECTED lab requests like other terminal states and prevents manually selecting REJECTED in the change-status modal (keeping it externally driven). Tests are updated to reflect the new mapping.

Written by Cursor Bugbot for commit 9ee475a. This will update automatically on new commits. Configure here.

When SENAITE rejects a sample, it sends a FHIR diagnostic report with
status 'cancelled'. This change introduces a new 'rejected' status to
distinguish rejected samples from cancelled ones.

Changes:
- Add REJECTED status constant to lab request statuses
- Map FHIR cancelled status to Tamanu rejected status
- Update UI to display and handle rejected status appropriately
- Update tests to expect rejected instead of cancelled
- Add rejected to hidden statuses and status change exclusions

Co-authored-by: Thomas Codling <tcodling@users.noreply.github.com>
@cursor
Copy link
Copy Markdown
Contributor

cursor Bot commented Feb 8, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @tcodling, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the lab request management system by introducing a distinct REJECTED status. This change improves the clarity and accuracy of tracking lab requests, particularly when samples are rejected in external systems like SENAITE. By mapping the FHIR cancelled status to this new REJECTED state, the system provides a more precise representation of a request's lifecycle, ensuring that users can differentiate between truly cancelled and explicitly rejected requests.

Highlights

  • New Lab Request Status: Introduced a new REJECTED status for lab requests in Tamanu, which is displayed with a red color.
  • FHIR Status Mapping Update: The FHIR diagnostic report cancelled status now maps to the new REJECTED status in Tamanu, instead of CANCELLED.
  • UI Visibility Control: The REJECTED status has been added to the list of hidden statuses in the LabRequestView, preventing it from being displayed by default.
  • Manual Status Selection Restriction: Manual selection of the REJECTED status is prevented in the LabRequestChangeStatusModal, as it is an externally set status.
  • Test Updates: Relevant tests have been updated to reflect the new mapping and status behavior.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • packages/central-server/tests/hl7fhir/materialised/DiagnosticReport.test.js
    • Updated test case to map FHIR CANCELLED status to LAB_REQUEST_STATUSES.REJECTED.
  • packages/constants/src/labs.ts
    • Added REJECTED to the LAB_REQUEST_STATUSES enum.
    • Defined Rejected as the label for the new status.
    • Assigned COLORS.red to the REJECTED status in LAB_REQUEST_STATUS_CONFIG.
  • packages/database/src/models/fhir/FhirDiagnosticReport.ts
    • Modified the getLabRequestStatus method to return LAB_REQUEST_STATUSES.REJECTED when the FHIR diagnostic report status is CANCELLED.
  • packages/web/app/views/patients/LabRequestView.jsx
    • Added LAB_REQUEST_STATUSES.REJECTED to the HIDDEN_STATUSES array.
  • packages/web/app/views/patients/components/LabRequestChangeStatusModal.jsx
    • Included LAB_REQUEST_STATUSES.REJECTED in the list of statuses that cannot be manually selected in the status change modal.
Activity
  • No human activity (comments, reviews, or progress updates) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly introduces a new REJECTED status for lab requests, mapping it from the FHIR cancelled status. The changes are consistently applied across constants, backend logic, UI components, and tests. The implementation is solid, but I have one minor suggestion to improve code maintainability in the LabRequestChangeStatusModal component.

@tcodling tcodling changed the title Lab request rejected status feat(fhir): NASS-1868: Lab request rejected status Feb 8, 2026
@tcodling tcodling marked this pull request as ready for review February 8, 2026 21:55
@tcodling
Copy link
Copy Markdown
Contributor Author

tcodling commented Feb 8, 2026

bugbot run

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 12, 2026

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 12, 2026

🍹 up on tamanu-on-k8s/bes/tamanu-on-k8s/cursor-nass-1868-lab-request-rejected-status-94da

Pulumi report
  Updating (cursor-nass-1868-lab-request-rejected-status-94da)

View Live: https://app.pulumi.com/bes/tamanu-on-k8s/cursor-nass-1868-lab-request-rejected-status-94da/updates/9

Downloading plugin random-4.19.0: starting
Downloading plugin random-4.19.0: done
Installing plugin random-4.19.0: starting
Installing plugin random-4.19.0: done

@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running 
@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read kubernetes:core/v1:Namespace tamanu-cursor-nass-1868-lab-request-rejected-status-94da
@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read pulumi:pulumi:StackReference bes/k8s-core/tamanu-internal-main
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Using tailscale proxy https://k8s-operator-tamanu-internal-main.tail53aef.ts.net
@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read pulumi:pulumi:StackReference bes/k8s-core/tamanu-internal-main
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read pulumi:pulumi:StackReference bes/core/tamanu-internal
@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read pulumi:pulumi:StackReference bes/core/tamanu-internal
@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read kubernetes:core/v1:Namespace tamanu-cursor-nass-1868-lab-request-rejected-status-94da
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Waiting for central-db...
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Waiting for facility-1-db...
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Waiting for facility-2-db...
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read kubernetes:core/v1:ConfigMap actual-provisioning
@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running read kubernetes:core/v1:ConfigMap actual-provisioning
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Secret facility-1-db-superuser not found or not ready: Error: HTTP-Code: 404
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Message: Unknown API Status Code!
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Body: "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"secrets \\\"facility-1-db-superuser\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"facility-1-db-superuser\",\"kind\":\"secrets\"},\"code\":404}
"
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Headers: {"audit-id":"316b6da8-f29c-4b39-9ed6-e28646143d84","cache-control":"no-cache, private","connection":"close","content-length":"220","content-type":"application/json","date":"Fri, 06 Mar 2026 02:44:00 GMT","x-kubernetes-pf-flowschema-uid":"3fb296fc-e46b-45d1-9306-057e37ddd229","x-kubernetes-pf-prioritylevel-uid":"feccf24d-a074-4fa8-aa6f-db82477fc2f5"}
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Secret facility-2-db-superuser not found or not ready: Error: HTTP-Code: 404
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Message: Unknown API Status Code!
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Body: "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"secrets \\\"facility-2-db-superuser\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"facility-2-db-superuser\",\"kind\":\"secrets\"},\"code\":404}
"
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Headers: {"audit-id":"9b6b68a6-3be1-4a64-9ebb-d99e4af9918d","cache-control":"no-cache, private","connection":"close","content-length":"220","content-type":"application/json","date":"Fri, 06 Mar 2026 02:44:00 GMT","x-kubernetes-pf-flowschema-uid":"3fb296fc-e46b-45d1-9306-057e37ddd229","x-kubernetes-pf-prioritylevel-uid":"feccf24d-a074-4fa8-aa6f-db82477fc2f5"}
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Secret central-db-superuser not found or not ready: Error: HTTP-Code: 404
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Message: Unknown API Status Code!
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Body: "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"secrets \\\"central-db-superuser\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"central-db-superuser\",\"kind\":\"secrets\"},\"code\":404}
"
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da running Headers: {"audit-id":"f3cbf437-3529-4a49-aa30-a9b29e900a4f","cache-control":"no-cache, private","connection":"close","content-length":"214","content-type":"application/json","date":"Fri, 06 Mar 2026 02:44:00 GMT","x-kubernetes-pf-flowschema-uid":"3fb296fc-e46b-45d1-9306-057e37ddd229","x-kubernetes-pf-prioritylevel-uid":"feccf24d-a074-4fa8-aa6f-db82477fc2f5"}
@ Updating....
  pulumi:pulumi:Stack tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da  16 messages
Diagnostics:
pulumi:pulumi:Stack (tamanu-on-k8s-cursor-nass-1868-lab-request-rejected-status-94da):
  Secret facility-1-db-superuser not found or not ready: Error: HTTP-Code: 404
  Message: Unknown API Status Code!
  Body: "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"secrets \\\"facility-1-db-superuser\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"facility-1-db-superuser\",\"kind\":\"secrets\"},\"code\":404}
"
  Headers: {"audit-id":"316b6da8-f29c-4b39-9ed6-e28646143d84","cache-control":"no-cache, private","connection":"close","content-length":"220","content-type":"application/json","date":"Fri, 06 Mar 2026 02:44:00 GMT","x-kubernetes-pf-flowschema-uid":"3fb296fc-e46b-45d1-9306-057e37ddd229","x-kubernetes-pf-prioritylevel-uid":"feccf24d-a074-4fa8-aa6f-db82477fc2f5"}
  Secret facility-2-db-superuser not found or not ready: Error: HTTP-Code: 404
  Message: Unknown API Status Code!
  Body: "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"secrets \\\"facility-2-db-superuser\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"facility-2-db-superuser\",\"kind\":\"secrets\"},\"code\":404}
"
  Headers: {"audit-id":"9b6b68a6-3be1-4a64-9ebb-d99e4af9918d","cache-control":"no-cache, private","connection":"close","content-length":"220","content-type":"application/json","date":"Fri, 06 Mar 2026 02:44:00 GMT","x-kubernetes-pf-flowschema-uid":"3fb296fc-e46b-45d1-9306-057e37ddd229","x-kubernetes-pf-prioritylevel-uid":"feccf24d-a074-4fa8-aa6f-db82477fc2f5"}
  Secret central-db-superuser not found or not ready: Error: HTTP-Code: 404
  Message: Unknown API Status Code!
  Body: "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"secrets \\\"central-db-superuser\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"central-db-superuser\",\"kind\":\"secrets\"},\"code\":404}
"
  Headers: {"audit-id":"f3cbf437-3529-4a49-aa30-a9b29e900a4f","cache-control":"no-cache, private","connection":"close","content-length":"214","content-type":"application/json","date":"Fri, 06 Mar 2026 02:44:00 GMT","x-kubernetes-pf-flowschema-uid":"3fb296fc-e46b-45d1-9306-057e37ddd229","x-kubernetes-pf-prioritylevel-uid":"feccf24d-a074-4fa8-aa6f-db82477fc2f5"}

  Waiting for central-db...
  Waiting for facility-1-db...
  Waiting for facility-2-db...

  Using tailscale proxy https://k8s-operator-tamanu-internal-main.tail53aef.ts.net

  [Pulumi Neo] Would you like help with these diagnostics?
  https://app.pulumi.com/bes/tamanu-on-k8s/cursor-nass-1868-lab-request-rejected-status-94da/updates/9?explainFailure

Outputs:
  urls: {
      Central      : "https://central.cursor-nass-1868-lab-request-rejected-status-94da.cd.tamanu.app"
      Facility- 1  : "https://facility-1.cursor-nass-1868-lab-request-rejected-status-94da.cd.tamanu.app"
      Facility- 2  : "https://facility-2.cursor-nass-1868-lab-request-rejected-status-94da.cd.tamanu.app"
      PatientPortal: "https://portal.cursor-nass-1868-lab-request-rejected-status-94da.cd.tamanu.app"
  }

Resources:
  67 unchanged

Duration: 8s

  

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: New REJECTED status missing from FHIR ServiceRequest mapping
    • Added REJECTED status case to statusFromLabRequest function to map it to FHIR_REQUEST_STATUS.REVOKED alongside other revoked statuses.

Create PR

Or push these changes by commenting:

@cursor push c1e88aa7e4
Preview (c1e88aa7e4)
diff --git a/packages/database/src/utils/fhir/ServiceRequest/getValues.ts b/packages/database/src/utils/fhir/ServiceRequest/getValues.ts
--- a/packages/database/src/utils/fhir/ServiceRequest/getValues.ts
+++ b/packages/database/src/utils/fhir/ServiceRequest/getValues.ts
@@ -238,6 +238,7 @@
     case LAB_REQUEST_STATUSES.PUBLISHED:
       return FHIR_REQUEST_STATUS.COMPLETED;
     case LAB_REQUEST_STATUSES.CANCELLED:
+    case LAB_REQUEST_STATUSES.REJECTED:
     case LAB_REQUEST_STATUSES.INVALIDATED:
     case LAB_REQUEST_STATUSES.DELETED:
       return FHIR_REQUEST_STATUS.REVOKED;

Comment thread packages/constants/src/labs.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants