From aac35edf936280575bda81964e3cfaec405918c7 Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Fri, 20 Mar 2026 15:14:40 +0000 Subject: [PATCH 01/10] CCM-14616: fix typo in the letter variant sent to Supplier API --- .../print-sender-lambda/src/__tests__/app/print-sender.test.ts | 2 +- lambdas/print-sender-lambda/src/app/print-sender.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lambdas/print-sender-lambda/src/__tests__/app/print-sender.test.ts b/lambdas/print-sender-lambda/src/__tests__/app/print-sender.test.ts index 639298964..8f9e71d81 100644 --- a/lambdas/print-sender-lambda/src/__tests__/app/print-sender.test.ts +++ b/lambdas/print-sender-lambda/src/__tests__/app/print-sender.test.ts @@ -74,7 +74,7 @@ describe('PrintSender', () => { url: mockPDFAnalysed.data.letterUri, clientId: mockPDFAnalysed.data.senderId, campaignId: 'digitalLetters', - letterVariantId: 'notify-digital-letter-standard', + letterVariantId: 'notify-digital-letters-standard', }), }), ]), diff --git a/lambdas/print-sender-lambda/src/app/print-sender.ts b/lambdas/print-sender-lambda/src/app/print-sender.ts index 5772d5cdf..188f538d0 100644 --- a/lambdas/print-sender-lambda/src/app/print-sender.ts +++ b/lambdas/print-sender-lambda/src/app/print-sender.ts @@ -47,7 +47,7 @@ export class PrintSender { url: item.data.letterUri, clientId: item.data.senderId, campaignId: 'digitalLetters', - letterVariantId: 'notify-digital-letter-standard', + letterVariantId: 'notify-digital-letters-standard', }, }; From 8f5dda859edd1065901398e38be1aede1c1229d9 Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Fri, 27 Mar 2026 10:56:38 +0000 Subject: [PATCH 02/10] CCM-14616: Supplier API upgrade --- lambdas/print-status-handler/package.json | 2 +- package-lock.json | 10 +++++----- tests/playwright/package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lambdas/print-status-handler/package.json b/lambdas/print-status-handler/package.json index fbdf48ec4..1ceb8833d 100644 --- a/lambdas/print-status-handler/package.json +++ b/lambdas/print-status-handler/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.11", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", "digital-letters-events": "^0.0.1", "utils": "^0.0.1", "zod": "^4.1.12" diff --git a/package-lock.json b/package-lock.json index adf6ab2d3..c9793a6a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2737,7 +2737,7 @@ "name": "nhs-notify-digital-letters-print-status-handler", "version": "0.0.1", "dependencies": { - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.11", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", "digital-letters-events": "^0.0.1", "utils": "^0.0.1", "zod": "^4.1.12" @@ -9391,9 +9391,9 @@ } }, "node_modules/@nhsdigital/nhs-notify-event-schemas-supplier-api": { - "version": "1.0.11", - "resolved": "https://npm.pkg.github.com/download/@nhsdigital/nhs-notify-event-schemas-supplier-api/1.0.11/0893c5f6aecfcb8d1562188d30c718acd7dc5637", - "integrity": "sha512-1sFPv1f6O5uRvsVxkwd0IVjDsn6l4YqLMCbHduAwnzhObTacQQEI5eB1LGFBQwhvI4q6P1k6FZI0KdDavDd6Iw==", + "version": "1.0.17", + "resolved": "https://npm.pkg.github.com/download/@nhsdigital/nhs-notify-event-schemas-supplier-api/1.0.17/05b451c993a18b89f4a91922a7affc1d23c1e2a8", + "integrity": "sha512-QDWOasKri3iky7StzWdrkV0YIQMnPJNlG4tQZoCOG8BTtAuMte/Xh5vZpQFm1DHQJxUVWMYrAL6n9ZSrKNxVkQ==", "license": "MIT", "dependencies": { "@asyncapi/bundler": "^0.6.4", @@ -22756,7 +22756,7 @@ "@aws-sdk/lib-dynamodb": "^3.900.0", "@aws-sdk/util-dynamodb": "^3.933.0", "@faker-js/faker": "^9.6.0", - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.11", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", "@playwright/test": "^1.51.1", "csv-parse": "^6.1.0", "digital-letters-events": "^0.0.1", diff --git a/tests/playwright/package.json b/tests/playwright/package.json index f9cd899a9..8be7af124 100644 --- a/tests/playwright/package.json +++ b/tests/playwright/package.json @@ -10,7 +10,7 @@ "@aws-sdk/lib-dynamodb": "^3.900.0", "@aws-sdk/util-dynamodb": "^3.933.0", "@faker-js/faker": "^9.6.0", - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.11", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", "@playwright/test": "^1.51.1", "csv-parse": "^6.1.0", "digital-letters-events": "^0.0.1", From 3a049b446b04d432e78af7af33e9cb814a213635 Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Mon, 30 Mar 2026 11:09:42 +0100 Subject: [PATCH 03/10] CCM-14616: changed validation for the incoming subject from Supplier API --- .../src/__tests__/apis/sqs-handler.test.ts | 40 +++++++++- .../src/__tests__/test-data.ts | 79 ++++++++++++++----- .../src/apis/sqs-handler.ts | 11 ++- .../print-status-handler.component.spec.ts | 19 ++--- 4 files changed, 117 insertions(+), 32 deletions(-) diff --git a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts index bb6df0531..c384cebd1 100644 --- a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts +++ b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts @@ -5,6 +5,7 @@ import { EventPublisher, Logger } from 'utils'; import { acceptedLetterEvent, failedLetterEvent, + pendingLetterEvent, recordEvent, } from '__tests__/test-data'; @@ -32,6 +33,43 @@ describe('SQS Handler', () => { describe('letter status transitions', () => { it('should send print.letter.transitioned event when letter.ACCEPTED received', async () => { + const response = await handler(recordEvent([pendingLetterEvent])); + + expect(eventPublisher.sendEvents).toHaveBeenCalledWith( + [ + { + ...pendingLetterEvent, + id: '550e8400-e29b-41d4-a716-446655440001', + time: '2023-06-20T12:00:00.250Z', + recordedtime: '2023-06-20T12:00:00.250Z', + dataschema: + 'https://notify.nhs.uk/cloudevents/schemas/digital-letters/2025-10-draft/data/digital-letters-print-letter-transitioned-data.schema.json', + type: 'uk.nhs.notify.digital.letters.print.letter.transitioned.v1', + source: + '/nhs/england/notify/production/primary/data-plane/digitalletters/print', + data: { + senderId: pendingLetterEvent.data.origin.subject.split('/')[1], + messageReference: + pendingLetterEvent.data.origin.subject.split('/')[3], + specificationId: pendingLetterEvent.data.specificationId, + status: pendingLetterEvent.data.status, + supplierId: pendingLetterEvent.data.supplierId, + time: pendingLetterEvent.time, + }, + }, + ], + expect.any(Function), + ); + expect(logger.info).toHaveBeenCalledWith( + 'Received SQS Event of 1 record(s)', + ); + expect(logger.info).toHaveBeenCalledWith( + '1 of 1 records processed successfully', + ); + expect(response).toEqual({ batchItemFailures: [] }); + }); + + it('should send print.letter.transitioned event when letter.PENDING received', async () => { const response = await handler(recordEvent([acceptedLetterEvent])); expect(eventPublisher.sendEvents).toHaveBeenCalledWith( @@ -220,7 +258,7 @@ describe('SQS Handler', () => { issues: expect.arrayContaining([ expect.objectContaining({ message: - 'Subject must be in format: client/{senderId}/digital-letters/{messageReference}', + 'Subject must be in format: client/{senderId}/letter-request/{messageReference}', }), ]), }), diff --git a/lambdas/print-status-handler/src/__tests__/test-data.ts b/lambdas/print-status-handler/src/__tests__/test-data.ts index abfff8e42..e1c518e4a 100644 --- a/lambdas/print-status-handler/src/__tests__/test-data.ts +++ b/lambdas/print-status-handler/src/__tests__/test-data.ts @@ -6,11 +6,11 @@ export const acceptedLetterEvent = { specversion: '1.0', source: '/data-plane/supplier-api/prod/update-status', subject: - 'letter-origin/digital-letters/letter/f47ac10b-58cc-4372-a567-0e02b2c3d479', + 'letter-origin/digital-letters/letter/f47ac10b-58cc-4372-a567-0e02b2c3d479_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', type: 'uk.nhs.notify.supplier-api.letter.ACCEPTED.v1', dataschema: - 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.0.schema.json', - dataschemaversion: '1.0.0', + 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.16.schema.json', + dataschemaversion: '1.0.16', time: '2023-06-20T12:00:00Z', recordedtime: '2023-06-20T12:00:00.250Z', severitynumber: 2, @@ -19,32 +19,70 @@ export const acceptedLetterEvent = { severitytext: 'INFO', plane: 'data', data: { - domainId: 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + domainId: + 'f47ac10b-58cc-4372-a567-0e02b2c3d479_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', groupId: 'client_template', + specificationId: '1y3q9v1zzzz', + supplierId: 'supplier-1', + status: 'ACCEPTED', + billingRef: '1y3q9v1zzzz', origin: { domain: 'letter-rendering', event: 'f47ac10b-58cc-4372-a567-0e02b2c3d479', source: '/data-plane/letter-rendering/prod/render-pdf', subject: - 'client/00f3b388-bbe9-41c9-9e76-052d37ee8988/digital-letters/b9c0c7f8-8204-400d-8348-7e7ddf775dae', + 'client/f47ac10b-58cc-4372-a567-0e02b2c3d479/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', }, - specificationId: '1y3q9v1zzzz', - supplierId: 'supplier-1', - status: 'ACCEPTED', - billingRef: '1y3q9v1zzzz', }, } as LetterEvent; +export const pendingLetterEvent = { + specversion: '1.0', + id: '281d1b5f-a6d2-42c1-9ec4-d1fc26ad2a6f', + type: 'uk.nhs.notify.supplier-api.letter.PENDING.v1', + plane: 'data', + dataschema: + 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.PENDING.1.0.16.schema.json', + dataschemaversion: '1.0.16', + source: + '/data-plane/supplier-api/nhs-supplier-api-nonprod/main/update-status', + subject: + 'letter-origin/letter-rendering/letter/32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', + data: { + domainId: + '32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', + status: 'PENDING', + specificationId: 'notify-c5', + billingRef: 'notify-c5', + specificationBillingId: 'default', + supplierId: 'synertec', + groupId: '32124dde-4b36-4a49-8686-e9da9cbff725digitalLettersundefined', + origin: { + domain: 'letter-rendering', + source: '/data-plane/digital-letters/nonprod/main', + subject: + 'client/32124dde-4b36-4a49-8686-e9da9cbff725/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', + event: '281d1b5f-a6d2-42c1-9ec4-d1fc26ad2a6f', + }, + }, + time: '2026-03-27T16:59:16.515Z', + datacontenttype: 'application/json', + traceparent: '00-15c1d7050c2dbeb7f762bff8874c9a5b-a7043d96b780e5ef-01', + recordedtime: '2026-03-27T16:59:16.515Z', + severitynumber: 2, + severitytext: 'INFO', +} as LetterEvent; + export const failedLetterEvent = { id: '550e8400-e29b-41d4-a716-446655440002', specversion: '1.0', source: '/data-plane/supplier-api/prod/update-status', subject: - 'letter-origin/digital-letters/letter/f47ac10b-58cc-4372-a567-0e02b2c3d480', + 'letter-origin/digital-letters/letter/f47ac10b-58cc-4372-a567-0e02b2c3d480_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', type: 'uk.nhs.notify.supplier-api.letter.FAILED.v1', dataschema: - 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.FAILED.1.0.0.schema.json', - dataschemaversion: '1.0.0', + 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.FAILED.1.0.16.schema.json', + dataschemaversion: '1.0.16', time: '2023-06-20T13:00:00Z', recordedtime: '2023-06-20T13:00:00.250Z', severitynumber: 3, @@ -53,21 +91,22 @@ export const failedLetterEvent = { severitytext: 'WARN', plane: 'data', data: { - domainId: 'f47ac10b-58cc-4372-a567-0e02b2c3d480', + domainId: + 'f47ac10b-58cc-4372-a567-0e02b2c3d480_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', groupId: 'client_template', - origin: { - domain: 'letter-rendering', - event: 'f47ac10b-58cc-4372-a567-0e02b2c3d480', - source: '/data-plane/letter-rendering/prod/render-pdf', - subject: - 'client/00f3b388-bbe9-41c9-9e76-052d37ee8988/digital-letters/c8d1d8g9-9305-511e-9459-8f8eeg886ebf', - }, specificationId: '1y3q9v1zzzz', supplierId: 'supplier-1', status: 'FAILED', billingRef: '1y3q9v1zzzz', reasonCode: 'FAILURE001', reasonText: 'Letter has too many pages', + origin: { + domain: 'letter-rendering', + event: 'f47ac10b-58cc-4372-a567-0e02b2c3d480', + source: '/data-plane/letter-rendering/prod/render-pdf', + subject: + 'client/f47ac10b-58cc-4372-a567-0e02b2c3d480/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', + }, }, } as LetterEvent; diff --git a/lambdas/print-status-handler/src/apis/sqs-handler.ts b/lambdas/print-status-handler/src/apis/sqs-handler.ts index d75d7a678..76746cbf7 100644 --- a/lambdas/print-status-handler/src/apis/sqs-handler.ts +++ b/lambdas/print-status-handler/src/apis/sqs-handler.ts @@ -28,8 +28,8 @@ type ValidatedRecord = { const originSubjectSchema = z .string() .regex( - /^client\/[^/]+\/digital-letters\/[^/]+$/, - 'Subject must be in format: client/{senderId}/digital-letters/{messageReference}', + /^client\/[^/]+\/letter-request\/[^/]+$/, + 'Subject must be in format: client/{senderId}/letter-request/{messageReference}', ); function validateRecord( @@ -68,6 +68,10 @@ function validateRecord( return null; } + logger.info( + `Successfully validated SQS record with messageId: ${messageId}, subject: ${item.data.origin.subject}`, + ); + return { messageId, event: item }; } catch (error) { logger.warn({ @@ -147,6 +151,9 @@ export const createHandler = ({ try { const { event } = validatedRecord; validEvents.push(generateUpdatedEvent(event)); + logger.info( + `Generated event for incoming event with domainID: ${event.data.domainId}, subject: ${event.subject}`, + ); } catch (error: any) { logger.warn({ err: error.message, diff --git a/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts b/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts index 27ca4c444..c89a03e17 100644 --- a/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts +++ b/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts @@ -16,8 +16,8 @@ const baseLetterEvent = { specversion: '1.0', source: '/data-plane/supplier-api/prod/update-status', subject: - 'letter-origin/digital-letters/letter/f47ac10b-58cc-4372-a567-0e02b2c3d479', - dataschemaversion: '1.0.0', + 'letter-origin/letter-rendering/letter/32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', + dataschemaversion: '1.0.16', time: '2023-06-20T12:00:00Z', recordedtime: '2023-06-20T12:00:00.250Z', severitynumber: 2, @@ -26,16 +26,17 @@ const baseLetterEvent = { severitytext: 'INFO', plane: 'data', data: { - domainId: 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + domainId: + '32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', groupId: 'client_template', + specificationId: '1y3q9v1zzzz', + supplierId: 'supplier-1', + billingRef: '1y3q9v1zzzz', origin: { domain: 'letter-rendering', event: 'f47ac10b-58cc-4372-a567-0e02b2c3d479', source: '/data-plane/letter-rendering/prod/render-pdf', }, - specificationId: '1y3q9v1zzzz', - supplierId: 'supplier-1', - billingRef: '1y3q9v1zzzz', }, } as LetterEvent; @@ -65,13 +66,13 @@ test.describe('Print status handler', () => { const letterEvent = { ...baseLetterEvent, type: `uk.nhs.notify.supplier-api.letter.${status}.v1`, - dataschema: `https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.${status}.1.0.0.schema.json`, + dataschema: `https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.${status}.1.0.16.schema.json`, data: { ...baseLetterEvent.data, status, origin: { ...baseLetterEvent.data.origin, - subject: `client/00f3b388-bbe9-41c9-9e76-052d37ee8988/digital-letters/${messageReference}`, + subject: `client/00f3b388-bbe9-41c9-9e76-052d37ee8988/letter-request/${messageReference}`, }, }, }; @@ -110,7 +111,7 @@ test.describe('Print status handler', () => { ...baseLetterEvent.data, origin: { ...baseLetterEvent.data.origin, - subject: `client/00f3b388-bbe9-41c9-9e76-052d37ee8988/digital-letters/${messageReference}`, + subject: `client/00f3b388-bbe9-41c9-9e76-052d37ee8988/letter-request/${messageReference}`, }, }, }, From e0e31cc3fda4b8c4db6e67498096bf78f56de243 Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Mon, 30 Mar 2026 15:17:58 +0100 Subject: [PATCH 04/10] CCM-14616: Log adding incoming event to published event --- lambdas/print-status-handler/src/apis/sqs-handler.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lambdas/print-status-handler/src/apis/sqs-handler.ts b/lambdas/print-status-handler/src/apis/sqs-handler.ts index 76746cbf7..c5703463d 100644 --- a/lambdas/print-status-handler/src/apis/sqs-handler.ts +++ b/lambdas/print-status-handler/src/apis/sqs-handler.ts @@ -150,10 +150,12 @@ export const createHandler = ({ validatedRecords.map(async (validatedRecord: ValidatedRecord) => { try { const { event } = validatedRecord; - validEvents.push(generateUpdatedEvent(event)); + const generatedEvent = generateUpdatedEvent(event); + validEvents.push(generatedEvent); logger.info( `Generated event for incoming event with domainID: ${event.data.domainId}, subject: ${event.subject}`, ); + logger.info(`From SupplierAPI: ${JSON.stringify(event)} To PrintLetterTransitioned: ${JSON.stringify(generatedEvent)}`); } catch (error: any) { logger.warn({ err: error.message, From da1e637082428281ae0858bd2051bfd506eb09fb Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Tue, 31 Mar 2026 09:45:27 +0100 Subject: [PATCH 05/10] CCM-14616: Status handler subject change --- .../src/__tests__/apis/sqs-handler.test.ts | 24 +++++++++++++++++++ .../src/apis/sqs-handler.ts | 5 +++- .../print-status-handler.component.spec.ts | 6 ++--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts index c384cebd1..2dc9a4922 100644 --- a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts +++ b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts @@ -9,6 +9,8 @@ import { recordEvent, } from '__tests__/test-data'; +import { $LetterEvent } from '@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events'; + const logger = mock(); const eventPublisher = mock(); @@ -47,6 +49,8 @@ describe('SQS Handler', () => { type: 'uk.nhs.notify.digital.letters.print.letter.transitioned.v1', source: '/nhs/england/notify/production/primary/data-plane/digitalletters/print', + subject: + 'client/32124dde-4b36-4a49-8686-e9da9cbff725/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', data: { senderId: pendingLetterEvent.data.origin.subject.split('/')[1], messageReference: @@ -69,6 +73,22 @@ describe('SQS Handler', () => { expect(response).toEqual({ batchItemFailures: [] }); }); + it('should throw an error', async () => { + const { + data: item, + error: parseError, + success: parseSuccess, + } = $LetterEvent.safeParse(pendingLetterEvent); + + expect(parseSuccess).toBe(true); + expect(parseError).toBeUndefined(); + expect(item).toBeDefined(); + + expect(item?.subject).toBe( + 'letter-origin/letter-rendering/letter/32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', + ); + }); + it('should send print.letter.transitioned event when letter.PENDING received', async () => { const response = await handler(recordEvent([acceptedLetterEvent])); @@ -84,6 +104,8 @@ describe('SQS Handler', () => { type: 'uk.nhs.notify.digital.letters.print.letter.transitioned.v1', source: '/nhs/england/notify/production/primary/data-plane/digitalletters/print', + subject: + 'client/f47ac10b-58cc-4372-a567-0e02b2c3d479/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', data: { senderId: acceptedLetterEvent.data.origin.subject.split('/')[1], messageReference: @@ -121,6 +143,8 @@ describe('SQS Handler', () => { type: 'uk.nhs.notify.digital.letters.print.letter.transitioned.v1', source: '/nhs/england/notify/production/primary/data-plane/digitalletters/print', + subject: + 'client/f47ac10b-58cc-4372-a567-0e02b2c3d480/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', data: { senderId: failedLetterEvent.data.origin.subject.split('/')[1], messageReference: diff --git a/lambdas/print-status-handler/src/apis/sqs-handler.ts b/lambdas/print-status-handler/src/apis/sqs-handler.ts index c5703463d..446fa7d11 100644 --- a/lambdas/print-status-handler/src/apis/sqs-handler.ts +++ b/lambdas/print-status-handler/src/apis/sqs-handler.ts @@ -106,6 +106,7 @@ function generateUpdatedEvent(event: LetterEvent): PrintLetterTransitioned { id: randomUUID(), time: eventTime, recordedtime: eventTime, + subject: `client/${senderId}/letter-request/${messageReference}`, dataschema: 'https://notify.nhs.uk/cloudevents/schemas/digital-letters/2025-10-draft/data/digital-letters-print-letter-transitioned-data.schema.json', type: 'uk.nhs.notify.digital.letters.print.letter.transitioned.v1', @@ -155,7 +156,9 @@ export const createHandler = ({ logger.info( `Generated event for incoming event with domainID: ${event.data.domainId}, subject: ${event.subject}`, ); - logger.info(`From SupplierAPI: ${JSON.stringify(event)} To PrintLetterTransitioned: ${JSON.stringify(generatedEvent)}`); + logger.info( + `From SupplierAPI: ${JSON.stringify(event)} To PrintLetterTransitioned: ${JSON.stringify(generatedEvent)}`, + ); } catch (error: any) { logger.warn({ err: error.message, diff --git a/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts b/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts index c89a03e17..e79794be8 100644 --- a/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts +++ b/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts @@ -15,8 +15,6 @@ const baseLetterEvent = { id: '550e8400-e29b-41d4-a716-446655440001', specversion: '1.0', source: '/data-plane/supplier-api/prod/update-status', - subject: - 'letter-origin/letter-rendering/letter/32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', dataschemaversion: '1.0.16', time: '2023-06-20T12:00:00Z', recordedtime: '2023-06-20T12:00:00.250Z', @@ -27,7 +25,7 @@ const baseLetterEvent = { plane: 'data', data: { domainId: - '32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', + '00f3b388-bbe9-41c9-9e76-052d37ee8988_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', groupId: 'client_template', specificationId: '1y3q9v1zzzz', supplierId: 'supplier-1', @@ -65,6 +63,7 @@ test.describe('Print status handler', () => { const messageReference = uuidv4(); const letterEvent = { ...baseLetterEvent, + subject: `letter-origin/letter-rendering/letter/00f3b388-bbe9-41c9-9e76-052d37ee8988_${messageReference}`, type: `uk.nhs.notify.supplier-api.letter.${status}.v1`, dataschema: `https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.${status}.1.0.16.schema.json`, data: { @@ -105,6 +104,7 @@ test.describe('Print status handler', () => { [ { ...baseLetterEvent, + subject: `letter-origin/letter-rendering/letter/00f3b388-bbe9-41c9-9e76-052d37ee8988_${messageReference}`, type: `uk.nhs.notify.supplier-api.letter.ACCEPTED.v1`, dataschema: `https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.0.schema.json`, data: { From 2ddd35180bb464a0fe95b532b37904ea4200b48c Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Tue, 31 Mar 2026 11:29:00 +0100 Subject: [PATCH 06/10] CCM-14616: removed verbose logging --- lambdas/print-status-handler/src/apis/sqs-handler.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lambdas/print-status-handler/src/apis/sqs-handler.ts b/lambdas/print-status-handler/src/apis/sqs-handler.ts index 446fa7d11..73bebb9bb 100644 --- a/lambdas/print-status-handler/src/apis/sqs-handler.ts +++ b/lambdas/print-status-handler/src/apis/sqs-handler.ts @@ -151,14 +151,7 @@ export const createHandler = ({ validatedRecords.map(async (validatedRecord: ValidatedRecord) => { try { const { event } = validatedRecord; - const generatedEvent = generateUpdatedEvent(event); - validEvents.push(generatedEvent); - logger.info( - `Generated event for incoming event with domainID: ${event.data.domainId}, subject: ${event.subject}`, - ); - logger.info( - `From SupplierAPI: ${JSON.stringify(event)} To PrintLetterTransitioned: ${JSON.stringify(generatedEvent)}`, - ); + validEvents.push(generateUpdatedEvent(event)); } catch (error: any) { logger.warn({ err: error.message, From 7b1e34d25b50f23175acb3aab54cd3f36c2c1b21 Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Tue, 31 Mar 2026 12:25:48 +0100 Subject: [PATCH 07/10] CCM-14616: fix to specific version with Supplier API dependency --- lambdas/print-status-handler/package.json | 2 +- package-lock.json | 4 ++-- tests/playwright/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lambdas/print-status-handler/package.json b/lambdas/print-status-handler/package.json index 1ceb8833d..5db2c2d8c 100644 --- a/lambdas/print-status-handler/package.json +++ b/lambdas/print-status-handler/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.17", "digital-letters-events": "^0.0.1", "utils": "^0.0.1", "zod": "^4.1.12" diff --git a/package-lock.json b/package-lock.json index c9793a6a3..fc0276ee9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2737,7 +2737,7 @@ "name": "nhs-notify-digital-letters-print-status-handler", "version": "0.0.1", "dependencies": { - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.17", "digital-letters-events": "^0.0.1", "utils": "^0.0.1", "zod": "^4.1.12" @@ -22756,7 +22756,7 @@ "@aws-sdk/lib-dynamodb": "^3.900.0", "@aws-sdk/util-dynamodb": "^3.933.0", "@faker-js/faker": "^9.6.0", - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.17", "@playwright/test": "^1.51.1", "csv-parse": "^6.1.0", "digital-letters-events": "^0.0.1", diff --git a/tests/playwright/package.json b/tests/playwright/package.json index 8be7af124..7ebede52e 100644 --- a/tests/playwright/package.json +++ b/tests/playwright/package.json @@ -10,7 +10,7 @@ "@aws-sdk/lib-dynamodb": "^3.900.0", "@aws-sdk/util-dynamodb": "^3.933.0", "@faker-js/faker": "^9.6.0", - "@nhsdigital/nhs-notify-event-schemas-supplier-api": "^1.0.17", + "@nhsdigital/nhs-notify-event-schemas-supplier-api": "1.0.17", "@playwright/test": "^1.51.1", "csv-parse": "^6.1.0", "digital-letters-events": "^0.0.1", From fab730620a5c75a5fe29b2e5d7e65b3aee1a1bae Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Wed, 1 Apr 2026 09:55:42 +0100 Subject: [PATCH 08/10] CCM-14616: remove redundant code --- .../src/__tests__/apis/sqs-handler.test.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts index 2dc9a4922..4d15c4934 100644 --- a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts +++ b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts @@ -9,8 +9,6 @@ import { recordEvent, } from '__tests__/test-data'; -import { $LetterEvent } from '@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events'; - const logger = mock(); const eventPublisher = mock(); @@ -73,22 +71,6 @@ describe('SQS Handler', () => { expect(response).toEqual({ batchItemFailures: [] }); }); - it('should throw an error', async () => { - const { - data: item, - error: parseError, - success: parseSuccess, - } = $LetterEvent.safeParse(pendingLetterEvent); - - expect(parseSuccess).toBe(true); - expect(parseError).toBeUndefined(); - expect(item).toBeDefined(); - - expect(item?.subject).toBe( - 'letter-origin/letter-rendering/letter/32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', - ); - }); - it('should send print.letter.transitioned event when letter.PENDING received', async () => { const response = await handler(recordEvent([acceptedLetterEvent])); From d0a09d974adda5f8b6c92f2a57d622d0631ddebd Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Wed, 1 Apr 2026 10:00:53 +0100 Subject: [PATCH 09/10] CCM-14616: remove redundant code --- .../src/__tests__/apis/sqs-handler.test.ts | 40 ------------------- .../src/__tests__/test-data.ts | 37 ----------------- 2 files changed, 77 deletions(-) diff --git a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts index 4d15c4934..34100f8c5 100644 --- a/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts +++ b/lambdas/print-status-handler/src/__tests__/apis/sqs-handler.test.ts @@ -5,7 +5,6 @@ import { EventPublisher, Logger } from 'utils'; import { acceptedLetterEvent, failedLetterEvent, - pendingLetterEvent, recordEvent, } from '__tests__/test-data'; @@ -33,45 +32,6 @@ describe('SQS Handler', () => { describe('letter status transitions', () => { it('should send print.letter.transitioned event when letter.ACCEPTED received', async () => { - const response = await handler(recordEvent([pendingLetterEvent])); - - expect(eventPublisher.sendEvents).toHaveBeenCalledWith( - [ - { - ...pendingLetterEvent, - id: '550e8400-e29b-41d4-a716-446655440001', - time: '2023-06-20T12:00:00.250Z', - recordedtime: '2023-06-20T12:00:00.250Z', - dataschema: - 'https://notify.nhs.uk/cloudevents/schemas/digital-letters/2025-10-draft/data/digital-letters-print-letter-transitioned-data.schema.json', - type: 'uk.nhs.notify.digital.letters.print.letter.transitioned.v1', - source: - '/nhs/england/notify/production/primary/data-plane/digitalletters/print', - subject: - 'client/32124dde-4b36-4a49-8686-e9da9cbff725/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', - data: { - senderId: pendingLetterEvent.data.origin.subject.split('/')[1], - messageReference: - pendingLetterEvent.data.origin.subject.split('/')[3], - specificationId: pendingLetterEvent.data.specificationId, - status: pendingLetterEvent.data.status, - supplierId: pendingLetterEvent.data.supplierId, - time: pendingLetterEvent.time, - }, - }, - ], - expect.any(Function), - ); - expect(logger.info).toHaveBeenCalledWith( - 'Received SQS Event of 1 record(s)', - ); - expect(logger.info).toHaveBeenCalledWith( - '1 of 1 records processed successfully', - ); - expect(response).toEqual({ batchItemFailures: [] }); - }); - - it('should send print.letter.transitioned event when letter.PENDING received', async () => { const response = await handler(recordEvent([acceptedLetterEvent])); expect(eventPublisher.sendEvents).toHaveBeenCalledWith( diff --git a/lambdas/print-status-handler/src/__tests__/test-data.ts b/lambdas/print-status-handler/src/__tests__/test-data.ts index e1c518e4a..4d6235f43 100644 --- a/lambdas/print-status-handler/src/__tests__/test-data.ts +++ b/lambdas/print-status-handler/src/__tests__/test-data.ts @@ -36,43 +36,6 @@ export const acceptedLetterEvent = { }, } as LetterEvent; -export const pendingLetterEvent = { - specversion: '1.0', - id: '281d1b5f-a6d2-42c1-9ec4-d1fc26ad2a6f', - type: 'uk.nhs.notify.supplier-api.letter.PENDING.v1', - plane: 'data', - dataschema: - 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.PENDING.1.0.16.schema.json', - dataschemaversion: '1.0.16', - source: - '/data-plane/supplier-api/nhs-supplier-api-nonprod/main/update-status', - subject: - 'letter-origin/letter-rendering/letter/32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', - data: { - domainId: - '32124dde-4b36-4a49-8686-e9da9cbff725_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', - status: 'PENDING', - specificationId: 'notify-c5', - billingRef: 'notify-c5', - specificationBillingId: 'default', - supplierId: 'synertec', - groupId: '32124dde-4b36-4a49-8686-e9da9cbff725digitalLettersundefined', - origin: { - domain: 'letter-rendering', - source: '/data-plane/digital-letters/nonprod/main', - subject: - 'client/32124dde-4b36-4a49-8686-e9da9cbff725/letter-request/2503cbd5-6722-4e90-9fbd-5f1e96d65c22', - event: '281d1b5f-a6d2-42c1-9ec4-d1fc26ad2a6f', - }, - }, - time: '2026-03-27T16:59:16.515Z', - datacontenttype: 'application/json', - traceparent: '00-15c1d7050c2dbeb7f762bff8874c9a5b-a7043d96b780e5ef-01', - recordedtime: '2026-03-27T16:59:16.515Z', - severitynumber: 2, - severitytext: 'INFO', -} as LetterEvent; - export const failedLetterEvent = { id: '550e8400-e29b-41d4-a716-446655440002', specversion: '1.0', From e3fae42c8fd467bddd0174f2401401386f2597b8 Mon Sep 17 00:00:00 2001 From: Angel Pastor Date: Thu, 2 Apr 2026 11:27:27 +0100 Subject: [PATCH 10/10] CCM-14616: Address review comments --- lambdas/print-status-handler/src/__tests__/test-data.ts | 8 ++++---- lambdas/print-status-handler/src/apis/sqs-handler.ts | 8 +++++--- .../print-status-handler.component.spec.ts | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lambdas/print-status-handler/src/__tests__/test-data.ts b/lambdas/print-status-handler/src/__tests__/test-data.ts index 4d6235f43..d950876c3 100644 --- a/lambdas/print-status-handler/src/__tests__/test-data.ts +++ b/lambdas/print-status-handler/src/__tests__/test-data.ts @@ -9,8 +9,8 @@ export const acceptedLetterEvent = { 'letter-origin/digital-letters/letter/f47ac10b-58cc-4372-a567-0e02b2c3d479_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', type: 'uk.nhs.notify.supplier-api.letter.ACCEPTED.v1', dataschema: - 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.16.schema.json', - dataschemaversion: '1.0.16', + 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.ACCEPTED.1.0.17.schema.json', + dataschemaversion: '1.0.17', time: '2023-06-20T12:00:00Z', recordedtime: '2023-06-20T12:00:00.250Z', severitynumber: 2, @@ -44,8 +44,8 @@ export const failedLetterEvent = { 'letter-origin/digital-letters/letter/f47ac10b-58cc-4372-a567-0e02b2c3d480_2503cbd5-6722-4e90-9fbd-5f1e96d65c22', type: 'uk.nhs.notify.supplier-api.letter.FAILED.v1', dataschema: - 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.FAILED.1.0.16.schema.json', - dataschemaversion: '1.0.16', + 'https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.FAILED.1.0.17.schema.json', + dataschemaversion: '1.0.17', time: '2023-06-20T13:00:00Z', recordedtime: '2023-06-20T13:00:00.250Z', severitynumber: 3, diff --git a/lambdas/print-status-handler/src/apis/sqs-handler.ts b/lambdas/print-status-handler/src/apis/sqs-handler.ts index 73bebb9bb..9d599c9fd 100644 --- a/lambdas/print-status-handler/src/apis/sqs-handler.ts +++ b/lambdas/print-status-handler/src/apis/sqs-handler.ts @@ -68,9 +68,11 @@ function validateRecord( return null; } - logger.info( - `Successfully validated SQS record with messageId: ${messageId}, subject: ${item.data.origin.subject}`, - ); + logger.info({ + description: 'Successfully validated SQS record', + messageId, + subject: item.data.origin.subject, + }); return { messageId, event: item }; } catch (error) { diff --git a/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts b/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts index e79794be8..d6b013389 100644 --- a/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts +++ b/tests/playwright/digital-letters-component-tests/print-status-handler.component.spec.ts @@ -15,7 +15,7 @@ const baseLetterEvent = { id: '550e8400-e29b-41d4-a716-446655440001', specversion: '1.0', source: '/data-plane/supplier-api/prod/update-status', - dataschemaversion: '1.0.16', + dataschemaversion: '1.0.17', time: '2023-06-20T12:00:00Z', recordedtime: '2023-06-20T12:00:00.250Z', severitynumber: 2, @@ -65,7 +65,7 @@ test.describe('Print status handler', () => { ...baseLetterEvent, subject: `letter-origin/letter-rendering/letter/00f3b388-bbe9-41c9-9e76-052d37ee8988_${messageReference}`, type: `uk.nhs.notify.supplier-api.letter.${status}.v1`, - dataschema: `https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.${status}.1.0.16.schema.json`, + dataschema: `https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.${status}.1.0.17.schema.json`, data: { ...baseLetterEvent.data, status,