Skip to content

Commit 1b606d2

Browse files
committed
Merge branch 'main' into CCM-12869-excel-parser
2 parents 21b2499 + 2326a6a commit 1b606d2

6 files changed

Lines changed: 123 additions & 2 deletions

File tree

packages/event-builder/src/__tests__/letter-variant-event-builder.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ describe("letter-variant-event-builder", () => {
1111
description: "Test",
1212
volumeGroupId: "volume-group-123" as any,
1313
type: "STANDARD",
14+
priority: 10,
1415
packSpecificationIds: ["00000000-0000-0000-0000-000000000001" as any],
1516
clientId: "client-1",
1617
};

packages/events/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,5 @@
3939
"test:unit": "jest"
4040
},
4141
"types": "dist/index.d.ts",
42-
"version": "1.0.2"
42+
"version": "1.1.0"
4343
}

packages/events/src/domain/letter-variant.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { $PackSpecification } from "@nhsdigital/nhs-notify-event-schemas-supplie
44
import { z } from "zod";
55
import { $VolumeGroup } from "./volume-group";
66
import { $Supplier } from "./supplier";
7-
import { $Constraint, $Constraints } from "./constraint";
7+
import { $Constraints } from "./constraint";
88

99
export const $LetterType = z.enum(["STANDARD", "BRAILLE", "AUDIO"]);
1010

