Skip to content

Commit a32b943

Browse files
authored
Feature/ccm 12937- publish supplier letter events (#274)
* CCM-12937 Letter updates transformer lambda
1 parent d3e95f2 commit a32b943

30 files changed

+3312
-618
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
resource "aws_lambda_event_source_mapping" "letter_updates_transformer_kinesis" {
2+
event_source_arn = aws_kinesis_stream.letter_change_stream.arn
3+
function_name = module.letter_updates_transformer.function_arn
4+
starting_position = "LATEST"
5+
batch_size = 10
6+
maximum_batching_window_in_seconds = 1
7+
8+
depends_on = [
9+
module.letter_updates_transformer # ensures updates transformer exists
10+
]
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
resource "aws_kinesis_stream" "letter_change_stream" {
2+
name = "${local.csi}-letter-change-stream"
3+
shard_count = 1
4+
retention_period = 24
5+
}
6+
7+
resource "aws_dynamodb_kinesis_streaming_destination" "letter_streaming_destination" {
8+
stream_arn = aws_kinesis_stream.letter_change_stream.arn
9+
table_name = aws_dynamodb_table.letters.name
10+
approximate_creation_date_time_precision = "MILLISECOND"
11+
}

infrastructure/terraform/components/api/module_lambda_letter_updates_transformer.tf

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,39 @@ module "letter_updates_transformer" {
3636
log_subscription_role_arn = local.acct.log_subscription_role_arn
3737

3838
lambda_env_vars = merge(local.common_lambda_env_vars, {
39-
EVENTPUB_SNS_TOPIC_ARN = module.eventpub.sns_topic.arn
39+
EVENTPUB_SNS_TOPIC_ARN = "${module.eventpub.sns_topic.arn}"
4040
})
4141
}
4242

4343
data "aws_iam_policy_document" "letter_updates_transformer_lambda" {
4444
statement {
45-
sid = "KMSPermissions"
45+
sid = "AllowSNSPublish"
4646
effect = "Allow"
4747

4848
actions = [
49-
"kms:Decrypt",
50-
"kms:GenerateDataKey",
49+
"sns:Publish"
5150
]
5251

5352
resources = [
54-
module.kms.key_arn,
53+
module.eventpub.sns_topic.arn
5554
]
5655
}
5756

5857
statement {
59-
sid = "AllowSNSPublish"
58+
sid = "AllowKinesisGet"
6059
effect = "Allow"
6160

6261
actions = [
63-
"sns:Publish"
62+
"kinesis:GetRecords",
63+
"kinesis:GetShardIterator",
64+
"kinesis:DescribeStream",
65+
"kinesis:DescribeStreamSummary",
66+
"kinesis:ListShards",
67+
"kinesis:ListStreams",
6468
]
6569

6670
resources = [
67-
module.eventpub.sns_topic.arn
71+
aws_kinesis_stream.letter_change_stream.arn
6872
]
6973
}
7074
}

internal/events/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,5 @@
5050
"typecheck": "tsc --noEmit"
5151
},
5252
"types": "dist/index.d.ts",
53-
"version": "1.0.3"
53+
"version": "1.0.4"
5454
}

internal/events/src/domain/letter.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ The identifier will be included as the origin domain in the subject of any corre
7676
examples: ["1y3q9v1zzzz"],
7777
}),
7878

