Skip to content

Feat(admin): in house labs config#6777

Merged
alexwillingham merged 15 commits intorelease/1.31from
abraun/otr-2051-ehr-admin-in-house-labs-implementation
Apr 2, 2026
Merged

Feat(admin): in house labs config#6777
alexwillingham merged 15 commits intorelease/1.31from
abraun/otr-2051-ehr-admin-in-house-labs-implementation

Conversation

@abraun-ml
Copy link
Copy Markdown
Contributor

@abraun-ml abraun-ml commented Mar 30, 2026

Design doc: https://docs.google.com/document/d/1YAwU_-oHrvD8JXz3wY4SztofKbEqb-ZbsK7eYuygBBQ/edit?tab=t.0#heading=h.x6a041rpf36e

Sorry this is a monster. You can roughly review by commit to help break it up.

One thing to note for future improvements: there are types that are 85% the same between the form we render in house lab test results in and the admin meta forms. It was too much of an overhaul for this already very tiny PR, so there is some duplication in the meantime.

@abraun-ml abraun-ml force-pushed the abraun/otr-2051-ehr-admin-in-house-labs-implementation branch 2 times, most recently from ec6e03a to 160e05a Compare March 30, 2026 20:37
@abraun-ml abraun-ml marked this pull request as ready for review April 1, 2026 09:08
@abraun-ml abraun-ml requested a review from Copilot April 1, 2026 09:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This is a large feature PR implementing admin configuration management for in-house laboratory tests. It adds backend zambdas for CRUD operations on in-house lab test definitions, refactors type naming for clarity between data entry and admin contexts, and provides a comprehensive frontend admin UI for managing test configurations. The PR includes proper type definitions, validation schemas using Zod, conversion functions between ActivityDefinition (FHIR format) and AdminInHouseLabItemDefinition (admin format), test coverage, and supporting UI components.

Changes:

  • Added 4 new admin zambdas (list, add, get config, update) for managing in-house lab test definitions
  • Refactored type system: renamed TestItemDataEntryTestItem, TestItemComponentDataEntryComponent with specific subtypes
  • Implemented bidirectional conversion functions between ActivityDefinition and AdminInHouseLabItemDefinition formats
  • Created comprehensive admin UI with form components for test configuration, including CPT code selection, test components, and validation
  • Added Zod validation schema for admin input validation
  • Updated all references throughout codebase to use new renamed types
  • Added test data and unit tests for conversion functions

Reviewed changes

Copilot reviewed 48 out of 48 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/zambdas/test/unit/in-house-lab.test.ts Unit tests for bidirectional conversion between ActivityDefinition and AdminInHouseLabItemDefinition
packages/zambdas/test/data/in-house-lab-admin-test-config.ts Test data with 6 test configurations covering different component types and features
packages/zambdas/src/ehr/lab/shared/in-house-labs.ts Core conversion and helper functions for admin lab management
packages/zambdas/src/ehr/lab/in-house/admin-*/ Four new zambdas for admin operations (list, add, get config, update)
packages/utils/lib/types/data/in-house/ Type definitions and Zod schemas for admin in-house lab configuration
apps/ehr/src/features/visits/telemed/components/admin/in-house-labs/ Complete admin UI implementation with forms, lists, and detail pages
apps/ehr/src/api/api.ts API wrapper functions for the new admin zambdas
Various feature files Updated imports/types to use new DataEntryTestItem and DataEntryComponent names

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/zambdas/src/ehr/lab/in-house/admin-update-in-house-lab/index.ts Outdated
Comment thread packages/zambdas/src/ehr/lab/in-house/admin-list-in-house-labs/index.ts Outdated
Comment thread packages/zambdas/src/ehr/lab/in-house/admin-add-in-house-lab/index.ts Outdated
@abraun-ml abraun-ml requested a review from szaccagni April 1, 2026 09:38

