Skip to content

Commit 706e6bf

Browse files
committed
Add update-letter-queue lambda
1 parent 4e37376 commit 706e6bf

16 files changed

Lines changed: 10724 additions & 15067 deletions

File tree

infrastructure/terraform/components/api/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ No requirements.
6262
| <a name="module_s3bucket_test_letters"></a> [s3bucket\_test\_letters](#module\_s3bucket\_test\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-s3bucket.zip | n/a |
6363
| <a name="module_sqs_letter_updates"></a> [sqs\_letter\_updates](#module\_sqs\_letter\_updates) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-sqs.zip | n/a |
6464
| <a name="module_supplier_ssl"></a> [supplier\_ssl](#module\_supplier\_ssl) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-ssl.zip | n/a |
65+
| <a name="module_update_letter_queue"></a> [update\_letter\_queue](#module\_update\_letter\_queue) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
6566
| <a name="module_upsert_letter"></a> [upsert\_letter](#module\_upsert\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
6667
## Outputs
6768

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" "update_letter_queue_kinesis" {
2+
event_source_arn = aws_kinesis_stream.letter_change_stream.arn
3+
function_name = module.update_letter_queue.function_arn
4+
starting_position = "LATEST"
5+
batch_size = 10
6+
maximum_batching_window_in_seconds = 1
7+
8+
depends_on = [
9+
module.update_letter_queue # ensures update letter queue lambda exists
10+
]
11+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
module "update_letter_queue" {
2+
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip"
3+
4+
function_name = "update-letter-queue"
5+
description = "Populates the letter queue table with new pending letters from the letter change stream"
6+
7+
aws_account_id = var.aws_account_id
8+
component = var.component
9+
environment = var.environment
10+
project = var.project
11+
region = var.region
12+
group = var.group
13+
14+
log_retention_in_days = var.log_retention_in_days
15+
kms_key_arn = module.kms.key_arn
16+
17+
iam_policy_document = {
18+
body = data.aws_iam_policy_document.update_letter_queue_lambda.json
19+
}
20+
21+
function_s3_bucket = local.acct.s3_buckets["lambda_function_artefacts"]["id"]
22+
function_code_base_path = local.aws_lambda_functions_dir_path
23+
function_code_dir = "update-letter-queue/dist"
24+
function_include_common = true
25+
handler_function_name = "handler"
26+
runtime = "nodejs22.x"
27+
memory = 512
28+
timeout = 29
29+
log_level = var.log_level
30+
31+
force_lambda_code_deploy = var.force_lambda_code_deploy
32+
enable_lambda_insights = false
33+
34+
log_destination_arn = local.destination_arn
35+
log_subscription_role_arn = local.acct.log_subscription_role_arn
36+
37+
lambda_env_vars = merge(local.common_lambda_env_vars, {
38+
LETTER_QUEUE_TABLE_NAME = aws_dynamodb_table.letter-queue.name,
39+
LETTER_QUEUE_TTL_HOURS = 168 # 7 days
40+
})
41+
}
42+
43+
data "aws_iam_policy_document" "update_letter_queue_lambda" {
44+
statement {
45+
sid = "AllowDynamoDBWrite"
46+
effect = "Allow"
47+
48+
actions = [
49+
"dynamodb:PutItem",
50+
]
51+
52+
resources = [
53+
aws_dynamodb_table.letter-queue.arn,
54+
"${aws_dynamodb_table.letter-queue.arn}/index/*"
55+
]
56+
}
57+
58+
statement {
59+
sid = "AllowKinesisGet"
60+
effect = "Allow"
61+
62+
actions = [
63+
"kinesis:GetRecords",
64+
]
65+
66+
resources = [
67+
aws_kinesis_stream.letter_change_stream.arn
68+
]
69+
}
70+
}

internal/datastore/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export * from "./types";
22
export * from "./mi-repository";
33
export * from "./letter-repository";
44
export * from "./supplier-repository";
5+
export { default as LetterQueueRepository } from "./letter-queue-repository";
56
export { default as DBHealthcheck } from "./healthcheck";
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist
2+
node_modules
3+
.reports
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist
2+
node_modules
3+
.reports
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
export const baseJestConfig = {
2+
preset: "ts-jest",
3+
extensionsToTreatAsEsm: [".ts"],
4+
transform: {
5+
"^.+\\.ts$": [
6+
"ts-jest",
7+
{
8+
useESM: true,
9+
},
10+
],
11+
},
12+
13+
// Automatically clear mock calls, instances, contexts and results before every test
14+
clearMocks: true,
15+
16+
// Indicates whether the coverage information should be collected while executing the test
17+
collectCoverage: true,
18+
19+
// The directory where Jest should output its coverage files
20+
coverageDirectory: "./.reports/unit/coverage",
21+
22+
// Indicates which provider should be used to instrument code for coverage
23+
coverageProvider: "babel",
24+
25+
coverageThreshold: {
26+
global: {
27+
branches: 100,
28+
functions: 100,
29+
lines: 100,
30+
statements: -10,
31+
},
32+
},
33+
34+
coveragePathIgnorePatterns: ["/__tests__/"],
35+
testPathIgnorePatterns: [".build"],
36+
testMatch: ["**/?(*.)+(spec|test).[jt]s?(x)"],
37+
38+
// Use this configuration option to add custom reporters to Jest
39+
reporters: [
40+
"default",
41+
[
42+
"jest-html-reporter",
43+
{
44+
pageTitle: "Test Report",
45+
outputPath: "./.reports/unit/test-report.html",
46+
includeFailureMsg: true,
47+
},
48+
],
49+
],
50+
51+
// The test environment that will be used for testing
52+
testEnvironment: "node",
53+
};
54+
55+
const utilsJestConfig = {
56+
...baseJestConfig,
57+
58+
testEnvironment: "node",
59+
60+
coveragePathIgnorePatterns: [
61+
...(baseJestConfig.coveragePathIgnorePatterns ?? []),
62+
],
63+
};
64+
65+
export default utilsJestConfig;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"dependencies": {
3+
"@aws-sdk/client-dynamodb": "^3.984.0",
4+
"@aws-sdk/lib-dynamodb": "^3.984.0",
5+
"@aws-sdk/util-dynamodb": "^3.943.0",
6+
"@internal/datastore": "*",
7+
"aws-embedded-metrics": "^4.2.1",
8+
"aws-lambda": "^1.0.6",
9+
"esbuild": "0.27.2",
10+
"pino": "^10.3.0",
11+
"zod": "^4.1.13"
12+
},
13+
"devDependencies": {
14+
"@tsconfig/node22": "^22.0.2",
15+
"@types/aws-lambda": "^8.10.148",
16+
"@types/jest": "^30.0.0",
17+
"jest": "^30.2.0",
18+
"jest-mock-extended": "^4.0.0",
19+
"ts-jest": "^29.4.0",
20+
"typescript": "^5.8.3"
21+
},
22+
"name": "nhs-notify-supplier-api-update-letter-queue",
23+
"private": true,
24+
"scripts": {
25+
"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",
26+
"lint": "eslint .",
27+
"lint:fix": "eslint . --fix",
28+
"test:unit": "jest",
29+
"typecheck": "tsc --noEmit"
30+
},
31+
"version": "0.0.1"
32+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { z } from "zod";
2+
import { LetterStatus } from "internal/datastore/src";
3+
4+
export const IncomingLetterSchema = z.object({
5+
id: z.string(),
6+
status: LetterStatus,
7+
specificationId: z.string(),
8+
supplierId: z.string(),
9+
groupId: z.string(),
10+
});
11+
12+
export type IncomingLetter = z.infer<typeof IncomingLetterSchema>;

0 commit comments

Comments
 (0)