diff --git a/packages/commons/src/fhir/index.ts b/packages/commons/src/fhir/index.ts index e16846ad8ee..244eff546a9 100644 --- a/packages/commons/src/fhir/index.ts +++ b/packages/commons/src/fhir/index.ts @@ -20,7 +20,12 @@ import { SavedCompositionSection } from './composition' import { SavedTask, Task, TaskHistory } from './task' -import { Practitioner, SavedPractitioner } from './practitioner' +import { + Practitioner, + PractitionerRole, + PractitionerRoleHistory, + SavedPractitioner +} from './practitioner' import { Location, SavedLocation, Office, SavedOffice } from './location' export * from './practitioner' @@ -103,7 +108,7 @@ type SavedResource = T extends Encounter ? SavedRelatedPerson : T extends Composition ? SavedComposition - : T extends SavedCompositionHistory + : T extends CompositionHistory ? SavedCompositionHistory : T extends Reference ? SavedReference @@ -202,7 +207,7 @@ type SavedQuestionnaireResponse = Omit< status: 'completed' } -export type CompositionHistory = Saved & { +export type CompositionHistory = Omit, 'resourceType'> & { resourceType: 'CompositionHistory' } @@ -388,10 +393,12 @@ export function toHistoryResource>(resource: T) { return { ...resource, resourceType: `${resource.resourceType}History` - } as T extends Task + } as unknown as T extends Task ? TaskHistory : T extends Composition ? CompositionHistory + : T extends PractitionerRole + ? PractitionerRoleHistory : never } export { updateFHIRBundle, buildFHIRBundle } from './transformers' diff --git a/packages/commons/src/fhir/practitioner.ts b/packages/commons/src/fhir/practitioner.ts index 5d796aedfd9..3d5540fafc6 100644 --- a/packages/commons/src/fhir/practitioner.ts +++ b/packages/commons/src/fhir/practitioner.ts @@ -13,7 +13,8 @@ import { Resource, WithStrictExtensions, WithUUID, - SavedReference + SavedReference, + Saved } from '.' export type OpenCRVSPractitionerName = Omit & { @@ -23,7 +24,12 @@ export type OpenCRVSPractitionerName = Omit & { export type PractitionerRole = Omit & { location: [SavedReference] } -export type PractitionerRoleHistory = PractitionerRole +export type PractitionerRoleHistory = Omit< + Saved, + 'resourceType' +> & { + resourceType: 'PractitionerRoleHistory' +} export type Practitioner = WithStrictExtensions< Omit & { @@ -85,7 +91,7 @@ export function getPractitionerContactDetails(practitioner: Practitioner) { } export const getUserRoleFromHistory = ( - practitionerRoleHistory: PractitionerRoleHistory[], + practitionerRoleHistory: (PractitionerRole | PractitionerRoleHistory)[], lastModified: string ) => { const practitionerRoleHistorySorted = practitionerRoleHistory.sort((a, b) => { diff --git a/packages/workflow/src/features/user/utils.ts b/packages/workflow/src/features/user/utils.ts index 60f59e538e5..ba31af04a1b 100644 --- a/packages/workflow/src/features/user/utils.ts +++ b/packages/workflow/src/features/user/utils.ts @@ -15,8 +15,12 @@ import { getFromFhir } from '@workflow/features/registration/fhir/fhir-utils' import { Practitioner, PractitionerRole, + PractitionerRoleHistory, resourceIdentifierToUUID, - SavedPractitioner + Saved, + SavedBundle, + SavedPractitioner, + toHistoryResource } from '@opencrvs/commons/types' import { UUID } from '@opencrvs/commons' @@ -130,6 +134,22 @@ export const getPractitionerOfficeId = async (practitionerId: string) => { return resourceIdentifierToUUID(roleEntry.location[0].reference) } +export const getPractitionerRoleWithHistory = async ( + practitionerId: string +): Promise<(Saved | Saved)[]> => { + const roleBundle: SavedBundle = await getFromFhir( + `/PractitionerRole?practitioner=${practitionerId}` + ) + const role = roleBundle.entry[0].resource + const roleHistoryBundle: SavedBundle = await getFromFhir( + `/PractitionerRole/${role.id}/_history` + ) + const roleHistories = roleHistoryBundle.entry.map((e) => + toHistoryResource(e.resource) + ) + return [role, ...roleHistories] +} + export async function getLoggedInPractitionerResource( token: string ): Promise { diff --git a/packages/workflow/src/records/fhir.ts b/packages/workflow/src/records/fhir.ts index 21c65edb01c..c25a623f302 100644 --- a/packages/workflow/src/records/fhir.ts +++ b/packages/workflow/src/records/fhir.ts @@ -52,7 +52,10 @@ import { getResourceFromBundleById, TransactionResponse, TaskIdentifierSystem, - Location + Location, + Saved, + PractitionerRole, + PractitionerRoleHistory } from '@opencrvs/commons/types' import { FHIR_URL } from '@workflow/constants' import fetch from 'node-fetch' @@ -69,7 +72,8 @@ import { badRequest, internal } from '@hapi/boom' import { getUserOrSystem, isSystem } from './user' import { getLoggedInPractitionerResource, - getPractitionerOfficeId + getPractitionerOfficeId, + getPractitionerRoleWithHistory } from '@workflow/features/user/utils' import { z } from 'zod' import { fetchLocationHierarchy } from '@workflow/utils/location' @@ -93,7 +97,12 @@ function getFHIRValueField(value: unknown) { export async function mergeChangedResourcesIntoRecord( record: ValidRecord, unsavedChangedResources: Bundle, - practitionerResourcesBundle: SavedBundle + practitionerResourcesBundle: SavedBundle< + | SavedLocation + | SavedPractitioner + | Saved + | Saved + > ) { const responseBundle = await sendBundleToHearth(unsavedChangedResources) @@ -110,7 +119,17 @@ export async function mergeChangedResourcesIntoRecord( export async function withPractitionerDetails( task: T, token: string -): Promise<[T, SavedBundle]> { +): Promise< + [ + T, + SavedBundle< + | SavedLocation + | SavedPractitioner + | Saved + | Saved + > + ] +> { const userOrSystem = await getUserOrSystem(token) const newTask: T = { ...task, @@ -143,6 +162,9 @@ export async function withPractitionerDetails( } const user = userOrSystem const practitioner = await getLoggedInPractitionerResource(token) + const practitionerRoleHistory = await getPractitionerRoleWithHistory( + practitioner.id + ) const practitionerOfficeId = await getPractitionerOfficeId(practitioner.id) const hierarchy = await fetchLocationHierarchy(practitionerOfficeId) @@ -167,7 +189,7 @@ export async function withPractitionerDetails( { type: 'document', resourceType: 'Bundle', - entry: [practitioner, ...hierarchy].map((r) => + entry: [practitioner, ...hierarchy, ...practitionerRoleHistory].map((r) => resourceToSavedBundleEntry(r) ) } @@ -666,17 +688,17 @@ export function createCorrectedTask( export async function createViewTask( previousTask: SavedTask, token: string -): Promise { +): Promise<[SavedTask, Bundle]> { const taskWithoutPracitionerExtensions = createNewTaskResource(previousTask, [ { url: 'http://opencrvs.org/specs/extension/regViewed' } ]) - const [viewedTask] = await withPractitionerDetails( + const [viewedTask, bundle] = await withPractitionerDetails( taskWithoutPracitionerExtensions, token ) - return viewedTask + return [viewedTask, bundle] } export function createDownloadTask(previousTask: SavedTask) { diff --git a/packages/workflow/src/records/state-transitions.ts b/packages/workflow/src/records/state-transitions.ts index 3cef1a2e668..2cbee69b957 100644 --- a/packages/workflow/src/records/state-transitions.ts +++ b/packages/workflow/src/records/state-transitions.ts @@ -297,7 +297,10 @@ export async function toViewed( token: string ): Promise { const previousTask: SavedTask = getTaskFromSavedBundle(record) - const viewedTask = await createViewTask(previousTask, token) + const [viewedTask, bundleWithRelatedResources] = await createViewTask( + previousTask, + token + ) const taskHistoryEntry = resourceToBundleEntry( toHistoryResource(previousTask) @@ -322,7 +325,7 @@ export async function toViewed( ] } as T - return viewedRecord + return mergeBundles(viewedRecord, bundleWithRelatedResources) } export function toIdentifierUpserted(