Skip to content

Commit 4331f24

Browse files
Refactor schemas and add test for letter priority
1 parent eb2e25b commit 4331f24

10 files changed

Lines changed: 238 additions & 69 deletions

File tree

internal/events/src/cli/generate-json.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { z } from "zod";
22
import * as fs from "node:fs";
33
import { $Letter } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/domain/letter";
44
import {
5-
$LetterEvent,
5+
$LetterStatusChangeEvent,
66
letterEventMap,
77
} from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events";
88
import { $MISubmittedEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/mi-events";
@@ -36,7 +36,7 @@ for (const [key, schema] of Object.entries(letterEventMap)) {
3636
}
3737

3838
// Generic letter status change event schema
39-
const json = z.toJSONSchema($LetterEvent, {
39+
const json = z.toJSONSchema($LetterStatusChangeEvent, {
4040
io: "input",
4141
target: "openapi-3.0",
4242
reused: "ref",

internal/events/src/events/__tests__/letter-mapper.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { $LetterEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src";
1+
import { $LetterStatusChangeEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src";
22
import { Letter } from "@internal/datastore";
33
import { mapLetterToCloudEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-mapper";
44

@@ -22,7 +22,7 @@ describe("letter-mapper", () => {
2222
const event = mapLetterToCloudEvent(letter, source);
2323

2424
// Check it conforms to the letter event schema - parse will throw an error if not
25-
$LetterEvent.parse(event);
25+
$LetterStatusChangeEvent.parse(event);
2626
expect(event.type).toBe("uk.nhs.notify.supplier-api.letter.PRINTED.v1");
2727
expect(event.dataschema).toBe(
2828
`https://notify.nhs.uk/cloudevents/schemas/supplier-api/letter.PRINTED.${event.dataschemaversion}.schema.json`,

internal/events/src/events/letter-events.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { EventEnvelope } from "@nhsdigital/nhs-notify-event-schemas-supplier-api
99
/**
1010
* A generic schema for parsing any letter status change event
1111
*/
12-
export const $LetterEvent = EventEnvelope(
12+
export const $LetterStatusChangeEvent = EventEnvelope(
1313
"letter",
1414
"letter",
1515
$Letter,
@@ -19,7 +19,7 @@ export const $LetterEvent = EventEnvelope(
1919
title: `letter.* Event`,
2020
description: `Event schema for generic letter status change`,
2121
});
22-
export type LetterEvent = z.infer<typeof $LetterEvent>;
22+
export type LetterStatusChangeEvent = z.infer<typeof $LetterStatusChangeEvent>;
2323

2424
/**
2525
* Specialise the generic event schema for a single status

internal/events/src/events/letter-mapper.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { randomBytes, randomUUID } from "node:crypto";
22
import eventSchemaPackage from "@nhsdigital/nhs-notify-event-schemas-supplier-api/package.json";
33
import { Letter } from "@internal/datastore";
4-
import { LetterEvent } from "./letter-events";
4+
import { LetterStatusChangeEvent } from "./letter-events";
55

66
// eslint-disable-next-line import-x/prefer-default-export
77
export function mapLetterToCloudEvent(
88
letter: Letter,
99
source: string,
10-
): LetterEvent {
10+
): LetterStatusChangeEvent {
1111
const eventId = randomUUID();
1212
const dataschemaversion = eventSchemaPackage.version;
1313
return {
@@ -21,7 +21,7 @@ export function mapLetterToCloudEvent(
2121
subject: `letter-origin/letter-rendering/letter/${letter.id}`,
2222

2323
data: {
24-
domainId: letter.id as LetterEvent["data"]["domainId"],
24+
domainId: letter.id as LetterStatusChangeEvent["data"]["domainId"],
2525
status: letter.status,
2626
specificationId: letter.specificationId,
2727
billingRef: letter.billingRef,

lambdas/api-handler/src/handlers/amendment-event-transformer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SQSBatchItemFailure, SQSEvent, SQSHandler } from "aws-lambda";
22
import { PublishCommand } from "@aws-sdk/client-sns";
3-
import { LetterEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events";
3+
import { LetterStatusChangeEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events";
44
import { mapLetterToCloudEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-mapper";
55
import { Unit } from "aws-embedded-metrics";
66
import pino from "pino";
@@ -66,7 +66,7 @@ export default function createTransformAmendmentEventHandler(
6666
}
6767

6868
function buildSnsCommand(
69-
letterEvent: LetterEvent,
69+
letterEvent: LetterStatusChangeEvent,
7070
topicArn: string,
7171
): PublishCommand {
7272
return new PublishCommand({

lambdas/upsert-letter/src/handler/__tests__/upsert-handler.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { LetterRepository } from "internal/datastore/src";
44
import { LetterRequestPreparedEventV2 } from "@nhsdigital/nhs-notify-event-schemas-letter-rendering";
55
import { LetterRequestPreparedEvent } from "@nhsdigital/nhs-notify-event-schemas-letter-rendering-v1";
66
import {
7-
$LetterEvent,
8-
LetterEvent,
7+
$LetterStatusChangeEvent,
8+
LetterStatusChangeEvent,
99
} from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events";
1010
import createUpsertLetterHandler from "../upsert-handler";
1111
import { Deps } from "../../config/deps";
@@ -77,10 +77,10 @@ function createPreparedV1Event(
7777

7878
function createSupplierStatusChangeEventWithoutSupplier(
7979
overrides: Partial<any> = {},
80-
): LetterEvent {
80+
): LetterStatusChangeEvent {
8181
const now = new Date().toISOString();
8282

83-
return $LetterEvent.parse({
83+
return $LetterStatusChangeEvent.parse({
8484
data: {
8585
domainId: overrides.domainId ?? "f47ac10b-58cc-4372-a567-0e02b2c3d479",
8686
groupId: "client_template",
@@ -132,10 +132,10 @@ function createPreparedV2Event(
132132

133133
function createSupplierStatusChangeEvent(
134134
overrides: Partial<any> = {},
135-
): LetterEvent {
135+
): LetterStatusChangeEvent {
136136
const now = new Date().toISOString();
137137

138-
return $LetterEvent.parse({
138+
return $LetterStatusChangeEvent.parse({
139139
data: {
140140
domainId: overrides.domainId ?? "f47ac10b-58cc-4372-a567-0e02b2c3d479",
141141
groupId: "client_template",
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
$LetterRequestPreparedEvent,
3+
LetterRequestPreparedEvent,
4+
} from "@nhsdigital/nhs-notify-event-schemas-letter-rendering-v1";
5+
import { $LetterStatusChangeEvent } from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events";
6+
import {
7+
$LetterRequestPreparedEventV2,
8+
LetterRequestPreparedEventV2,
9+
} from "@nhsdigital/nhs-notify-event-schemas-letter-rendering";
10+
import z from "zod";
11+
import { Deps } from "../config/deps";
12+
13+
export type PreparedEvents =
14+
| LetterRequestPreparedEventV2
15+
| LetterRequestPreparedEvent;
16+
17+
const SupplierSpecSchema = z.object({
18+
supplierId: z.string().min(1),
19+
specId: z.string().min(1),
20+
priority: z.int().min(0).max(99).default(10),
21+
billingId: z.string().min(1),
22+
});
23+
24+
export type SupplierSpec = z.infer<typeof SupplierSpecSchema>;
25+
26+
export const PreparedEventUnionSchema = z.discriminatedUnion("type", [
27+
$LetterRequestPreparedEventV2,
28+
$LetterRequestPreparedEvent,
29+
]);
30+
31+
export const AllocatedLetterSchema = z.object({
32+
letterEvent: PreparedEventUnionSchema,
33+
supplierSpec: SupplierSpecSchema,
34+
});
35+
36+
export type AllocatedLetter = z.infer<typeof AllocatedLetterSchema>;
37+
38+
export const QueueMessageSchema = z.union([
39+
$LetterStatusChangeEvent,
40+
AllocatedLetterSchema,
41+
]);
42+
43+
export type QueueMessage = z.infer<typeof QueueMessageSchema>;
44+
45+
export type UpsertOperation = {
46+
name: "Insert" | "Update";
47+
schemas: z.ZodSchema[];
48+
handler: (
49+
request: unknown,
50+
supplierSpec: SupplierSpec,
51+
deps: Deps,
52+
) => Promise<void>;
53+
};

lambdas/upsert-letter/src/handler/upsert-handler.ts

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,20 @@
11
import { SQSBatchItemFailure, SQSEvent, SQSHandler } from "aws-lambda";
22
import { InsertLetter, UpdateLetter } from "@internal/datastore";
3+
import { $LetterRequestPreparedEvent } from "@nhsdigital/nhs-notify-event-schemas-letter-rendering-v1";
34
import {
4-
$LetterRequestPreparedEvent,
5-
LetterRequestPreparedEvent,
6-
} from "@nhsdigital/nhs-notify-event-schemas-letter-rendering-v1";
7-
import {
8-
$LetterEvent,
9-
LetterEvent,
5+
$LetterStatusChangeEvent,
6+
LetterStatusChangeEvent,
107
} from "@nhsdigital/nhs-notify-event-schemas-supplier-api/src/events/letter-events";
11-
import {
12-
$LetterRequestPreparedEventV2,
13-
LetterRequestPreparedEventV2,
14-
} from "@nhsdigital/nhs-notify-event-schemas-letter-rendering";
15-
import z from "zod";
8+
import { $LetterRequestPreparedEventV2 } from "@nhsdigital/nhs-notify-event-schemas-letter-rendering";
169
import { MetricsLogger, Unit, metricScope } from "aws-embedded-metrics";
1710
import { Deps } from "../config/deps";
18-
19-
type PreparedEvents = LetterRequestPreparedEventV2 | LetterRequestPreparedEvent;
20-
21-
const SupplierSpecSchema = z.object({
22-
supplierId: z.string().min(1),
23-
specId: z.string().min(1),
24-
priority: z.int().min(0).max(99).default(10),
25-
billingId: z.string().min(1),
26-
});
27-
28-
type SupplierSpec = z.infer<typeof SupplierSpecSchema>;
29-
30-
const PreparedEventUnionSchema = z.discriminatedUnion("type", [
31-
$LetterRequestPreparedEventV2,
32-
$LetterRequestPreparedEvent,
33-
]);
34-
35-
const QueueMessageSchema = z.union([
36-
$LetterEvent,
37-
z.object({
38-
letterEvent: PreparedEventUnionSchema,
39-
supplierSpec: SupplierSpecSchema,
40-
}),
41-
]);
42-
43-
type QueueMessage = z.infer<typeof QueueMessageSchema>;
44-
45-
type UpsertOperation = {
46-
name: "Insert" | "Update";
47-
schemas: z.ZodSchema[];
48-
handler: (
49-
request: unknown,
50-
supplierSpec: SupplierSpec,
51-
deps: Deps,
52-
) => Promise<void>;
53-
};
11+
import {
12+
PreparedEvents,
13+
QueueMessage,
14+
QueueMessageSchema,
15+
SupplierSpec,
16+
UpsertOperation,
17+
} from "./schemas";
5418

5519
function getOperationFromType(type: string): UpsertOperation {
5620
if (
@@ -83,9 +47,9 @@ function getOperationFromType(type: string): UpsertOperation {
8347
// if it's not an insert type, it must be an update as we've already parsed the message, but we want to have a separate operation for better logging and metrics
8448
return {
8549
name: "Update",
86-
schemas: [$LetterEvent],
50+
schemas: [$LetterStatusChangeEvent],
8751
handler: async (request, supplierSpec, deps) => {
88-
const supplierEvent = request as LetterEvent;
52+
const supplierEvent = request as LetterStatusChangeEvent;
8953
const letterToUpdate: UpdateLetter = mapToUpdateLetter(supplierEvent);
9054
await deps.letterRepo.updateLetterStatus(letterToUpdate);
9155

@@ -129,7 +93,7 @@ function mapToInsertLetter(
12993
};
13094
}
13195

132-
function mapToUpdateLetter(upsertRequest: LetterEvent): UpdateLetter {
96+
function mapToUpdateLetter(upsertRequest: LetterStatusChangeEvent): UpdateLetter {
13397
return {
13498
id: upsertRequest.data.domainId,
13599
eventId: upsertRequest.id,
@@ -216,7 +180,7 @@ export default function createUpsertLetterHandler(deps: Deps): SQSHandler {
216180

217181
const queueMessage: QueueMessage = parseQueueMessage(sqsMessage);
218182

219-
let letterEvent: LetterEvent | PreparedEvents;
183+
let letterEvent: LetterStatusChangeEvent | PreparedEvents;
220184
let supplierSpec: SupplierSpec | undefined;
221185

222186
if ("letterEvent" in queueMessage) {

0 commit comments

Comments
 (0)