NCommander / vaksina

MIT License
35 stars 5 forks source link

Should the API specifically handle multiple validation tests at once? (Validation Data Modelling) #16

Open NCommander opened 2 years ago

NCommander commented 2 years ago

While I was beginning to refactor code to handle vaccinationresults, I had a thought. Currently, in API.md, we define an example result as such:

{
    "card_validation_status": "good",
    "card_decoded_content": {
        "card_type": "smart_health_card",
        "persons": [
            {
                "names" : [
                    "John A. Person"
                ],
                "dob": "01-05-1950",
                "immunizations": [
                    {
                        "vaccine": "MODERNA",
                        "given_on": "01-01-2021",
                        "lot_number": "1"
                    },
                    {
                        "vaccine": "MODERNA",
                        "given_on": "01-29-2021",
                        "lot_number": "20"
                    }
                ]
            }
        ],
        "issued_by": "Example Issuer"
    },
    "validation_error": ""
}

However, this doesn't work properly because a validation result needs to handle a person, and it is legal per FIRS/SHC for multiple persons/patients to be within one dataset, and when I brought this up on SHC (https://github.com/smart-on-fhir/health-cards/issues/223), this seems to be by design.

As such, we refactored the card representation/results to look like this:

{
  "card_type": "smart_health_card",
  "issued_by": "https://spec.smarthealth.cards/examples/issuer",
  "persons": {
    "person0": {
      "name": [
        "John B. Anyperson"
      ],
      "dob": "1951-01-20",
      "immunizations": [
        {
          "vaccine_administered": "MODERNA",
          "date_given": "2021-01-01",
          "lot_number": "0000001"
        },
        {
          "vaccine_administered": "MODERNA",
          "date_given": "2021-01-29",
          "lot_number": "0000007"
        }
      ]
    }
  }
}

with the expectation that the end result would look like this (abbreviated):

{
    "cards": {
        "card0": {
            "persons": {
                "person0": {
                    "person_object": "data goes here"
                },
            }
        }
    },
    "validation": {
        "person0": "good"
    }
}  

This seemed fine at the time, but I don't think its flexible enough. For one, it makes the assumption that a given vaksina instance only has a single validator, and well, I can envision user stories where I can see multiple validators may need to be run (i.e., someone having to be checked for multiple criteria for different locations).

I'm thinking we need to model this list so:

{
    "cards": {
        "card0": {
            "persons": {
                "person0": {
                    "person_object": "data goes here"
                }
            }
        }
    },
    "validations": [
        {
            "validation_method": "osha2022",
            "results": {
                "person0": "good"
            }
        }
    ]
}

This might be more a job for the API than the library itself, but I don't want to make this difficult to implement either. It may be worth having REST endpoints for different validations, but that doesn't handle cases where something is interfacing w/ the library directly. I'm undecided on how best to represent the validation results as of right now, or if I should handle it in the core library at all ...

Guiorgy commented 2 years ago

I have a question about the possibility of a person having several cards of different standards. Suppose they got a vaccine in one state and the other in another state with a completely different card standard. Is this possible, and would we have to validate 2 different cards and combine them into 1 to determine if the person is immune? If the above is a concern, then perhaps we should allow the API to take a list of cards as input, and as an output have an array of Persons with an array of cards as it's field, something like this:

{
    "persons": [
        {
            "status" : "green/orange/red/etc",
            "names" : [
                "John A. Person"
            ],
            "dob": "01-05-1950",
            "cards" : [
                "card0" : {
                    "card_validation_status": "good",
                    "validation_error": "",
                    "card_type": "smart_health_card",
                    "issued_by": "Example Issuer 1",
                    "immunizations": [
                        {
                            "vaccine": "MODERNA",
                            "given_on": "01-01-2021",
                            "lot_number": "1"
                        }
                    ]
                },
                "card1" : {
                    "card_validation_status": "good",
                    "validation_error": "",
                    "card_type": "[some other type]",
                    "issued_by": "Example Issuer 2",
                    "immunizations": [
                        {
                            "vaccine": "MODERNA",
                            "given_on": "01-29-2021",
                            "lot_number": "20"
                        }
                    ]
                }
            ]
        }
    ],
}

Of course in this case there will be some duplication of card data (for example issuer, type and etc.). If this is a problem, we can put the card data separatly in an array and refere to it in Person object through the name.

If the above is not a concern, and the Vaksina API will only ever parse single cards, then your last example looks good to me.