Skip to content

Commit

Permalink
Merge pull request #2235 from metriport/develop
Browse files Browse the repository at this point in the history
RELEASE 2167
  • Loading branch information
thomasyopes committed Jun 7, 2024
2 parents b5b5e0d + 9447620 commit bafe789
Show file tree
Hide file tree
Showing 72 changed files with 5,345 additions and 683 deletions.
39 changes: 20 additions & 19 deletions packages/api/src/command/medical/patient/create-patient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@ import {
PatientDemoData,
} from "@metriport/core/domain/patient";
import { uuidv7 } from "@metriport/core/util/uuid-v7";
import cqCommands from "../../../external/carequality";
import cwCommands from "../../../external/commonwell";
import { processAsyncError } from "@metriport/core/util/error/shared";
import { PatientModel } from "../../../models/medical/patient";
import { getFacilityOrFail } from "../facility/get-facility";
import { getCqOrgIdsToDenyOnCw } from "../../../external/hie/cross-hie-ids";
import { addCoordinatesToAddresses } from "./add-coordinates";
import { getPatientByDemo } from "./get-patient";
import { sanitize, validate } from "./shared";
import { runInitialPatientDiscoveryAcrossHies } from "../../../external/hie/run-initial-patient-discovery";

type Identifier = Pick<Patient, "cxId" | "externalId"> & { facilityId: string };
type PatientNoExternalData = Omit<PatientData, "externalData">;
export type PatientCreateCmd = PatientNoExternalData & Identifier;

