diff --git a/data-serving/data-service/api/openapi.yaml b/data-serving/data-service/api/openapi.yaml
index 6bd8d5df7..5cb28cf97 100644
--- a/data-serving/data-service/api/openapi.yaml
+++ b/data-serving/data-service/api/openapi.yaml
@@ -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:
@@ -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:
@@ -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]
@@ -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:
@@ -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:
@@ -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:
@@ -875,8 +869,7 @@ components:
                     type: object
                     properties:
                         vaccination:
-                            type: string
-                            enum: ['Y', 'N', 'NA']
+                            $ref: '#/components/schemas/YesNo'
                         vaccineName:
                             type: string
                         vaccineDate:
diff --git a/data-serving/data-service/src/controllers/case.ts b/data-serving/data-service/src/controllers/case.ts
index 2b16ac2ec..1e40064ff 100644
--- a/data-serving/data-service/src/controllers/case.ts
+++ b/data-serving/data-service/src/controllers/case.ts
@@ -355,6 +355,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();
@@ -798,6 +806,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,
diff --git a/data-serving/data-service/src/types/enums.ts b/data-serving/data-service/src/types/enums.ts
index 56d5ef12c..e6d5ed844 100644
--- a/data-serving/data-service/src/types/enums.ts
+++ b/data-serving/data-service/src/types/enums.ts
@@ -8,7 +8,7 @@ export enum CaseStatus {
 export enum YesNo {
     Y = 'Y',
     N = 'N',
-    NA = 'NA',
+    None = '',
 }
 
 export enum Role {
diff --git a/data-serving/data-service/src/util/case.ts b/data-serving/data-service/src/util/case.ts
index db8faba83..3989908f0 100644
--- a/data-serving/data-service/src/util/case.ts
+++ b/data-serving/data-service/src/util/case.ts
@@ -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>> => {
@@ -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 || '';
@@ -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;
 };
@@ -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'] =
@@ -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 || '';
 
diff --git a/data-serving/data-service/test/util/case.test.ts b/data-serving/data-service/test/util/case.test.ts
index 205bcb7d7..fcc1108a4 100644
--- a/data-serving/data-service/test/util/case.test.ts
+++ b/data-serving/data-service/test/util/case.test.ts
@@ -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;
 
@@ -364,7 +369,7 @@ describe('Case', () => {
             ageBuckets: [anAgeBucket._id],
             gender: 'male',
             occupation: 'Anesthesiologist',
-            healthcareWorker: 'Y',
+            healthcareWorker: YesNo.Y,
         } as DemographicsDocument;
 
         const caseDoc = {
@@ -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 = {
@@ -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('');
@@ -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 = {
@@ -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',
         );
@@ -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',
@@ -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',
@@ -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',
@@ -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',
@@ -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',
@@ -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',
@@ -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('');
+    });
 });
diff --git a/data-serving/scripts/setup-db/manual-migration-helpers/age-buckets-transition/docker-compose-test.yml b/data-serving/scripts/setup-db/manual-migration-helpers/age-buckets-transition/docker-compose-test.yml
index 413591d83..7fa0db21a 100644
--- a/data-serving/scripts/setup-db/manual-migration-helpers/age-buckets-transition/docker-compose-test.yml
+++ b/data-serving/scripts/setup-db/manual-migration-helpers/age-buckets-transition/docker-compose-test.yml
@@ -6,6 +6,6 @@ services:
       context: .
       dockerfile: Dockerfile-test
   mongo:
-    image: mongo:5.0
+    image: mongo:6.0.17
     ports:
       - "27017:27017"
diff --git a/data-serving/scripts/setup-db/migrations/20210902121948-initial.js b/data-serving/scripts/setup-db/migrations/20210902121948-initial.js
index 27063fa83..3b3bc08e5 100644
--- a/data-serving/scripts/setup-db/migrations/20210902121948-initial.js
+++ b/data-serving/scripts/setup-db/migrations/20210902121948-initial.js
@@ -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,
-  });
 }
-
diff --git a/data-serving/scripts/setup-db/migrations/20210922082905-additional-case-indexes.js b/data-serving/scripts/setup-db/migrations/20210922082905-additional-case-indexes.js
index 4fe9bbbee..b47fbf266 100644
--- a/data-serving/scripts/setup-db/migrations/20210922082905-additional-case-indexes.js
+++ b/data-serving/scripts/setup-db/migrations/20210922082905-additional-case-indexes.js
@@ -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'],
+        });
+    },
 };
diff --git a/data-serving/scripts/setup-db/package.json b/data-serving/scripts/setup-db/package.json
index 1eec4d3a5..fcdd3b211 100644
--- a/data-serving/scripts/setup-db/package.json
+++ b/data-serving/scripts/setup-db/package.json
@@ -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": {
diff --git a/data-serving/scripts/setup-db/schemas/cases.indexes.json b/data-serving/scripts/setup-db/schemas/day0cases.indexes.json
similarity index 78%
rename from data-serving/scripts/setup-db/schemas/cases.indexes.json
rename to data-serving/scripts/setup-db/schemas/day0cases.indexes.json
index 210417dd7..b55dd708a 100644
--- a/data-serving/scripts/setup-db/schemas/cases.indexes.json
+++ b/data-serving/scripts/setup-db/schemas/day0cases.indexes.json
@@ -4,9 +4,12 @@
         "key": {
             "demographics.occupation": "text",
             "location.country": "text",
-            "location.city": "text",
+            "location.admin1": "text",
+            "location.admin2": "text",
+            "location.admin3": "text",
             "caseReference.sourceUrl": "text",
-            "caseStatus": "text"
+            "caseStatus": "text",
+            "comment": "text"
         }
     },
     {
@@ -74,9 +77,29 @@
         }
     },
     {
-        "name": "locationCityIdx",
+        "name": "locationAdmin1Idx",
         "key": {
-            "location.city": -1
+            "location.admin1": -1
+        },
+        "collation": {
+            "locale": "en_US",
+            "strength": 2
+        }
+    },
+    {
+        "name": "locationAdmin2Idx",
+        "key": {
+            "location.admin2": -1
+        },
+        "collation": {
+            "locale": "en_US",
+            "strength": 2
+        }
+    },
+    {
+        "name": "locationAdmin3Idx",
+        "key": {
+            "location.admin3": -1
         },
         "collation": {
             "locale": "en_US",
@@ -123,6 +146,16 @@
             "strength": 2
         }
     },
