From cfae694fd0657ebd4ad3880356fdd0fa7d8e9065 Mon Sep 17 00:00:00 2001 From: Monchee Date: Fri, 21 Aug 2026 05:28:20 +1000 Subject: [PATCH] fix: sync reviewed protocol dates and freeze order check --- scripts/verify-order.mjs | 79 ++++++++++++--------- src/shared/data/drugMasterlist.generated.ts | 10 +-- src/shared/data/drugMasterlist.test.ts | 2 +- src/shared/data/protocols.snapshot.json | 24 +++---- 4 files changed, 63 insertions(+), 52 deletions(-) diff --git a/scripts/verify-order.mjs b/scripts/verify-order.mjs index 3fe9207..fad7b61 100644 --- a/scripts/verify-order.mjs +++ b/scripts/verify-order.mjs @@ -1,20 +1,46 @@ #!/usr/bin/env node -import { execSync } from 'node:child_process'; import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..'); +const FIXTURE_PATH = join(ROOT, 'src', 'shared', 'data', 'expectedProtocolOrder.json'); -// 1. Read old drugMasterlist.ts from git HEAD -// Baseline must be a revision where drugMasterlist.ts still holds the hand-typed -// records. HEAD stops being that as soon as this change is committed, so default to -// origin/main and allow an override: `node scripts/verify-order.mjs `. -const BASELINE_REF = process.argv[2] || 'origin/main'; -const oldFileContent = execSync( - `GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 git show ${BASELINE_REF}:src/shared/data/drugMasterlist.ts`, - { encoding: 'utf8' } -); +// 1. Read and validate expectedProtocolOrder.json fixture +let fixture; +try { + const fixtureContent = readFileSync(FIXTURE_PATH, 'utf8'); + fixture = JSON.parse(fixtureContent); +} catch (err) { + console.error(`BROKEN CHECK: Failed to read or parse fixture at ${FIXTURE_PATH}: ${err.message}`); + process.exit(2); +} + +const EXPECTED_PROTOCOL_COUNT = 116; +if ( + !fixture || + typeof fixture !== 'object' || + !Array.isArray(fixture.order) || + !Number.isInteger(fixture.count) || + fixture.count !== EXPECTED_PROTOCOL_COUNT || + fixture.order.length !== EXPECTED_PROTOCOL_COUNT +) { + console.error( + `BROKEN CHECK: fixture is malformed or count mismatch (count: ${fixture?.count}, order.length: ${fixture?.order?.length}).\n` + + `Expected an object with 'order' array and matching integer 'count' equal to ${EXPECTED_PROTOCOL_COUNT}.` + ); + process.exit(2); +} + +for (let i = 0; i < fixture.order.length; i++) { + const item = fixture.order[i]; + if (!item || typeof item.drugName !== 'string' || typeof item.testType !== 'string' || typeof item.protocolLabel !== 'string') { + console.error(`BROKEN CHECK: fixture entry at index ${i} is malformed: ${JSON.stringify(item)}`); + process.exit(2); + } +} + +const expectedTuples = fixture.order; function extractTuples(fileContent) { const tuples = []; @@ -30,21 +56,6 @@ function extractTuples(fileContent) { return tuples; } -const oldTuples = extractTuples(oldFileContent); - -// A baseline that yields almost no records means the ref is not the pre-change file -// (e.g. it already points at the thin module). Fail loudly as a broken check rather -// than silently reporting every position as a mismatch. -const MIN_EXPECTED_BASELINE = 50; -if (oldTuples.length < MIN_EXPECTED_BASELINE) { - console.error( - `BROKEN CHECK: baseline ref '${BASELINE_REF}' yielded only ${oldTuples.length} records ` + - `(expected >= ${MIN_EXPECTED_BASELINE}).\nThis is not a reordering failure — the baseline is wrong. ` + - `Pass a ref where drugMasterlist.ts still holds the hand-typed records.` - ); - process.exit(2); -} - // 2. Read generated and dream-only files to reconstruct the merged DRUG_MASTERLIST order const generatedContent = readFileSync(join(ROOT, 'src', 'shared', 'data', 'drugMasterlist.generated.ts'), 'utf8'); const dreamOnlyContent = readFileSync(join(ROOT, 'src', 'shared', 'data', 'dreamOnlyProtocols.ts'), 'utf8'); @@ -61,7 +72,7 @@ function findGenTuple(drugName, testType, label) { } // Reconstruct merged array order exactly as drugMasterlist.ts does -const newTuples = [ +const actualTuples = [ findGenTuple('Cis-atracurium', 'skin'), findGenTuple('Rocuronium', 'skin'), findGenTuple('Pancuronium', 'skin'), @@ -77,21 +88,21 @@ const newTuples = [ console.log('================================================================================'); console.log('DRUG MASTERLIST POSITIONAL ORDER VERIFICATION'); console.log('================================================================================'); -console.log(`OLD (${BASELINE_REF}) record count: ${oldTuples.length}`); -console.log(`NEW (merged) record count: ${newTuples.length}`); +console.log(`EXPECTED (fixture) record count: ${expectedTuples.length}`); +console.log(`ACTUAL (merged) record count: ${actualTuples.length}`); let mismatches = 0; -const total = Math.max(oldTuples.length, newTuples.length); +const total = Math.max(expectedTuples.length, actualTuples.length); for (let i = 0; i < total; i++) { - const o = oldTuples[i]; - const n = newTuples[i]; + const exp = expectedTuples[i]; + const act = actualTuples[i]; - if (!o || !n || o.drugName !== n.drugName || o.testType !== n.testType || o.protocolLabel !== n.protocolLabel) { + if (!exp || !act || exp.drugName !== act.drugName || exp.testType !== act.testType || exp.protocolLabel !== act.protocolLabel) { mismatches++; console.error(`MISMATCH at index ${i}:`); - console.error(` OLD: ${JSON.stringify(o)}`); - console.error(` NEW: ${JSON.stringify(n)}`); + console.error(` EXPECTED: ${JSON.stringify(exp)}`); + console.error(` ACTUAL: ${JSON.stringify(act)}`); } } diff --git a/src/shared/data/drugMasterlist.generated.ts b/src/shared/data/drugMasterlist.generated.ts index 3cc7820..7495672 100644 --- a/src/shared/data/drugMasterlist.generated.ts +++ b/src/shared/data/drugMasterlist.generated.ts @@ -51,7 +51,7 @@ export const GENERATED_PROTOCOLS: DrugProtocol[] = [ protocolLabel: "IV", sourceSlug: "cis-atracurium", underReview: false, - lastReviewed: "2026-08-20", + lastReviewed: "2026-03-28", }, { id: "iv", @@ -66,7 +66,7 @@ export const GENERATED_PROTOCOLS: DrugProtocol[] = [ protocolLabel: "IV", sourceSlug: "pancuronium", underReview: false, - lastReviewed: "2026-08-20", + lastReviewed: "2026-03-28", }, { id: "iv", @@ -81,7 +81,7 @@ export const GENERATED_PROTOCOLS: DrugProtocol[] = [ protocolLabel: "IV", sourceSlug: "rocuronium", underReview: false, - lastReviewed: "2026-08-20", + lastReviewed: "2026-03-28", }, { id: "iv", @@ -96,7 +96,7 @@ export const GENERATED_PROTOCOLS: DrugProtocol[] = [ protocolLabel: "IV", sourceSlug: "suxamethonium", underReview: false, - lastReviewed: "2026-08-20", + lastReviewed: "2026-03-28", }, { id: "iv", @@ -111,6 +111,6 @@ export const GENERATED_PROTOCOLS: DrugProtocol[] = [ protocolLabel: "IV", sourceSlug: "vecuronium", underReview: false, - lastReviewed: "2026-08-20", + lastReviewed: "2026-03-28", }, ]; diff --git a/src/shared/data/drugMasterlist.test.ts b/src/shared/data/drugMasterlist.test.ts index dfc9f1e..54585a4 100644 --- a/src/shared/data/drugMasterlist.test.ts +++ b/src/shared/data/drugMasterlist.test.ts @@ -93,7 +93,7 @@ describe('drugMasterlist diluents & snapshot data', () => { const rocuronium = getSkinProtocolsForDrug('Rocuronium')[0]; expect(rocuronium.sourceSlug).toBe('rocuronium'); expect(rocuronium.underReview).toBe(false); - expect(rocuronium.lastReviewed).toBe('2026-08-20'); + expect(rocuronium.lastReviewed).toBe('2026-03-28'); expect(rocuronium.id).toBe('iv'); }); diff --git a/src/shared/data/protocols.snapshot.json b/src/shared/data/protocols.snapshot.json index 1b3354f..469959a 100644 --- a/src/shared/data/protocols.snapshot.json +++ b/src/shared/data/protocols.snapshot.json @@ -1,7 +1,7 @@ { "schema_version": "1.0", - "generated_at": "2026-08-20T09:16:09Z", - "source_commit": "6d12cec", + "generated_at": "2026-08-20T11:45:36Z", + "source_commit": "254b399", "drugs": [ { "slug": "cefazolin", @@ -63,8 +63,8 @@ { "slug": "cis-atracurium", "title": "Cis-atracurium", - "version": "1.3", - "last_reviewed": "2026-08-20", + "version": "1.4", + "last_reviewed": "2026-03-28", "dream": { "category": "Muscle Relaxants" }, @@ -97,8 +97,8 @@ { "slug": "pancuronium", "title": "Pancuronium", - "version": "1.3", - "last_reviewed": "2026-08-20", + "version": "1.4", + "last_reviewed": "2026-03-28", "dream": { "category": "Muscle Relaxants" }, @@ -136,8 +136,8 @@ { "slug": "rocuronium", "title": "Rocuronium", - "version": "1.3", - "last_reviewed": "2026-08-20", + "version": "1.4", + "last_reviewed": "2026-03-28", "dream": { "category": "Muscle Relaxants" }, @@ -175,8 +175,8 @@ { "slug": "suxamethonium", "title": "Suxamethonium", - "version": "1.3", - "last_reviewed": "2026-08-20", + "version": "1.4", + "last_reviewed": "2026-03-28", "dream": { "category": "Muscle Relaxants" }, @@ -219,8 +219,8 @@ { "slug": "vecuronium", "title": "Vecuronium", - "version": "1.3", - "last_reviewed": "2026-08-20", + "version": "1.4", + "last_reviewed": "2026-03-28", "dream": { "category": "Muscle Relaxants" },