Skip to content

Commit 29fa28c

Browse files
authored
Merge branch 'main' into feature/CCM-12616_mesh_poll_retrieve
2 parents 19b16de + 05e5233 commit 29fa28c

File tree

40 files changed

+757
-156
lines changed

40 files changed

+757
-156
lines changed

.gitleaksignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ cc74128e4207833109339e96f3aaebf3cd40dd65:src/TESTING_PLAN.md:ipv4:2507
1515
973c8a1feb76f3cd8743ce27b14e4acc4252240c:src/TESTING_PLAN.md:ipv4:2507
1616
cc74128e4207833109339e96f3aaebf3cd40dd65:src/TESTING_PLAN.md:ipv4:2507
1717
791619daf5af4806da7266fa301c0e82145b6de8:src/TESTING_PLAN.md:ipv4:2507
18+
f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generation/validate-private-key.test.ts:private-key:7
19+
f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:23
20+
f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:30
21+
f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:46

README.md

Lines changed: 20 additions & 5 deletions
Large diffs are not rendered by default.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
resource "aws_cloudwatch_event_rule" "mesh_inbox_message_downloaded" {
2+
name = "${local.csi}-mesh-inbox-message-downloaded"
3+
description = "MESH inbox message downloaded event rule"
4+
event_bus_name = aws_cloudwatch_event_bus.main.name
5+
6+
event_pattern = jsonencode({
7+
"detail" : {
8+
"type" : [
9+
"uk.nhs.notify.digital.letters.mesh.inbox.message.downloaded.v1"
10+
],
11+
"dataschemaversion" : [{
12+
"prefix" : "1."
13+
}]
14+
}
15+
})
16+
}
17+
18+
resource "aws_cloudwatch_event_target" "mesh_inbox_message_downloaded" {
19+
rule = aws_cloudwatch_event_rule.mesh_inbox_message_downloaded.name
20+
arn = module.sqs_ttl.sqs_queue_arn
21+
target_id = "mesh-inbox-message-downloaded-target"
22+
event_bus_name = aws_cloudwatch_event_bus.main.name
23+
}

lambdas/ttl-create-lambda/src/__tests__/apis/sqs-trigger-lambda.test.ts

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createHandler } from 'apis/sqs-trigger-lambda';
22
import type { SQSEvent } from 'aws-lambda';
3-
import { $TtlItemEvent, TtlItemEvent } from 'utils';
3+
import { $TtlItemBusEvent, TtlItemBusEvent } from 'utils';
44
import { randomUUID } from 'node:crypto';
55

