Skip to content

Commit

Permalink
Merge branch 'main' into 111-date-last-modified-field-is-empty
Browse files Browse the repository at this point in the history
  • Loading branch information
stanislaw-zakrzewski committed Jan 13, 2025
2 parents dc06def + 4fb80a3 commit 6ca98a6
Show file tree
Hide file tree
Showing 29 changed files with 374 additions and 231 deletions.
33 changes: 13 additions & 20 deletions data-serving/data-service/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,9 @@ paths:
$ref: '#/components/responses/500'
components:
schemas:
YesNo:
type: string
enum: ['Y', 'N', '']
BatchUpdateResponse:
description: Response to batch update cases API requests
properties:
Expand Down Expand Up @@ -766,8 +769,7 @@ components:
occupation:
type: string
healthcareWorker:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
location:
$ref: '#/components/schemas/Location'
events:
Expand All @@ -788,8 +790,7 @@ components:
dateOfFirstConsult:
$ref: '#/components/schemas/Date'
hospitalized:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
reasonForHospitalization:
type: string
enum: [monitoring, treatment, unknown]
Expand All @@ -798,18 +799,15 @@ components:
dateDischargeHospital:
$ref: '#/components/schemas/Date'
intensiveCare:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
dateAdmissionICU:
$ref: '#/components/schemas/Date'
dateDischargeICU:
$ref: '#/components/schemas/Date'
homeMonitoring:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
isolated:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
dateIsolation:
$ref: '#/components/schemas/Date'
outcome:
Expand All @@ -825,21 +823,18 @@ components:
type: object
properties:
previousInfection:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
coInfection:
type: string
preexistingCondition:
type: string
pregnancyStatus:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
transmission:
type: object
properties:
contactWithCase:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
contactId:
type: string
contactSetting:
Expand All @@ -854,8 +849,7 @@ components:
type: object
properties:
travelHistory:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
travelHistoryEntry:
$ref: '#/components/schemas/Date'
travelHistoryStart:
Expand All @@ -875,8 +869,7 @@ components:
type: object
properties:
vaccination:
type: string
enum: ['Y', 'N', 'NA']
$ref: '#/components/schemas/YesNo'
vaccineName:
type: string
vaccineDate:
Expand Down
8 changes: 8 additions & 0 deletions data-serving/data-service/src/controllers/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,14 @@ export class CasesController {
header: false,
columns: this.csvHeaders,
delimiter: delimiter,
cast: {
date: (value: Date) => {
if (value) {
return new Date(value).toISOString().split('T')[0];
}
return value;
},
}
});
res.write(stringifiedCase);
doc = await cursor.next();
Expand Down
2 changes: 1 addition & 1 deletion data-serving/data-service/src/types/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export enum CaseStatus {
export enum YesNo {
Y = 'Y',
N = 'N',
NA = 'NA',
None = '',
}

export enum Role {
Expand Down
65 changes: 39 additions & 26 deletions data-serving/data-service/src/util/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ export const removeBlankHeader = (headers: string[]): string[] => {
return headers;
};

export const formatDateWithoutTime = (date: Date | undefined): string => {
if (!date) return '';
return date.toISOString().split('T')[0];
};

export const denormalizeFields = async (
doc: CaseDocument,
): Promise<Partial<CaseDocument>> => {
Expand Down Expand Up @@ -178,9 +183,8 @@ function denormalizeCaseReferenceFields(
additionalSources.push(source.sourceUrl);
}
}
denormalizedData[
'caseReference.additionalSources'
] = additionalSources.join(',');
denormalizedData['caseReference.additionalSources'] =
additionalSources.join(',');
denormalizedData['caseReference.sourceEntryId'] = doc.sourceEntryId || '';
denormalizedData['caseReference.sourceId'] = doc.sourceId || '';
denormalizedData['caseReference.sourceUrl'] = doc.sourceUrl || '';
Expand Down Expand Up @@ -211,38 +215,46 @@ export const denormalizeEventsFields = (
const denormalizedData: Record<string, string> = {};

denormalizedData['events.dateEntry'] = doc.dateEntry
? doc.dateEntry.toDateString()
? formatDateWithoutTime(doc.dateEntry)
: undefined || '';
denormalizedData['events.dateReported'] = doc.dateReported
? doc.dateReported.toDateString()
? formatDateWithoutTime(doc.dateReported)
: undefined || '';
denormalizedData['events.dateOnset'] = doc.dateOnset?.toDateString() || '';
denormalizedData['events.dateConfirmation'] =
doc.dateConfirmation?.toDateString() || '';
denormalizedData['events.dateOnset'] = formatDateWithoutTime(doc.dateOnset);
denormalizedData['events.dateConfirmation'] = formatDateWithoutTime(
doc.dateConfirmation,
);
denormalizedData['events.confirmationMethod'] =
doc.confirmationMethod || '';
denormalizedData['events.dateOfFirstConsult'] =
doc.dateOfFirstConsult?.toDateString() || '';
denormalizedData['events.dateOfFirstConsult'] = formatDateWithoutTime(
doc.dateOfFirstConsult,
);
denormalizedData['events.hospitalized'] = doc.hospitalized || '';
denormalizedData['events.reasonForHospitalization'] =
doc.reasonForHospitalization || '';
denormalizedData['events.dateHospitalization'] =
doc.dateHospitalization?.toDateString() || '';
denormalizedData['events.dateDischargeHospital'] =
doc.dateDischargeHospital?.toDateString() || '';
denormalizedData['events.dateHospitalization'] = formatDateWithoutTime(
doc.dateHospitalization,
);
denormalizedData['events.dateDischargeHospital'] = formatDateWithoutTime(
doc.dateDischargeHospital,
);
denormalizedData['events.intensiveCare'] = doc.intensiveCare || '';
denormalizedData['events.dateAdmissionICU'] =
doc.dateAdmissionICU?.toDateString() || '';
denormalizedData['events.dateDischargeICU'] =
doc.dateDischargeICU?.toDateString() || '';
denormalizedData['events.dateAdmissionICU'] = formatDateWithoutTime(
doc.dateAdmissionICU,
);
denormalizedData['events.dateDischargeICU'] = formatDateWithoutTime(
doc.dateDischargeICU,
);
denormalizedData['events.homeMonitoring'] = doc.homeMonitoring || '';
denormalizedData['events.isolated'] = doc.isolated || '';
denormalizedData['events.dateIsolation'] =
doc.dateIsolation?.toDateString() || '';
denormalizedData['events.dateIsolation'] = formatDateWithoutTime(
doc.dateIsolation,
);
denormalizedData['events.outcome'] = doc.outcome || '';
denormalizedData['events.dateDeath'] = doc.dateDeath?.toDateString() || '';
denormalizedData['events.dateRecovered'] =
doc.dateRecovered?.toDateString() || '';
denormalizedData['events.dateDeath'] = formatDateWithoutTime(doc.dateDeath);
denormalizedData['events.dateRecovered'] = formatDateWithoutTime(
doc.dateRecovered,
);

return denormalizedData;
};
Expand Down Expand Up @@ -334,7 +346,7 @@ function denormalizeTravelHistoryFields(

denormalizedData['travelHistory.travelHistory'] = doc?.travelHistory || '';
denormalizedData['travelHistory.travelHistoryEntry'] =
doc?.travelHistoryEntry?.toDateString() || '';
formatDateWithoutTime(doc?.travelHistoryEntry);
denormalizedData['travelHistory.travelHistoryStart'] =
doc?.travelHistoryStart || '';
denormalizedData['travelHistory.travelHistoryLocation'] =
Expand All @@ -352,8 +364,9 @@ function denormalizeVaccineFields(

denormalizedData['vaccination.vaccination'] = doc?.vaccination || '';
denormalizedData['vaccination.vaccineName'] = doc?.vaccineName || '';
denormalizedData['vaccination.vaccineDate'] =
doc?.vaccineDate?.toDateString() || '';
denormalizedData['vaccination.vaccineDate'] = formatDateWithoutTime(
doc?.vaccineDate,
);
denormalizedData['vaccination.vaccineSideEffects'] =
doc?.vaccineSideEffects || '';

Expand Down
52 changes: 33 additions & 19 deletions data-serving/data-service/test/util/case.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ import { RevisionMetadataDocument } from '../model/revision-metadata';
import { TransmissionDocument } from '../model/transmission';
import { TravelHistoryDocument } from '../model/travel-history';
import { VaccineDocument } from '../model/vaccine';
import { removeBlankHeader, denormalizeFields } from '../../src/util/case';
import {
removeBlankHeader,
denormalizeFields,
formatDateWithoutTime,
} from '../../src/util/case';
import mongoose from 'mongoose';
import { MongoMemoryServer } from 'mongodb-memory-server';
import { GenomeSequenceDocument } from '../../src/model/genome-sequence';
import { EventsDocument } from '../../src/model/events';
import { YesNo } from '../../src/types/enums';

let mongoServer: MongoMemoryServer;

Expand Down Expand Up @@ -364,7 +369,7 @@ describe('Case', () => {
ageBuckets: [anAgeBucket._id],
gender: 'male',
occupation: 'Anesthesiologist',
healthcareWorker: 'Y',
healthcareWorker: YesNo.Y,
} as DemographicsDocument;

const caseDoc = {
Expand All @@ -391,7 +396,7 @@ describe('Case', () => {
expect(denormalizedCase['demographics.occupation']).toEqual(
'Anesthesiologist',
);
expect(denormalizedCase['demographics.healthcareWorker']).toEqual('Y');
expect(denormalizedCase['demographics.healthcareWorker']).toEqual(YesNo.Y);
});
it('denormalizes events fields', async () => {
const eventsDoc = {
Expand Down Expand Up @@ -421,16 +426,16 @@ describe('Case', () => {
const denormalizedCase = await denormalizeFields(caseDoc);

expect(denormalizedCase['events.dateEntry']).toEqual(
eventsDoc.dateEntry.toDateString(),
formatDateWithoutTime(eventsDoc.dateEntry),
);
expect(denormalizedCase['events.dateReported']).toEqual(
eventsDoc.dateReported.toDateString(),
formatDateWithoutTime(eventsDoc.dateReported),
);
expect(denormalizedCase['events.dateOnset']).toEqual(
eventsDoc.dateOnset?.toDateString(),
formatDateWithoutTime(eventsDoc.dateOnset),
);
expect(denormalizedCase['events.dateConfirmation']).toEqual(
eventsDoc.dateConfirmation?.toDateString(),
formatDateWithoutTime(eventsDoc.dateConfirmation),
);
expect(denormalizedCase['events.confirmationMethod']).toEqual('');
expect(denormalizedCase['events.dateOfFirstConsult']).toEqual('');
Expand Down Expand Up @@ -503,10 +508,10 @@ describe('Case', () => {
});
it('denormalizes preexisting conditions fields', async () => {
const conditionsDoc = {
previousInfection: 'Y',
previousInfection: YesNo.Y,
coInfection: 'Flu',
preexistingCondition: '',
pregnancyStatus: 'NA',
pregnancyStatus: YesNo.None,
} as PreexistingConditionsDocument;

const caseDoc = {
Expand All @@ -529,7 +534,7 @@ describe('Case', () => {
const denormalizedCase = await denormalizeFields(caseDoc);
expect(
denormalizedCase['preexistingConditions.previousInfection'],
).toEqual('Y');
).toEqual(YesNo.Y);
expect(denormalizedCase['preexistingConditions.coInfection']).toEqual(
'Flu',
);
Expand All @@ -538,11 +543,11 @@ describe('Case', () => {
).toEqual('');
expect(
denormalizedCase['preexistingConditions.pregnancyStatus'],
).toEqual('NA');
).toEqual(YesNo.None);
});
it('denormalizes transmission fields', async () => {
const transmissionDoc = {
contactWithCase: 'Y',
contactWithCase: YesNo.Y,
contactId: 'abc123',
contactSetting: 'setting',
contactAnimal: 'animal',
Expand All @@ -568,7 +573,7 @@ describe('Case', () => {

const denormalizedCase = await denormalizeFields(caseDoc);

expect(denormalizedCase['transmission.contactWithCase']).toEqual('Y');
expect(denormalizedCase['transmission.contactWithCase']).toEqual(YesNo.Y);
expect(denormalizedCase['transmission.contactId']).toEqual('abc123');
expect(denormalizedCase['transmission.contactSetting']).toEqual(
'setting',
Expand All @@ -585,7 +590,7 @@ describe('Case', () => {
});
it('denormalizes travel history fields', async () => {
const travelHistoryDoc = {
travelHistory: 'Y',
travelHistory: YesNo.Y,
travelHistoryEntry: new Date('2020-11-01'),
travelHistoryStart: 'start',
travelHistoryLocation: 'London',
Expand All @@ -610,9 +615,9 @@ describe('Case', () => {

const denormalizedCase = await denormalizeFields(caseDoc);

expect(denormalizedCase['travelHistory.travelHistory']).toEqual('Y');
expect(denormalizedCase['travelHistory.travelHistory']).toEqual(YesNo.Y);
expect(denormalizedCase['travelHistory.travelHistoryEntry']).toEqual(
travelHistoryDoc.travelHistoryEntry.toDateString(),
formatDateWithoutTime(travelHistoryDoc.travelHistoryEntry),
);
expect(denormalizedCase['travelHistory.travelHistoryStart']).toEqual(
'start',
Expand All @@ -626,7 +631,7 @@ describe('Case', () => {
});
it('denormalizes vaccine fields', async () => {
const vaccinationDoc = {
vaccination: 'Y',
vaccination: YesNo.Y,
vaccineName: 'Pfizer',
vaccineDate: new Date('2020-11-01'),
vaccineSideEffects: 'cough',
Expand All @@ -649,10 +654,10 @@ describe('Case', () => {
} as CaseDocument;

const denormalizedCase = await denormalizeFields(caseDoc);
expect(denormalizedCase['vaccination.vaccination']).toEqual('Y');
expect(denormalizedCase['vaccination.vaccination']).toEqual(YesNo.Y);
expect(denormalizedCase['vaccination.vaccineName']).toEqual('Pfizer');
expect(denormalizedCase['vaccination.vaccineDate']).toEqual(
vaccinationDoc.vaccineDate.toDateString(),
formatDateWithoutTime(vaccinationDoc.vaccineDate),
);
expect(denormalizedCase['vaccination.vaccineSideEffects']).toEqual(
'cough',
Expand Down Expand Up @@ -689,4 +694,13 @@ describe('Case', () => {
'1234',
);
});

it('formatsDateWithoutTimeCorrectly', async () => {
const correctDateString = '2024-01-01';
const correctDate = new Date(`${correctDateString}T03:24:00`);
const missingDate = undefined;

expect(formatDateWithoutTime(correctDate)).toEqual(correctDateString);
expect(formatDateWithoutTime(missingDate)).toEqual('');
});
});
Loading

0 comments on commit 6ca98a6

Please sign in to comment.