Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5feaa38
CCM-12937 Letter updates transformer lambda
stevebux Nov 25, 2025
d53313c
Address review comments
stevebux Dec 2, 2025
0544695
Apply linting rules
stevebux Dec 3, 2025
35465ed
CM-12952 - MI Updates Transformer
nhsd-david-wass Nov 27, 2025
10b7e63
Added terraform and stream forwarder
nhsd-david-wass Nov 27, 2025
98bd62a
Unique stream name
nhsd-david-wass Nov 27, 2025
46dbae8
copy fixes from base commit
nhsd-david-wass Nov 27, 2025
2abd23e
new envelope fields
nhsd-david-wass Dec 1, 2025
d6e6d7a
logging
nhsd-david-wass Dec 1, 2025
7d6d1fe
lint fixes
nhsd-david-wass Dec 2, 2025
8c49dde
update lackage lock
nhsd-david-wass Dec 2, 2025
3d2d527
fix imports
nhsd-david-wass Dec 2, 2025
6c3a58b
back out export changes
nhsd-david-wass Dec 2, 2025
cb41158
Remove stream forwarder and pass direct from db to kinesis
nhsd-david-wass Dec 3, 2025
a40e34e
rebase updates
nhsd-david-wass Dec 3, 2025
5c8fb01
logging and refactor
nhsd-david-wass Dec 4, 2025
de6b962
logging for investigation
nhsd-david-wass Dec 4, 2025
f3289d2
fix extract payload
nhsd-david-wass Dec 4, 2025
733de30
fix mapping
nhsd-david-wass Dec 4, 2025
de50fdb
Fix default export in index.ts
nhsd-david-wass Dec 4, 2025
e3bdbbf
rebase fix
nhsd-david-wass Dec 16, 2025
cefd277
review changes
nhsd-david-wass Dec 18, 2025
433332d
trivy job setup of node for nhs packages
masl2 Dec 19, 2025
9743c03
tsconfig to use project base
masl2 Dec 24, 2025
c54d91d
Merge branch 'main' into feature/CCM-12952-Publish-MI-Events
masl2 Dec 24, 2025
3407b49
jest and lock (for some reason)
masl2 Dec 24, 2025
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
3 changes: 3 additions & 0 deletions infrastructure/terraform/components/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ No requirements.
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes |
| <a name="input_ca_pem_filename"></a> [ca\_pem\_filename](#input\_ca\_pem\_filename) | Filename for the CA truststore file within the s3 bucket | `string` | `null` | no |
| <a name="input_component"></a> [component](#input\_component) | The variable encapsulating the name of this component | `string` | `"supapi"` | no |
| <a name="input_core_account_id"></a> [core\_account\_id](#input\_core\_account\_id) | AWS Account ID for Core | `string` | `"000000000000"` | no |
| <a name="input_core_environment"></a> [core\_environment](#input\_core\_environment) | Environment of Core | `string` | `"prod"` | no |
| <a name="input_default_tags"></a> [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no |
| <a name="input_enable_backups"></a> [enable\_backups](#input\_enable\_backups) | Enable backups | `bool` | `false` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
Expand Down Expand Up @@ -47,6 +49,7 @@ No requirements.
| <a name="module_letter_status_updates_queue"></a> [letter\_status\_updates\_queue](#module\_letter\_status\_updates\_queue) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
| <a name="module_letter_updates_transformer"></a> [letter\_updates\_transformer](#module\_letter\_updates\_transformer) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_logging_bucket"></a> [logging\_bucket](#module\_logging\_bucket) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-s3bucket.zip | n/a |
| <a name="module_mi_updates_transformer"></a> [mi\_updates\_transformer](#module\_mi\_updates\_transformer) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_patch_letter"></a> [patch\_letter](#module\_patch\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_post_letters"></a> [post\_letters](#module\_post\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
| <a name="module_post_mi"></a> [post\_mi](#module\_post\_mi) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "aws_lambda_event_source_mapping" "mi_updates_transformer_kinesis" {
event_source_arn = aws_kinesis_stream.mi_change_stream.arn
function_name = module.mi_updates_transformer.function_arn
starting_position = "LATEST"
batch_size = 10
maximum_batching_window_in_seconds = 1

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

resource "aws_dynamodb_kinesis_streaming_destination" "mi_streaming_destination" {
stream_arn = aws_kinesis_stream.mi_change_stream.arn
table_name = aws_dynamodb_table.mi.name
approximate_creation_date_time_precision = "MILLISECOND"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
module "mi_updates_transformer" {
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip"

function_name = "mi-updates-transformer"
description = "MI Update Filter/Producer"

aws_account_id = var.aws_account_id
component = var.component
environment = var.environment
project = var.project
region = var.region
group = var.group

log_retention_in_days = var.log_retention_in_days
kms_key_arn = module.kms.key_arn

iam_policy_document = {
body = data.aws_iam_policy_document.mi_updates_transformer_lambda.json
}

function_s3_bucket = local.acct.s3_buckets["lambda_function_artefacts"]["id"]
function_code_base_path = local.aws_lambda_functions_dir_path
function_code_dir = "mi-updates-transformer/dist"
function_include_common = true
handler_function_name = "handler"
runtime = "nodejs22.x"
memory = 128
timeout = 29
log_level = var.log_level

force_lambda_code_deploy = var.force_lambda_code_deploy
enable_lambda_insights = false

send_to_firehose = true
log_destination_arn = local.destination_arn
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}"
})
}

data "aws_iam_policy_document" "mi_updates_transformer_lambda" {
statement {
sid = "AllowSNSPublish"
effect = "Allow"

actions = [
"sns:Publish"
]

resources = [
module.eventpub.sns_topic.arn
]
}

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

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

resources = [
aws_kinesis_stream.mi_change_stream.arn
]
}
}
4 changes: 2 additions & 2 deletions lambdas/api-handler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
},
"devDependencies": {
"@tsconfig/node22": "^22.0.2",
"@types/jest": "^29.5.14",
"@types/jest": "^30.0.0",
"jest": "^30.2.0",
"jest-mock-extended": "^3.0.7",
"jest-mock-extended": "^4.0.0",
"typescript": "^5.9.3",
"zod": "^4.1.11"
},
Expand Down
60 changes: 60 additions & 0 deletions lambdas/mi-updates-transformer/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { Config } from "jest";

export const baseJestConfig: Config = {
preset: "ts-jest",

// Automatically clear mock calls, instances, contexts and results before every test
clearMocks: true,

// Indicates whether the coverage information should be collected while executing the test
collectCoverage: true,

// The directory where Jest should output its coverage files
coverageDirectory: "./.reports/unit/coverage",

// Indicates which provider should be used to instrument code for coverage
coverageProvider: "babel",

coverageThreshold: {
global: {
branches: 100,
functions: 100,
lines: 100,
statements: -10,
},
},

coveragePathIgnorePatterns: ["/__tests__/"],
transform: { "^.+\\.ts$": "ts-jest" },
testPathIgnorePatterns: [".build"],
testMatch: ["**/?(*.)+(spec|test).[jt]s?(x)"],

// Use this configuration option to add custom reporters to Jest
reporters: [
"default",
[
"jest-html-reporter",
{
pageTitle: "Test Report",
outputPath: "./.reports/unit/test-report.html",
includeFailureMsg: true,
},
],
],

// The test environment that will be used for testing
testEnvironment: "jsdom",
};

const utilsJestConfig = {
...baseJestConfig,

testEnvironment: "node",

coveragePathIgnorePatterns: [
...(baseJestConfig.coveragePathIgnorePatterns ?? []),
"zod-validators.ts",
],
};

export default utilsJestConfig;
30 changes: 30 additions & 0 deletions lambdas/mi-updates-transformer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"dependencies": {
"@aws-sdk/client-sns": "^3.954.0",
"@aws-sdk/util-dynamodb": "^3.943.0",
"@internal/datastore": "^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",
"@types/aws-lambda": "^8.10.148",
"@types/jest": "^30.0.0",
"jest": "^30.2.0",
"jest-mock-extended": "^4.0.0",
"typescript": "^5.8.3"
},
"name": "nhs-notify-supplier-api-mi-updates-transformer",
"private": true,
"scripts": {
"lambda-build": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "jest",
"typecheck": "tsc --noEmit"
},
"version": "0.0.1"
}
Loading
Loading