Added new diseases; updated metadata parsing and versions.

This commit is contained in:
Bruno Silva committed 2026-11-04 15:10:18 -05:00
1 parent 99248af7ba
commit fe1ec614b7
4 files changed
+30 -10

No files matched your search

+6 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "ctm-document-builder", "name": "ctm-document-builder",
"version": "1.2.2", "version": "1.3.0",
"description": "CTM Document Builder — Electron + React with cloud PocketBase", "description": "CTM Document Builder — Electron + React with cloud PocketBase",
"author": "Wirediv", "author": "Wirediv",
"license": "MIT", "license": "MIT",
@@ -28,7 +28,7 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-react": "^4.3.3", "@vitejs/plugin-react": "^4.3.3",
"electron": "^33.2.0", "electron": "^33.4.11",
"electron-builder": "^24.13.3", "electron-builder": "^24.13.3",
"vite": "^5.4.11", "vite": "^5.4.11",
"vite-plugin-electron": "^0.29.0", "vite-plugin-electron": "^0.29.0",
@@ -75,5 +75,9 @@
], ],
"artifactName": "${productName}_${version}.${ext}" "artifactName": "${productName}_${version}.${ext}"
} }
},
"allowScripts": {
"electron@33.4.11": true,
"esbuild@0.21.5": true
} }
} }
+1 -1
View File
@@ -351,7 +351,7 @@ export function buildVaccinationRecordHtml({
</tr> </tr>
<tr> <tr>
<th class="col-date">Date</th> <th class="col-date">Date</th>
<th class="col-brand">Product brand</th> <th class="col-brand">Product Brand</th>
${diseaseHeaders} ${diseaseHeaders}
</tr> </tr>
</thead> </thead>
+2 -1
View File
@@ -13,7 +13,8 @@ export const DISEASE_OPTIONS = [
{ key: 'cholera', value: 'ETEC-Cholera' }, { key: 'cholera', value: 'ETEC-Cholera' },
{ key: 'tdap', value: 'TdaP' }, { key: 'tdap', value: 'TdaP' },
{ key: 'rabies', value: 'Rabies' }, { key: 'rabies', value: 'Rabies' },
{ key: 'meningococcal', value: 'Meningococcal' }, { key: 'men-groups', value: 'Meningococcal (Groups A,C,Y,W)' },
{ key: 'men-c-c', value: 'Meningococcal C-C' },
{ key: 'yellow-fever', value: 'Yellow Fever' }, { key: 'yellow-fever', value: 'Yellow Fever' },
{ key: 'hpv', value: 'HPV' }, { key: 'hpv', value: 'HPV' },
{ key: 'polio', value: 'Polio' }, { key: 'polio', value: 'Polio' },
+21 -6
View File
@@ -5,9 +5,12 @@ import {
} from './vaccinationRecordDiseases.js' } from './vaccinationRecordDiseases.js'
export const VR_METADATA_MARKER = 'CTM_VR' export const VR_METADATA_MARKER = 'CTM_VR'
export const VR_METADATA_LATEST_VERSION = 1 export const VR_METADATA_LATEST_VERSION = 2
const DISEASE_KEYS = new Set(DISEASE_OPTIONS.map((d) => d.key)) const DISEASE_KEYS = new Set(DISEASE_OPTIONS.map((d) => d.key))
const LEGACY_DISEASE_KEY_MAP = {
meningococcal: 'men-groups',
}
const METADATA_RE = /CTM_VR:(\d+):([A-Za-z0-9_-]+)/ const METADATA_RE = /CTM_VR:(\d+):([A-Za-z0-9_-]+)/
function encodeBase64Url(str) { function encodeBase64Url(str) {
@@ -36,7 +39,7 @@ function str(value) {
return value == null ? '' : String(value) return value == null ? '' : String(value)
} }
function buildV1Payload({ patientName, dateOfBirth, notes, rows }) { function buildLatestPayload({ patientName, dateOfBirth, notes, rows }) {
const normalizedRows = (rows ?? []) const normalizedRows = (rows ?? [])
.slice(0, VACCINATION_RECORD_MAX_ROWS) .slice(0, VACCINATION_RECORD_MAX_ROWS)
.map((row) => { .map((row) => {
@@ -61,7 +64,7 @@ function buildV1Payload({ patientName, dateOfBirth, notes, rows }) {
} }
} }
function parseV1Payload(raw) { function parsePayload(raw, { migrateLegacyKeys = false } = {}) {
if (!raw || typeof raw !== 'object') { if (!raw || typeof raw !== 'object') {
throw new Error('Invalid vaccination record metadata payload.') throw new Error('Invalid vaccination record metadata payload.')
} }
@@ -82,9 +85,12 @@ function parseV1Payload(raw) {
if (!row || typeof row !== 'object') { if (!row || typeof row !== 'object') {
throw new Error(`Invalid row at index ${index} in vaccination record metadata.`) throw new Error(`Invalid row at index ${index} in vaccination record metadata.`)
} }
const diseaseKey = str(row.diseaseKey) const rawDiseaseKey = str(row.diseaseKey)
const diseaseKey = migrateLegacyKeys
? (LEGACY_DISEASE_KEY_MAP[rawDiseaseKey] ?? rawDiseaseKey)
: rawDiseaseKey
if (!DISEASE_KEYS.has(diseaseKey)) { if (!DISEASE_KEYS.has(diseaseKey)) {
throw new Error(`Invalid disease key at row ${index}: ${diseaseKey}`) throw new Error(`Invalid disease key at row ${index}: ${rawDiseaseKey}`)
} }
const date = str(row.date) const date = str(row.date)
if (date && !isValidIsoDate(date)) { if (date && !isValidIsoDate(date)) {
@@ -102,15 +108,24 @@ function parseV1Payload(raw) {
return { patientName, dateOfBirth, notes, rows } return { patientName, dateOfBirth, notes, rows }
} }
function parseV1Payload(raw) {
return parsePayload(raw, { migrateLegacyKeys: true })
}
function parseV2Payload(raw) {
return parsePayload(raw, { migrateLegacyKeys: false })
}
const VERSION_PARSERS = { const VERSION_PARSERS = {
1: parseV1Payload, 1: parseV1Payload,
2: parseV2Payload,
} }
/** /**
* @param {{ patientName?: string, dateOfBirth?: string, notes?: string, rows?: object[] }} data * @param {{ patientName?: string, dateOfBirth?: string, notes?: string, rows?: object[] }} data
*/ */
export function buildEncodedVaccinationRecordMetadata(data) { export function buildEncodedVaccinationRecordMetadata(data) {
const payload = buildV1Payload(data) const payload = buildLatestPayload(data)
const encoded = encodeBase64Url(JSON.stringify(payload)) const encoded = encodeBase64Url(JSON.stringify(payload))
return `${VR_METADATA_MARKER}:${VR_METADATA_LATEST_VERSION}:${encoded}` return `${VR_METADATA_MARKER}:${VR_METADATA_LATEST_VERSION}:${encoded}`
} }