@@ -44,6 +44,11 @@ export const $LetterVariant = z
4444
"This is used to restrict a particular variant to a single supplier, " +
4545
"for example individual admail campaigns.",
4646
}),
47+
priority: z.int().min(1).max(99).default(50).meta({
48+
title: "Priority",
49+
description:
50+
"Integer priority used to order letters for dispatch to suppliers on a 1 to 99 scale, where lower values indicate higher priority. Defaults to 50 when omitted.",
51+
}),
4752
packSpecificationIds: z.array(idRef($PackSpecification)).nonempty().meta({
4853
title: "Pack Specifications",
4954
description:

packages/events/src/events/__tests__/letter-variant-events.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ describe("LetterVariant Events", () => {
2828
description: "A standard letter variant for general correspondence",
2929
volumeGroupId: "supplier-framework-123",
3030
type: "STANDARD",
31+
priority: 10,
3132
status: "PROD",
3233
packSpecificationIds: ["bau-standard-c5", "bau-standard-c4"],
3334
},
@@ -68,6 +69,7 @@ describe("LetterVariant Events", () => {
6869
name: "Braille Letter Variant",
6970
volumeGroupId: "supplier-framework-123",
7071
type: "BRAILLE",
72+
priority: 20,
7173
status: "PROD",
7274
packSpecificationIds: ["braille"],
7375
},
@@ -85,6 +87,7 @@ describe("LetterVariant Events", () => {
8587
name: "Audio Letter Variant",
8688
volumeGroupId: "supplier-framework-123",
8789
type: "AUDIO",
90+
priority: 30,
8891
status: "PROD",
8992
packSpecificationIds: ["audio"],
9093
},
@@ -173,6 +176,86 @@ describe("LetterVariant Events", () => {
173176
expect(result.success).toBe(false);
174177
});
175178

179+
it("should reject event with non-integer priority", () => {
180+
const invalidEvent = {
181+
...validProdEvent,
182+
data: {
183+
...validProdEvent.data,
184+
priority: 1.5,
185+
},
186+
};
187+
188+
const result = $LetterVariantEvent.safeParse(invalidEvent);
189+
expect(result.success).toBe(false);
190+
});
191+
192+
it("should default priority to 50 when omitted", () => {
193+
const { priority, ...dataWithoutPriority } = validProdEvent.data;
194+
expect(priority).toBe(10);
195+
const eventWithoutPriority = {
196+
...validProdEvent,
197+
data: dataWithoutPriority,
198+
};
199+
200+
const result = $LetterVariantEvent.safeParse(eventWithoutPriority);
201+
expect(result.success).toBe(true);
202+
expect(result.data?.data.priority).toBe(50);
203+
});
204+
205+
it("should validate priority at the highest boundary value", () => {
206+
const eventAtHighestPriority = {
207+
...validProdEvent,
208+
data: {
209+
...validProdEvent.data,
210+
priority: 1,
211+
},
212+
};
213+
214+
const result = $LetterVariantEvent.safeParse(eventAtHighestPriority);
215+
expect(result.success).toBe(true);
216+
expect(result.data?.data.priority).toBe(1);
217+
});
218+
219+
it("should validate priority at the lowest boundary value", () => {
220+
const eventAtLowestPriority = {
221+
...validProdEvent,
222+
data: {
223+
...validProdEvent.data,
224+
priority: 99,
225+
},
226+
};
227+
228+
const result = $LetterVariantEvent.safeParse(eventAtLowestPriority);
229+
expect(result.success).toBe(true);
230+
expect(result.data?.data.priority).toBe(99);
231+
});
232+
233+
it("should reject priority lower than the allowed range", () => {
234+
const invalidEvent = {
235+
...validProdEvent,
236+
data: {
237+
...validProdEvent.data,
238+
priority: 0,
239+
},
240+
};
241+
242+
const result = $LetterVariantEvent.safeParse(invalidEvent);
243+
expect(result.success).toBe(false);
244+
});
245+
246+
it("should reject priority higher than the allowed range", () => {
247+
const invalidEvent = {
248+
...validProdEvent,
249+
data: {
250+
...validProdEvent.data,
251+
priority: 100,
252+
},
253+
};
254+
255+
const result = $LetterVariantEvent.safeParse(invalidEvent);
256+
expect(result.success).toBe(false);
257+
});
258+
176259
it("should validate specialised schema enforces PROD status", () => {
177260
const prodSchema = letterVariantEvents["letter-variant.prod"];
178261

@@ -290,6 +373,7 @@ describe("LetterVariant Events", () => {
290373
name: "Disabled Letter Variant",
291374
volumeGroupId: "supplier-framework-123",
292375
type: "STANDARD",
376+
priority: 15,
293377
status: "INT",
294378
packSpecificationIds: ["bau-standard-c5"],
295379
},
@@ -350,6 +434,7 @@ describe("LetterVariant Events", () => {
350434
description: "A letter variant that has been disabled",
351435
volumeGroupId: "supplier-framework-123",
352436
type: "STANDARD",
437+
priority: 15,
353438
status: "DISABLED",
354439
packSpecificationIds: ["bau-standard-c5"],
355440
},

packages/events/src/examples/specification-examples.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ const variants: Record<string, LetterVariant> = {
167167
volumeGroupId: "volume-group-12345",
168168
packSpecificationIds: [bauStandardC5.id, bauStandardC4.id],
169169
type: "STANDARD",
170+
priority: 10,
170171
status: "PROD",
171172
constraints: {
172173
sheets: {
@@ -186,6 +187,7 @@ const variants: Record<string, LetterVariant> = {
186187
volumeGroupId: "volume-group-12345",
187188
packSpecificationIds: [braille.id],
188189
type: "BRAILLE",
190+
priority: 20,
189191
status: "PROD",
190192
constraints: {
191193
sheets: {
@@ -205,6 +207,7 @@ const variants: Record<string, LetterVariant> = {
205207
volumeGroupId: "volume-group-12345",
206208
packSpecificationIds: [audio.id],
207209
type: "AUDIO",
210+
priority: 30,
208211
status: "PROD",
209212
constraints: {
210213
sheets: {
@@ -224,6 +227,7 @@ const variants: Record<string, LetterVariant> = {
224227
volumeGroupId: "volume-group-12345",
225228
packSpecificationIds: [sameDay.id],
226229
type: "STANDARD",
230+
priority: 5,
227231
status: "PROD",
228232
constraints: {
229233
sheets: {
@@ -243,6 +247,7 @@ const variants: Record<string, LetterVariant> = {
243247
volumeGroupId: "volume-group-campaign1",
244248
packSpecificationIds: [clientPack1.id],
245249
type: "STANDARD",
250+
priority: 40,
246251
status: "PROD",
247252
clientId: "client1",
248253
campaignIds: ["client1-campaign1"],

packages/file-store/src/__tests__/config-store-validator.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jest.mock("@nhsdigital/nhs-notify-event-schemas-supplier-config", () => {
1414
}),
1515
$LetterVariant: z.object({
1616
id: z.string(),
17+
priority: z.number().int().min(1).max(99).default(50),
1718
packSpecificationIds: z.array(z.string()).min(1),
1819
}),
1920
$PackSpecification: z.object({
@@ -154,6 +155,7 @@ describe("validateConfigStore", () => {
154155
records: [
155156
makeRecord("letter-variant", "lv-1", {
156157
id: "lv-1",
158+
priority: 10,
157159
packSpecificationIds: [123],
158160
}),
159161
],
@@ -163,6 +165,29 @@ describe("validateConfigStore", () => {
163165
expect(result.issues[0]?.path).toEqual(["packSpecificationIds", 0]);
164166
});
165167

168+
it("should reject letter variant priority values outside the allowed range", () => {
169+
const result = validateConfigStore({
170+
rootPath: mockRootPath,
171+
records: [
172+
makeRecord("letter-variant", "lv-1", {
173+
id: "lv-1",
174+
priority: 100,
175+
packSpecificationIds: ["pack-spec-1"],
176+
}),
177+
],
178+
});
179+
180+
expect(result.ok).toBe(false);
181+
expect(result.issues).toEqual(
182+
expect.arrayContaining([
183+
expect.objectContaining({
184+
entity: "letter-variant",
185+
path: ["priority"],
186+
}),
187+
]),
188+
);
189+
});
190+
166191
it("should return ok=true with no issues when all records are valid", () => {
167192
const result = validateConfigStore({
168193
rootPath: mockRootPath,

0 commit comments

Comments
 (0)