export const createPatient = async (
patient: PatientCreateCmd,
forceCommonwell?: boolean,
forceCarequality?: boolean
): Promise<Patient> => {
export async function createPatient({
patient,
rerunPdOnNewDemographics,
forceCommonwell,
forceCarequality,
}: {
patient: PatientCreateCmd;
rerunPdOnNewDemographics?: boolean;
forceCommonwell?: boolean;
forceCarequality?: boolean;
}): Promise<Patient> {
const { cxId, facilityId, externalId } = patient;

const sanitized = sanitize(patient);
Expand All @@ -45,7 +50,6 @@ export const createPatient = async (
// validate facility exists and cx has access to it
await getFacilityOrFail({ cxId, id: facilityId });

const requestId = uuidv7();
const patientCreate: PatientCreate = {
id: uuidv7(),
cxId,
Expand All @@ -59,7 +63,6 @@ export const createPatient = async (
personalIdentifiers,
address,
contact,
patientDiscovery: { requestId, startedAt: new Date() },
},
};
const addressWithCoordinates = await addCoordinatesToAddresses({
Expand All @@ -71,15 +74,13 @@ export const createPatient = async (

const newPatient = await PatientModel.create(patientCreate);

await cwCommands.patient.create(
newPatient,
runInitialPatientDiscoveryAcrossHies({
patient: newPatient.dataValues,
facilityId,
getCqOrgIdsToDenyOnCw,
requestId,
forceCommonwell
);

await cqCommands.patient.discover(newPatient, facilityId, requestId, forceCarequality);
rerunPdOnNewDemographics,
forceCarequality,
forceCommonwell,
}).catch(processAsyncError("runInitialPatientDiscoveryAcrossHies"));

return newPatient;
};
}
47 changes: 21 additions & 26 deletions packages/api/src/command/medical/patient/update-patient.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { Patient, PatientData } from "@metriport/core/domain/patient";
import { toFHIR } from "@metriport/core/external/fhir/patient/index";
import { uuidv7 } from "@metriport/core/util/uuid-v7";
import { processAsyncError } from "@metriport/core/util/error/shared";
import { patientEvents } from "../../../event/medical/patient-event";
import cqCommands from "../../../external/carequality";
import cwCommands from "../../../external/commonwell";
import { upsertPatientToFHIRServer } from "../../../external/fhir/patient/upsert-patient";
import { PatientModel } from "../../../models/medical/patient";
import { executeOnDBTx } from "../../../models/transaction-wrapper";
import { validateVersionForUpdate } from "../../../models/_default";
import { BaseUpdateCmdWithCustomer } from "../base-update-command";
import { getFacilityOrFail } from "../facility/get-facility";
import { getCqOrgIdsToDenyOnCw } from "../../../external/hie/cross-hie-ids";
import { addCoordinatesToAddresses } from "./add-coordinates";
import { getPatientOrFail } from "./get-patient";
import { sanitize, validate } from "./shared";
import { runOrSchedulePatientDiscoveryAcrossHies } from "../../../external/hie/run-or-schedule-patient-discovery";

type PatientNoExternalData = Omit<PatientData, "externalData">;
export type PatientUpdateCmd = BaseUpdateCmdWithCustomer &
Expand All @@ -22,40 +20,38 @@ export type PatientUpdateCmd = BaseUpdateCmdWithCustomer &
// TODO build unit test to validate the patient is being sent correctly to Sequelize
// See: document-query.test.ts, "send a modified object to Sequelize"
// See: https://metriport.slack.com/archives/C04DMKE9DME/p1686779391180389
export async function updatePatient(
patientUpdate: PatientUpdateCmd,
export async function updatePatient({
patientUpdate,
rerunPdOnNewDemographics,
forceCommonwell,
forceCarequality,
emit = true,
}: {
patientUpdate: PatientUpdateCmd;
rerunPdOnNewDemographics?: boolean;
// START TODO #1572 - remove
forceCommonwell?: boolean,
forceCarequality?: boolean
forceCommonwell?: boolean;
forceCarequality?: boolean;
// END TODO #1572 - remove
): Promise<Patient> {
emit?: boolean;
}): Promise<Patient> {
const { cxId, facilityId } = patientUpdate;

// validate facility exists and cx has access to it
const facility = await getFacilityOrFail({ cxId, id: facilityId });

const requestId = uuidv7();
await getFacilityOrFail({ cxId, id: facilityId });

const patientUpdateWithPD: PatientUpdateCmd = {
...patientUpdate,
patientDiscovery: { requestId, startedAt: new Date() },
};

const patient = await updatePatientWithoutHIEs(patientUpdateWithPD, emit);
const patient = await updatePatientWithoutHIEs(patientUpdate, emit);

const fhirPatient = toFHIR(patient);
await upsertPatientToFHIRServer(patientUpdate.cxId, fhirPatient);

await cqCommands.patient.discover(patient, facility.id, requestId, forceCarequality);

await cwCommands.patient.update(
runOrSchedulePatientDiscoveryAcrossHies({
patient,
facilityId,
getCqOrgIdsToDenyOnCw,
requestId,
forceCommonwell
);
rerunPdOnNewDemographics,
forceCommonwell,
forceCarequality,
}).catch(processAsyncError("runOrSchedulePatientDiscoveryAcrossHies"));

return patient;
}
Expand Down Expand Up @@ -97,7 +93,6 @@ export async function updatePatientWithoutHIEs(
personalIdentifiers: sanitized.personalIdentifiers,
address: patientUpdate.address,
contact: sanitized.contact,
patientDiscovery: sanitized.patientDiscovery,
},
externalId: sanitized.externalId,
},
Expand Down
138 changes: 138 additions & 0 deletions packages/api/src/domain/medical/__tests__/demographics.const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { Patient, PatientDemoData } from "@metriport/core/domain/patient";
import { USState } from "@metriport/core/domain/geographic-locations";
import { LinkDemographics } from "@metriport/core/domain/patient-demographics";

export const coreDemographics: LinkDemographics = {
dob: "1900-02-28",
gender: "male",
names: [
{ firstName: "john", lastName: "smith" },
{ firstName: "johnathan", lastName: "smith" },
{ firstName: "john", lastName: "douglas" },
{ firstName: "johnathan", lastName: "douglas" },
].map(name => JSON.stringify(name, Object.keys(name).sort())),
addresses: [
{
line: ["1 mordhaus st", "apt 1a"],
city: "mordhaus",
state: "ny",
zip: "66666",
country: "usa",
},
{
line: ["777 elm ave"],
city: "los angeles",
state: "ca",
zip: "12345",
country: "usa",
},
].map(address => JSON.stringify(address, Object.keys(address).sort())),
telephoneNumbers: ["4150000000", "4157770000"],
emails: ["[email protected]", "[email protected]"],
driversLicenses: [{ value: "i1234568", state: "ca" }].map(dl =>
JSON.stringify(dl, Object.keys(dl).sort())
),
ssns: ["123014442"],
};
export const linkDemographics: LinkDemographics = {
dob: "1900-02-28",
gender: "male",
names: [
{ firstName: "john", lastName: "george" },
{ firstName: "johnathan", lastName: "george" },
].map(name => JSON.stringify(name, Object.keys(name).sort())),
addresses: [
{
line: ["88 75th st.", "apt 8"],
city: "ny",
state: "ny",
zip: "66622",
country: "usa",
},
].map(address => JSON.stringify(address, Object.keys(address).sort())),
telephoneNumbers: ["6194009999"],
emails: ["[email protected]"],
driversLicenses: [{ value: "ny1234", state: "ny" }].map(dl =>
JSON.stringify(dl, Object.keys(dl).sort())
),
ssns: ["123456789"],
};
export const consolidatedLinkDemographics = {
names: [
{ firstName: "john", lastName: "george" },
{ firstName: "johnathan", lastName: "george" },
].map(name => JSON.stringify(name, Object.keys(name).sort())),
addresses: [
{
line: ["88 75th st.", "apt 8"],
city: "ny",
state: "ny",
zip: "66622",
country: "usa",
},
].map(address => JSON.stringify(address, Object.keys(address).sort())),
telephoneNumbers: ["6194009999"],
emails: ["[email protected]"],
driversLicenses: [{ value: "ny1234", state: "ny" }].map(dl =>
JSON.stringify(dl, Object.keys(dl).sort())
),
ssns: ["123456789"],
};
export const patientDemo: PatientDemoData = {
dob: "1900-02-28",
genderAtBirth: "M",
lastName: "Smith, Douglas",
firstName: "John Johnathan",
address: [
{
zip: "66666",
city: "Mordhaus",
state: "NY" as USState,
country: "USA",
addressLine1: "1 Mordhaus ST",
addressLine2: "Apt 1A",
},
{
zip: "12345-8080",
city: "Los Angeles",
state: "CA" as USState,
addressLine1: "777 Elm Avenue ",
},
],
personalIdentifiers: [
{
type: "driversLicense",
value: "I1234568",
state: "CA" as USState,
},
{
type: "ssn",
value: "123-01-4442",
},
],
contact: [
{
phone: "1-415-000-0000",
email: "[email protected]",
},
{
phone: "415-777-0000",
},
{
email: "[email protected]",
phone: undefined,
},
],
};
export const patient: Patient = {
id: "",
cxId: "",
data: {
...patientDemo,
consolidatedLinkDemographics,
},
createdAt: new Date(),
updatedAt: new Date(),
facilityIds: [""],
eTag: "",
};
Loading

0 comments on commit bafe789

Please sign in to comment.