diff --git a/lib/ccl/functions/__analyzeDccWallet.js b/lib/ccl/functions/__analyzeDccWallet.js index 9d3b642..816d242 100644 --- a/lib/ccl/functions/__analyzeDccWallet.js +++ b/lib/ccl/functions/__analyzeDccWallet.js @@ -317,24 +317,6 @@ const descriptor = { } ] }, - { - assign: [ - 'it.__isTemporarilyEqualToBoosterWithoutContext', - { - and: [ - { var: 'it.__isSeriesComplete' }, - { - '===': [ - { var: 'it.hcert.v.0.dn' }, - 2 - ] - }, - { var: 'it.__isOlderThan14Days' }, - { var: 'it.__isYoungerThan91Days' } - ] - } - ] - }, { assign: [ 'it.__isRecoveryVaccinationWithoutContext', @@ -367,6 +349,34 @@ const descriptor = { } ] }, + { + assign: [ + 'it.__isTemporarilyEqualToBoosterWithoutContext', + { + or: [ + { + and: [ + { var: 'it.__isSeriesComplete' }, + { + '===': [ + { var: 'it.hcert.v.0.dn' }, + 2 + ] + }, + { var: 'it.__isOlderThan14Days' }, + { var: 'it.__isYoungerThan91Days' } + ] + }, + { + and: [ + { var: 'it.__isRecoveryVaccinationWithoutContext' }, + { var: 'it.__isYoungerThan91Days' } + ] + } + ] + } + ] + }, { assign: [ 'it.__isFullImmunizationWithoutContext', @@ -531,6 +541,27 @@ const descriptor = { } ] }, + { + assign: [ + 'it.__isTemporarilyEqualToBooster', + { + or: [ + { var: 'it.__isTemporarilyEqualToBoosterWithoutContext' }, + { + and: [ + { + or: [ + { var: 'it.__isRecoveryVaccination' }, + { var: 'it.__isRecoveryVaccinationWithoutContext' } // TODO: fixme, this should be redundant + ] + }, + { var: 'it.__isYoungerThan91Days' } + ] + } + ] + } + ] + }, { assign: [ 'it.__isBooster', @@ -543,6 +574,22 @@ const descriptor = { { or: [ { var: 'it.__hasPreviousRecoveryVaccination' }, + // new 2/1 notation + { + and: [ + { + '>': [ + { var: 'it.hcert.v.0.dn' }, + { var: 'it.hcert.v.0.sd' } + ] + }, + { + '!': [ + { var: 'it.__hasSomePreviousVaccination' } + ] + } + ] + }, { and: [ { @@ -834,7 +881,7 @@ const descriptor = { { filter: [ { var: 'allRelevantVCsAndRCsAnnotatedWithContext' }, - { var: 'it.__isTemporarilyEqualToBoosterWithoutContext' }, + { var: 'it.__isTemporarilyEqualToBooster' }, 'it' ] } @@ -1582,9 +1629,8 @@ const descriptor = { { init: [ 'object', - '__allRelevantVCsAnnotated', { var: 'allRelevantVCsAnnotated' }, + // '__allRelevantVCsAnnotated', { var: 'allRelevantVCsAnnotated' }, '__allRelevantVCsAndRCsAnnotatedWithContext', { var: 'allRelevantVCsAndRCsAnnotatedWithContext' }, - // '__allVCsAndRCsWithFullImmunization', { var: 'allVCsAndRCsWithFullImmunization' }, // '__allBoosterVCs', { var: 'allBoosterVCs' }, '__allTCsWithValidRAT', { var: 'allTCsWithValidRAT' }, diff --git a/lib/ccl/functions/__sortCertificatesByDate.js b/lib/ccl/functions/__sortCertificatesByDate.js index 7f9cc67..f6a62a5 100644 --- a/lib/ccl/functions/__sortCertificatesByDate.js +++ b/lib/ccl/functions/__sortCertificatesByDate.js @@ -25,7 +25,7 @@ const descriptor = { { var: 'a.hcert.v.0' }, { var: 'a.hcert.v.0.dt' }, { var: 'a.hcert.r.0' }, - { var: 'a.hcert.r.0.df' }, + { var: 'a.hcert.r.0.fr' }, { var: 'a.hcert.t.0' }, { var: 'a.hcert.t.0.sc' }, null @@ -36,7 +36,7 @@ const descriptor = { { var: 'b.hcert.v.0' }, { var: 'b.hcert.v.0.dt' }, { var: 'b.hcert.r.0' }, - { var: 'b.hcert.r.0.df' }, + { var: 'b.hcert.r.0.fr' }, { var: 'b.hcert.t.0' }, { var: 'b.hcert.t.0.sc' }, null @@ -59,7 +59,7 @@ const descriptor = { { var: 'a.hcert.v.0' }, { var: 'a.hcert.v.0.dt' }, { var: 'a.hcert.r.0' }, - { var: 'a.hcert.r.0.df' }, + { var: 'a.hcert.r.0.fr' }, { var: 'a.hcert.t.0' }, { var: 'a.hcert.t.0.sc' }, null @@ -70,7 +70,7 @@ const descriptor = { { var: 'b.hcert.v.0' }, { var: 'b.hcert.v.0.dt' }, { var: 'b.hcert.r.0' }, - { var: 'b.hcert.r.0.df' }, + { var: 'b.hcert.r.0.fr' }, { var: 'b.hcert.t.0' }, { var: 'b.hcert.t.0.sc' }, null @@ -95,7 +95,7 @@ const descriptor = { { var: 'a.hcert.v.0' }, { var: 'a.hcert.v.0.dt' }, { var: 'a.hcert.r.0' }, - { var: 'a.hcert.r.0.df' }, + { var: 'a.hcert.r.0.fr' }, { var: 'a.hcert.t.0' }, { var: 'a.hcert.t.0.sc' }, null @@ -106,7 +106,7 @@ const descriptor = { { var: 'b.hcert.v.0' }, { var: 'b.hcert.v.0.dt' }, { var: 'b.hcert.r.0' }, - { var: 'b.hcert.r.0.df' }, + { var: 'b.hcert.r.0.fr' }, { var: 'b.hcert.t.0' }, { var: 'b.hcert.t.0.sc' }, null @@ -129,7 +129,7 @@ const descriptor = { { var: 'a.hcert.v.0' }, { var: 'a.hcert.v.0.dt' }, { var: 'a.hcert.r.0' }, - { var: 'a.hcert.r.0.df' }, + { var: 'a.hcert.r.0.fr' }, { var: 'a.hcert.t.0' }, { var: 'a.hcert.t.0.sc' }, null @@ -140,7 +140,7 @@ const descriptor = { { var: 'b.hcert.v.0' }, { var: 'b.hcert.v.0.dt' }, { var: 'b.hcert.r.0' }, - { var: 'b.hcert.r.0.df' }, + { var: 'b.hcert.r.0.fr' }, { var: 'b.hcert.t.0' }, { var: 'b.hcert.t.0.sc' }, null diff --git a/test/fixtures/ccl/dcc-series-janssen.yaml b/test/fixtures/ccl/dcc-series-janssen.yaml index 9824c86..d4a3829 100644 --- a/test/fixtures/ccl/dcc-series-janssen.yaml +++ b/test/fixtures/ccl/dcc-series-janssen.yaml @@ -254,35 +254,24 @@ # Complete vaccination is not yet valid - time: janssen2/1 assertions: - admissionState: OTHER - mostRelevantCertificate: janssen2/1 - vaccinationState: COMPLETE_IMMUNIZATION_PENDING - vaccinationValidFrom: janssen2/1+P15D - mostRecentVaccination: janssen2/1 - hasBooster: false - verificationCertificates: - - certificate: janssen2/1 - # Complete vaccination still not valid after 14 days - - time: janssen2/1+P14D - assertions: - admissionState: OTHER + admissionState: 2G_PLUS mostRelevantCertificate: janssen2/1 - vaccinationState: COMPLETE_IMMUNIZATION_PENDING - vaccinationValidFrom: janssen2/1+P15D + vaccinationState: COMPLETE_IMMUNIZATION + vaccinationValidFrom: janssen2/1 mostRecentVaccination: janssen2/1 - hasBooster: false + hasBooster: true # we assume the better result for 2/1 if in doubt verificationCertificates: - certificate: janssen2/1 - # Complete vaccination valid after 15 days counts as 2G+ for 90 days - - time: janssen2/1+P15D + # Admission State still 2G+ after 91 days (because this could be a vacc. after recovery vacc. + - time: janssen2/1+P91D assertions: admissionState: 2G_PLUS mostRelevantCertificate: janssen2/1 vaccinationState: COMPLETE_IMMUNIZATION - vaccinationValidFrom: janssen2/1+P15D + vaccinationValidFrom: janssen2/1 mostRecentVaccination: janssen2/1 - hasBooster: false - hasBoosterEquivalent: true + hasBooster: true # we assume the better result for 2/1 if in doubt + hasBoosterEquivalent: false verificationCertificates: - certificate: janssen2/1 # 2Booster on J&J diff --git a/test/fixtures/ccl/dcc-series-recovery.yaml b/test/fixtures/ccl/dcc-series-recovery.yaml index cf7dcaf..b1fb187 100644 --- a/test/fixtures/ccl/dcc-series-recovery.yaml +++ b/test/fixtures/ccl/dcc-series-recovery.yaml @@ -9,7 +9,7 @@ tc: rat1 - time: rc1+P7M vc: biontech1/1 - - time: +P5W + - time: +P4M tc: pcr2 - time: +P6W tc: rat2 @@ -98,6 +98,30 @@ - certificate: rc1 # Complete vaccination immedeately valid after first vaccination - time: biontech1/1 + assertions: + admissionState: 2G_PLUS + mostRelevantCertificate: biontech1/1 + vaccinationState: COMPLETE_IMMUNIZATION + vaccinationValidFrom: biontech1/1 + mostRecentVaccination: biontech1/1 + hasBooster: false + hasBoosterEquivalent: true + verificationCertificates: + - certificate: biontech1/1 + # Still 2G+ after 90 days + - time: biontech1/1+P90D + assertions: + admissionState: 2G_PLUS + mostRelevantCertificate: biontech1/1 + vaccinationState: COMPLETE_IMMUNIZATION + vaccinationValidFrom: biontech1/1 + mostRecentVaccination: biontech1/1 + hasBooster: false + hasBoosterEquivalent: true + verificationCertificates: + - certificate: biontech1/1 + # 2G after 91 days + - time: biontech1/1+P91D assertions: admissionState: 2G mostRelevantCertificate: biontech1/1 @@ -105,8 +129,10 @@ vaccinationValidFrom: biontech1/1 mostRecentVaccination: biontech1/1 hasBooster: false + hasBoosterEquivalent: false verificationCertificates: - certificate: biontech1/1 + # Additional valid PCR test changes admission state - time: pcr2 assertions: @@ -171,7 +197,7 @@ rc: rc1 - time: +P2M vc: biontech1/1 - - time: +P1M + - time: +P4M vc: biontech2/2 testCases: - time: biontech1/1 @@ -183,8 +209,34 @@ vaccinationValidFrom: biontech1/1 mostRecentVaccination: biontech1/1 hasBooster: false + hasBoosterEquivalent: true + verificationCertificates: + - certificate: biontech1/1 + # Still 2G+ after 90 days + - time: biontech1/1+P90D + assertions: + admissionState: 2G_PLUS + mostRelevantCertificate: biontech1/1 + vaccinationState: COMPLETE_IMMUNIZATION + vaccinationValidFrom: biontech1/1 + mostRecentVaccination: biontech1/1 + hasBooster: false + hasBoosterEquivalent: true verificationCertificates: - certificate: biontech1/1 + # 2G after 91 days + - time: biontech1/1+P91D + assertions: + admissionState: 2G + mostRelevantCertificate: biontech1/1 + vaccinationState: COMPLETE_IMMUNIZATION + vaccinationValidFrom: biontech1/1 + mostRecentVaccination: biontech1/1 + hasBooster: false + hasBoosterEquivalent: false + verificationCertificates: + - certificate: biontech1/1 + # Booster results in 2G+ - time: biontech2/2 description: booster vaccination valid immediately (2G+) assertions: @@ -354,6 +406,30 @@ testCases: # Vaccination immediately valid after first vaccination with J&J - time: janssen1/1 + assertions: + admissionState: 2G_PLUS + mostRelevantCertificate: janssen1/1 + vaccinationState: COMPLETE_IMMUNIZATION + vaccinationValidFrom: janssen1/1 + mostRecentVaccination: janssen1/1 + hasBooster: false + hasBoosterEquivalent: true + verificationCertificates: + - certificate: janssen1/1 + # Still 2G+ after 90 days + - time: janssen1/1+P90D + assertions: + admissionState: 2G_PLUS + mostRelevantCertificate: janssen1/1 + vaccinationState: COMPLETE_IMMUNIZATION + vaccinationValidFrom: janssen1/1 + mostRecentVaccination: janssen1/1 + hasBooster: false + hasBoosterEquivalent: true + verificationCertificates: + - certificate: janssen1/1 + # Vaccination immediately valid after first vaccination with J&J + - time: janssen1/1+P91D assertions: admissionState: 2G mostRelevantCertificate: janssen1/1 @@ -456,40 +532,8 @@ hasBooster: false verificationCertificates: - certificate: rc1 - # vaccination valid immedeately, but wouldn't be prioritized over rc1 if it was still valid - - time: biontech2/2 - assertions: - admissionState: 2G_PLUS - mostRelevantCertificate: biontech2/2 - vaccinationState: COMPLETE_IMMUNIZATION - vaccinationValidFrom: biontech2/2 - mostRecentVaccination: biontech2/2 - hasBooster: true - verificationCertificates: - - certificate: biontech2/2 -- description: incomplete vaccination + recovery + booster while RC is still valid - t0: '2022-01-01' - series: - - time: t0 - vc: biontech1/2 - - time: +P3M - rc: rc1 - - time: +P40D # must be between 29 and 180 days after rc1 - vc: biontech2/2 - testCases: + # vaccination valid immedeately - time: biontech2/2 - description: vaccination valid immediately and prioritized, despite not valid by itself - assertions: - admissionState: 2G_PLUS - mostRelevantCertificate: biontech2/2 - vaccinationState: COMPLETE_IMMUNIZATION - vaccinationValidFrom: biontech2/2 - mostRecentVaccination: biontech2/2 - hasBooster: true - verificationCertificates: - - certificate: biontech2/2 - - time: biontech2/2+P15D - description: vaccination still prioritized after 15 days assertions: admissionState: 2G_PLUS mostRelevantCertificate: biontech2/2 @@ -520,7 +564,7 @@ hasBooster: true verificationCertificates: - certificate: biontech2/1 -- description: biontech 1/1 + booster 2/2 +- description: biontech 1/1 + booster 2/2 treated as recovery vaccination t0: '2022-01-01' series: - time: t0 @@ -567,7 +611,7 @@ hasBooster: false verificationCertificates: - certificate: rc1 - # recovery still valid after 91 days + # recovery still valid after 91 days, but 2G only - time: rc1+P91D assertions: admissionState: 2G diff --git a/test/unit/ccl/functions/__analyzeDccWallet.spec.js b/test/unit/ccl/functions/__analyzeDccWallet.spec.js index e3ddc98..728495f 100644 --- a/test/unit/ccl/functions/__analyzeDccWallet.spec.js +++ b/test/unit/ccl/functions/__analyzeDccWallet.spec.js @@ -82,6 +82,16 @@ ${terminal.yaml(dccData)} ${chalk.cyan('Output of the operation')} ${terminal.yaml(output)} +${chalk.cyan('Relevant output')} +${terminal.yaml(output.__allRelevantVCsAndRCsAnnotatedWithContext.map(it => { + const { + barcodeData, cose, cwt, ...rest + } = it + delete rest.hcert.nam + delete rest.hcert.dob + return rest +}))} + End of debugging: ${chalk.magenta(testCaseDescription)}` console.log(terminal.prefixLine(debugLog, prefix))