Skip to content
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,11 @@
resource "aws_lambda_event_source_mapping" "letter_updates_transformer_kinesis" {
event_source_arn = aws_kinesis_stream.letter_change_stream.arn
function_name = module.letter_updates_transformer.function_arn
starting_position = "LATEST"
batch_size = 10
maximum_batching_window_in_seconds = 1

depends_on = [
module.letter_updates_transformer # ensures updates transformer exists
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "aws_kinesis_stream" "letter_change_stream" {
name = "${local.csi}-letter-change-stream"
shard_count = 1
retention_period = 24
}

resource "aws_dynamodb_kinesis_streaming_destination" "letter_streaming_destination" {
stream_arn = aws_kinesis_stream.letter_change_stream.arn
table_name = aws_dynamodb_table.letters.name
approximate_creation_date_time_precision = "MILLISECOND"
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,35 +36,39 @@ module "letter_updates_transformer" {
log_subscription_role_arn = local.acct.log_subscription_role_arn

lambda_env_vars = merge(local.common_lambda_env_vars, {
EVENTPUB_SNS_TOPIC_ARN = module.eventpub.sns_topic.arn
EVENTPUB_SNS_TOPIC_ARN = "${module.eventpub.sns_topic.arn}"
})
}

data "aws_iam_policy_document" "letter_updates_transformer_lambda" {
statement {
sid = "KMSPermissions"
sid = "AllowSNSPublish"
effect = "Allow"

actions = [
"kms:Decrypt",
"kms:GenerateDataKey",
"sns:Publish"
]

resources = [
module.kms.key_arn,
module.eventpub.sns_topic.arn
]
}

statement {
sid = "AllowSNSPublish"
sid = "AllowKinesisGet"
effect = "Allow"

actions = [
"sns:Publish"
"kinesis:GetRecords",
"kinesis:GetShardIterator",
"kinesis:DescribeStream",
"kinesis:DescribeStreamSummary",
"kinesis:ListShards",
"kinesis:ListStreams",
]

resources = [
module.eventpub.sns_topic.arn
aws_kinesis_stream.letter_change_stream.arn
]
}
}
2 changes: 1 addition & 1 deletion internal/events/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@
"typecheck": "tsc --noEmit"
},
"types": "dist/index.d.ts",
"version": "1.0.3"
"version": "1.0.4"
}
6 changes: 6 additions & 0 deletions internal/events/src/domain/letter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ The identifier will be included as the origin domain in the subject of any corre
examples: ["1y3q9v1zzzz"],
}),

supplierId: z.string().meta({
title: "Supplier ID",
description: "Supplier ID allocated to the letter during creation.",
examples: ["supplier-1"],
}),

