Skip to content

Commit f48355a

Browse files
authored
CCM-12740: Filter out items where the TTL has been deleted (#98)
1 parent bfe8272 commit f48355a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+5949
-2042
lines changed

.gitleaksignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ cd9c0efec38c5d63053dd865e5d4e207c0760d91:docs/guides/Perform_static_analysis.md:
99
0cbdddbf54927dfc4a226b88d2fed045dfc0cb92:docs/cloudevents/digital-letters/2025-10/example-events/file-deleted-event.md:ipv4:42
1010
0cbdddbf54927dfc4a226b88d2fed045dfc0cb92:docs/cloudevents/digital-letters/2025-10/example-events/file-deleted-event.json:ipv4:21
1111
52386bca9b88c0c8c7dee52ab0ec69d04fb72c46:src/TESTING_PLAN.md:ipv4:145
12+
973c8a1feb76f3cd8743ce27b14e4acc4252240c:src/TESTING_PLAN.md:ipv4:2507
13+
cc74128e4207833109339e96f3aaebf3cd40dd65:src/TESTING_PLAN.md:ipv4:2507
14+
791619daf5af4806da7266fa301c0e82145b6de8:src/TESTING_PLAN.md:ipv4:2507

docs/package-lock.json

Lines changed: 0 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eslint.config.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,10 @@ export default defineConfig([
229229
},
230230
},
231231
{
232-
files: ['utils/**'],
232+
files: ['utils/**', '**/jest.config.ts'],
233233
rules: {
234234
'no-relative-import-paths/no-relative-import-paths': 0,
235+
'import-x/no-relative-packages': 0,
235236
},
236237
},
237238
{

infrastructure/terraform/components/dl/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ No requirements.
3636
| <a name="module_s3bucket_letters"></a> [s3bucket\_letters](#module\_s3bucket\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-s3bucket.zip | n/a |
3737
| <a name="module_sqs_event_publisher_errors"></a> [sqs\_event\_publisher\_errors](#module\_sqs\_event\_publisher\_errors) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
3838
| <a name="module_sqs_ttl"></a> [sqs\_ttl](#module\_sqs\_ttl) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
39+
| <a name="module_sqs_ttl_handle_expiry_errors"></a> [sqs\_ttl\_handle\_expiry\_errors](#module\_sqs\_ttl\_handle\_expiry\_errors) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
3940
| <a name="module_ttl_create"></a> [ttl\_create](#module\_ttl\_create) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
41+
| <a name="module_ttl_handle_expiry"></a> [ttl\_handle\_expiry](#module\_ttl\_handle\_expiry) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
4042
| <a name="module_ttl_poll"></a> [ttl\_poll](#module\_ttl\_poll) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
4143
## Outputs
4244

infrastructure/terraform/components/dl/lambda_event_source_mapping_ttl_create_lambda.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ resource "aws_lambda_event_source_mapping" "ttl_create_lambda" {
33
function_name = module.ttl_create.function_name
44
batch_size = var.queue_batch_size
55
maximum_batching_window_in_seconds = var.queue_batch_window_seconds
6+
67
function_response_types = [
78
"ReportBatchItemFailures"
89
]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
resource "aws_lambda_event_source_mapping" "ttl_handle_expiry_lambda" {
2+
event_source_arn = aws_dynamodb_table.ttl.stream_arn
3+
function_name = module.ttl_handle_expiry.function_arn
4+
starting_position = "TRIM_HORIZON"
5+
batch_size = 50
6+
maximum_batching_window_in_seconds = 10
7+
maximum_retry_attempts = 3
8+
9+
function_response_types = [
10+
"ReportBatchItemFailures"
11+
]
12+
13+
destination_config {
14+
on_failure {
15+
destination_arn = module.sqs_ttl_handle_expiry_errors.sqs_queue_arn
16+
}
17+
}
18+
19+
filter_criteria {
20+
filter {
21+
pattern = jsonencode({
22+
eventName : ["REMOVE"]
23+
})
24+
}
25+
}
26+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
module "ttl_handle_expiry" {
2+
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip"
3+
4+
function_name = "ttl-handle-expiry"
5+
description = "A function for handling deleted TTL records"
6+
7+
aws_account_id = var.aws_account_id
8+
component = local.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.ttl_handle_expiry_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 = "ttl-handle-expiry-lambda/dist"
24+
function_include_common = true
25+
handler_function_name = "handler"
26+
runtime = "nodejs22.x"
27+
memory = 128
28+
timeout = 360
29+
log_level = var.log_level
30+
31+
force_lambda_code_deploy = var.force_lambda_code_deploy
32+
enable_lambda_insights = false
33+
34+
send_to_firehose = true
35+
log_destination_arn = local.log_destination_arn
36+
log_subscription_role_arn = local.acct.log_subscription_role_arn
37+
38+
lambda_env_vars = {
39+
"EVENT_PUBLISHER_EVENT_BUS_ARN" = aws_cloudwatch_event_bus.main.arn
40+
"EVENT_PUBLISHER_DLQ_URL" = module.sqs_event_publisher_errors.sqs_queue_url
41+
"DLQ_URL" = module.sqs_ttl_handle_expiry_errors.sqs_queue_url
42+
}
43+
}
44+
45+
data "aws_iam_policy_document" "ttl_handle_expiry_lambda" {
46+
statement {
47+
sid = "AllowTtlDynamoAccess"
48+
effect = "Allow"
49+
50+
actions = [
51+
"dynamodb:DescribeStream",
52+
"dynamodb:GetRecords",
53+
"dynamodb:GetShardIterator",
54+
"dynamodb:ListStreams",
55+
]
56+
57+
resources = [
58+
aws_dynamodb_table.ttl.stream_arn
59+
]
60+
}
61+
62+
statement {
63+
sid = "KMSPermissions"
64+
effect = "Allow"
65+
66+
actions = [
67+
"kms:Decrypt",
68+
"kms:GenerateDataKey",
69+
]
70+
71+
resources = [
72+
module.kms.key_arn,
73+
]
74+
}
75+
76+
statement {
77+
sid = "PutEvents"
78+
effect = "Allow"
79+
80+
actions = [
81+
"events:PutEvents",
82+
]
83+
84+
resources = [
85+
aws_cloudwatch_event_bus.main.arn,
86+
]
87+
}
88+
89+
statement {
90+
sid = "SQSPermissionsDLQs"
91+
effect = "Allow"
92+
93+
actions = [
94+
"sqs:SendMessage",
95+
"sqs:SendMessageBatch",
96+
]
97+
98+
resources = [
99+
module.sqs_ttl_handle_expiry_errors.sqs_queue_arn,
100+
module.sqs_event_publisher_errors.sqs_queue_arn,
101+
]
102+
}
103+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module "sqs_ttl_handle_expiry_errors" {
2+
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip"
3+
4+
aws_account_id = var.aws_account_id
5+
component = local.component
6+
environment = var.environment
7+
project = var.project
8+
region = var.region
9+
name = "ttl-handle-expiry-errors"
10+
11+
sqs_kms_key_arn = module.kms.key_arn
12+
13+
visibility_timeout_seconds = 60
14+
}

jest.config.base.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import type { Config } from 'jest';
2+
3+
export const baseJestConfig: Config = {
4+
preset: 'ts-jest',
5+
6+
// Automatically clear mock calls, instances, contexts and results before every test
7+
clearMocks: true,
8+
9+
// Indicates whether the coverage information should be collected while executing the test
10+
collectCoverage: true,
11+
12+
// An array of glob patterns indicating a set of files for which coverage information should be collected
13+
collectCoverageFrom: [
14+
'src/**/*.{ts,tsx}',
15+
'!src/**/*.d.ts',
16+
'!src/**/__tests__/**',
17+
'!src/**/*.test.{ts,tsx}',
18+
'!src/**/*.spec.{ts,tsx}',
19+
],
20+
21+
// The directory where Jest should output its coverage files
22+
coverageDirectory: './.reports/unit/coverage',
23+
24+
// Indicates which provider should be used to instrument code for coverage
25+
coverageProvider: 'babel',
26+
27+
coverageThreshold: {
28+
global: {
29+
branches: 100,
30+
functions: 100,
31+
lines: 100,
32+
statements: -10,
33+
},
34+
},
35+
36+
coveragePathIgnorePatterns: ['/__tests__/'],
37+
transform: { '^.+\\.ts$': 'ts-jest' },
38+
testPathIgnorePatterns: ['.build'],
39+
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
40+
41+
// Use this configuration option to add custom reporters to Jest
42+
reporters: [
43+
'default',
44+
[
45+
'jest-html-reporter',
46+
{
47+
pageTitle: 'Test Report',
48+
outputPath: './.reports/unit/test-report.html',
49+
includeFailureMsg: true,
50+
},
51+
],
52+
],
53+
54+
// The test environment that will be used for testing
55+
testEnvironment: 'node',
56+
57+
moduleDirectories: ['node_modules', 'src'],
58+
};

lambdas/mesh-poll/jest.config.ts

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,5 @@
1-
import type { Config } from 'jest';
1+
import { baseJestConfig } from '../../jest.config.base';
22

3-
export const baseJestConfig: Config = {
4-
preset: 'ts-jest',
3+
const config = baseJestConfig;
54

6-
// Automatically clear mock calls, instances, contexts and results before every test
7-
clearMocks: true,
8-
9-
// Indicates whether the coverage information should be collected while executing the test
10-
collectCoverage: true,
11-
12-
// The directory where Jest should output its coverage files
13-
coverageDirectory: './.reports/unit/coverage',
14-
15-
// Indicates which provider should be used to instrument code for coverage
16-
coverageProvider: 'babel',
17-
18-
coverageThreshold: {
19-
global: {
20-
branches: 100,
21-
functions: 100,
22-
lines: 100,
23-
statements: -10,
24-
},
25-
},
26-
27-
coveragePathIgnorePatterns: ['/__tests__/'],
28-
transform: { '^.+\\.ts$': 'ts-jest' },
29-
testPathIgnorePatterns: ['.build'],
30-
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
31-
32-
// Use this configuration option to add custom reporters to Jest
33-
reporters: [
34-
'default',
35-
[
36-
'jest-html-reporter',
37-
{
38-
pageTitle: 'Test Report',
39-
outputPath: './.reports/unit/test-report.html',
40-
includeFailureMsg: true,
41-
},
42-
],
43-
],
44-
45-
// The test environment that will be used for testing
46-
testEnvironment: 'jsdom',
47-
};
48-
49-
const utilsJestConfig = {
50-
...baseJestConfig,
51-
52-
testEnvironment: 'node',
53-
54-
coveragePathIgnorePatterns: [
55-
...(baseJestConfig.coveragePathIgnorePatterns ?? []),
56-
'zod-validators.ts',
57-
],
58-
};
59-
60-
export default utilsJestConfig;
5+
export default config;

0 commit comments

Comments
 (0)