diff --git a/client/src/components/records.tsx b/client/src/components/records.tsx index 23a4ad5..bcf6444 100644 --- a/client/src/components/records.tsx +++ b/client/src/components/records.tsx @@ -8,13 +8,42 @@ export type EOBRecord = { amount: number } +export type DiagnosisRecord = { + id: string, + sequence: string, + diagnosisCode: string, + diagnosisDisplay: string, + typeCode: string, + typeDisplay: string +} + +export type PatientRecord = { + id: string, + name: string, + gender: string, + dateOfBirth: string, + addressState: string, + addressZip: string +} + +export type CoverageRecord = { + id: string, + subscriberId: string, + status: string, + beneRef: string, + payor: string +} + export type ErrorResponse = { type: string, content: string, } export default function Records() { - const [records, setRecords] = useState([]); + const [eobs, setRecords] = useState([]); + const [diagnosis, setDiagnosis] = useState([]); + const [patients, setPatients] = useState([]); + const [coverages, setCoverages] = useState([]); const [message, setMessage] = useState(); /* * DEVELOPER NOTES: @@ -33,12 +62,12 @@ export default function Records() { * Carrier Claims, SNF, HHA, Hospice, Inpatient, and Outpatient */ useEffect(() => { - fetch('/api/data/benefit') + fetch('/api/data/beneficiary_data') .then(res => { return res.json(); - }).then(eobData => { - if (eobData.entry) { - const records: EOBRecord[] = eobData.entry.map((resourceData: any) => { + }).then(beneData => { + if (beneData.eobData && beneData.eobData.entry) { + const records: EOBRecord[] = beneData.eobData.entry.map((resourceData: any) => { const resource = resourceData.resource; return { id: resource.id, @@ -47,12 +76,73 @@ export default function Records() { amount: resource.item[0]?.adjudication[7]?.amount?.value || '0' } }); + setRecords(records); + + const diagnosisRecords: DiagnosisRecord[] = beneData.eobData.entry.filter((resourceData: any) => { + const resource = resourceData.resource; + if (resource.diagnosis) { + return true; + } + else { + return false; + } + }).map((resourceData: any) => { + const resource = resourceData.resource; + return { + id: resource.id, + sequence: resource?.diagnosis[0]?.sequence || 'Unknown', + diagnosisCode: resource?.diagnosis[0]?.diagnosisCodeableConcept?.coding[0]?.code || 'Unknown', + diagnosisDisplay: resource?.diagnosis[0]?.diagnosisCodeableConcept?.coding[0]?.display || 'Unknown', + typeCode: resource?.diagnosis[0]?.type[0]?.coding[0]?.code || 'Unknown', + typeDisplay: resource?.diagnosis[0]?.type[0]?.coding[0]?.display || 'Unknown', + } + }); + setDiagnosis(diagnosisRecords); } - else { - if (eobData.message) { - setMessage({"type": "error", "content": eobData.message || "Unknown"}) - } + + if (beneData.patient && beneData.patient.entry) { + const records: PatientRecord[] = beneData.patient.entry.map((resourceData: any) => { + const resource = resourceData.resource; + return { + id: resource.id, + name: resource?.name[0]?.family || 'Unknown', + gender: resource?.gender || 'Unknown Gender', + dateOfBirth: resource?.birthDate || 'Unknown DOB', + addressState: resource?.address[0]?.state || 'Unknown State', + addressZip: resource?.address[0]?.postalCode || 'Unknown ZIP', + } + }); + setPatients(records); + } + + if (beneData.coverage && beneData.coverage.entry) { + const records: CoverageRecord[] = beneData.coverage.entry.map((resourceData: any) => { + const resource = resourceData.resource; + if (resource.payor) { + return { + id: resource.id, + subscriberId: resource?.subscriberId || 'Unknown', + status: resource?.status || 'Unknown Status', + beneRef: resource?.beneficiary?.reference || 'Unknown Beneficiary', + payor: resource?.payor[0]?.identifier?.value || 'Unknown Payor', + } + } + else { + return { + id: resource.id, + subscriberId: resource?.subscriberId || 'Undefined', + status: resource?.status || 'Undefined', + beneRef: resource?.beneficiary?.reference || 'Undefined', + payor: 'Undefined', + } + } + }); + setCoverages(records); + } + + if (beneData.eobData && beneData.eobData.message) { + setMessage({"type": "error", "content": beneData.eobData.message || "Unknown"}) } }); }, []) @@ -83,20 +173,103 @@ export default function Records() { ); } else { return ( +
+
+ + Medicare Patient Info + + + ID + Name + Gender + Birth Date + Address State + Address ZIP + + + + {patients.map(record => { + return ( + + + {record.id} + + + {record.name} + + + {record.gender} + + + {record.dateOfBirth} + + + {record.addressState} + + + {record.addressZip} + + + ) + })} + +
+
+
+ + Medicare Coverage Info + + + ID + Subscriber ID + Status + Beneficiary Reference + Payor + + + + {coverages.map(record => { + return ( + + + {record.id} + + + {record.subscriberId} + + + {record.status} + + + {record.beneRef} + + + {record.payor} + + + ) + })} + +
+
Medicare Prescription Drug Claims Data + ID NDC Code Prescription Drug Name Cost - {records.map(record => { + {eobs.map(record => { return ( + + {record.id} + {record.code} @@ -112,6 +285,48 @@ export default function Records() {
- ); +
+ + Medicare Diagnosis Data + + + ID + Sequence + Code + Name + Type Code + Type Name + + + + {diagnosis.map(record => { + return ( + + + {record.id} + + + {record.sequence} + + + {record.diagnosisCode} + + + {record.diagnosisDisplay} + + + {record.typeCode} + + + {record.typeDisplay} + + + ) + })} + +
+
+
+ ); } }; \ No newline at end of file diff --git a/server/Dockerfile b/server/Dockerfile index ab15b2d..da25f04 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -14,4 +14,4 @@ RUN yarn install EXPOSE 3001 -CMD ["yarn","start:dev"] \ No newline at end of file +CMD ["yarn","start:debug"] \ No newline at end of file diff --git a/server/src/routes/Authorize.ts b/server/src/routes/Authorize.ts index dd86112..0caa9ca 100644 --- a/server/src/routes/Authorize.ts +++ b/server/src/routes/Authorize.ts @@ -3,7 +3,7 @@ import AuthorizationToken from '../entities/AuthorizationToken'; import Settings from '../entities/Settings'; import db from '../utils/db'; import { getAccessToken, generateAuthorizeUrl } from '../utils/bb2'; -import { getBenefitData } from './Data'; +import { getExplanationOfBenefitData, getPatientJSON, getCoverageJSON } from './Data'; import logger from '@shared/Logger'; import { clearBB2Data, getLoggedInUser } from 'src/utils/user'; @@ -56,12 +56,15 @@ export async function authorizationCallback(req: Request, res: Response) { * You could also request data for the Patient endpoint and/or the Coverage endpoint here * using similar functionality */ - const eobData = await getBenefitData( req, res); - loggedInUser.eobData = eobData; + loggedInUser.eobData = await getExplanationOfBenefitData( req, res); + loggedInUser.patient = await getPatientJSON( req, res); + loggedInUser.coverage = await getCoverageJSON( req, res); } else { // send generic error message to FE loggedInUser.eobData = JSON.parse('{"message": "Unable to load EOB Data - authorization failed."}'); + loggedInUser.patient = JSON.parse('{"message": "Unable to load Patient Data - authorization failed."}'); + loggedInUser.coverage = JSON.parse('{"message": "Unable to load Coverage Data - authorization failed."}'); } } catch (e) { diff --git a/server/src/routes/Data.ts b/server/src/routes/Data.ts index c713c4d..595c54b 100644 --- a/server/src/routes/Data.ts +++ b/server/src/routes/Data.ts @@ -14,7 +14,7 @@ import { refreshAccessToken } from 'src/utils/bb2'; // this function is used to query eob data for the authenticated Medicare.gov // user and returned - we are then storing in a mocked DB -export async function getBenefitData(req: Request, res: Response) { +export async function getExplanationOfBenefitData(req: Request, res: Response) { const loggedInUser = getLoggedInUser(db); const envConfig = config[db.settings.env]; const BB2_BENEFIT_URL = envConfig.bb2BaseUrl + '/' + db.settings.version + '/fhir/ExplanationOfBenefit/'; @@ -49,28 +49,44 @@ export async function getBenefitData(req: Request, res: Response) { * This would be replaced by a persistence service layer for whatever * DB you would choose to use */ -export async function getBenefitDataEndPoint(req: Request, res: Response) { +export async function getBeneficiaryDataEndPoint(req: Request, res: Response) { const loggedInUser = getLoggedInUser(db); - const data = loggedInUser.eobData; - if ( data ) { - res.json(data) + const beneData = {'eobData': loggedInUser.eobData, 'patient': loggedInUser.patient, 'coverage': loggedInUser.coverage}; + if ( beneData ) { + res.json(beneData); } } export async function getPatientData(req: Request, res: Response) { + // const loggedInUser = getLoggedInUser(db); + // const envConfig = config[db.settings.env]; + // get Patient end point + const data = await getPatientJSON(req, res); + res.json(data); +} + +export async function getPatientJSON(req: Request, res: Response) { const loggedInUser = getLoggedInUser(db); const envConfig = config[db.settings.env]; // get Patient end point const response = await get(`${envConfig.bb2BaseUrl}/${db.settings.version}/fhir/Patient/`, req.query, `${loggedInUser.authToken?.access_token}`); - res.json(response.data); + return response.data; } export async function getCoverageData(req: Request, res: Response) { + // const loggedInUser = getLoggedInUser(db); + // const envConfig = config[db.settings.env]; + // get Coverage end point + const data = await getCoverageJSON(req, res); + res.json(data); +} + +export async function getCoverageJSON(req: Request, res: Response) { const loggedInUser = getLoggedInUser(db); const envConfig = config[db.settings.env]; // get Coverage end point const response = await get(`${envConfig.bb2BaseUrl}/${db.settings.version}/fhir/Coverage/`, req.query, `${loggedInUser.authToken?.access_token}`); - res.json(response.data); + return response.data; } export async function getUserProfileData(req: Request, res: Response) { @@ -83,7 +99,8 @@ export async function getUserProfileData(req: Request, res: Response) { const router = Router(); -router.get('/benefit', getBenefitDataEndPoint); +router.get('/beneficiary_data', getBeneficiaryDataEndPoint); +router.get('/eob', getExplanationOfBenefitData); router.get('/patient', getPatientData); router.get('/coverage', getCoverageData); router.get('/userprofile', getUserProfileData); diff --git a/server/src/utils/db.ts b/server/src/utils/db.ts index 1f78ea5..734937a 100644 --- a/server/src/utils/db.ts +++ b/server/src/utils/db.ts @@ -17,6 +17,8 @@ export interface User { authToken?: AuthorizationToken, userInfo: UserInfo, eobData?: any, + patient?: any, + coverage?: any, errors: string[] } export interface DB { diff --git a/server/src/utils/request.ts b/server/src/utils/request.ts old mode 100644 new mode 100755 diff --git a/server/src/utils/user.ts b/server/src/utils/user.ts index 324431b..2cd9c8e 100644 --- a/server/src/utils/user.ts +++ b/server/src/utils/user.ts @@ -14,4 +14,6 @@ export function getLoggedInUser(db : DB) { export function clearBB2Data(user: User) { user.authToken = undefined; user.eobData = undefined; + user.patient = undefined; + user.coverage = undefined; } \ No newline at end of file