groupId: z.string().meta({
title: "Group ID",
description:
Expand Down
10 changes: 10 additions & 0 deletions internal/events/src/events/__tests__/event-envelope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ describe("EventEnvelope schema validation", () => {
const baseValidEnvelope: Envelope = {
dataschema:
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/order.READ.1.0.0.schema.json",
dataschemaversion: "1.0.0",
specversion: "1.0",
id: "6f1c2a53-3d54-4a0a-9a0b-0e9ae2d4c111",
source: "/data-plane/supplier-api/ordering",
subject: "order/769acdd4",
type: "uk.nhs.notify.supplier-api.order.READ.v1",
plane: "data",
time: "2025-10-01T10:15:30.000Z",
datacontenttype: "application/json",
data: {
"notify-payload": {
"notify-data": { nhsNumber: "9434765919" },
Expand Down Expand Up @@ -241,10 +244,13 @@ describe("EventEnvelope schema validation", () => {
specversion: "1.0" as const,
id: "6f1c2a53-3d54-4a0a-9a0b-0e02b2c3d479",
type: "uk.nhs.notify.supplier-api.letter.CREATED.v1" as const,
plane: "data",
dataschema:
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.CREATED.1.0.0.schema.json",
dataschemaversion: "1.0.0",
source: "/data-plane/supplier-api/letters",
time: "2025-10-01T10:15:30.000Z",
datacontenttype: "application/json",
data: { status: "CREATED" },
traceparent: "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
recordedtime: "2025-10-01T10:15:30.250Z",
Expand Down Expand Up @@ -294,11 +300,14 @@ describe("EventEnvelope schema validation", () => {
specversion: "1.0" as const,
id: "6f1c2a53-3d54-4a0a-9a0b-0e9ae2d4c111",
type: "uk.nhs.notify.supplier-api.order.READ.v1" as const,
plane: "data",
dataschema:
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/order.READ.1.0.0.schema.json",
dataschemaversion: "1.0.0",
source: "/data-plane/supplier-api/ordering",
subject: "order/769acdd4",
time: "2025-10-01T10:15:30.000Z",
datacontenttype: "application/json",
data: { status: "READ" },
traceparent: "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
recordedtime: "2025-10-01T10:15:30.250Z",
Expand Down Expand Up @@ -341,6 +350,7 @@ describe("EventEnvelope schema validation", () => {
type: "uk.nhs.notify.supplier-api.order.read.v1" as const,
dataschema:
"https://notify.nhs.uk/cloudevents/schemas/supplier-api/order.read.1.0.0.schema.json",
dataschemaversion: "1.0.0",
source: "/data-plane/supplier-api/ordering",
subject: "prefix/letter-rendering/order/769acdd4",
time: "2025-10-01T10:15:30.000Z",
Expand Down
1 change: 1 addition & 0 deletions internal/events/src/events/__tests__/mi-events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe("MI event validations", () => {
expect(event).toEqual(
expect.objectContaining({
type: "uk.nhs.notify.supplier-api.mi.SUBMITTED.v1",
plane: "data",
specversion: "1.0",
source: "/data-plane/supplier-api/prod/submit-mi",
id: "8f2c3b44-4e65-5b1b-a678-1f0bf3d4d222",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
"subject": "client/00f3b388-bbe9-41c9-9e76-052d37ee8988/letter-request/0o5Fs0EELR0fUjHjbCnEtdUwQe4_0o5Fs0EELR0fUjHjbCnEtdUwQe5"
},
"specificationId": "1y3q9v1zzzz",
"status": "ACCEPTED"
"status": "ACCEPTED",
"supplierId": "supplier1"
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.0.1.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
"plane": "data",
"recordedtime": "2025-08-28T08:45:00.000Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
"source": "/data-plane/letter-rendering/prod/render-pdf"
},
"specificationId": "1y3q9v1zzzz",
"status": "ACCEPTED"
"status": "ACCEPTED",
"supplierId": "supplier1"
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
"plane": "data",
"recordedtime": "2025-08-28T08:45:00.000Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
"subject": "client/00f3b388-bbe9-41c9-9e76-052d37ee8988/letter-request/0o5Fs0EELR0fUjHjbCnEtdUwQe4_0o5Fs0EELR0fUjHjbCnEtdUwQe5"
},
"specificationId": "1y3q9v1zzzz",
"status": "ACCEPTED"
"status": "ACCEPTED",
"supplierId": "supplier1"
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
"plane": "data",
"recordedtime": "2025-08-28T08:45:00.000Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@
"reasonCode": "RNIB",
"reasonText": "RNIB",
"specificationId": "1y3q9v1zzzz",
"status": "FORWARDED"
"status": "FORWARDED",
"supplierId": "supplier1"
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.FORWARDED.1.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
"plane": "data",
"recordedtime": "2025-08-28T08:45:00.000Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@
"reasonCode": "R07",
"reasonText": "No such address",
"specificationId": "1y3q9v1zzzz",
"status": "RETURNED"
"status": "RETURNED",
"supplierId": "supplier1"
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.RETURNED.1.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "23f1f09c-a555-4d9b-8405-0b33490bc920",
"plane": "data",
"recordedtime": "2025-08-28T08:45:00.000Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/mi.SUBMITTED.1.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "9a3d4c55-5f76-6c2c-b789-2f1cf4e5e333",
"plane": "data",
"recordedtime": "2025-11-16T15:00:00.250Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/mi.SUBMITTED.2.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "8f2c3b44-4e65-5b1b-a678-1f0bf3d4d222",
"plane": "data",
"recordedtime": "2025-11-16T10:30:00.250Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/mi.SUBMITTED.1.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "8f2c3b44-4e65-5b1b-a678-1f0bf3d4d222",
"plane": "data",
"recordedtime": "2025-11-16T10:30:00.250Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
},
"datacontenttype": "application/json",
"dataschema": "https://notify.nhs.uk/cloudevents/schemas/supplier-api/mi.SUBMITTED.1.0.0.schema.json",
"dataschemaversion": "1.0.0",
"id": "8f2c3b44-4e65-5b1b-a678-1f0bf3d4d222",
"plane": "data",
"recordedtime": "2025-11-16T10:30:00.250Z",
"severitynumber": 2,
"severitytext": "INFO",
Expand Down
29 changes: 21 additions & 8 deletions internal/events/src/events/event-envelope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ export function EventEnvelope<TData extends z.ZodTypeAny>(
examples: typeStrings,
}),

plane: z.literal("data").meta({
title: "plane",
description: "The event bus that this event will be published to",
examples: ["data"],
}),

dataschema: z
.string()
.regex(
Expand All @@ -64,6 +70,15 @@ export function EventEnvelope<TData extends z.ZodTypeAny>(
examples: schemaExamples,
}),

dataschemaversion: z
.string()
.regex(/^1\.\d+\.\d+$/)
.meta({
title: "Data Schema URI",
description: `Version of the schema that describes the event data\n\nMust match the version in dataschema`,
examples: ["1.0.0"],
}),

source: z
.string()
.regex(/^\/data-plane\/supplier-api(?:\/.*)?$/)
Expand Down Expand Up @@ -94,14 +109,12 @@ export function EventEnvelope<TData extends z.ZodTypeAny>(
examples: ["2025-10-01T10:15:30.000Z"],
}),

datacontenttype: z.optional(
z.literal("application/json").meta({
title: "Data Content Type",
description:
"Media type for the data field (fixed to application/json).",
examples: ["application/json"],
}),
),
datacontenttype: z.literal("application/json").meta({
title: "Data Content Type",
description:
"Media type for the data field (fixed to application/json).",
examples: ["application/json"],
}),

traceparent: z
.string()
Expand Down
11 changes: 9 additions & 2 deletions lambdas/letter-updates-transformer/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
{
"dependencies": {
"@types/aws-lambda": "^8.10.148",
"esbuild": "^0.24.0"
"@aws-sdk/client-sns": "^3.943.0",
"@aws-sdk/util-dynamodb": "^3.943.0",
"@internal/datastore": "^0.1.0",
"@internal/helpers": "^0.1.0",
"@nhsdigital/nhs-notify-event-schemas-supplier-api": "*",
"aws-lambda": "^1.0.7",
"esbuild": "^0.24.0",
"pino": "^10.1.0",
"zod": "^4.1.13"
},
"devDependencies": {
"@tsconfig/node22": "^22.0.2",
Expand Down
17 changes: 0 additions & 17 deletions lambdas/letter-updates-transformer/src/__tests__/index.test.ts

This file was deleted.

Loading
Loading