Skip to content

Commit

Permalink
Merge branch 'main' into 93-add-bulk-verification
Browse files Browse the repository at this point in the history
  • Loading branch information
stanislaw-zakrzewski committed Nov 21, 2024
2 parents 8182447 + 8db28d3 commit 33b69dd
Show file tree
Hide file tree
Showing 17 changed files with 580 additions and 180 deletions.
15 changes: 15 additions & 0 deletions data-serving/data-service/src/controllers/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,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 Expand Up @@ -888,6 +896,13 @@ export class CasesController {
res.status(201).json(result);
} catch (e) {
const err = e as Error;
if (err.name === 'MongoServerError') {
logger.error((e as any).errInfo);
res.status(422).json({
message: (err as any).errInfo,
});
return;
}
if (err instanceof GeocodeNotFoundError) {
res.status(404).json({
message: err.message,
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
27 changes: 20 additions & 7 deletions data-serving/data-service/test/util/case.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ 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';
Expand Down Expand Up @@ -421,16 +425,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 @@ -612,7 +616,7 @@ describe('Case', () => {

expect(denormalizedCase['travelHistory.travelHistory']).toEqual('Y');
expect(denormalizedCase['travelHistory.travelHistoryEntry']).toEqual(
travelHistoryDoc.travelHistoryEntry.toDateString(),
formatDateWithoutTime(travelHistoryDoc.travelHistoryEntry),
);
expect(denormalizedCase['travelHistory.travelHistoryStart']).toEqual(
'start',
Expand Down Expand Up @@ -652,7 +656,7 @@ describe('Case', () => {
expect(denormalizedCase['vaccination.vaccination']).toEqual('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 +693,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('');
});
});
99 changes: 51 additions & 48 deletions data-serving/scripts/setup-db/migrations/20210902121948-initial.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,60 @@
const fs = require('fs');

module.exports = {
async up(db, client) {
await createCollectionValidationAndIndexes(
db,
'cases',
'schemas/cases.schema.json',
'schemas/cases.indexes.json'
);

await createCollectionValidationAndIndexes(
db,
'sources',
'schemas/sources.schema.json',
'schemas/sources.indexes.json'
);
},

async down(db, client) {
// initial migration has no rollback
}
async up(db, client) {
await createCollectionValidationAndIndexes(
db,
'day0cases',
'schemas/day0cases.schema.json',
'schemas/day0cases.indexes.json',
);

await createCollectionValidationAndIndexes(
db,
'sources',
'schemas/sources.schema.json',
'schemas/sources.indexes.json',
);
},

async down(db, client) {
// initial migration has no rollback
},
};

async function createCollectionValidationAndIndexes(db, collectionName, schemaPath, indexPath) {
const schemaFile = await fs.promises.readFile(schemaPath);
const schema = JSON.parse(schemaFile);
async function createCollectionValidationAndIndexes(
db,
collectionName,
schemaPath,
indexPath,
) {
const schemaFile = await fs.promises.readFile(schemaPath);
const schema = JSON.parse(schemaFile);

const indexFile = await fs.promises.readFile(indexPath);
const indexes = JSON.parse(indexFile);
/*
* because this migration might run against a DB from before we had the migrations infra,
* check whether the collection already exists. If it does, then modify its validation schema.
* If it doesn't, then create it.
*/
try {
await db.collection(collectionName);
await db.command({
collMod: collectionName,
validator: schema,
});
} catch {
await db.createCollection(collectionName, {
validator: schema,
});
}

const collection = db.collection(collectionName);
await collection.dropIndexes();

const indexFile = await fs.promises.readFile(indexPath);
const indexes = JSON.parse(indexFile);
/*
* because this migration might run against a DB from before we had the migrations infra,
* check whether the collection already exists. If it does, then modify its validation schema.
* If it doesn't, then create it.
*/
try {
await db.collection(collectionName);
await db.command({
collMod: collectionName,
validator: schema,
});
}
catch {
await db.createCollection(collectionName, {
validator: schema,
createIndexes: collectionName,
indexes: indexes,
});
}

const collection = db.collection(collectionName);
await collection.dropIndexes();

await db.command({
createIndexes: collectionName,
indexes: indexes,
});
}

Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
const indexes = [
{
name: 'byGenderAndCountry',
key: {
'demographics.gender': -1,
'location.countryISO3': -1
{
name: 'byGenderAndCountry',
key: {
'demographics.gender': -1,
'location.countryISO3': -1,
},
collation: {
locale: 'en_US',
strength: 2,
},
},
collation: {
locale: 'en_US',
strength: 2,
},
}
];

module.exports = {
async up(db, client) {
await db.command({
createIndexes: 'cases',
indexes: indexes,
});
},
async up(db, client) {
await db.command({
createIndexes: 'day0cases',
indexes: indexes,
});
},

async down(db, client) {
await db.command({
dropIndexes: 'cases',
index: ['byGenderAndCountry']
});
}
async down(db, client) {
await db.command({
dropIndexes: 'day0cases',
index: ['byGenderAndCountry'],
});
},
};
1 change: 1 addition & 0 deletions data-serving/scripts/setup-db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"lint": "tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix",
"import-sample-data": "python3 ./import-sample-data.py",
"migrate": "npm ci && migrate-mongo up",
"migrate-down": "npm ci && migrate-mongo down",
"delete-all-cases": "mongosh $CONN --eval 'db.cases.deleteMany({})'"
},
"repository": {
Expand Down
Loading

0 comments on commit 33b69dd

Please sign in to comment.