Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup JSON schemas and add ADR #174

Merged
merged 8 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 4. Use JSON schemas to define LPA structure

Date: 2024-04-22

## Status

Accepted

## Context

When a donor signs their LPA online, or the OPG receives it on paper, it is stored in the LPA Store as a golden copy of the record. As well as storing the data that the donor submitted, we also need to store the context in which is was executed: the agreed-upon conditions and the meaning of their choices.

This context needs to live with the LPA for its entire lifetime, which is likely to be decades, even if the context of new LPAs changes in the future (for example, if OPG updates the wording of the confirmation statement).

## Decision

To ensure we capture and preserve the context of LPAs, each LPA will be associated with a JSON schema at point of execution (online) or ingestion (paper). That schema will document the shape of the LPA's data.

The schema file will be mapped to translation files that contain any important text associated with the LPA, such as the terms the donor agreed to. There will be a file for each language a donor can use (currently English or Welsh).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this also say something about the decision made that the language signed in is assumed to be the same as the contactLanguagePreference for the donor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure if we'd landed on a definitive answer for that yet so didn't want to specify it in here


The schema file, and translation files, will live in the opg-data-lpa-store repository.

The schemas will be hosted on [the OPG's data dictionary](https://data-dictionary.opg.service.justice.gov.uk/) website to ensure they have a fully resolvable URI under our control.

As the schema changes, it will be versioned by year and month (YYYY-MM). If multiple releases are made within the same month, an increasing integer will be appended to the end (YYYY-MM-N) to differentiate further.

The JSON schema associated with the LPA will be stored inside the LPA (JSON) document itself, in a `$schema` field. It will point to the resolvable URI of the JSON schema noted above.

mattmachell marked this conversation as resolved.
Show resolved Hide resolved
## Consequences

As validation is currently done manually, there is a risk that the structure of the LPA will not match the JSON schema. We should introduce schema validation when storing an LPA to ensure this is not the case.

We need to ensure that any changes to the structure of the data are properly updated in the schema, managed through pull requests to this repository that need cross-team ratification. Non essential changes will likely be delayed and grouped to minimise the number of active schemas. An exception to this is before the start of private beta, since we will only be working with test data and can more easily change the schema.

Services that display an LPA may need to pull content from the translation files to ensure they are presenting accurate information.

The JSON schemas will need to be kept (and preferably be resolvable at their URI) for as long as we have any LPAs using them. This could be mitigated in the future by migrating older LPAs to a future structure.
4 changes: 3 additions & 1 deletion docs/openapi/openapi-aws.override.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
openapi: "3.0.3"
components:
schemas:
InitialLpa:
DonorDetails:
$ref: "#/components/schemas/Empty"
Lpa:
$ref: "#/components/schemas/Empty"
Empty:
type: object
32 changes: 3 additions & 29 deletions docs/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/InitialLpa"
$ref: "#/components/schemas/DonorDetails"
responses:
"201":
description: Case created
Expand Down Expand Up @@ -202,35 +202,9 @@ components:
code:
enum: ["NOT_FOUND"]
Lpa:
allOf:
- $ref: "#/components/schemas/InitialLpa"
type: object
required:
- uid
- status
- registrationDate
- updatedAt
properties:
uid:
type: string
pattern: M-([A-Z0-9]{4})-([A-Z0-9]{4})-([A-Z0-9]{4})
example: M-789Q-P4DF-4UX3
status:
type: string
enum:
- processing
- registered
registrationDate:
oneOf:
- type: string
format: date
- type: "null"
updatedAt:
type: string
format: date
additionalProperties: false
InitialLpa:
$ref: "../schemas/2024-04/lpa.json"
DonorDetails:
$ref: "../schemas/2024-04/donor-details.json"
Update:
type: object
required:
Expand Down
263 changes: 263 additions & 0 deletions docs/schemas/2024-04/donor-details.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://data-dictionary.opg.service.justice.gov.uk/schema/lpa/2024-04/donor-details.json",
"description": "The data that should be provided when an LPA is executed",
"type": "object",
"required": [
"lpaType",
"donor",
"attorneys",
"certificateProvider",
"signedAt"
],
"properties": {
"lpaType": {
"type": "string",
"enum": ["property-and-affairs", "personal-welfare"]
},
"donor": {
"allOf": [
{
"$ref": "#/$defs/Person"
}
],
"type": "object",
"required": ["dateOfBirth", "email"],
"properties": {
"dateOfBirth": {
"type": "string",
"format": "date"
},
"email": {
"type": "string",
"x-faker": "internet.email"
},
"otherNamesKnownBy": {
"type": "string",
"x-faker": "name.findName"
},
"contactLanguagePreference": {
"type": "string",
"enum": ["en", "cy"]
}
}
},
"attorneys": {
"type": "array",
"items": {
"$ref": "#/$defs/Attorney"
},
"minLength": 1
},
"trustCorporations": {
"type": "array",
"items": {
"$ref": "#/$defs/TrustCorporation"
}
},
"certificateProvider": {
"allOf": [
{
"$ref": "#/$defs/Person"
}
],
"type": "object",
"required": ["phone", "channel"],
"if": {
"required": ["channel"],
"properties": {
"channel": { "const": "online" }
}
},
"then": {
"required": ["email"]
},
"properties": {
"email": {
"type": "string",
"x-faker": "internet.email"
},
"phone": {
"type": "string",
"x-faker": "phone.number"
},
"channel": {
"type": "string",
"enum": ["paper", "online"]
}
}
},
"peopleToNotify": {
"type": "array",
"items": {
"$ref": "#/$defs/PersonToNotify"
}
},
"howAttorneysMakeDecisions": {
"type": "string",
"enum": [
"jointly",
"jointly-and-severally",
"jointly-for-some-severally-for-others"
]
},
"howAttorneysMakeDecisionsDetails": {
"type": "string"
},
"howReplacementAttorneysMakeDecisions": {
"type": "string",
"enum": [
"jointly",
"jointly-and-severally",
"jointly-for-some-severally-for-others"
]
},
"howReplacementAttorneysMakeDecisionsDetails": {
"type": "string"
},
"howReplacementAttorneysStepIn": {
"type": "string",
"enum": ["all-can-no-longer-act", "one-can-no-longer-act", "another-way"]
},
"howReplacementAttorneysStepInDetails": {
"type": "string"
},
"whenTheLpaCanBeUsed": {
"type": "string",
"enum": ["when-capacity-lost", "when-has-capacity"]
},
"lifeSustainingTreatmentOption": {
"type": "string",
"enum": ["option-a", "option-b"]
},
"restrictionsAndConditions": {
"type": "string"
},
"signedAt": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false,
"$defs": {
"Address": {
"type": "object",
"required": ["line1", "town", "country"],
"properties": {
"line1": {
"type": "string",
"x-faker": "address.streetAddress"
},
"line2": {
"type": "string",
"x-faker": "address.streetName"
},
"line3": {
"type": "string",
"x-faker": "address.cityName"
},
"town": {
"type": "string",
"x-faker": "address.cityName"
},
"postcode": {
"type": "string",
"x-faker": {
"helpers.replaceSymbols": "??# #??"
}
},
"country": {
"type": "string",
"format": "ISO-3166-1",
"minLength": 2,
"maxLength": 2,
"x-faker": "address.countryCode"
}
},
"additionalProperties": false,
"example": {
"line1": "Flat 3",
"line2": "42 Primrose Lane",
"line3": "Greenfields",
"town": "Manchester",
"postcode": "M17 2XY",
"country": "GB"
}
},
"Person": {
"type": "object",
"required": ["uid", "firstNames", "lastName", "address"],
"properties": {
"uid": {
"type": "string",
"format": "uuid"
},
"firstNames": {
"type": "string",
"x-faker": "name.firstName"
},
"lastName": {
"type": "string",
"x-faker": "name.lastName"
},
"address": {
"$ref": "#/$defs/Address"
}
}
},
"Attorney": {
"allOf": [
{
"$ref": "#/$defs/Person"
}
],
"type": "object",
"required": ["dateOfBirth", "email", "status"],
"properties": {
"dateOfBirth": {
"type": "string",
"format": "date"
},
"email": {
"type": "string",
"x-faker": "internet.email"
},
"status": {
"type": "string",
"enum": ["active", "replacement", "removed"]
}
}
},
"TrustCorporation": {
"type": "object",
"required": ["name", "companyNumber", "email", "address", "status"],
"properties": {
"name": {
"type": "string"
},
"companyNumber": {
"type": "string"
},
"email": {
"type": "string",
"x-faker": "internet.email"
},
"address": {
"$ref": "#/$defs/Address"
},
"status": {
"type": "string",
"enum": ["active", "replacement", "removed"]
}
}
},
"PersonToNotify": {
"allOf": [
{
"$ref": "#/$defs/Person"
}
],
"type": "object"
}
}
}
Loading
Loading