79+
supplierId: z.string().meta({
80+
title: "Supplier ID",
81+
description: "Supplier ID allocated to the letter during creation.",
82+
examples: ["supplier-1"],
83+
}),
84+
7985
groupId: z.string().meta({
8086
title: "Group ID",
8187
description:

internal/events/src/events/__tests__/event-envelope.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ describe("EventEnvelope schema validation", () => {
88
const baseValidEnvelope: Envelope = {
99
dataschema:
1010
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/order.READ.1.0.0.schema.json",
11+
dataschemaversion: "1.0.0",
1112
specversion: "1.0",
1213
id: "6f1c2a53-3d54-4a0a-9a0b-0e9ae2d4c111",
1314
source: "/data-plane/supplier-api/ordering",
1415
subject: "order/769acdd4",
1516
type: "uk.nhs.notify.supplier-api.order.READ.v1",
17+
plane: "data",
1618
time: "2025-10-01T10:15:30.000Z",
19+
datacontenttype: "application/json",
1720
data: {
1821
"notify-payload": {
1922
"notify-data": { nhsNumber: "9434765919" },
@@ -241,10 +244,13 @@ describe("EventEnvelope schema validation", () => {
241244
specversion: "1.0" as const,
242245
id: "6f1c2a53-3d54-4a0a-9a0b-0e02b2c3d479",
243246
type: "uk.nhs.notify.supplier-api.letter.CREATED.v1" as const,
247+
plane: "data",
244248
dataschema:
245249
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.CREATED.1.0.0.schema.json",
250+
dataschemaversion: "1.0.0",
246251
source: "/data-plane/supplier-api/letters",
247252
time: "2025-10-01T10:15:30.000Z",
253+
datacontenttype: "application/json",
248254
data: { status: "CREATED" },
249255
traceparent: "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
250256
recordedtime: "2025-10-01T10:15:30.250Z",
@@ -294,11 +300,14 @@ describe("EventEnvelope schema validation", () => {
294300
specversion: "1.0" as const,
295301
id: "6f1c2a53-3d54-4a0a-9a0b-0e9ae2d4c111",
296302
type: "uk.nhs.notify.supplier-api.order.READ.v1" as const,
303+
plane: "data",
297304
dataschema:
298305
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/order.READ.1.0.0.schema.json",
306+
dataschemaversion: "1.0.0",
299307
source: "/data-plane/supplier-api/ordering",
300308
subject: "order/769acdd4",
301309
time: "2025-10-01T10:15:30.000Z",
310+
datacontenttype: "application/json",
302311
data: { status: "READ" },
303312
traceparent: "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
304313
recordedtime: "2025-10-01T10:15:30.250Z",
@@ -341,6 +350,7 @@ describe("EventEnvelope schema validation", () => {
341350
type: "uk.nhs.notify.supplier-api.order.read.v1" as const,
342351
dataschema:
343352
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/order.read.1.0.0.schema.json",
353+
dataschemaversion: "1.0.0",
344354
source: "/data-plane/supplier-api/ordering",
345355
subject: "prefix/letter-rendering/order/769acdd4",
346356
time: "2025-10-01T10:15:30.000Z",

internal/events/src/events/__tests__/mi-events.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe("MI event validations", () => {
1818
expect(event).toEqual(
1919
expect.objectContaining({
2020
type: "uk.nhs.notify.supplier-api.mi.SUBMITTED.v1",
21+
plane: "data",
2122
specversion: "1.0",
2223
source: "/data-plane/supplier-api/prod/submit-mi",
2324
id: "8f2c3b44-4e65-5b1b-a678-1f0bf3d4d222",

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
"subject": "client/00f3b388-bbe9-41c9-9e76-052d37ee8988/letter-request/0o5Fs0EELR0fUjHjbCnEtdUwQe4_0o5Fs0EELR0fUjHjbCnEtdUwQe5"
1010
},
1111
"specificationId": "1y3q9v1zzzz",
12-
"status": "ACCEPTED"
12+
"status": "ACCEPTED",
13+
"supplierId": "supplier1"
1314
},
1415
"datacontenttype": "application/json",
1516
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.0.1.0.schema.json",
17+
"dataschemaversion": "1.0.0",
1618
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
19+
"plane": "data",
1720
"recordedtime": "2025-08-28T08:45:00.000Z",
1821
"severitynumber": 2,
1922
"severitytext": "INFO",

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
"source": "/data-plane/letter-rendering/prod/render-pdf"
99
},
1010
"specificationId": "1y3q9v1zzzz",
11-
"status": "ACCEPTED"
11+
"status": "ACCEPTED",
12+
"supplierId": "supplier1"
1213
},
1314
"datacontenttype": "application/json",
1415
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.0.schema.json",
16+
"dataschemaversion": "1.0.0",
1517
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
18+
"plane": "data",
1619
"recordedtime": "2025-08-28T08:45:00.000Z",
1720
"severitynumber": 2,
1821
"severitytext": "INFO",

internal/events/src/events/__tests__/testData/letter.ACCEPTED.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
"subject": "client/00f3b388-bbe9-41c9-9e76-052d37ee8988/letter-request/0o5Fs0EELR0fUjHjbCnEtdUwQe4_0o5Fs0EELR0fUjHjbCnEtdUwQe5"
1010
},
1111
"specificationId": "1y3q9v1zzzz",
12-
"status": "ACCEPTED"
12+
"status": "ACCEPTED",
13+
"supplierId": "supplier1"
1314
},
1415
"datacontenttype": "application/json",
1516
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.0.schema.json",
17+
"dataschemaversion": "1.0.0",
1618
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
19+
"plane": "data",
1720
"recordedtime": "2025-08-28T08:45:00.000Z",
1821
"severitynumber": 2,
1922
"severitytext": "INFO",

0 commit comments

Comments
 (0)