Skip to content

Commit 6c156ab

Browse files
committed
CCM-12842: Update Create TTL lambda to accept Event Bus envelope
1 parent 91dbd4a commit 6c156ab

File tree

3 files changed

+52
-47
lines changed

3 files changed

+52
-47
lines changed

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

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
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

55
describe('createHandler', () => {
66
let createTtl: any;
77
let eventPublisher: any;
88
let logger: any;
99
let handler: any;
1010

11-
const validItem: TtlItemEvent = {
12-
profileversion: '1.0.0',
13-
profilepublished: '2025-10',
14-
id: '550e8400-e29b-41d4-a716-446655440001',
15-
specversion: '1.0',
16-
source: '/nhs/england/notify/production/primary/data-plane/digital-letters',
17-
subject:
18-
'customer/920fca11-596a-4eca-9c47-99f624614658/recipient/769acdd4-6a47-496f-999f-76a6fd2c3959',
19-
type: 'uk.nhs.notify.digital.letters.sent.v1',
20-
time: '2023-06-20T12:00:00Z',
21-
recordedtime: '2023-06-20T12:00:00.250Z',
22-
severitynumber: 2,
23-
traceparent: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',
24-
datacontenttype: 'application/json',
25-
dataschema:
26-
'https://notify.nhs.uk/schemas/events/digital-letters/2025-10/digital-letters.schema.json',
27-
dataschemaversion: '1.0',
28-
severitytext: 'INFO',
29-
data: {
30-
uri: 'https://example.com/ttl/resource',
31-
'digital-letter-id': '123e4567-e89b-12d3-a456-426614174000',
11+
const validItem: TtlItemBusEvent = {
12+
detail: {
13+
profileversion: '1.0.0',
14+
profilepublished: '2025-10',
15+
id: '550e8400-e29b-41d4-a716-446655440001',
16+
specversion: '1.0',
17+
source:
18+
'/nhs/england/notify/production/primary/data-plane/digital-letters',
19+
subject:
20+
'customer/920fca11-596a-4eca-9c47-99f624614658/recipient/769acdd4-6a47-496f-999f-76a6fd2c3959',
21+
type: 'uk.nhs.notify.digital.letters.sent.v1',
22+
time: '2023-06-20T12:00:00Z',
23+
recordedtime: '2023-06-20T12:00:00.250Z',
24+
severitynumber: 2,
25+
traceparent: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',
26+
datacontenttype: 'application/json',
27+
dataschema:
28+
'https://notify.nhs.uk/schemas/events/digital-letters/2025-10/digital-letters.schema.json',
29+
dataschemaversion: '1.0',
30+
severitytext: 'INFO',
31+
data: {
32+
uri: 'https://example.com/ttl/resource',
33+
'digital-letter-id': '123e4567-e89b-12d3-a456-426614174000',
34+
},
3235
},
3336
};
3437

@@ -41,7 +44,7 @@ describe('createHandler', () => {
4144

4245
it('processes a valid SQS event and returns success', async () => {
4346
jest
44-
.spyOn($TtlItemEvent, 'safeParse')
47+
.spyOn($TtlItemBusEvent, 'safeParse')
4548
.mockReturnValue({ success: true, data: validItem });
4649
createTtl.send.mockResolvedValue('sent');
4750
const event: SQSEvent = {
@@ -51,8 +54,8 @@ describe('createHandler', () => {
5154
const res = await handler(event);
5255

5356
expect(res.batchItemFailures).toEqual([]);
54-
expect(createTtl.send).toHaveBeenCalledWith(validItem);
55-
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([validItem]);
57+
expect(createTtl.send).toHaveBeenCalledWith(validItem.detail);
58+
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([validItem.detail]);
5659
expect(logger.info).toHaveBeenCalledWith({
5760
description: 'Processed SQS Event.',
5861
failed: 0,
@@ -64,7 +67,7 @@ describe('createHandler', () => {
6467
it('handles parse failure and logs error', async () => {
6568
const zodError = { errors: [] } as any;
6669
jest
67-
.spyOn($TtlItemEvent, 'safeParse')
70+
.spyOn($TtlItemBusEvent, 'safeParse')
6871
.mockReturnValue({ success: false, error: zodError });
6972
const event: SQSEvent = {
7073
Records: [{ body: '{}', messageId: 'msg2' }],
@@ -88,7 +91,7 @@ describe('createHandler', () => {
8891

8992
it('handles createTtl.send failure', async () => {
9093
jest
91-
.spyOn($TtlItemEvent, 'safeParse')
94+
.spyOn($TtlItemBusEvent, 'safeParse')
9295
.mockReturnValue({ success: true, data: validItem });
9396
createTtl.send.mockResolvedValue('failed');
9497
const event: SQSEvent = {
@@ -107,7 +110,7 @@ describe('createHandler', () => {
107110
});
108111

109112
it('handles thrown error and logs', async () => {
110-
jest.spyOn($TtlItemEvent, 'safeParse').mockImplementation(() => {
113+
jest.spyOn($TtlItemBusEvent, 'safeParse').mockImplementation(() => {
111114
throw new Error('bad json');
112115
});
113116
const event: SQSEvent = {
@@ -159,7 +162,7 @@ describe('createHandler', () => {
159162

160163
it('processes multiple successful events and sends them as a batch', async () => {
161164
jest
162-
.spyOn($TtlItemEvent, 'safeParse')
165+
.spyOn($TtlItemBusEvent, 'safeParse')
163166
.mockReturnValue({ success: true, data: validItem });
164167
createTtl.send.mockResolvedValue('sent');
165168
const event: SQSEvent = {
@@ -175,9 +178,9 @@ describe('createHandler', () => {
175178
expect(res.batchItemFailures).toEqual([]);
176179
expect(createTtl.send).toHaveBeenCalledTimes(3);
177180
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([
178-
validItem,
179-
validItem,
180-
validItem,
181+
validItem.detail,
182+
validItem.detail,
183+
validItem.detail,
181184
]);
182185
expect(logger.info).toHaveBeenCalledWith({
183186
description: 'Processed SQS Event.',
@@ -189,7 +192,7 @@ describe('createHandler', () => {
189192

190193
it('handles partial event publishing failures and logs warning', async () => {
191194
jest
192-
.spyOn($TtlItemEvent, 'safeParse')
195+
.spyOn($TtlItemBusEvent, 'safeParse')
193196
.mockReturnValue({ success: true, data: validItem });
194197
createTtl.send.mockResolvedValue('sent');
195198
const failedEvents = [validItem];
@@ -206,8 +209,8 @@ describe('createHandler', () => {
206209

207210
expect(res.batchItemFailures).toEqual([]);
208211
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([
209-
validItem,
210-
validItem,
212+
validItem.detail,
213+
validItem.detail,
211214
]);
212215
expect(logger.warn).toHaveBeenCalledWith({
213216
description: 'Some events failed to publish',
@@ -218,7 +221,7 @@ describe('createHandler', () => {
218221

219222
it('handles event publishing exception and logs warning', async () => {
220223
jest
221-
.spyOn($TtlItemEvent, 'safeParse')
224+
.spyOn($TtlItemBusEvent, 'safeParse')
222225
.mockReturnValue({ success: true, data: validItem });
223226
createTtl.send.mockResolvedValue('sent');
224227
const publishError = new Error('EventBridge error');
@@ -231,7 +234,7 @@ describe('createHandler', () => {
231234
const res = await handler(event);
232235

233236
expect(res.batchItemFailures).toEqual([]);
234-
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([validItem]);
237+
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([validItem.detail]);
235238
expect(logger.warn).toHaveBeenCalledWith({
236239
err: publishError,
237240
description: 'Failed to send events to EventBridge',
@@ -241,7 +244,7 @@ describe('createHandler', () => {
241244

242245
it('does not call eventPublisher when no successful events', async () => {
243246
jest
244-
.spyOn($TtlItemEvent, 'safeParse')
247+
.spyOn($TtlItemBusEvent, 'safeParse')
245248
.mockReturnValue({ success: true, data: validItem });
246249
createTtl.send.mockResolvedValue('failed');
247250

@@ -263,7 +266,7 @@ describe('createHandler', () => {
263266

264267
it('handles mixed success and failure scenarios', async () => {
265268
jest
266-
.spyOn($TtlItemEvent, 'safeParse')
269+
.spyOn($TtlItemBusEvent, 'safeParse')
267270
.mockReturnValueOnce({ success: true, data: validItem })
268271
.mockReturnValueOnce({ success: false, error: { errors: [] } as any })
269272
.mockReturnValueOnce({ success: true, data: validItem });
@@ -285,7 +288,7 @@ describe('createHandler', () => {
285288
{ itemIdentifier: 'msg2' },
286289
{ itemIdentifier: 'msg3' },
287290
]);
288-
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([validItem]);
291+
expect(eventPublisher.sendEvents).toHaveBeenCalledWith([validItem.detail]);
289292
expect(logger.info).toHaveBeenCalledWith({
290293
description: 'Processed SQS Event.',
291294
failed: 2,

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

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

99
interface ProcessingResult {
1010
result: CreateTtlOutcome;
@@ -33,7 +33,7 @@ export const createHandler = ({
3333
data: item,
3434
error: parseError,
3535
success: parseSuccess,
36-
} = $TtlItemEvent.safeParse(JSON.parse(body));
36+
} = $TtlItemBusEvent.safeParse(JSON.parse(body));
3737

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

47-
const result = await createTtl.send(item);
47+
const result = await createTtl.send(item.detail);
4848

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

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

utils/utils/src/types/ttl-item-event.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ export const $TtlItemEvent = $CloudEvent.extend({
1313
data: $TtlItemData,
1414
});
1515

16+
export const $TtlItemBusEvent = z.object({
17+
detail: $TtlItemEvent,
18+
});
19+
1620
export type TtlItemEvent = z.infer<typeof $TtlItemEvent>;
1721

18-
export type TtlItemBusEvent = {
19-
detail: TtlItemEvent;
20-
};
22+
export type TtlItemBusEvent = z.infer<typeof $TtlItemBusEvent>;
2123

2224
export const validateTtlItemEvent = (data: unknown) => {
2325
return $TtlItemEvent.safeParse(data);

0 commit comments

Comments
 (0)