Skip to content

Commit 9ed6d5d

Browse files
CCM-13752 add specification billing (#454)
* CCM-13752 Added specificationBillingId * add to cloudevents * CCM-15148 - Add BillingId to variant map * update test utility * rebase against main * minor post merge fixes and linting * event schema increment --------- Co-authored-by: Mark Slowey <mark.slowey1@nhs.net>
1 parent 58e95bc commit 9ed6d5d

File tree

29 files changed

+129
-23
lines changed

29 files changed

+129
-23
lines changed

infrastructure/terraform/components/api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ No requirements.
3535
| <a name="input_kms_deletion_window"></a> [kms\_deletion\_window](#input\_kms\_deletion\_window) | When a kms key is deleted, how long should it wait in the pending deletion state? | `string` | `"30"` | no |
3636
| <a name="input_letter_event_source"></a> [letter\_event\_source](#input\_letter\_event\_source) | Source value to use for the letter status event updates | `string` | `"/data-plane/supplier-api/nhs-supplier-api-prod/main/update-status"` | no |
3737
| <a name="input_letter_table_ttl_hours"></a> [letter\_table\_ttl\_hours](#input\_letter\_table\_ttl\_hours) | Number of hours to set as TTL on letters table | `number` | `24` | no |
38-
| <a name="input_letter_variant_map"></a> [letter\_variant\_map](#input\_letter\_variant\_map) | n/a | `map(object({ supplierId = string, specId = string, priority = number }))` | <pre>{<br/> "lv1": {<br/> "priority": 10,<br/> "specId": "spec1",<br/> "supplierId": "supplier1"<br/> },<br/> "lv2": {<br/> "priority": 10,<br/> "specId": "spec2",<br/> "supplierId": "supplier1"<br/> },<br/> "lv3": {<br/> "priority": 10,<br/> "specId": "spec3",<br/> "supplierId": "supplier2"<br/> }<br/>}</pre> | no |
38+
| <a name="input_letter_variant_map"></a> [letter\_variant\_map](#input\_letter\_variant\_map) | n/a | `map(object({ supplierId = string, specId = string, priority = number, billingId = string }))` | <pre>{<br/> "lv1": {<br/> "billingId": "billing1",<br/> "priority": 10,<br/> "specId": "spec1",<br/> "supplierId": "supplier1"<br/> },<br/> "lv2": {<br/> "billingId": "billing1",<br/> "priority": 10,<br/> "specId": "spec2",<br/> "supplierId": "supplier1"<br/> },<br/> "lv3": {<br/> "billingId": "billing1",<br/> "priority": 10,<br/> "specId": "spec3",<br/> "supplierId": "supplier2"<br/> }<br/>}</pre> | no |
3939
| <a name="input_log_level"></a> [log\_level](#input\_log\_level) | The log level to be used in lambda functions within the component. Any log with a lower severity than the configured value will not be logged: https://docs.python.org/3/library/logging.html#levels | `string` | `"INFO"` | no |
4040
| <a name="input_log_retention_in_days"></a> [log\_retention\_in\_days](#input\_log\_retention\_in\_days) | The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite | `number` | `0` | no |
4141
| <a name="input_manually_configure_mtls_truststore"></a> [manually\_configure\_mtls\_truststore](#input\_manually\_configure\_mtls\_truststore) | Manually manage the truststore used for API Gateway mTLS (e.g. for prod environment) | `bool` | `false` | no |

infrastructure/terraform/components/api/variables.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ variable "eventpub_control_plane_bus_arn" {
136136
}
137137

138138
variable "letter_variant_map" {
139-
type = map(object({ supplierId = string, specId = string, priority = number }))
139+
type = map(object({ supplierId = string, specId = string, priority = number, billingId = string }))
140140
default = {
141-
"lv1" = { supplierId = "supplier1", specId = "spec1", priority = 10 },
142-
"lv2" = { supplierId = "supplier1", specId = "spec2", priority = 10 },
143-
"lv3" = { supplierId = "supplier2", specId = "spec3", priority = 10 }
141+
"lv1" = { supplierId = "supplier1", specId = "spec1", priority = 10, billingId = "billing1" },
142+
"lv2" = { supplierId = "supplier1", specId = "spec2", priority = 10, billingId = "billing1" },
143+
"lv3" = { supplierId = "supplier2", specId = "spec3", priority = 10, billingId = "billing1" }
144144
}
145145
}
146146

internal/datastore/src/__test__/letter-repository.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ function createLetter(
3030
source: "/data-plane/letter-rendering/pdf",
3131
subject: `client/1/letter-request/${letterId}`,
3232
billingRef: "specification1",
33+
specificationBillingId: "billing1",
3334
};
3435
}
3536

internal/datastore/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export const LetterSchema = LetterSchemaBase.extend({
5454
source: z.string(),
5555
subject: z.string(),
5656
billingRef: z.string(),
57+
specificationBillingId: z.string(),
5758
}).describe("Letter");
5859

5960
/**

internal/events/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@
3737
"typecheck": "tsc --noEmit"
3838
},
3939
"types": "dist/index.d.ts",
40-
"version": "1.0.14"
40+
"version": "1.0.15"
4141
}

internal/events/src/domain/letter.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ The identifier will be included as the origin domain in the subject of any corre
8383
examples: ["1y3q9v1zzzz"],
8484
}),
8585

86+
specificationBillingId: z.string().meta({
87+
title: "Specification Billing ID",
88+
description:
89+
"The billing ID from the letter specification which was used to produce a letter pack for this request.",
90+
examples: ["1y3q9v1zzzz"],
91+
}),
92+
8693
supplierId: z.string().meta({
8794
title: "Supplier ID",
8895
description: "Supplier ID allocated to the letter during creation.",

internal/events/src/events/__tests__/letter-mapper.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ describe("letter-mapper", () => {
1616
updatedAt: "2025-11-24T15:55:18.000Z",
1717
source: "letter-rendering/source/test",
1818
subject: "letter-rendering/source/letter/letter-id",
19+
specificationBillingId: "billing123",
1920
} as Letter;
2021
const source = "/data-plane/supplier-api/nhs-supplier-api-dev/main/letters";
2122
const event = mapLetterToCloudEvent(letter, source);
@@ -35,6 +36,7 @@ describe("letter-mapper", () => {
3536
status: "PRINTED",
3637
specificationId: "spec1",
3738
billingRef: "spec1",
39+
specificationBillingId: "billing123",
3840
supplierId: "supplier1",
3941
groupId: "group1",
4042
reasonCode: "R02",

internal/events/src/events/__tests__/letter-status-change-events.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ describe("LetterStatus event validations", () => {
4040
billingRef: "1y3q9v1zzzz",
4141
groupId: "client_template",
4242
status,
43+
specificationBillingId: "billing123",
4344
}),
4445
}),
4546
);

internal/events/src/events/__tests__/testData/letter.ACCEPTED-with-invalid-major-version.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"source": "/data-plane/letter-rendering/prod/render-pdf",
1010
"subject": "client/00f3b388-bbe9-41c9-9e76-052d37ee8988/letter-request/0o5Fs0EELR0fUjHjbCnEtdUwQe4_0o5Fs0EELR0fUjHjbCnEtdUwQe5"
1111
},
12+
"specificationBillingId": "billing123",
1213
"specificationId": "1y3q9v1zzzz",
1314
"status": "ACCEPTED",
1415
"supplierId": "supplier1"

internal/events/src/events/__tests__/testData/letter.ACCEPTED-with-missing-fields.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"event": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
99
"source": "/data-plane/letter-rendering/prod/render-pdf"
1010
},
11+
"specificationBillingId": "billing123",
1112
"specificationId": "1y3q9v1zzzz",
1213
"status": "ACCEPTED",
1314
"supplierId": "supplier1"

0 commit comments

Comments
 (0)