+    {
+        "name": "commentIdx",
+        "key": {
+            "comment": -1
+        },
+        "collation": {
+            "locale": "en_US",
+            "strength": 2
+        }
+    },
     {
         "name": "countryAndDate",
         "key": {
diff --git a/data-serving/scripts/setup-db/schemas/cases.schema.json b/data-serving/scripts/setup-db/schemas/day0cases.schema.json
similarity index 60%
rename from data-serving/scripts/setup-db/schemas/cases.schema.json
rename to data-serving/scripts/setup-db/schemas/day0cases.schema.json
index addf0e2c8..4175de3de 100644
--- a/data-serving/scripts/setup-db/schemas/cases.schema.json
+++ b/data-serving/scripts/setup-db/schemas/day0cases.schema.json
@@ -2,6 +2,7 @@
     "$jsonSchema": {
         "bsonType": "object",
         "additionalProperties": false,
+        "required": ["caseStatus"],
         "properties": {
             "_id": {
                 "bsonType": "number",
@@ -13,6 +14,102 @@
             "list": {
                 "bsonType": "bool"
             },
+            "caseStatus": {
+                "bsonType": "string"
+            },
+            "comment": {
+                "bsonType": "string"
+            },
+            "curators": {
+                "bsonType": "object",
+                "additionalProperties": false,
+                "properties": {
+                    "verifiedBy": {
+                        "bsonType": "object",
+                        "additionalProperties": false,
+                        "properties": {
+                            "_id": {
+                                "bsonType": "objectId"
+                            },
+                            "name": {
+                                "bsonType": "string"
+                            },
+                            "email": {
+                                "bsonType": "string"
+                            },
+                            "roles": {
+                                "bsonType": "array",
+                                "uniqueItems": true,
+                                "items": {
+                                    "bsonType": "string"
+                                }
+                            }
+                        }
+                    },
+                    "createdBy": {
+                        "bsonType": "object",
+                        "additionalProperties": false,
+                        "properties": {
+                            "_id": {
+                                "bsonType": "objectId"
+                            },
+                            "name": {
+                                "bsonType": "string"
+                            },
+                            "email": {
+                                "bsonType": "string"
+                            },
+                            "roles": {
+                                "bsonType": "array",
+                                "uniqueItems": true,
+                                "items": {
+                                    "bsonType": "string"
+                                }
+                            }
+                        }
+                    }
+                }
+            },
+            "revisionMetadata": {
+                "bsonType": "object",
+                "additionalProperties": false,
+                "properties": {
+                    "revisionNumber": {
+                        "bsonType": "number",
+                        "minimum": 0
+                    },
+                    "creationMetadata": {
+                        "bsonType": "object",
+                        "additionalProperties": false,
+                        "properties": {
+                            "curator": {
+                                "bsonType": "string"
+                            },
+                            "date": {
+                                "bsonType": "date"
+                            },
+                            "notes": {
+                                "bsonType": "string"
+                            }
+                        }
+                    },
+                    "updateMetadata": {
+                        "bsonType": "object",
+                        "additionalProperties": false,
+                        "properties": {
+                            "curator": {
+                                "bsonType": "string"
+                            },
+                            "date": {
+                                "bsonType": "date"
+                            },
+                            "notes": {
+                                "bsonType": "string"
+                            }
+                        }
+                    }
+                }
+            },
             "caseReference": {
                 "bsonType": "object",
                 "additionalProperties": false,
@@ -26,6 +123,9 @@
                     "sourceUrl": {
                         "bsonType": "string"
                     },
+                    "isGovernmentSource": {
+                        "bsonType": "bool"
+                    },
                     "uploadIds": {
                         "bsonType": "array",
                         "uniqueItems": true,
@@ -42,6 +142,9 @@
                             "properties": {
                                 "sourceUrl": {
                                     "bsonType": "string"
+                                },
+                                "isGovernmentSource": {
+                                    "bsonType": "bool"
                                 }
                             }
                         }
@@ -68,6 +171,13 @@
                             }
                         }
                     },
+                    "ageBuckets": {
+                        "bsonType": "array",
+                        "uniqueItems": true,
+                        "items": {
+                            "bsonType": "objectId"
+                        }
+                    },
                     "gender": {
                         "bsonType": "string"
                     },
@@ -111,16 +221,56 @@
                 "bsonType": "object",
                 "additionalProperties": false,
                 "properties": {
+                    "admin1": {
+                        "bsonType": "string"
+                    },
+                    "admin1WikiId": {
+                        "bsonType": "string"
+                    },
+                    "admin2": {
+                        "bsonType": "string"
+                    },
+                    "admin2WikiId": {
+                        "bsonType": "string"
+                    },
+                    "admin3": {
+                        "bsonType": "string"
+                    },
+                    "admin3WikiId": {
+                        "bsonType": "string"
+                    },
+                    "comment": {
+                        "bsonType": "string"
+                    },
                     "country": {
                         "bsonType": "string"
                     },
                     "countryISO3": {
                         "bsonType": "string"
                     },
+                    "geometry": {
+                        "bsonType": "object",
+                        "additionalProperties": false,
+                        "properties": {
+                            "latitude": {
+                                "bsonType": "number",
+                                "minimum": -90,
+                                "maximum": 90
+                            },
+                            "longitude": {
+                                "bsonType": "number",
+                                "minimum": -180,
+                                "maximum": 180
+                            }
+                        }
+                    },
+                    "geoResolution": {
+                        "bsonType": "string"
+                    },
                     "location": {
                         "bsonType": "string"
                     },
-                    "place": {
+                    "name": {
                         "bsonType": "string"
                     },
                     "query": {
@@ -135,7 +285,7 @@
                         "bsonType": ["date"]
                     },
                     "dateLastModified": {
-                        "bsonType": ["date"]
+                        "bsonType": ["date", "null"]
                     },
                     "dateOnset": {
                         "bsonType": ["date"]
diff --git a/dev/README.md b/dev/README.md
index b05064b04..619e09eb6 100644
--- a/dev/README.md
+++ b/dev/README.md
@@ -52,6 +52,11 @@ For local development, it's fine to use your own values for these
 secrets if you have them. For instance, if you have a developer Mapbox API
 token, or if you'd like to use a different GMail account for mailing notifications, or different OAuth client values.
 
+#### Database Schema
+
+Before inputting any case data to the local portal instance a database schema migration needs to be run.
+Navigate to the `data-serving/scripts/setup-db/` and follow instructions in the [README](../data-serving/scripts/setup-db/README.md) to set up the database schema.
+
 #### Permissions
 
 Give your user all the permissions to access the portal and make CRUD updates.
diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml
index ee28d8b52..d5129743b 100644
--- a/dev/docker-compose.yml
+++ b/dev/docker-compose.yml
@@ -18,7 +18,7 @@ services:
       retries: 3
       start_period: 30s
   mongo:
-    image: mongo:5.0.6
+    image: mongo:6.0.17
     restart: always
     init: true
     ports:
diff --git a/dev/make_superuser.sh b/dev/make_superuser.sh
index 2e53d722a..5ff05f6f5 100755
--- a/dev/make_superuser.sh
+++ b/dev/make_superuser.sh
@@ -10,6 +10,6 @@ cd `dirname "$0"`
 # Pass database name as the first parameter
 DB="${GDH_DATABASE:-$1}"
 # Pass email of user to grant an admin role as second parameter
-docker-compose -f docker-compose.yml -f docker-compose.dev.yml exec mongo mongo "${DB}" --eval "var email='$2'; var roles=['admin', 'curator'];" /verification/scripts/roles.js
+docker compose -f docker-compose.yml -f docker-compose.dev.yml exec mongo mongosh "${DB}" --eval "var email='$2'; var roles=['admin', 'curator'];" /verification/scripts/roles.js
 # Restore directory.
 popd
\ No newline at end of file
diff --git a/geocoding/location-service/Dockerfile b/geocoding/location-service/Dockerfile
index 7b156c704..03b99b645 100644
--- a/geocoding/location-service/Dockerfile
+++ b/geocoding/location-service/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.10-slim
+FROM python:3.10-bullseye
 
 RUN apt-get update -y
 RUN apt-get install -y python3-pip
@@ -14,7 +14,7 @@ WORKDIR /usr/src/app/geocoding/location-service
 USER flask
 
 # install dependencies
-RUN pip install poetry
+RUN pip install poetry==1.8.5
 COPY geocoding/location-service/pyproject.toml .
 COPY geocoding/location-service/poetry.lock .
 RUN /home/flask/.local/bin/poetry install
diff --git a/geocoding/location-service/Dockerfile-test b/geocoding/location-service/Dockerfile-test
index 7c7a80aa2..0a346eea5 100644
--- a/geocoding/location-service/Dockerfile-test
+++ b/geocoding/location-service/Dockerfile-test
@@ -1,5 +1,5 @@
 # `python-base` sets up all our shared environment variables
-FROM python:3.10-slim as python-base
+FROM python:3.10-bullseye as python-base
 
 ENV PYTHONUNBUFFERED=1 \
     # prevents python creating .pyc files
diff --git a/geocoding/location-service/docker-compose-test.yml b/geocoding/location-service/docker-compose-test.yml
index 413591d83..7fa0db21a 100644
--- a/geocoding/location-service/docker-compose-test.yml
+++ b/geocoding/location-service/docker-compose-test.yml
@@ -6,6 +6,6 @@ services:
       context: .
       dockerfile: Dockerfile-test
   mongo:
-    image: mongo:5.0
+    image: mongo:6.0.17
     ports:
       - "27017:27017"
diff --git a/verification/curator-service/api/openapi/openapi.yaml b/verification/curator-service/api/openapi/openapi.yaml
index 062408b0f..ac7241369 100644
--- a/verification/curator-service/api/openapi/openapi.yaml
+++ b/verification/curator-service/api/openapi/openapi.yaml
@@ -1283,6 +1283,9 @@ paths:
 
 components:
     schemas:
+        YesNo:
+            type: string
+            enum: [ 'Y', 'N', '' ]
         Parser:
             description: A parser for automated ingestion
             type: object
@@ -1593,8 +1596,7 @@ components:
                         occupation:
                             type: string
                         healthcareWorker:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                 location:
                     $ref: '#/components/schemas/Location'
                 events:
@@ -1615,8 +1617,7 @@ components:
                         dateOfFirstConsult:
                             $ref: '#/components/schemas/Date'
                         hospitalized:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         reasonForHospitalization:
                             type: string
                             enum: [monitoring, treatment, unknown]
@@ -1625,18 +1626,15 @@ components:
                         dateDischargeHospital:
                             $ref: '#/components/schemas/Date'
                         intensiveCare:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         dateAdmissionICU:
                             $ref: '#/components/schemas/Date'
                         dateDischargeICU:
                             $ref: '#/components/schemas/Date'
                         homeMonitoring:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         isolated:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         dateIsolation:
                             $ref: '#/components/schemas/Date'
                         outcome:
@@ -1653,22 +1651,19 @@ components:
                     type: object
                     properties:
                         previousInfection:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         coInfection:
                             type: string
                         preexistingCondition:
                             type: string
                         pregnancyStatus:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                 transmission:
                     description: How this case got infected and by who if known
                     type: object
                     properties:
                         contactWithCase:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         contactId:
                             type: string
                         contactSetting:
@@ -1684,8 +1679,7 @@ components:
                     description: Travel history of the patient if known
                     properties:
                         travelHistory:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         travelHistoryEntry:
                             $ref: '#/components/schemas/Date'
                         travelHistoryStart:
@@ -1709,8 +1703,7 @@ components:
                     type: object
                     properties:
                         vaccination:
-                            type: string
-                            enum: ['Y', 'N', 'NA', undefined]
+                            $ref: '#/components/schemas/YesNo'
                         vaccineName:
                             type: string
                         vaccineDate:
diff --git a/verification/curator-service/api/package-lock.json b/verification/curator-service/api/package-lock.json
index 5b1f08919..2ad47fdae 100644
--- a/verification/curator-service/api/package-lock.json
+++ b/verification/curator-service/api/package-lock.json
@@ -9,6 +9,10 @@
       "version": "1.0.0",
       "license": "MIT",
       "dependencies": {
+        "@types/passport": "^1.0.4",
+        "@types/passport-google-oauth20": "^2.0.4",
+        "@types/passport-http-bearer": "^1.0.36",
+        "@types/passport-local": "^1.0.33",
         "@types/swagger-ui-express": "^4.1.6",
         "aws-sdk": "^2.1631.0",
         "axios": "^1.7.2",
@@ -32,7 +36,7 @@
         "mongodb": "^6.7.0",
         "mongodb-memory-server": "^9.2.0",
         "nodemailer": "^6.9.13",
-        "passport": "^0.7.0",
+        "passport": "^0.5.3",
         "passport-google-oauth20": "^2.0.0",
         "passport-http-bearer": "^1.0.1",
         "passport-local": "^1.0.0",
@@ -55,10 +59,6 @@
         "@types/lodash": "^4.17.4",
         "@types/node": "^20.12.13",
         "@types/nodemailer": "^6.4.15",
-        "@types/passport": "^1.0.16",
-        "@types/passport-google-oauth20": "^2.0.16",
-        "@types/passport-http-bearer": "^1.0.41",
-        "@types/passport-local": "^1.0.38",
         "@types/pino": "^7.0.5",
         "@types/supertest": "^6.0.2",
         "@types/yamljs": "^0.2.34",
@@ -1410,7 +1410,6 @@
       "version": "1.3.7",
       "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz",
       "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==",
-      "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
@@ -1485,8 +1484,7 @@
     "node_modules/@types/content-disposition": {
       "version": "0.5.8",
       "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz",
-      "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==",
-      "dev": true
+      "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg=="
     },
     "node_modules/@types/cookie-parser": {
       "version": "1.4.7",
@@ -1507,7 +1505,6 @@
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz",
       "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==",
-      "dev": true,
       "dependencies": {
         "@types/connect": "*",
         "@types/express": "*",
@@ -1593,14 +1590,12 @@
     "node_modules/@types/http-assert": {
       "version": "1.5.5",
       "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz",
-      "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==",
-      "dev": true
+      "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g=="
     },
     "node_modules/@types/http-errors": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
-      "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
-      "dev": true
+      "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="
     },
     "node_modules/@types/istanbul-lib-coverage": {
       "version": "2.0.4",
@@ -1644,14 +1639,12 @@
     "node_modules/@types/keygrip": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz",
-      "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==",
-      "dev": true
+      "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ=="
     },
     "node_modules/@types/koa": {
       "version": "2.15.0",
       "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz",
       "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==",
-      "dev": true,
       "dependencies": {
         "@types/accepts": "*",
         "@types/content-disposition": "*",
@@ -1667,7 +1660,6 @@
       "version": "3.2.8",
       "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz",
       "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==",
-      "dev": true,
       "dependencies": {
         "@types/koa": "*"
       }
@@ -1718,25 +1710,22 @@
       "version": "0.9.5",
       "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.5.tgz",
       "integrity": "sha512-+oQ3C2Zx6ambINOcdIARF5Z3Tu3x//HipE889/fqo3sgpQZbe9c6ExdQFtN6qlhpR7p83lTZfPJt0tCAW29dog==",
-      "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
     },
     "node_modules/@types/passport": {
-      "version": "1.0.16",
-      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz",
-      "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==",
-      "dev": true,
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.4.tgz",
+      "integrity": "sha512-h5OfAbfBBYSzjeU0GTuuqYEk9McTgWeGQql9g3gUw2/NNCfD7VgExVRYJVVeU13Twn202Mvk9BT0bUrl30sEgA==",
       "dependencies": {
         "@types/express": "*"
       }
     },
     "node_modules/@types/passport-google-oauth20": {
-      "version": "2.0.16",
-      "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.16.tgz",
-      "integrity": "sha512-ayXK2CJ7uVieqhYOc6k/pIr5pcQxOLB6kBev+QUGS7oEZeTgIs1odDobXRqgfBPvXzl0wXCQHftV5220czZCPA==",
-      "dev": true,
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.4.tgz",
+      "integrity": "sha512-lYLsLzbYKlCopSO1b/FdxsBOgpIIZfvhVdVj5Wgx97udiPDGqv3g8Sq5OsWk20idtPL606SnfPRFgWfx698Nkw==",
       "dependencies": {
         "@types/express": "*",
         "@types/passport": "*",
@@ -1744,10 +1733,9 @@
       }
     },
     "node_modules/@types/passport-http-bearer": {
-      "version": "1.0.41",
-      "resolved": "https://registry.npmjs.org/@types/passport-http-bearer/-/passport-http-bearer-1.0.41.tgz",
-      "integrity": "sha512-ecW+9e8C+0id5iz3YZ+uIarsk/vaRPkKSajt1i1Am66t0mC9gDfQDKXZz9fnPOW2xKUufbmCSou4005VM94Feg==",
-      "dev": true,
+      "version": "1.0.36",
+      "resolved": "https://registry.npmjs.org/@types/passport-http-bearer/-/passport-http-bearer-1.0.36.tgz",
+      "integrity": "sha512-D6yFiojv/JSxuQY2FcT/dzFHw+ypVOkKN4QzTdt6xZyrmMQBI7p1wr5F3+clCNUgxRgoNaBVRuzlwu5NSV530w==",
       "dependencies": {
         "@types/express": "*",
         "@types/koa": "*",
@@ -1755,10 +1743,9 @@
       }
     },
     "node_modules/@types/passport-local": {
-      "version": "1.0.38",
-      "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.38.tgz",
-      "integrity": "sha512-nsrW4A963lYE7lNTv9cr5WmiUD1ibYJvWrpE13oxApFsRt77b0RdtZvKbCdNIY4v/QZ6TRQWaDDEwV1kCTmcXg==",
-      "dev": true,
+      "version": "1.0.33",
+      "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.33.tgz",
+      "integrity": "sha512-+rn6ZIxje0jZ2+DAiWFI8vGG7ZFKB0hXx2cUdMmudSWsigSq6ES7Emso46r4HJk0qCgrZVfI8sJiM7HIYf4SbA==",
       "dependencies": {
         "@types/express": "*",
         "@types/passport": "*",
@@ -1769,7 +1756,6 @@
       "version": "1.4.17",
       "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.17.tgz",
       "integrity": "sha512-ODiAHvso6JcWJ6ZkHHroVp05EHGhqQN533PtFNBkg8Fy5mERDqsr030AX81M0D69ZcaMvhF92SRckEk2B0HYYg==",
-      "dev": true,
       "dependencies": {
         "@types/express": "*",
         "@types/oauth": "*",
@@ -1780,7 +1766,6 @@
       "version": "0.2.38",
       "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
       "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==",
-      "dev": true,
       "dependencies": {
         "@types/express": "*",
         "@types/passport": "*"
@@ -8074,13 +8059,12 @@
       }
     },
     "node_modules/passport": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz",
-      "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==",
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.3.tgz",
+      "integrity": "sha512-gGc+70h4gGdBWNsR3FuV3byLDY6KBTJAIExGFXTpQaYfbbcHCBlRRKx7RBQSpqEqc5Hh2qVzRs7ssvSfOpkUEA==",
       "dependencies": {
         "passport-strategy": "1.x.x",
-        "pause": "0.0.1",
-        "utils-merge": "^1.0.1"
+        "pause": "0.0.1"
       },
       "engines": {
         "node": ">= 0.4.0"
@@ -11678,7 +11662,6 @@
       "version": "1.3.7",
       "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz",
       "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==",
-      "dev": true,
       "requires": {
         "@types/node": "*"
       }
@@ -11753,8 +11736,7 @@
     "@types/content-disposition": {
       "version": "0.5.8",
       "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz",
-      "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==",
-      "dev": true
+      "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg=="
     },
     "@types/cookie-parser": {
       "version": "1.4.7",
@@ -11775,7 +11757,6 @@
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz",
       "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==",
-      "dev": true,
       "requires": {
         "@types/connect": "*",
         "@types/express": "*",
@@ -11860,14 +11841,12 @@
     "@types/http-assert": {
       "version": "1.5.5",
       "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz",
-      "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==",
-      "dev": true
+      "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g=="
     },
     "@types/http-errors": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
-      "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
-      "dev": true
+      "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="
     },
     "@types/istanbul-lib-coverage": {
       "version": "2.0.4",
@@ -11911,14 +11890,12 @@
     "@types/keygrip": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz",
-      "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==",
-      "dev": true
+      "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ=="
     },
     "@types/koa": {
       "version": "2.15.0",
       "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz",
       "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==",
-      "dev": true,
       "requires": {
         "@types/accepts": "*",
         "@types/content-disposition": "*",
@@ -11934,7 +11911,6 @@
       "version": "3.2.8",
       "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz",
       "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==",
-      "dev": true,
       "requires": {
         "@types/koa": "*"
       }
@@ -11985,25 +11961,22 @@
       "version": "0.9.5",
       "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.5.tgz",
       "integrity": "sha512-+oQ3C2Zx6ambINOcdIARF5Z3Tu3x//HipE889/fqo3sgpQZbe9c6ExdQFtN6qlhpR7p83lTZfPJt0tCAW29dog==",
-      "dev": true,
       "requires": {
         "@types/node": "*"
       }
     },
     "@types/passport": {
-      "version": "1.0.16",
-      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz",
-      "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==",
-      "dev": true,
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.4.tgz",
+      "integrity": "sha512-h5OfAbfBBYSzjeU0GTuuqYEk9McTgWeGQql9g3gUw2/NNCfD7VgExVRYJVVeU13Twn202Mvk9BT0bUrl30sEgA==",
       "requires": {
         "@types/express": "*"
       }
     },
     "@types/passport-google-oauth20": {
-      "version": "2.0.16",
-      "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.16.tgz",
-      "integrity": "sha512-ayXK2CJ7uVieqhYOc6k/pIr5pcQxOLB6kBev+QUGS7oEZeTgIs1odDobXRqgfBPvXzl0wXCQHftV5220czZCPA==",
-      "dev": true,
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.4.tgz",
+      "integrity": "sha512-lYLsLzbYKlCopSO1b/FdxsBOgpIIZfvhVdVj5Wgx97udiPDGqv3g8Sq5OsWk20idtPL606SnfPRFgWfx698Nkw==",
       "requires": {
         "@types/express": "*",
         "@types/passport": "*",
@@ -12011,10 +11984,9 @@
       }
     },
     "@types/passport-http-bearer": {
-      "version": "1.0.41",
-      "resolved": "https://registry.npmjs.org/@types/passport-http-bearer/-/passport-http-bearer-1.0.41.tgz",
-      "integrity": "sha512-ecW+9e8C+0id5iz3YZ+uIarsk/vaRPkKSajt1i1Am66t0mC9gDfQDKXZz9fnPOW2xKUufbmCSou4005VM94Feg==",
-      "dev": true,
+      "version": "1.0.36",
+      "resolved": "https://registry.npmjs.org/@types/passport-http-bearer/-/passport-http-bearer-1.0.36.tgz",
+      "integrity": "sha512-D6yFiojv/JSxuQY2FcT/dzFHw+ypVOkKN4QzTdt6xZyrmMQBI7p1wr5F3+clCNUgxRgoNaBVRuzlwu5NSV530w==",
       "requires": {
         "@types/express": "*",
         "@types/koa": "*",
@@ -12022,10 +11994,9 @@
       }
     },
     "@types/passport-local": {
-      "version": "1.0.38",
-      "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.38.tgz",
-      "integrity": "sha512-nsrW4A963lYE7lNTv9cr5WmiUD1ibYJvWrpE13oxApFsRt77b0RdtZvKbCdNIY4v/QZ6TRQWaDDEwV1kCTmcXg==",
-      "dev": true,
+      "version": "1.0.33",
+      "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.33.tgz",
+      "integrity": "sha512-+rn6ZIxje0jZ2+DAiWFI8vGG7ZFKB0hXx2cUdMmudSWsigSq6ES7Emso46r4HJk0qCgrZVfI8sJiM7HIYf4SbA==",
       "requires": {
         "@types/express": "*",
         "@types/passport": "*",
@@ -12036,7 +12007,6 @@
       "version": "1.4.17",
       "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.17.tgz",
       "integrity": "sha512-ODiAHvso6JcWJ6ZkHHroVp05EHGhqQN533PtFNBkg8Fy5mERDqsr030AX81M0D69ZcaMvhF92SRckEk2B0HYYg==",
-      "dev": true,
       "requires": {
         "@types/express": "*",
         "@types/oauth": "*",
@@ -12047,7 +12017,6 @@
       "version": "0.2.38",
       "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
       "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==",
-      "dev": true,
       "requires": {
         "@types/express": "*",
         "@types/passport": "*"
@@ -16655,13 +16624,12 @@
       "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
     },
     "passport": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz",
-      "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==",
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.3.tgz",
+      "integrity": "sha512-gGc+70h4gGdBWNsR3FuV3byLDY6KBTJAIExGFXTpQaYfbbcHCBlRRKx7RBQSpqEqc5Hh2qVzRs7ssvSfOpkUEA==",
       "requires": {
         "passport-strategy": "1.x.x",
-        "pause": "0.0.1",
-        "utils-merge": "^1.0.1"
+        "pause": "0.0.1"
       }
     },
     "passport-google-oauth20": {
diff --git a/verification/curator-service/api/package.json b/verification/curator-service/api/package.json
index fdab145a6..2fc81dbe5 100644
--- a/verification/curator-service/api/package.json
+++ b/verification/curator-service/api/package.json
@@ -38,10 +38,6 @@
     "@types/lodash": "^4.17.4",
     "@types/node": "^20.12.13",
     "@types/nodemailer": "^6.4.15",
-    "@types/passport": "^1.0.16",
-    "@types/passport-google-oauth20": "^2.0.16",
-    "@types/passport-http-bearer": "^1.0.41",
-    "@types/passport-local": "^1.0.38",
     "@types/pino": "^7.0.5",
     "@types/supertest": "^6.0.2",
     "@types/yamljs": "^0.2.34",
@@ -63,6 +59,10 @@
     "typescript": "^5.4.5"
   },
   "dependencies": {
+    "@types/passport": "^1.0.4",
+    "@types/passport-google-oauth20": "^2.0.4",
+    "@types/passport-http-bearer": "^1.0.36",
+    "@types/passport-local": "^1.0.33",
     "@types/swagger-ui-express": "^4.1.6",
     "aws-sdk": "^2.1631.0",
     "axios": "^1.7.2",
@@ -86,7 +86,7 @@
     "mongodb": "^6.7.0",
     "mongodb-memory-server": "^9.2.0",
     "nodemailer": "^6.9.13",
-    "passport": "^0.7.0",
+    "passport": "^0.5.3",
     "passport-google-oauth20": "^2.0.0",
     "passport-http-bearer": "^1.0.1",
     "passport-local": "^1.0.0",
diff --git a/verification/curator-service/api/src/controllers/auth.ts b/verification/curator-service/api/src/controllers/auth.ts
index b881d96f1..47546eeae 100644
--- a/verification/curator-service/api/src/controllers/auth.ts
+++ b/verification/curator-service/api/src/controllers/auth.ts
@@ -293,11 +293,9 @@ export class AuthController {
             },
         );
 
-        this.router.get('/logout', (req: Request, res: Response, next: NextFunction): void => {
-            req.logout(function(err) {
-                if (err) { return next(err); }
-                res.redirect('/');
-            });
+        this.router.get('/logout', function(req, res, next) {
+            req.logout();
+            res.status(200).json({ message: 'Logged out' });
         });
 
         // Starts the authentication flow with Google OAuth.
diff --git a/verification/curator-service/api/test/auth.test.ts b/verification/curator-service/api/test/auth.test.ts
index 58cf267b1..a16587e60 100644
--- a/verification/curator-service/api/test/auth.test.ts
+++ b/verification/curator-service/api/test/auth.test.ts
@@ -57,8 +57,7 @@ describe('auth', () => {
         // Redirects to /
         request(app)
             .get('/auth/logout')
-            .expect(302)
-            .expect('Location', '/')
+            .expect(200)
             .end(done);
     });
     it('handles redirect from google', (done) => {
@@ -93,7 +92,7 @@ describe('bearer token auth', () => {
                 roles: ['curator'],
             })
             .expect(200, /test-user/);
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         mockedAxios.get.mockResolvedValueOnce({
             data: { email: 'foo@bar.com' },
         });
@@ -111,7 +110,7 @@ describe('bearer token auth', () => {
                 roles: ['curator'],
             })
             .expect(200, /test-user/);
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         mockedAxios.get.mockResolvedValueOnce({
             data: { name: 'my name' },
         });
@@ -129,7 +128,7 @@ describe('bearer token auth', () => {
                 roles: ['curator'],
             })
             .expect(200, /test-user/);
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         mockedAxios.get.mockRejectedValueOnce('Oops!');
         await request
             .get('/api/sources?access_token=mF_9.B5f-4.1JqM')
@@ -229,7 +228,7 @@ describe('mustHaveAnyRole', () => {
                 roles: ['curator', 'admin'],
             })
             .expect(200, /test-curator/);
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         mockedAxios.get.mockResolvedValueOnce({
             data: { email: 'foo@bar.com' },
         });
@@ -288,7 +287,7 @@ describe('api keys', () => {
         await request.post('/auth/profile/apiKey').expect(201);
         const apiKey = await request.get('/auth/profile/apiKey');
         request.set('X-API-key', apiKey.body);
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         await request.get('/auth/profile').expect(200, /test-curator/);
     });
 
@@ -303,7 +302,7 @@ describe('api keys', () => {
             .expect(200, /test-curator/);
         await request.post('/auth/profile/apiKey').expect(201);
         const apiKey = await request.get('/auth/profile/apiKey');
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         await request
             .post('/auth/register')
             .send({
@@ -316,7 +315,7 @@ describe('api keys', () => {
             .post(`/auth/deleteApiKey/${userRes.body._id}`)
             .expect(204);
         // now try to use the API key
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         request.set('X-API-key', apiKey.body);
         await request.get('/auth/profile').expect(403);
     });
@@ -332,7 +331,7 @@ describe('api keys', () => {
             .expect(200, /test-curator/);
         await request.post('/auth/profile/apiKey').expect(201);
         const apiKey = await request.get('/auth/profile/apiKey');
-        await request.get('/auth/logout').expect(302);
+        await request.get('/auth/logout').expect(200);
         await request
             .post('/auth/register')
             .send({
diff --git a/verification/curator-service/ui/cypress/e2e/components/Curator.spec.ts b/verification/curator-service/ui/cypress/e2e/components/Curator.spec.ts
index ab24ff822..1007db534 100644
--- a/verification/curator-service/ui/cypress/e2e/components/Curator.spec.ts
+++ b/verification/curator-service/ui/cypress/e2e/components/Curator.spec.ts
@@ -1,4 +1,6 @@
 /* eslint-disable no-undef */
+import { YesNo } from '../../support/commands';
+
 describe('Curator', function () {
     beforeEach(() => {
         cy.task('clearCasesDB', {});
@@ -56,27 +58,35 @@ describe('Curator', function () {
         // GENERAL
         cy.get('div[data-testid="caseStatus"]').click();
         cy.get('li[data-value="confirmed"').click();
-        cy.get('div[data-testid="comment"]').type('This case should be consulted with Supervisor.');
+        cy.get('div[data-testid="comment"]').type(
+            'This case should be consulted with Supervisor.',
+        );
 
         // DATA SOURCE
         cy.get('div[data-testid="caseReference"]').type('www.example.com');
         cy.contains('www.example.com').click();
-        cy.get('input[name="caseReference.isGovernmentSource"]').click()
+        cy.get('input[name="caseReference.isGovernmentSource"]').click();
         cy.get('button[data-testid="add-additional-source"]').click();
-        cy.get('div[data-testid="additional-source-0"]').type('www.example2.com');
+        cy.get('div[data-testid="additional-source-0"]').type(
+            'www.example2.com',
+        );
         cy.get('button[data-testid="add-additional-source"]').click();
-        cy.get('div[data-testid="additional-source-1"]').type('www.example3.com');
+        cy.get('div[data-testid="additional-source-1"]').type(
+            'www.example3.com',
+        );
         cy.get('span[data-testid="government-source-1"]').click();
 
         // LOCATION
-        cy.get('div[data-testid="location.geocodeLocation"]').type('France', { delay: 0});
+        cy.get('div[data-testid="location.geocodeLocation"]').type('France', {
+            delay: 0,
+        });
         cy.wait('@geolocationFranceSuggest');
         cy.contains('France').click();
         /* Change France to something else to check we can edit geocode results.
          * We need to change it to a valid country so that we can find the ISO code!
          */
-        cy.get('div[data-testid="location.country"]').click()
-        cy.get('input[name="location.country"]').clear().type('Germany')
+        cy.get('div[data-testid="location.country"]').click();
+        cy.get('input[name="location.country"]').clear().type('Germany');
         cy.get('p').contains('Germany').click();
         cy.get('input[name="location.admin1"]').type('Berlin');
         cy.get('p').contains('Berlin').click();
@@ -84,7 +94,9 @@ describe('Curator', function () {
         cy.get('p').contains('SK Berlin').click();
         cy.get('input[name="location.admin3"]').type('Berlin');
         cy.get('p').contains('Berlin').click();
-        cy.get('div[data-testid="location.comment"]').type('Martin Luther Hospital');
+        cy.get('div[data-testid="location.comment"]').type(
+            'Martin Luther Hospital',
+        );
 
         // EVENTS
         cy.get('input[name="events.dateEntry"]').type('2020-01-01');
@@ -94,16 +106,16 @@ describe('Curator', function () {
         cy.get('input[name="events.dateOnset"]').type('2020-01-03');
         cy.get('input[name="events.dateOfFirstConsult"]').type('2020-01-04');
         cy.get('div[data-testid="events.homeMonitoring"').click();
-        cy.get('li[data-value="Y"]').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('div[data-testid="events.isolated"]').click();
-        cy.get('li[data-value="Y"]').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('input[name="events.dateIsolation"]').type('2020-01-05');
         cy.get('div[data-testid="events.hospitalized"]').click();
-        cy.get('li[data-value="Y"]').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('input[name="events.dateHospitalization"]').type('2020-01-06');
         cy.get('input[name="events.dateDischargeHospital"]').type('2020-01-07');
         cy.get('div[data-testid="events.intensiveCare"]').click();
-        cy.get('li[data-value="Y"]').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('input[name="events.dateAdmissionICU"]').type('2020-01-08');
         cy.get('input[name="events.dateDischargeICU"]').type('2020-01-09');
         cy.get('div[data-testid="events.outcome"]').click();
@@ -117,7 +129,7 @@ describe('Curator', function () {
         cy.get('div[data-testid="occupation"]').click();
         cy.contains('li', 'Accountant').click();
         cy.get('div[data-testid="demographics.healthcareWorker"]').click();
-        cy.get('li[data-value="N"]').click();
+        cy.get(`li[data-value="${YesNo.N}"]`).click();
 
         // SYMPTOMS
         cy.get('div[data-testid="symptoms"]').type('dry cough');
@@ -129,7 +141,7 @@ describe('Curator', function () {
         cy.get(
             'div[data-testid="preexistingConditions.previousInfection"]',
         ).click();
-        cy.get('li[data-value="Y"').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('input[name="preexistingConditions.coInfection"]').type('Flu');
         cy.get('div[data-testid="preexistingConditionsHelper"]').type(
             'ABCD syndrome',
@@ -142,11 +154,11 @@ describe('Curator', function () {
         cy.get(
             'div[data-testid="preexistingConditions.pregnancyStatus"]',
         ).click();
-        cy.get('li[data-value="N"]').click();
+        cy.get(`li[data-value="${YesNo.N}"]`).click();
 
         // TRANSMISSION
         cy.get('div[data-testid="transmission.contactWithCase"]').click();
-        cy.get('li[data-value="Y"]').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('input[name="transmission.contactId"]').type('ABC123');
         cy.get('input[name="transmission.contactSetting"]').type(
             'test setting',
@@ -160,7 +172,7 @@ describe('Curator', function () {
 
         // TRAVEL HISTORY
         cy.get('div[data-testid="travelHistory.travelHistory"]').click();
-        cy.get('li[data-value="Y"]').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('input[name="travelHistory.travelHistoryEntry"]').type(
             '2020-02-01',
         );
@@ -184,7 +196,7 @@ describe('Curator', function () {
 
         // VACCINES
         cy.get('div[data-testid="vaccination.vaccination"]').click();
-        cy.get('li[data-value="Y"]').click();
+        cy.get(`li[data-value="${YesNo.Y}"]`).click();
         cy.get('input[name="vaccination.vaccineName"]').type('Moderna');
         cy.get('input[name="vaccination.vaccineDate"]').type('2020-03-01');
         cy.get('div[data-testid="vaccineSideEffects"]').click();
@@ -268,7 +280,7 @@ describe('Curator', function () {
                 'have.value',
                 'Berlin',
             );
-            cy.get('input[value="Martin Luther Hospital"]').should("exist");
+            cy.get('input[value="Martin Luther Hospital"]').should('exist');
 
             // Events.
             cy.get('input[name="events.dateEntry"]').should(
@@ -297,16 +309,19 @@ describe('Curator', function () {
             );
             cy.get('input[name="events.homeMonitoring"]').should(
                 'have.value',
-                'Y',
+                YesNo.Y,
+            );
+            cy.get('input[name="events.isolated"]').should(
+                'have.value',
+                YesNo.Y,
             );
-            cy.get('input[name="events.isolated"]').should('have.value', 'Y');
             cy.get('input[name="events.dateIsolation"]').should(
                 'have.value',
                 '2020/01/05',
             );
             cy.get('input[name="events.hospitalized"]').should(
                 'have.value',
-                'Y',
+                YesNo.Y,
             );
             cy.get('input[name="events.dateHospitalization"]').should(
                 'have.value',
@@ -318,7 +333,7 @@ describe('Curator', function () {
             );
             cy.get('input[name="events.intensiveCare"]').should(
                 'have.value',
-                'Y',
+                YesNo.Y,
             );
             cy.get('input[name="events.dateAdmissionICU"]').should(
                 'have.value',
@@ -344,7 +359,7 @@ describe('Curator', function () {
             // Preconditions.
             cy.get(
                 'input[name="preexistingConditions.previousInfection"]',
-            ).should('have.value', 'Y');
+            ).should('have.value', YesNo.Y);
             cy.get('input[name="preexistingConditions.coInfection"]').should(
                 'have.value',
                 'Flu',
@@ -353,12 +368,12 @@ describe('Curator', function () {
             cy.contains('ADULT syndrome');
             cy.get(
                 'input[name="preexistingConditions.pregnancyStatus"]',
-            ).should('have.value', 'N');
+            ).should('have.value', YesNo.N);
 
             // Transmission
             cy.get('input[name="transmission.contactWithCase"]').should(
                 'have.value',
-                'Y',
+                YesNo.Y,
             );
             cy.get('input[name="transmission.contactId"]').should(
                 'have.value',
@@ -386,7 +401,7 @@ describe('Curator', function () {
             // Travel history.
             cy.get('input[name="travelHistory.travelHistory"]').should(
                 'have.value',
-                'Y',
+                YesNo.Y,
             );
             cy.get('input[name="travelHistory.travelHistoryEntry"]').should(
                 'have.value',
@@ -408,7 +423,7 @@ describe('Curator', function () {
             // Vaccination
             cy.get('input[name="vaccination.vaccination"]').should(
                 'have.value',
-                'Y',
+                YesNo.Y,
             );
             cy.get('input[name="vaccination.vaccineName"]').should(
                 'have.value',
@@ -428,7 +443,7 @@ describe('Curator', function () {
                 cy.get('input[type="text"]').clear().type('Test occupation');
             });
             cy.contains('li', 'Test occupation').click();
-            cy.get('div[data-testid="location.comment"]').clear()
+            cy.get('div[data-testid="location.comment"]').clear();
             cy.contains('li', 'Martin Luther Hospital').click();
             // Submit the changes.
             cy.get('button[data-testid="submit"]').click();
diff --git a/verification/curator-service/ui/cypress/e2e/components/LinelistTableTest.spec.ts b/verification/curator-service/ui/cypress/e2e/components/LinelistTableTest.spec.ts
index e11307ab7..be520b375 100644
--- a/verification/curator-service/ui/cypress/e2e/components/LinelistTableTest.spec.ts
+++ b/verification/curator-service/ui/cypress/e2e/components/LinelistTableTest.spec.ts
@@ -491,4 +491,90 @@ describe('Linelist table', function () {
 
         cy.get('tr').eq(1).contains('France');
     });
+
+    it('Can search the data', () => {
+        cy.addCase({
+            country: 'France',
+            countryISO3: 'FRA',
+            dateEntry: '2020-05-01',
+            dateReported: '2020-05-01',
+            sourceUrl: 'www.example.com',
+            caseStatus: CaseStatus.Confirmed,
+            occupation: 'Actor',
+            comment: 'note',
+        });
+        cy.addCase({
+            country: 'Germany',
+            countryISO3: 'DEU',
+            dateEntry: '2020-05-01',
+            dateReported: '2020-05-01',
+            sourceUrl: 'www.example.com',
+            caseStatus: CaseStatus.Confirmed,
+            occupation: 'Doctor',
+        });
+        cy.addCase({
+            country: 'Argentina',
+            countryISO3: 'ARG',
+            dateEntry: '2020-05-01',
+            dateReported: '2020-05-01',
+            sourceUrl: 'www.example.com',
+            caseStatus: CaseStatus.Confirmed,
+            occupation: 'Engineer',
+        });
+
+        cy.intercept('GET', getDefaultQuery({ limit: 50 })).as('getCases');
+        cy.intercept('GET', getDefaultQuery({ limit: 50, query: 'Argentina' })).as('getCasesWithSearch1');
+        cy.intercept('GET', getDefaultQuery({ limit: 50, query: 'Doctor' })).as('getCasesWithSearch2');
+        cy.intercept('GET', getDefaultQuery({ limit: 50, query: 'note' })).as('getCasesWithSearch3');
+
+        cy.visit('/cases');
+        cy.wait('@getCases');
+
+        cy.contains('Argentina').should('exist');
+        cy.contains('France').should('exist');
+        cy.contains('Germany').should('exist');
+
+        cy.get('#search-field').type('Argentina');
+        cy.wait('@getCasesWithSearch1');
+        cy.contains('Argentina').should('exist');
+        cy.contains('France').should('not.exist');
+        cy.contains('Germany').should('not.exist');
+
+        cy.get('#clear-search').click();
+        cy.wait('@getCases');
+        cy.contains('Argentina').should('exist');
+        cy.contains('France').should('exist');
+        cy.contains('Germany').should('exist');
+
+        cy.get('#search-field').type('Doctor');
+        cy.wait('@getCasesWithSearch2');
+        cy.contains('Argentina').should('not.exist');
+        cy.contains('France').should('not.exist');
+        cy.contains('Germany').should('exist');
+
+        cy.get('#clear-search').click();
+        cy.wait('@getCases');
+        cy.contains('Argentina').should('exist');
+        cy.contains('France').should('exist');
+        cy.contains('Germany').should('exist');
+
+        cy.get('#search-field').type('note');
+        cy.wait('@getCasesWithSearch3');
+        cy.contains('Argentina').should('not.exist');
+        cy.contains('France').should('exist');
+        cy.contains('Germany').should('not.exist');
+    });
+
+    it('Informs user when uneven number of quotes is present in free-text search', () => {
+        cy.intercept('GET', getDefaultQuery({ limit: 50, query: '"Bus driver"' })).as('getCasesWithSearch');
+        cy.visit('/cases');
+        cy.contains('Please make sure you have an even number of quotes.').should('not.exist');
+
+        cy.get('#search-field').type('"Bus driver');
+        cy.contains('Please make sure you have an even number of quotes.').should('exist');
+
+        cy.get('#search-field').type('"');
+        cy.wait('@getCasesWithSearch');
+        cy.contains('Please make sure you have an even number of quotes.').should('not.exist');
+    });
 });
diff --git a/verification/curator-service/ui/cypress/support/commands.ts b/verification/curator-service/ui/cypress/support/commands.ts
index 4ddc86446..ce7c0dbf4 100644
--- a/verification/curator-service/ui/cypress/support/commands.ts
+++ b/verification/curator-service/ui/cypress/support/commands.ts
@@ -12,7 +12,7 @@ export enum Outcome {
 export enum YesNo {
     Y = 'Y',
     N = 'N',
-    NA = 'NA',
+    None = '',
 }
 
 export enum Gender {
@@ -43,6 +43,7 @@ interface AddCaseProps {
     gender?: Gender;
     outcome?: Outcome;
     uploadIds?: string[];
+    comment?: string;
 }
 
 declare global {
@@ -111,6 +112,7 @@ export function addCase(opts: AddCaseProps): void {
             travelHistory: {},
             genomeSequences: {},
             vaccination: {},
+            comment: opts.comment || '',
         },
     });
 }
diff --git a/verification/curator-service/ui/src/api/models/Case.ts b/verification/curator-service/ui/src/api/models/Case.ts
index 65a113dea..dbcf13d9f 100644
--- a/verification/curator-service/ui/src/api/models/Case.ts
+++ b/verification/curator-service/ui/src/api/models/Case.ts
@@ -1,4 +1,6 @@
 // Case definitions as defined by the /api/cases endpoint.
+import {YesNo} from "./Day0Case";
+
 export enum VerificationStatus {
     Unverified = 'UNVERIFIED',
     Verified = 'VERIFIED',
@@ -132,7 +134,7 @@ export interface Vaccine {
     batch: string;
     date: Date;
     sideEffects: Symptoms;
-    previousInfection: 'yes' | 'no' | 'NA';
+    previousInfection: YesNo;
     previousInfectionDetectionMethod: string;
 }
 
diff --git a/verification/curator-service/ui/src/api/models/Day0Case.ts b/verification/curator-service/ui/src/api/models/Day0Case.ts
index 434a47f30..c56030ca1 100644
--- a/verification/curator-service/ui/src/api/models/Day0Case.ts
+++ b/verification/curator-service/ui/src/api/models/Day0Case.ts
@@ -14,7 +14,7 @@ export enum Gender {
 export enum YesNo {
     Y = 'Y',
     N = 'N',
-    NA = 'NA',
+    None = '',
 }
 
 export enum HospitalizationReason {
diff --git a/verification/curator-service/ui/src/components/App/index.tsx b/verification/curator-service/ui/src/components/App/index.tsx
index eb8a9e22d..44c0e58c4 100644
--- a/verification/curator-service/ui/src/components/App/index.tsx
+++ b/verification/curator-service/ui/src/components/App/index.tsx
@@ -146,6 +146,7 @@ const useStyles = makeStyles()((theme: Theme) => ({
 
 function ProfileMenu(props: { user: User; version: string }): JSX.Element {
     const dispatch = useAppDispatch();
+    const user = useAppSelector(selectUser);
 
     const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
 
@@ -157,6 +158,10 @@ function ProfileMenu(props: { user: User; version: string }): JSX.Element {
         setAnchorEl(null);
     };
 
+    useCallback((): void => {
+        dispatch(getUserProfile());
+    }, [user]);
+
     const { classes } = menuStyles();
 
     const releaseNotesUrl = getReleaseNotesUrl(props.version);
@@ -322,13 +327,14 @@ export default function App(): JSX.Element {
     };
 
     const onModalClose = (): void => {
+        const searchQueryObject = new URLSearchParams(searchQuery);
         navigate(
             {
                 pathname:
                     location.state && location.state.lastLocation
                         ? location.state.lastLocation
                         : '/cases',
-                search: searchQuery,
+                search: searchQueryObject.toString(),
             },
             { state: { lastLocation: '/case/view' } },
         );
@@ -366,7 +372,8 @@ export default function App(): JSX.Element {
         )
             return;
 
-        dispatch(setSearchQuery(location.search));
+        const searchParams = new URLSearchParams(location.search);
+        dispatch(setSearchQuery(searchParams.toString()));
 
         // Save searchQuery to local storage not to lost it when user goes through auth process
         localStorage.setItem('searchQuery', location.search);
diff --git a/verification/curator-service/ui/src/components/DataGuideDialog.tsx b/verification/curator-service/ui/src/components/DataGuideDialog.tsx
index 95c406d5b..8a3c92801 100644
--- a/verification/curator-service/ui/src/components/DataGuideDialog.tsx
+++ b/verification/curator-service/ui/src/components/DataGuideDialog.tsx
@@ -1,7 +1,7 @@
 import React, { useEffect } from 'react';
 import { Box, Portal, Theme, Typography } from '@mui/material';
 import { withStyles } from 'tss-react/mui';
-import CloseIcon from '@mui/icons-material/Close';
+import { Close as CloseIcon } from '@mui/icons-material';
 import Draggable, { ControlPosition } from 'react-draggable';
 
 // As per this issue from react-draggable library: https://github.com/react-grid-layout/react-draggable/pull/648
@@ -97,7 +97,48 @@ const SearchGuideDialog = ({
                         </Typography>
                         <Typography className={classes?.textSection}>
                             <strong>For full-text search</strong>, enter any
-                            combination of search terms.
+                            combination of search terms. Rules for full-text
+                            search:
+                            <br />
+                            <ul>
+                                <li>
+                                    Full-text search covers: occupation, admin0,
+                                    admin1, admin2, admin3, sourceUrl, comment
+                                    and caseStatus.
+                                </li>
+                                <li>
+                                    Search terms must be exact (example:{' '}
+                                    <b>
+                                        <i>German</i>
+                                    </b>{' '}
+                                    will not match{' '}
+                                    <b>
+                                        <i>Germany</i>
+                                    </b>
+                                    ).
+                                </li>
+                                <li>
+                                    Full-text search matches cases that contain
+                                    any of the search terms, not a combination.
+                                </li>
+                                <li>
+                                    To search for a combination of terms, wrap
+                                    the combination in quotation marks (example:{' '}
+                                    <b>
+                                        <i>"Bus driver"</i>
+                                    </b>
+                                    ).
+                                </li>
+                                <li>
+                                    No special characters apart from dot are
+                                    allowed. Search terms with dot must be
+                                    contained within quotation marks (example:{' '}
+                                    <b>
+                                        <i>"global.health"</i>
+                                    </b>
+                                    ).
+                                </li>
+                            </ul>
                         </Typography>
                         <Typography>
                             You can use the icons on the right to navigate
diff --git a/verification/curator-service/ui/src/components/FiltersDialog/index.tsx b/verification/curator-service/ui/src/components/FiltersDialog/index.tsx
index 810a28c8d..a18d3c69e 100644
--- a/verification/curator-service/ui/src/components/FiltersDialog/index.tsx
+++ b/verification/curator-service/ui/src/components/FiltersDialog/index.tsx
@@ -17,7 +17,7 @@ import {
     useMediaQuery,
 } from '@mui/material';
 import { Close as CloseIcon } from '@mui/icons-material';
-import { filtersToURL, URLToFilters } from '../util/searchQuery';
+import { URLToFilters } from '../util/searchQuery';
 import { hasAnyRole } from '../util/helperFunctions';
 import { useAppSelector, useAppDispatch } from '../../hooks/redux';
 import { fetchCountries } from '../../redux/filters/thunk';
@@ -153,13 +153,19 @@ export default function FiltersDialog({
             handleSetModalAlert();
             dispatch(setModalOpen(false));
 
-            const searchQuery = filtersToURL(values);
+            const searchParams = new URLSearchParams();
+            for (const [key, value] of Object.entries(values)) {
+                if (value) searchParams.set(key, value);
+            }
+            const q = (new URLSearchParams(location.search)).get('q')
+            if (q) searchParams.set('q', q);
+            const searchParamsString = searchParams.toString();
 
-            sendCustomGtmEvent('filters_applied', { query: searchQuery });
+            sendCustomGtmEvent('filters_applied', { query: searchParamsString });
 
             navigate({
                 pathname: '/cases',
-                search: searchQuery,
+                search: searchParamsString,
             });
         },
     });
diff --git a/verification/curator-service/ui/src/components/SearchBar.tsx b/verification/curator-service/ui/src/components/SearchBar.tsx
index 9b9d79d53..f45287740 100644
--- a/verification/curator-service/ui/src/components/SearchBar.tsx
+++ b/verification/curator-service/ui/src/components/SearchBar.tsx
@@ -15,7 +15,6 @@ import clsx from 'clsx';
 import DataGuideDialog from './DataGuideDialog';
 import { useDebounce } from '../hooks/useDebounce';
 import FiltersDialog from './FiltersDialog';
-import { searchQueryToURL, URLToSearchQuery } from './util/searchQuery';
 import { useLocation, useNavigate } from 'react-router-dom';
 import { KeyboardEvent, ChangeEvent } from 'react';
 import { useAppSelector, useAppDispatch } from '../hooks/redux';
@@ -85,9 +84,7 @@ export default function SearchBar({
     const [isUserTyping, setIsUserTyping] = useState<boolean>(false);
     const [isDataGuideOpen, setIsDataGuideOpen] = useState<boolean>(false);
     const [searchInput, setSearchInput] = useState<string>(
-        location.search.includes('?q=')
-            ? URLToSearchQuery(location.search)
-            : '',
+        new URLSearchParams(location.search).get('q') || '',
     );
     const [modalAlert, setModalAlert] = useState<boolean>(false);
     const guideButtonRef = React.useRef<HTMLButtonElement>(null);
@@ -103,28 +100,30 @@ export default function SearchBar({
         }
     }, [filtersBreadcrumb]);
 
+    useEffect(() => {
+        const q = new URLSearchParams(location.search).get('q') || '';
+        if (q !== searchInput) setSearchInput(q);
+    }, [location.search]);
+
     // Set search query debounce to 1000ms
     const debouncedSearch = useDebounce(searchInput, 2000);
 
-    // Update search input based on search query
-    useEffect(() => {
-        if (!location.search.includes('?q=')) {
-            setSearchInput('');
-            return;
-        }
+    const handleNavigating = (q: string) => {
+        const searchParams = new URLSearchParams(location.search);
+        q !== '' ? searchParams.set('q', q) : searchParams.delete('q');
 
-        setSearchInput(URLToSearchQuery(location.search));
-    }, [location.search]);
+        navigate({
+            pathname: '/cases',
+            search: searchParams.toString(),
+        });
+    };
 
     // Apply filter parameters after delay
     useEffect(() => {
         if (!isUserTyping) return;
-
         setIsUserTyping(false);
-        navigate({
-            pathname: '/cases',
-            search: searchQueryToURL(debouncedSearch),
-        });
+
+        handleNavigating(debouncedSearch);
         //eslint-disable-next-line
     }, [debouncedSearch]);
 
@@ -136,10 +135,8 @@ export default function SearchBar({
         if (ev.key === 'Enter') {
             ev.preventDefault();
             setIsUserTyping(false);
-            navigate({
-                pathname: '/cases',
-                search: searchQueryToURL(searchInput),
-            });
+
+            handleNavigating(searchInput);
         }
     };
 
@@ -174,16 +171,24 @@ export default function SearchBar({
         return searchStringStrippedOutColon;
     }
 
+    const renderSearchErrorMessage = () => {
+        if (searchError) {
+            return 'Incorrect entry. ":" characters have been removed. Please use filters instead.';
+        } else {
+            const quoteCount = searchInput.split('"').length - 1;
+            if (quoteCount % 2 !== 0) {
+                return 'Incorrect entry. Please make sure you have an even number of quotes.';
+            }
+        }
+    };
+
     return (
         <>
             <div className={classes.searchRoot}>
                 <StyledSearchTextField
                     size="small"
                     error={searchError}
-                    helperText={
-                        searchError &&
-                        'Incorrect entry. ":" characters have been removed. Please use filters instead.'
-                    }
+                    helperText={renderSearchErrorMessage()}
                     id="search-field"
                     data-testid="searchbar"
                     name="searchbar"
@@ -254,6 +259,7 @@ export default function SearchBar({
                                     <IconButton
                                         color="primary"
                                         aria-label="clear search"
+                                        id="clear-search"
                                         onClick={(): void => {
                                             setSearchInput('');
                                             navigate({
diff --git a/verification/curator-service/ui/src/components/ViewCase.tsx b/verification/curator-service/ui/src/components/ViewCase.tsx
index edc5eab8d..15b669087 100644
--- a/verification/curator-service/ui/src/components/ViewCase.tsx
+++ b/verification/curator-service/ui/src/components/ViewCase.tsx
@@ -1,6 +1,19 @@
+import axios from 'axios';
 import React, { useEffect, useState } from 'react';
+import Highlighter from 'react-highlight-words';
+import { useSelector } from 'react-redux';
+import { Link, useParams } from 'react-router-dom';
+import Scroll from 'react-scroll';
+import { makeStyles } from 'tss-react/mui';
 import {
+    CheckCircleOutline as CheckIcon,
+    Close as CloseIcon,
+    EditOutlined as EditIcon,
+} from '@mui/icons-material';
+import {
+    Alert,
     Button,
+    Chip,
     Dialog,
     DialogContent,
     DialogTitle,
@@ -9,30 +22,20 @@ import {
     LinearProgress,
     Paper,
     Typography,
+    useMediaQuery,
 } from '@mui/material';
+import { useTheme } from '@mui/material/styles';
+
 import { Day0Case, Outcome, YesNo } from '../api/models/Day0Case';
+import { Role } from '../api/models/User';
 import AppModal from './AppModal';
-import EditIcon from '@mui/icons-material/EditOutlined';
-import CheckIcon from '@mui/icons-material/CheckCircleOutline';
-import { Link, useParams } from 'react-router-dom';
-import MuiAlert from '@mui/material/Alert';
-import Scroll from 'react-scroll';
-import axios from 'axios';
-import createHref from './util/links';
-import { makeStyles } from 'tss-react/mui';
 import renderDate from './util/date';
-import useMediaQuery from '@mui/material/useMediaQuery';
-import { useTheme } from '@mui/material/styles';
-import Highlighter from 'react-highlight-words';
-import { useSelector } from 'react-redux';
+import createHref from './util/links';
 import { selectFilterBreadcrumbs } from '../redux/app/selectors';
+import { selectUser } from '../redux/auth/selectors';
 import { selectSearchQuery } from '../redux/linelistTable/selectors';
-import Chip from '@mui/material/Chip';
 import { nameCountry } from './util/countryNames';
 import { parseAgeRange } from './util/helperFunctions';
-import CloseIcon from '@mui/icons-material/Close';
-import { selectUser } from '../redux/auth/selectors';
-import { Role } from '../api/models/User';
 
 const styles = makeStyles()(() => ({
     errorMessage: {
@@ -98,14 +101,14 @@ export default function ViewCase(props: Props): JSX.Element {
         <AppModal title="Case details" onModalClose={props.onModalClose}>
             {loading && <LinearProgress />}
             {errorMessage && (
-                <MuiAlert
+                <Alert
                     className={classes.errorMessage}
                     elevation={6}
                     variant="filled"
                     severity="error"
                 >
                     {errorMessage}
-                </MuiAlert>
+                </Alert>
             )}
             {c && (
                 <CaseDetails
@@ -966,16 +969,36 @@ function RowContent(props: {
     linkComment?: string;
 }): JSX.Element {
     const searchQuery = useSelector(selectSearchQuery);
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    const searchQueryArray: any[] = [];
+    const searchQueryArray: string[] = [];
 
     function words(s: string) {
-        const regex = /"([^"]+)"|(\w{3,})/g;
-        let match;
-        while ((match = regex.exec(s))) {
-            searchQueryArray.push(match[match[1] ? 1 : 2]);
+        const q = new URLSearchParams(s).get('q');
+        if (!q) return;
+
+        const quoted: string[] = [];
+        const notQuoted: string[] = [];
+        if (q.includes('"') && q.replace(/[^"]/g, '').length % 2 !== 1) {
+            q.split('"').map((subs: string, i: number) => {
+                subs != '' && i % 2 ? quoted.push(subs) : notQuoted.push(subs);
+            });
+        } else notQuoted.push(q);
+
+        const regex = /"([^"]+)"|(\S{1,})/g;
+        // Make sure that terms in quotes will be highlighted as one search term
+        for (const quotedEntry of quoted) {
+            let match;
+            let accumulator: string[] = [];
+            while ((match = regex.exec(quotedEntry))) {
+                accumulator.push(match[match[1] ? 1 : 2]);
+            }
+            searchQueryArray.push(accumulator.join(' '));
+        }
+        for (const notQuotedEntry of notQuoted) {
+            let match;
+            while ((match = regex.exec(notQuotedEntry))) {
+                searchQueryArray.push(match[match[1] ? 1 : 2]);
+            }
         }
-        return searchQueryArray;
     }
     words(searchQuery);
 
diff --git a/verification/curator-service/ui/src/components/common-form-fields/FormikFields.tsx b/verification/curator-service/ui/src/components/common-form-fields/FormikFields.tsx
index 783ff5bcf..15b61bb6d 100644
--- a/verification/curator-service/ui/src/components/common-form-fields/FormikFields.tsx
+++ b/verification/curator-service/ui/src/components/common-form-fields/FormikFields.tsx
@@ -173,7 +173,7 @@ export function SelectField(props: SelectFieldProps): JSX.Element {
             >
                 {props.values.map((value) => (
                     <MenuItem key={value} value={value}>
-                        {value}
+                        {value === '' ? <i>None</i> : value}
                     </MenuItem>
                 ))}
             </FastField>
diff --git a/verification/curator-service/ui/src/components/fixtures/fullCase.json b/verification/curator-service/ui/src/components/fixtures/fullCase.json
index 8d3f915d9..cc5730249 100644
--- a/verification/curator-service/ui/src/components/fixtures/fullCase.json
+++ b/verification/curator-service/ui/src/components/fixtures/fullCase.json
@@ -37,7 +37,7 @@
     "symptoms": "Severe pneumonia, Dyspnea, Weakness",
     "preexistingConditions": {
         "previousInfection": "N",
-        "pregnancyStatus": "NA"
+        "pregnancyStatus": ""
     },
     "transmission": {
         "contactWithCase": "N"
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/CaseFormValues.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/CaseFormValues.tsx
index e40bf2e3f..ab9a71f1c 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/CaseFormValues.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/CaseFormValues.tsx
@@ -1,5 +1,6 @@
 import { CaseReferenceForm } from '../common-form-fields/Source';
 import { Location as Loc } from '../../api/models/Case';
+import { YesNo } from '../../api/models/Day0Case';
 
 /**
  * CaseFormValues defines all the values contained in the manual case entry form.
@@ -88,7 +89,7 @@ export interface Vaccine {
     batch?: string;
     date?: Date;
     sideEffects: Symptom;
-    previousInfection: 'yes' | 'no' | 'NA';
+    previousInfection: YesNo;
     previousInfectionDetectionMethod?: string;
 }
 
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/Demographics.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/Demographics.tsx
index 66baef092..3fcd37454 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/Demographics.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/Demographics.tsx
@@ -12,7 +12,7 @@ import { TextField } from 'formik-mui';
 import { StyledTooltip } from './StyledTooltip';
 import axios from 'axios';
 import { makeStyles } from 'tss-react/mui';
-import { Gender, Day0CaseFormValues } from '../../api/models/Day0Case';
+import { Gender, Day0CaseFormValues, YesNo } from '../../api/models/Day0Case';
 import { useStyles } from './styled';
 
 const styles = makeStyles()(() => ({
@@ -169,7 +169,7 @@ export default function Demographics(): JSX.Element {
             <SelectField
                 name="demographics.healthcareWorker"
                 label="Healthcare worker"
-                values={['Y', 'N', 'NA']}
+                values={Object.values(YesNo)}
             />
         </Scroll.Element>
     );
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/Events.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/Events.tsx
index c4da29e8e..73032ace3 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/Events.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/Events.tsx
@@ -1,15 +1,13 @@
 import clsx from 'clsx';
-import { FastField, useFormikContext } from 'formik';
-import { TextField } from 'formik-mui';
+import {FastField, useFormikContext} from 'formik';
+import {TextField} from 'formik-mui';
 import Scroll from 'react-scroll';
 
-import { Outcome, Day0CaseFormValues } from '../../api/models/Day0Case';
-import { DateField, SelectField } from '../common-form-fields/FormikFields';
+import {Day0CaseFormValues, Outcome, YesNo} from '../../api/models/Day0Case';
+import {DateField, SelectField} from '../common-form-fields/FormikFields';
 import FieldTitle from '../common-form-fields/FieldTitle';
-import { useStyles } from './styled';
-import { StyledTooltip } from './StyledTooltip';
-
-const yesNoUndefined = ['Y', 'N', 'NA'];
+import {useStyles} from './styled';
+import {StyledTooltip} from './StyledTooltip';
 
 const outcomes = ['recovered', 'death'];
 
@@ -184,14 +182,14 @@ export default function Events(): JSX.Element {
             <SelectField
                 name="events.homeMonitoring"
                 label="Home monitoring"
-                values={yesNoUndefined}
+                values={Object.values(YesNo)}
             />
             <SelectField
                 name="events.isolated"
                 label="Isolated"
-                values={yesNoUndefined}
+                values={Object.values(YesNo)}
             />
-            {values.events.isolated === 'Y' && (
+            {values.events.isolated === YesNo.Y && (
                 <DateField
                     name="events.dateIsolation"
                     label="Date of isolation"
@@ -206,9 +204,9 @@ export default function Events(): JSX.Element {
             <SelectField
                 name="events.hospitalized"
                 label="Hospital admission"
-                values={yesNoUndefined}
+                values={Object.values(YesNo)}
             />
-            {values.events.hospitalized === 'Y' && (
+            {values.events.hospitalized === YesNo.Y && (
                 <>
                     <DateField
                         name="events.dateHospitalization"
@@ -241,9 +239,9 @@ export default function Events(): JSX.Element {
             <SelectField
                 name="events.intensiveCare"
                 label="Intensive care"
-                values={yesNoUndefined}
+                values={Object.values(YesNo)}
             />
-            {values.events.intensiveCare === 'Y' && (
+            {values.events.intensiveCare === YesNo.Y && (
                 <>
                     <DateField
                         name="events.dateAdmissionICU"
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/Location.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/Location.tsx
index 607260287..906b812af 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/Location.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/Location.tsx
@@ -120,7 +120,6 @@ export default function Location(): JSX.Element {
                 setSelectedAdmin1(foundAdmin1Entry);
             }
         }
-        // eslint-disable-next-line react-hooks/exhaustive-deps
     }, [values.location.countryISO3, admin1Entries]);
 
     useEffect(() => {
@@ -177,8 +176,6 @@ export default function Location(): JSX.Element {
 
         // Update mapbox indicator for admin1
         setAdmin1AvailableOnMap(!!values.location.admin1WikiId);
-
-        // eslint-disable-next-line react-hooks/exhaustive-deps
     }, [values.location.admin1WikiId, values.location.admin1, admin2Entries]);
 
     useEffect(() => {
@@ -235,8 +232,6 @@ export default function Location(): JSX.Element {
 
         // Update mapbox indicator for admin2
         setAdmin2AvailableOnMap(!!values.location.admin2WikiId);
-
-        // eslint-disable-next-line react-hooks/exhaustive-deps
     }, [values.location.admin2WikiId, values.location.admin2, admin3Entries]);
 
     useEffect(() => {
@@ -258,8 +253,6 @@ export default function Location(): JSX.Element {
 
         // Update mapbox indicator for admin3
         setAdmin3AvailableOnMap(!!values.location.admin3WikiId);
-
-        // eslint-disable-next-line react-hooks/exhaustive-deps
     }, [values.location.admin3WikiId, values.location.admin3]);
 
     useEffect(() => {
@@ -326,15 +319,14 @@ export default function Location(): JSX.Element {
             'location.geometry.latitude',
             values.location.geocodeLocation.geometry?.latitude ||
                 values.location.geometry?.latitude ||
-                '',
+                undefined,
         );
         setFieldValue(
             'location.geometry.longitude',
             values.location.geocodeLocation.geometry?.longitude ||
                 values.location.geometry?.longitude ||
-                '',
+                undefined,
         );
-        // eslint-disable-next-line react-hooks/exhaustive-deps
     }, [values.location.geocodeLocation]);
 
     return (
@@ -486,7 +478,10 @@ export default function Location(): JSX.Element {
                             _: unknown,
                             newValue: adminEntry | null,
                         ): void => {
-                            setFieldValue('location.admin1', newValue?.name || '');
+                            setFieldValue(
+                                'location.admin1',
+                                newValue?.name || '',
+                            );
                             setFieldValue(
                                 'location.admin1WikiId',
                                 newValue?.wiki || '',
@@ -588,7 +583,10 @@ export default function Location(): JSX.Element {
                             _: unknown,
                             newValue: adminEntry | null,
                         ): void => {
-                            setFieldValue('location.admin2', newValue?.name || '');
+                            setFieldValue(
+                                'location.admin2',
+                                newValue?.name || '',
+                            );
                             setFieldValue(
                                 'location.admin2WikiId',
                                 newValue?.wiki || '',
@@ -690,7 +688,10 @@ export default function Location(): JSX.Element {
                             _: unknown,
                             newValue: adminEntry | null,
                         ): void => {
-                            setFieldValue('location.admin3', newValue?.name || '');
+                            setFieldValue(
+                                'location.admin3',
+                                newValue?.name || '',
+                            );
                             setFieldValue(
                                 'location.admin3WikiId',
                                 newValue?.wiki || '',
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/PreexistingConditions.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/PreexistingConditions.tsx
index 8fac45d58..1e3015ea0 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/PreexistingConditions.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/PreexistingConditions.tsx
@@ -3,7 +3,7 @@ import { FastField, useFormikContext } from 'formik';
 import { TextField } from 'formik-mui';
 import Scroll from 'react-scroll';
 
-import { Day0CaseFormValues } from '../../api/models/Day0Case';
+import { Day0CaseFormValues, YesNo } from '../../api/models/Day0Case';
 import {
     FormikAutocomplete,
     SelectField,
@@ -12,8 +12,6 @@ import FieldTitle from '../common-form-fields/FieldTitle';
 import { useStyles } from './styled';
 import { StyledTooltip } from './StyledTooltip';
 
-const hasPreexistingConditionsValues = ['Y', 'N', 'NA'];
-
 const TooltipText = () => (
     <StyledTooltip>
         <ul>
@@ -60,7 +58,7 @@ export default function PreexistingConditions(): JSX.Element {
             <SelectField
                 name="preexistingConditions.previousInfection"
                 label="Previous infection"
-                values={hasPreexistingConditionsValues}
+                values={Object.values(YesNo)}
             />
 
             <div className={clsx([classes.fieldRow, classes.halfWidth])}>
@@ -87,7 +85,7 @@ export default function PreexistingConditions(): JSX.Element {
             <SelectField
                 name="preexistingConditions.pregnancyStatus"
                 label="Pregnancy status"
-                values={hasPreexistingConditionsValues}
+                values={Object.values(YesNo)}
             />
         </Scroll.Element>
     );
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/Transmission.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/Transmission.tsx
index 300e00c82..77d5585ce 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/Transmission.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/Transmission.tsx
@@ -3,7 +3,7 @@ import { FastField, useFormikContext } from 'formik';
 import { TextField } from 'formik-mui';
 import Scroll from 'react-scroll';
 
-import { Day0CaseFormValues } from '../../api/models/Day0Case';
+import { Day0CaseFormValues, YesNo } from '../../api/models/Day0Case';
 import FieldTitle from '../common-form-fields/FieldTitle';
 import {
     FormikAutocomplete,
@@ -54,7 +54,7 @@ export default function Transmission(): JSX.Element {
             <SelectField
                 name="transmission.contactWithCase"
                 label="Contact with case"
-                values={['Y', 'N', 'NA']}
+                values={Object.values(YesNo)}
             />
             <div className={clsx([classes.fieldRow, classes.halfWidth])}>
                 <FastField
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/TravelHistory.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/TravelHistory.tsx
index 225d00e00..26e1e72cf 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/TravelHistory.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/TravelHistory.tsx
@@ -8,8 +8,7 @@ import { DateField, SelectField } from '../common-form-fields/FormikFields';
 import FieldTitle from '../common-form-fields/FieldTitle';
 import { useStyles } from './styled';
 import { StyledTooltip } from './StyledTooltip';
-
-const hasTravelledValues = ['Y', 'N', 'NA'];
+import { YesNo } from '../../api/models/Day0Case';
 
 const TooltipText = () => (
     <StyledTooltip>
@@ -59,9 +58,9 @@ export default function TravelHistory(): JSX.Element {
             <SelectField
                 name="travelHistory.travelHistory"
                 label="Travel history"
-                values={hasTravelledValues}
+                values={Object.values(YesNo)}
             />
-            {values.travelHistory.travelHistory === 'Y' && (
+            {values.travelHistory.travelHistory === YesNo.Y && (
                 <>
                     <DateField
                         name="travelHistory.travelHistoryEntry"
diff --git a/verification/curator-service/ui/src/components/new-case-form-fields/Vaccines.tsx b/verification/curator-service/ui/src/components/new-case-form-fields/Vaccines.tsx
index d04115690..88be2afe3 100644
--- a/verification/curator-service/ui/src/components/new-case-form-fields/Vaccines.tsx
+++ b/verification/curator-service/ui/src/components/new-case-form-fields/Vaccines.tsx
@@ -1,14 +1,14 @@
 import clsx from 'clsx';
-import { FastField, useFormikContext } from 'formik';
-import { TextField } from 'formik-mui';
+import {FastField, useFormikContext} from 'formik';
+import {TextField} from 'formik-mui';
 import Scroll from 'react-scroll';
 
-import { Day0CaseFormValues } from '../../api/models/Day0Case';
-import { DateField, SelectField } from '../common-form-fields/FormikFields';
+import {Day0CaseFormValues, YesNo} from '../../api/models/Day0Case';
+import {DateField, SelectField} from '../common-form-fields/FormikFields';
 import FieldTitle from '../common-form-fields/FieldTitle';
-import { useStyles } from './styled';
-import { StyledTooltip } from './StyledTooltip';
-import { VaccineSideEffects } from './Symptoms';
+import {useStyles} from './styled';
+import {StyledTooltip} from './StyledTooltip';
+import {VaccineSideEffects} from './Symptoms';
 
 const TooltipText = () => (
     <StyledTooltip>
@@ -45,9 +45,9 @@ export default function Vaccines(): JSX.Element {
             <SelectField
                 name="vaccination.vaccination"
                 label="Vaccination"
-                values={['Y', 'N', 'NA']}
+                values={Object.values(YesNo)}
             />
-            {values.vaccination.vaccination === 'Y' && (
+            {values.vaccination.vaccination === YesNo.Y && (
                 <>
                     <div
                         className={clsx([classes.fieldRow, classes.halfWidth])}
diff --git a/verification/curator-service/ui/src/redux/auth/slice.ts b/verification/curator-service/ui/src/redux/auth/slice.ts
index 3a56a5915..b4e38fee5 100644
--- a/verification/curator-service/ui/src/redux/auth/slice.ts
+++ b/verification/curator-service/ui/src/redux/auth/slice.ts
@@ -157,6 +157,7 @@ const authSlice = createSlice({
         // LOGOUT
         builder.addCase(logout.fulfilled, (state) => {
             state.user = undefined;
+            localStorage.removeItem('user');
         });
 
         // CHANGE PASSWORD