66
jest.mock('node:crypto', () => ({
@@ -18,29 +18,32 @@ describe('createHandler', () => {
1818
let logger: any;
1919
let handler: any;
2020

21-
const validItem: TtlItemEvent = {
22-
profileversion: '1.0.0',
23-
profilepublished: '2025-10',
24-
id: '999999999-9999-9999-9999-999999999999',
25-
specversion: '1.0',
26-
source: '/nhs/england/notify/production/primary/data-plane/digital-letters',
27-
subject:
28-
'customer/920fca11-596a-4eca-9c47-99f624614658/recipient/769acdd4-6a47-496f-999f-76a6fd2c3959',
29-
type: 'uk.nhs.notify.digital.letters.mesh.inbox.message.downloaded.v1',
30-
time: '2000-01-02T02:00:00Z',
31-
recordedtime: '2000-01-01T01:00:00Z',
32-
severitynumber: 2,
33-
traceparent: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',
34-
datacontenttype: 'application/json',
35-
dataschema:
36-
'https://notify.nhs.uk/cloudevents/schemas/digital-letters/2025-10/digital-letter-base-data.schema.json',
37-
dataschemaversion: '1.0',
38-
severitytext: 'INFO',
39-
data: {
40-
messageUri: 'https://example.com/ttl/resource',
41-
'digital-letter-id': '123e4567-e89b-12d3-a456-426614174000',
42-
messageReference: 'ref1',
43-
senderId: 'sender1',
21+
const validItem: TtlItemBusEvent = {
22+
detail: {
23+
profileversion: '1.0.0',
24+
profilepublished: '2025-10',
25+
id: '550e8400-e29b-41d4-a716-446655440001',
26+
specversion: '1.0',
27+
source:
28+
'/nhs/england/notify/production/primary/data-plane/digital-letters',
29+
subject:
30+
'customer/920fca11-596a-4eca-9c47-99f624614658/recipient/769acdd4-6a47-496f-999f-76a6fd2c3959',
31+
type: 'uk.nhs.notify.digital.letters.sent.v1',
32+
time: '2023-06-20T12:00:00Z',
33+
recordedtime: '2023-06-20T12:00:00.250Z',
34+
severitynumber: 2,
35+
traceparent: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',
36+
datacontenttype: 'application/json',
37+
dataschema:
38+
'https://notify.nhs.uk/cloudevents/schemas/digital-letters/2025-10/digital-letter-base-data.schema.json',
39+
dataschemaversion: '1.0',
40+
severitytext: 'INFO',
41+
data: {
42+
messageUri: 'https://example.com/ttl/resource',
43+
'digital-letter-id': '123e4567-e89b-12d3-a456-426614174000',
44+
messageReference: 'ref1',
45+
senderId: 'sender1',
46+
},
4447
},
4548
};
4649

@@ -53,7 +56,7 @@ describe('createHandler', () => {
5356

5457
it('processes a valid SQS event and returns success', async () => {
5558
jest
56-
.spyOn($TtlItemEvent, 'safeParse')
59+
.spyOn($TtlItemBusEvent, 'safeParse')
5760
.mockReturnValue({ success: true, data: validItem });
5861
createTtl.send.mockResolvedValue('sent');
5962
const event: SQSEvent = {
@@ -63,10 +66,10 @@ describe('createHandler', () => {
6366
const res = await handler(event);
6467

6568
expect(res.batchItemFailures).toEqual([]);
66-
expect(createTtl.send).toHaveBeenCalledWith(validItem);
69+
expect(createTtl.send).toHaveBeenCalledWith(validItem.detail);
6770
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([
6871
{
69-
...validItem,
72+
...validItem.detail,
7073
id: '550e8400-e29b-41d4-a716-446655440001',
7174
time: '2023-06-20T12:00:00.250Z',
7275
recordedtime: '2023-06-20T12:00:00.250Z',
@@ -84,7 +87,7 @@ describe('createHandler', () => {
8487
it('handles parse failure and logs error', async () => {
8588
const zodError = { errors: [] } as any;
8689
jest
87-
.spyOn($TtlItemEvent, 'safeParse')
90+
.spyOn($TtlItemBusEvent, 'safeParse')
8891
.mockReturnValue({ success: false, error: zodError });
8992
const event: SQSEvent = {
9093
Records: [{ body: '{}', messageId: 'msg2' }],
@@ -108,7 +111,7 @@ describe('createHandler', () => {
108111

109112
it('handles createTtl.send failure', async () => {
110113
jest
111-
.spyOn($TtlItemEvent, 'safeParse')
114+
.spyOn($TtlItemBusEvent, 'safeParse')
112115
.mockReturnValue({ success: true, data: validItem });
113116
createTtl.send.mockResolvedValue('failed');
114117
const event: SQSEvent = {
@@ -127,7 +130,7 @@ describe('createHandler', () => {
127130
});
128131

129132
it('handles thrown error and logs', async () => {
130-
jest.spyOn($TtlItemEvent, 'safeParse').mockImplementation(() => {
133+
jest.spyOn($TtlItemBusEvent, 'safeParse').mockImplementation(() => {
131134
throw new Error('bad json');
132135
});
133136
const event: SQSEvent = {
@@ -179,7 +182,7 @@ describe('createHandler', () => {
179182

180183
it('processes multiple successful events and sends them as a batch', async () => {
181184
jest
182-
.spyOn($TtlItemEvent, 'safeParse')
185+
.spyOn($TtlItemBusEvent, 'safeParse')
183186
.mockReturnValue({ success: true, data: validItem });
184187
createTtl.send.mockResolvedValue('sent');
185188
const sqsEvent: SQSEvent = {
@@ -196,21 +199,21 @@ describe('createHandler', () => {
196199
expect(createTtl.send).toHaveBeenCalledTimes(3);
197200
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([
198201
{
199-
...validItem,
202+
...validItem.detail,
200203
id: '550e8400-e29b-41d4-a716-446655440001',
201204
time: '2023-06-20T12:00:00.250Z',
202205
recordedtime: '2023-06-20T12:00:00.250Z',
203206
type: 'uk.nhs.notify.digital.letters.queue.item.enqueued.v1',
204207
},
205208
{
206-
...validItem,
209+
...validItem.detail,
207210
id: '550e8400-e29b-41d4-a716-446655440001',
208211
time: '2023-06-20T12:00:00.250Z',
209212
recordedtime: '2023-06-20T12:00:00.250Z',
210213
type: 'uk.nhs.notify.digital.letters.queue.item.enqueued.v1',
211214
},
212215
{
213-
...validItem,
216+
...validItem.detail,
214217
id: '550e8400-e29b-41d4-a716-446655440001',
215218
time: '2023-06-20T12:00:00.250Z',
216219
recordedtime: '2023-06-20T12:00:00.250Z',
@@ -227,7 +230,7 @@ describe('createHandler', () => {
227230

228231
it('handles partial event publishing failures and logs warning', async () => {
229232
jest
230-
.spyOn($TtlItemEvent, 'safeParse')
233+
.spyOn($TtlItemBusEvent, 'safeParse')
231234
.mockReturnValue({ success: true, data: validItem });
232235
createTtl.send.mockResolvedValue('sent');
233236
const failedEvents = [validItem];
@@ -245,14 +248,14 @@ describe('createHandler', () => {
245248
expect(res.batchItemFailures).toEqual([]);
246249
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([
247250
{
248-
...validItem,
251+
...validItem.detail,
249252
id: '550e8400-e29b-41d4-a716-446655440001',
250253
time: '2023-06-20T12:00:00.250Z',
251254
recordedtime: '2023-06-20T12:00:00.250Z',
252255
type: 'uk.nhs.notify.digital.letters.queue.item.enqueued.v1',
253256
},
254257
{
255-
...validItem,
258+
...validItem.detail,
256259
id: '550e8400-e29b-41d4-a716-446655440001',
257260
time: '2023-06-20T12:00:00.250Z',
258261
recordedtime: '2023-06-20T12:00:00.250Z',
@@ -268,7 +271,7 @@ describe('createHandler', () => {
268271

269272
it('handles event publishing exception and logs warning', async () => {
270273
jest
271-
.spyOn($TtlItemEvent, 'safeParse')
274+
.spyOn($TtlItemBusEvent, 'safeParse')
272275
.mockReturnValue({ success: true, data: validItem });
273276
createTtl.send.mockResolvedValue('sent');
274277
const publishError = new Error('EventBridge error');
@@ -283,7 +286,7 @@ describe('createHandler', () => {
283286
expect(res.batchItemFailures).toEqual([]);
284287
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([
285288
{
286-
...validItem,
289+
...validItem.detail,
287290
id: '550e8400-e29b-41d4-a716-446655440001',
288291
time: '2023-06-20T12:00:00.250Z',
289292
recordedtime: '2023-06-20T12:00:00.250Z',
@@ -299,7 +302,7 @@ describe('createHandler', () => {
299302

300303
it('does not call eventPublisher when no successful events', async () => {
301304
jest
302-
.spyOn($TtlItemEvent, 'safeParse')
305+
.spyOn($TtlItemBusEvent, 'safeParse')
303306
.mockReturnValue({ success: true, data: validItem });
304307
createTtl.send.mockResolvedValue('failed');
305308

@@ -321,7 +324,7 @@ describe('createHandler', () => {
321324

322325
it('handles mixed success and failure scenarios', async () => {
323326
jest
324-
.spyOn($TtlItemEvent, 'safeParse')
327+
.spyOn($TtlItemBusEvent, 'safeParse')
325328
.mockReturnValueOnce({ success: true, data: validItem })
326329
.mockReturnValueOnce({ success: false, error: { errors: [] } as any })
327330
.mockReturnValueOnce({ success: true, data: validItem });
@@ -345,7 +348,7 @@ describe('createHandler', () => {
345348
]);
346349
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([
347350
{
348-
...validItem,
351+
...validItem.detail,
349352
id: '550e8400-e29b-41d4-a716-446655440001',
350353
time: '2023-06-20T12:00:00.250Z',
351354
recordedtime: '2023-06-20T12:00:00.250Z',

lambdas/ttl-create-lambda/src/apis/sqs-trigger-lambda.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type {
55
} from 'aws-lambda';
66
import { randomUUID } from 'node:crypto';
77
import type { CreateTtl, CreateTtlOutcome } from 'app/create-ttl';
8-
import { $TtlItemEvent, EventPublisher, Logger, TtlItemEvent } from 'utils';
8+
import { $TtlItemBusEvent, EventPublisher, Logger, TtlItemEvent } from 'utils';
99

1010
interface ProcessingResult {
1111
result: CreateTtlOutcome;
@@ -34,7 +34,7 @@ export const createHandler = ({
3434
data: item,
3535
error: parseError,
3636
success: parseSuccess,
37-
} = $TtlItemEvent.safeParse(JSON.parse(body));
37+
} = $TtlItemBusEvent.safeParse(JSON.parse(body));
3838

3939
if (!parseSuccess) {
4040
logger.error({
@@ -45,14 +45,14 @@ export const createHandler = ({
4545
return { result: 'failed' };
4646
}
4747

48-
const result = await createTtl.send(item);
48+
const result = await createTtl.send(item.detail);
4949

5050
if (result === 'failed') {
5151
batchItemFailures.push({ itemIdentifier: messageId });
5252
return { result: 'failed' };
5353
}
5454

55-
return { result, item };
55+
return { result, item: item.detail };
5656
} catch (error) {
5757
logger.error({
5858
err: error,

0 commit comments

Comments
 (0)