diff --git a/imports/api/_dev/populate/eids.ts b/imports/api/_dev/populate/eids.ts index f7c374e67..b454bf130 100644 --- a/imports/api/_dev/populate/eids.ts +++ b/imports/api/_dev/populate/eids.ts @@ -9,6 +9,7 @@ const AGE_MAX = 130; export const newEidData = makeTemplate({ xml: { + // eslint-disable-next-line unicorn/text-encoding-identifier-case encoding: () => 'UTF-8', version: () => '1.0', }, @@ -20,7 +21,7 @@ export const newEidData = makeTemplate({ carddata_appl_version: () => faker.string.numeric(2), cardnumber: () => faker.string.numeric(12), chipnumber: () => faker.string.alphanumeric(32), - documenttype: () => "belgian_citizen", + documenttype: () => 'belgian_citizen', validitydatebegin: () => format(faker.date.past({years: 30}), DATE_FORMAT), validitydateend: () => format(faker.date.past({years: 30}), DATE_FORMAT), deliverymunicipality: () => faker.location.county(), diff --git a/imports/api/collection/eids.ts b/imports/api/collection/eids.ts index 8d4247a4b..d06e37729 100644 --- a/imports/api/collection/eids.ts +++ b/imports/api/collection/eids.ts @@ -3,47 +3,59 @@ import schema from '../../lib/schema'; import define from './define'; export const eidFields = schema.object({ - xml: schema.object({ - encoding: schema.string(), - version: schema.string(), - }).partial(), - eid: schema.object({ - graphpersoversion: schema.string(), - version: schema.string(), - }).partial(), - card: schema.object({ - carddata_appl_version: schema.string(), - cardnumber: schema.string(), - chipnumber: schema.string(), - documenttype: schema.string(), - validitydatebegin: schema.string(), - validitydateend: schema.string(), - deliverymunicipality: schema.string(), - }).partial(), - certificates: schema.object({ - authentication: schema.string(), - citizenca: schema.string(), - root: schema.string(), - rrn: schema.string(), - signing: schema.string(), - }).partial(), - identity: schema.object({ - nationality: schema.string(), - nationalnumber: schema.string(), - dateofbirth: schema.string(), - placeofbirth: schema.string(), - gender: schema.string(), - specialstatus: schema.string(), - name: schema.string(), - firstname: schema.string(), - middlenames: schema.string(), - photo: schema.string(), - }).partial(), - address: schema.object({ - municipality: schema.string(), - streetandnumber: schema.string(), - zip: schema.string(), - }).partial(), + xml: schema + .object({ + encoding: schema.string(), + version: schema.string(), + }) + .partial(), + eid: schema + .object({ + graphpersoversion: schema.string(), + version: schema.string(), + }) + .partial(), + card: schema + .object({ + carddata_appl_version: schema.string(), + cardnumber: schema.string(), + chipnumber: schema.string(), + documenttype: schema.string(), + validitydatebegin: schema.string(), + validitydateend: schema.string(), + deliverymunicipality: schema.string(), + }) + .partial(), + certificates: schema + .object({ + authentication: schema.string(), + citizenca: schema.string(), + root: schema.string(), + rrn: schema.string(), + signing: schema.string(), + }) + .partial(), + identity: schema + .object({ + nationality: schema.string(), + nationalnumber: schema.string(), + dateofbirth: schema.string(), + placeofbirth: schema.string(), + gender: schema.string(), + specialstatus: schema.string(), + name: schema.string(), + firstname: schema.string(), + middlenames: schema.string(), + photo: schema.string(), + }) + .partial(), + address: schema + .object({ + municipality: schema.string(), + streetandnumber: schema.string(), + zip: schema.string(), + }) + .partial(), }); export type EidFields = schema.infer; @@ -56,8 +68,7 @@ const eidMetadata = schema.object({ export type EidMetadata = schema.infer; -export const eidDocument = eidFields - .merge(eidMetadata); +export const eidDocument = eidFields.merge(eidMetadata); export type EidDocument = schema.infer; const collection = 'eids'; diff --git a/imports/api/collection/patients.ts b/imports/api/collection/patients.ts index bb579d96d..7aa22614c 100644 --- a/imports/api/collection/patients.ts +++ b/imports/api/collection/patients.ts @@ -31,18 +31,20 @@ export const patientTag = schema.object({ export type PatientTag = schema.infer; -export const patientIdFields = schema.object({ - niss: schema.string(), - firstname: schema.string(), - lastname: schema.string(), - birthdate: schema.string(), - sex: patientSex, - photo: schema.string(), - - municipality: schema.string(), - streetandnumber: schema.string(), - zip: schema.string(), -}).partial(); +export const patientIdFields = schema + .object({ + niss: schema.string(), + firstname: schema.string(), + lastname: schema.string(), + birthdate: schema.string(), + sex: patientSex, + photo: schema.string(), + + municipality: schema.string(), + streetandnumber: schema.string(), + zip: schema.string(), + }) + .partial(); export type PatientIdFields = schema.infer; diff --git a/imports/api/eidParseXML.ts b/imports/api/eidParseXML.ts index 8862ca32c..12a41e3ac 100644 --- a/imports/api/eidParseXML.ts +++ b/imports/api/eidParseXML.ts @@ -1,61 +1,78 @@ import {xml2json} from 'xml-js'; + import schema from '../lib/schema'; import {type EidFields} from './collection/eids'; const text = schema.object({ - _text: schema.string() + _text: schema.string(), }); export const eidXml = schema.object({ _declaration: schema.object({ - _attributes: schema.object({ - encoding: schema.string(), - version: schema.string(), - }).partial(), + _attributes: schema + .object({ + encoding: schema.string(), + version: schema.string(), + }) + .partial(), }), eid: schema.object({ - _attributes: schema.object({ - graphpersoversion: schema.string(), - version: schema.string(), - }).partial(), - address: schema.object({ - municipality: text.optional(), - streetandnumber: text.optional(), - zip: text.optional(), - }).optional(), - card: schema.object({ - _attributes: schema.object({ - carddata_appl_version: schema.string(), - cardnumber: schema.string(), - chipnumber: schema.string(), - documenttype: schema.string(), - validitydatebegin: schema.string(), - validitydateend: schema.string(), - }).partial(), - deliverymunicipality: text.optional(), - }).optional(), - certificates: schema.object({ - authentication: text.optional(), - citizenca: text.optional(), - root: text.optional(), - rrn: text.optional(), - signing: text.optional(), - }).optional(), - identity: schema.object({ - _attributes: schema.object({ - dateofbirth: schema.string(), - gender: schema.string(), - nationalnumber: schema.string(), - specialstatus: schema.string(), - }).partial(), - firstname: text.optional(), - middlenames: text.optional(), - name: text.optional(), - nationality: text.optional(), - photo: text.optional(), - placeofbirth: text.optional(), - }).optional(), + _attributes: schema + .object({ + graphpersoversion: schema.string(), + version: schema.string(), + }) + .partial(), + address: schema + .object({ + municipality: text.optional(), + streetandnumber: text.optional(), + zip: text.optional(), + }) + .optional(), + card: schema + .object({ + _attributes: schema + .object({ + carddata_appl_version: schema.string(), + cardnumber: schema.string(), + chipnumber: schema.string(), + documenttype: schema.string(), + validitydatebegin: schema.string(), + validitydateend: schema.string(), + }) + .partial(), + deliverymunicipality: text.optional(), + }) + .optional(), + certificates: schema + .object({ + authentication: text.optional(), + citizenca: text.optional(), + root: text.optional(), + rrn: text.optional(), + signing: text.optional(), + }) + .optional(), + identity: schema + .object({ + _attributes: schema + .object({ + dateofbirth: schema.string(), + gender: schema.string(), + nationalnumber: schema.string(), + specialstatus: schema.string(), + }) + .partial(), + firstname: text.optional(), + middlenames: text.optional(), + name: text.optional(), + nationality: text.optional(), + photo: text.optional(), + placeofbirth: text.optional(), + }) + .optional(), }), }); @@ -66,16 +83,8 @@ const eidParseXML = (xmlString: string): EidFields => { console.debug('eidXMLToJSON', {json}); const { - _declaration: { - _attributes: xml, - }, - eid: { - _attributes: eid, - address, - card, - certificates, - identity, - } + _declaration: {_attributes: xml}, + eid: {_attributes: eid, address, card, certificates, identity}, } = eidXml.parse(json); return { @@ -105,7 +114,7 @@ const eidParseXML = (xmlString: string): EidFields => { name: identity?.name?._text, photo: identity?.photo?._text, placeofbirth: identity?.placeofbirth?._text, - } + }, }; }; diff --git a/imports/api/endpoint/patients/insertFromEid.tests.ts b/imports/api/endpoint/patients/insertFromEid.tests.ts index c9a29941b..40e8e55cc 100644 --- a/imports/api/endpoint/patients/insertFromEid.tests.ts +++ b/imports/api/endpoint/patients/insertFromEid.tests.ts @@ -9,18 +9,21 @@ import {Insurances} from '../../collection/insurances'; import {newEidData} from '../../_dev/populate/eids'; import invoke from '../invoke'; + +import {normalizedName, patientFieldsFromEid} from '../../patients'; + import insertFromEid from './insertFromEid'; -import { normalizedName, patientFieldsFromEid } from '../../patients'; server(__filename, () => { it('cannot create a patient when not logged in', async () => { return throws( - async () => invoke( - insertFromEid, - // @ts-expect-error Type-checking is working as expected. - {userId: undefined}, - [newEidData()] - ), + async () => + invoke( + insertFromEid, + // @ts-expect-error Type-checking is working as expected. + {userId: undefined}, + [newEidData()], + ), /not-authorized/, ); }); @@ -38,8 +41,11 @@ server(__filename, () => { const expectedPatientFields = patientFieldsFromEid(eid); const expectedComputedFields = { - normalizedName: normalizedName(expectedPatientFields.firstname, expectedPatientFields.lastname), - } + normalizedName: normalizedName( + expectedPatientFields.firstname, + expectedPatientFields.lastname, + ), + }; const expected = { ...expectedPatientFields, @@ -55,17 +61,8 @@ server(__filename, () => { assert.isAtMost(createdAt.valueOf(), Date.now()); - assert.sameDeepMembers( - await Allergies.find().fetchAsync(), - [], - ); - assert.sameDeepMembers( - await Doctors.find().fetchAsync(), - [], - ); - assert.sameDeepMembers( - await Insurances.find().fetchAsync(), - [], - ); + assert.sameDeepMembers(await Allergies.find().fetchAsync(), []); + assert.sameDeepMembers(await Doctors.find().fetchAsync(), []); + assert.sameDeepMembers(await Insurances.find().fetchAsync(), []); }); }); diff --git a/imports/api/endpoint/patients/insertFromEid.ts b/imports/api/endpoint/patients/insertFromEid.ts index c22febacc..ffd721b85 100644 --- a/imports/api/endpoint/patients/insertFromEid.ts +++ b/imports/api/endpoint/patients/insertFromEid.ts @@ -1,12 +1,13 @@ import {AuthenticationLoggedIn} from '../../Authentication'; import schema from '../../../lib/schema'; -import { eidFields, Eids } from '../../collection/eids'; +import {eidFields, Eids} from '../../collection/eids'; import {patientFieldsFromEid} from '../../patients'; import type TransactionDriver from '../../transaction/TransactionDriver'; import define from '../define'; import compose from '../compose'; + import insert from './insert'; export default define({ diff --git a/imports/api/patients.ts b/imports/api/patients.ts index f2ec61e5d..cba43e740 100644 --- a/imports/api/patients.ts +++ b/imports/api/patients.ts @@ -8,6 +8,8 @@ import isValid from 'date-fns/isValid'; import schema from '../lib/schema'; +import removeUndefined from '../lib/object/removeUndefined'; + import { type PatientFields, type PatientComputedFields, @@ -17,8 +19,8 @@ import { type PatientDocument, type PatientTagFields, patientSex, - patientIdFields, - PatientIdFields, + patientIdFields, + type PatientIdFields, } from './collection/patients'; import {PatientsSearchIndex} from './collection/patients/search'; @@ -50,8 +52,7 @@ import { yieldResettableKey, } from './update'; import {type DocumentUpdate} from './DocumentUpdate'; -import { EidFields } from './collection/eids'; -import removeUndefined from '../lib/object/removeUndefined'; +import {type EidFields} from './collection/eids'; const splitNames = (string: string) => { const [firstname, ...middlenames] = names(string); @@ -60,11 +61,14 @@ const splitNames = (string: string) => { return [firstnameWords, middlenameWords] as const; }; -export const normalizedName = (firstname: string | undefined, lastname: string | undefined) => { +export const normalizedName = ( + firstname: string | undefined, + lastname: string | undefined, +) => { const lastnameHash = words(lastname ?? '').join(''); const firstnameHash = words(names(firstname ?? '')[0] ?? '').join(''); return `${lastnameHash} ${firstnameHash}`; -} +}; const updateIndex = async ( db: TransactionDriver, @@ -385,25 +389,25 @@ function createPatient(string: string) { export const patientFieldsFromEid = ({ address, - identity: { - nationalnumber, - gender, - firstname, - name, - photo, - dateofbirth - } -}: EidFields): PatientIdFields => removeUndefined(patientIdFields.parse({ - niss: nationalnumber, - firstname, - lastname: name, - photo, - birthdate: dateofbirth === undefined - ? undefined - : `${dateofbirth.slice(0, 4)}-${dateofbirth.slice(4, 6)}-${dateofbirth.slice(6, 8)}`, - sex: gender, - ...address, -})); + identity: {nationalnumber, gender, firstname, name, photo, dateofbirth}, +}: EidFields): PatientIdFields => + removeUndefined( + patientIdFields.parse({ + niss: nationalnumber, + firstname, + lastname: name, + photo, + birthdate: + dateofbirth === undefined + ? undefined + : `${dateofbirth.slice(0, 4)}-${dateofbirth.slice( + 4, + 6, + )}-${dateofbirth.slice(6, 8)}`, + sex: gender, + ...address, + }), + ); export const patients = { updateIndex, diff --git a/imports/ui/drag-and-drop/handleDrop.ts b/imports/ui/drag-and-drop/handleDrop.ts index 6cf035b01..095bb3ee0 100644 --- a/imports/ui/drag-and-drop/handleDrop.ts +++ b/imports/ui/drag-and-drop/handleDrop.ts @@ -5,13 +5,14 @@ import insertDrugs from '../../api/drugs/insertDrugs'; import insertDocument from '../../api/documents/insertDocument'; import type useDialog from '../modal/useDialog'; -function unpack(item: DataTransferItem): -['drugs', File] | -['attachment', File] | -['document', File] | -['patient', DataTransferItem] | -['unknown', DataTransferItem] -{ +function unpack( + item: DataTransferItem, +): + | ['drugs', File] + | ['attachment', File] + | ['document', File] + | ['patient', DataTransferItem] + | ['unknown', DataTransferItem] { if (item.kind === 'file') { const f = item.getAsFile()!; if (item.type === 'text/csv') { @@ -35,7 +36,7 @@ function unpack(item: DataTransferItem): const _items = (data: DataTransfer): Iterable => { // @ts-expect-error NOTE: DataTransferItem is actually an iterable. return data.items; -} +}; const handleDrop = ( diff --git a/imports/ui/eid/EidCardDialog.tsx b/imports/ui/eid/EidCardDialog.tsx index df931faa4..6fdf5e1b9 100644 --- a/imports/ui/eid/EidCardDialog.tsx +++ b/imports/ui/eid/EidCardDialog.tsx @@ -19,7 +19,13 @@ type Props = { readonly onCancel: () => void; }; -const EidCardDialog = ({navigate, eidInfo, open, onConfirm, onCancel}: Props) => { +const EidCardDialog = ({ + navigate, + eidInfo, + open, + onConfirm, + onCancel, +}: Props) => { const [selected, setSelected] = useState(new Set()); const [step, setStep] = useState('selection'); diff --git a/imports/ui/eid/EidCardDialogStepPreviewSingleProps.ts b/imports/ui/eid/EidCardDialogStepPreviewSingleProps.ts index ea2750dc7..98b9faac0 100644 --- a/imports/ui/eid/EidCardDialogStepPreviewSingleProps.ts +++ b/imports/ui/eid/EidCardDialogStepPreviewSingleProps.ts @@ -1,6 +1,6 @@ import {type useNavigate} from 'react-router-dom'; -import { EidFields } from '../../api/collection/eids'; +import {type EidFields} from '../../api/collection/eids'; type Props = { titleId?: string; diff --git a/imports/ui/eid/EidCardDialogStepSelection.tsx b/imports/ui/eid/EidCardDialogStepSelection.tsx index cbc7b20bd..041903fa8 100644 --- a/imports/ui/eid/EidCardDialogStepSelection.tsx +++ b/imports/ui/eid/EidCardDialogStepSelection.tsx @@ -32,9 +32,7 @@ import CancelButton from '../button/CancelButton'; import mergeFields from '../../api/query/mergeFields'; -import { - type PatientDocument, -} from '../../api/collection/patients'; +import {type PatientDocument} from '../../api/collection/patients'; import {patientFieldsFromEid, patients} from '../../api/patients'; import {onlyNumeric} from '../../api/string'; @@ -48,7 +46,7 @@ import SelectablePatientCard from '../patients/SelectablePatientCard'; import ReactivePatientCard from '../patients/ReactivePatientCard'; import GenericNewPatientCard from '../patients/GenericNewPatientCard'; import PatientsGrid from '../patients/PatientsGrid'; -import { EidFields } from '../../api/collection/eids'; +import {type EidFields} from '../../api/collection/eids'; const DEFAULT_LIMIT = 3; const DEFAULT_FIELDS = {