return { ...radioResultMap, ...tableResultMap };
if (testDetails.labDetails.components.type !== 'empty') {
return testDetails.labDetails.components.components.reduce((acc: any, item) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can components just be an array of DataEntryComponent ? and we can just include the type on each DataEntryComponent?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Think my aversion here is mostly just naming though, components.components

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We caught up over huddle but just capturing here -- it was overly ambitious to attempt this refactor in this PR, so I am going to take all the comments about the data entry components and related and address them in a separate PR for better clarity


interface ResultEntryFreeTextProps {
testItemComponent: TestItemComponent;
testItemComponent: DataEntryComponent;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Probably makes sense to rename testItemComponent too so things are a little more clear.

Comment thread packages/zambdas/src/ehr/lab/in-house/admin-add-in-house-lab/index.ts Outdated
| {
type: 'empty';
components: undefined;
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe im just missing the need for it but i feel like this could be simplifier further by removing

{
   type: 'empty';
   components: undefined;
}

and mapping undefined to components if there are none (do we really have any tests where there actually are none?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I had a reason when I added this and now I don't remember why. But I will address this in the subsequent PR

Comment thread packages/utils/lib/types/data/in-house/in-house.constants.ts Outdated
Comment thread packages/utils/lib/types/data/in-house/in-house.constants.ts
Comment thread packages/utils/lib/types/data/in-house/in-house.schema.ts Outdated
Comment thread packages/utils/lib/types/data/in-house/in-house.schema.ts
.filter((roleId) => roleId !== undefined);
};

export const checkUserHasProvidedRoles = async (
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you want to do zambda-level role enforcement, then it should be done in roles.json. make some roles not have access to the zambda function, then give explicit access to the zambda function to the roles that should have the access.

Copy link
Copy Markdown
Contributor Author

@abraun-ml abraun-ml Apr 2, 2026

Choose a reason for hiding this comment

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

Per our convo I am going to take out all the places where I do this and let these zambdas be wild west perms wise for this PR, and then in a separate PR will implement the correct role validation through roles.json for these and the other zambdas

Comment thread packages/zambdas/src/ehr/lab/in-house/admin-update-in-house-lab/index.ts Outdated
Comment thread packages/zambdas/src/ehr/lab/in-house/admin-add-in-house-lab/index.ts Outdated
Comment thread apps/ehr/src/features/visits/telemed/components/admin/admin.queries.tsx Outdated
Comment thread apps/ehr/src/features/visits/telemed/components/admin/admin.queries.tsx Outdated
Copy link
Copy Markdown
Contributor

@alexwillingham alexwillingham left a comment

Choose a reason for hiding this comment

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

Looks generally very good. I left some notes. Re-request my review when you have responded / addressed them please and I will give the approval.

@abraun-ml abraun-ml force-pushed the abraun/otr-2051-ehr-admin-in-house-labs-implementation branch from b3099a8 to 03edcb9 Compare April 2, 2026 06:08
@abraun-ml abraun-ml changed the base branch from develop to release/1.31 April 2, 2026 06:08
@abraun-ml abraun-ml requested a review from Copilot April 2, 2026 06:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/zambdas/test/unit/in-house-lab.test.ts Outdated
Comment thread packages/zambdas/src/ehr/lab/shared/in-house-labs.ts Outdated
if (item.result?.entry) acc[item.observationDefinitionId] = item.result.entry;
return acc;
}, {});
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

When testDetails.labDetails.components.type === 'empty', the useMemo returns undefined implicitly. However, the old code would have returned an empty object {} when there were no radio or grouped components. This behavioral change could cause the form to fail to initialize correctly. The function should explicitly return {} when type is 'empty' to match the previous behavior.

Suggested change
}
}
return {};

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will handle in a separate PR

@abraun-ml
Copy link
Copy Markdown
Contributor Author

@alexwillingham the three commits after a9fb1ce "pr feedback" address the sorting bug you found, a tag bug I found, and an editing edge case to prevent editing old versions.

Regarding the IaC disabling bug you found (where the disabled IaC managed AD disappears from the list)

  • the list view filters out any retired AD's that are not latest (denoted by tag). This is by design.
  • none of the IaC managed AD's on any customer/env have that tag
  • rather than go through every customer env and add the tag manually to every AD, I chose to handle the edge case when we go to de-activate an AD that was IaC managed. I figured it was quicker and could serve any builder customers
  • I'm on the fence about whether that fix ^ this is actually better than updating secrets everywhere. Curious for your take

@abraun-ml abraun-ml requested a review from alexwillingham April 2, 2026 06:41
@alexwillingham
Copy link
Copy Markdown
Contributor

I'm on the fence about whether that fix ^ this is actually better than updating secrets everywhere. Curious for your take

i think this ok

@alexwillingham alexwillingham merged commit 79c727a into release/1.31 Apr 2, 2026
18 checks passed
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.

4 participants