Added new diseases; updated metadata parsing and versions.
This commit is contained in:
1 parent
99248af7ba
commit
fe1ec614b7
4 files changed
+30
-10
No files matched your search
+6
-2
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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' },
|
||||||
|
|||||||
@@ -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}`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user