placementt-core 1.400.1251 → 1.400.1253
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bulkEngagement.d.ts +30 -0
- package/lib/bulkEngagement.js +30 -1
- package/lib/bulkEngagement.js.map +1 -1
- package/lib/bulkEngagement.test.js +56 -0
- package/lib/bulkEngagement.test.js.map +1 -1
- package/lib/callables/engagement.d.ts +54 -0
- package/lib/callables/engagement.js +20 -0
- package/lib/callables/engagement.js.map +1 -1
- package/lib/callables/registry.d.ts +96 -0
- package/package.json +1 -1
- package/src/bulkEngagement.test.ts +75 -1
- package/src/bulkEngagement.ts +44 -0
- package/src/callables/engagement.ts +20 -0
package/lib/bulkEngagement.d.ts
CHANGED
|
@@ -12,6 +12,23 @@ export type BulkEngagementFlag = "noContacts" | "noRenewalDate" | "noQuote" | "n
|
|
|
12
12
|
export declare const BULK_ENGAGEMENT_FLAG_LABELS: Record<BulkEngagementFlag, string>;
|
|
13
13
|
/** Flags that stop a school being sent the email at all. */
|
|
14
14
|
export declare const BULK_ENGAGEMENT_BLOCKING_FLAGS: BulkEngagementFlag[];
|
|
15
|
+
/** The account types the send popup filters by, and what it calls them. */
|
|
16
|
+
export declare const BULK_ENGAGEMENT_PACKAGE_LABELS: {
|
|
17
|
+
[pkg: string]: string;
|
|
18
|
+
};
|
|
19
|
+
/** The products the send popup filters by. Flags on ResolvedProducts. */
|
|
20
|
+
export type BulkEngagementProduct = "wex" | "employerEvents" | "destinations";
|
|
21
|
+
export declare const BULK_ENGAGEMENT_PRODUCTS: BulkEngagementProduct[];
|
|
22
|
+
export declare const BULK_ENGAGEMENT_PRODUCT_LABELS: Record<BulkEngagementProduct, string>;
|
|
23
|
+
/** What the admin has ticked in the send popup's filters. Empty means any. */
|
|
24
|
+
export type BulkEngagementFilters = {
|
|
25
|
+
packages: string[];
|
|
26
|
+
products: string[];
|
|
27
|
+
};
|
|
28
|
+
/** Who the popup's "Send test" goes to. Fixed on the server, never taken from the request. */
|
|
29
|
+
export declare const BULK_TEST_RECIPIENT = "tom@careerthread.co.uk";
|
|
30
|
+
/** How many schools' copies one test sends. Matches the cap in the callable's contract. */
|
|
31
|
+
export declare const BULK_TEST_SCHOOLS = 3;
|
|
15
32
|
/** A school that had this email this recently isn't suggested it again. */
|
|
16
33
|
export declare const RECENTLY_SENT_DAYS = 60;
|
|
17
34
|
export type BulkEngagementSchool = {
|
|
@@ -46,3 +63,16 @@ export type BulkEngagementSuggestion = {
|
|
|
46
63
|
* @return {BulkEngagementSuggestion} whether to suggest it, why, and its flags.
|
|
47
64
|
*/
|
|
48
65
|
export declare const bulkEngagementSuggestion: (templateKey: string, school: BulkEngagementSchool) => BulkEngagementSuggestion;
|
|
66
|
+
/**
|
|
67
|
+
* Whether a school passes the send popup's filters: its package is one of
|
|
68
|
+
* those ticked, and it has any of the products ticked. An empty filter
|
|
69
|
+
* matches everything.
|
|
70
|
+
*
|
|
71
|
+
* @param {object} school the school's package and products.
|
|
72
|
+
* @param {BulkEngagementFilters} filters what is ticked.
|
|
73
|
+
* @return {boolean} whether the school matches.
|
|
74
|
+
*/
|
|
75
|
+
export declare const matchesBulkFilters: (school: {
|
|
76
|
+
package: string;
|
|
77
|
+
products: string[];
|
|
78
|
+
}, { packages, products }: BulkEngagementFilters) => boolean;
|
package/lib/bulkEngagement.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.bulkEngagementSuggestion = exports.RECENTLY_SENT_DAYS = exports.BULK_ENGAGEMENT_BLOCKING_FLAGS = exports.BULK_ENGAGEMENT_FLAG_LABELS = void 0;
|
|
3
|
+
exports.matchesBulkFilters = exports.bulkEngagementSuggestion = exports.RECENTLY_SENT_DAYS = exports.BULK_TEST_SCHOOLS = exports.BULK_TEST_RECIPIENT = exports.BULK_ENGAGEMENT_PRODUCT_LABELS = exports.BULK_ENGAGEMENT_PRODUCTS = exports.BULK_ENGAGEMENT_PACKAGE_LABELS = exports.BULK_ENGAGEMENT_BLOCKING_FLAGS = exports.BULK_ENGAGEMENT_FLAG_LABELS = void 0;
|
|
4
4
|
const renewals_1 = require("./renewals");
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
6
|
exports.BULK_ENGAGEMENT_FLAG_LABELS = {
|
|
@@ -12,6 +12,23 @@ exports.BULK_ENGAGEMENT_FLAG_LABELS = {
|
|
|
12
12
|
};
|
|
13
13
|
/** Flags that stop a school being sent the email at all. */
|
|
14
14
|
exports.BULK_ENGAGEMENT_BLOCKING_FLAGS = ["noContacts"];
|
|
15
|
+
/** The account types the send popup filters by, and what it calls them. */
|
|
16
|
+
exports.BULK_ENGAGEMENT_PACKAGE_LABELS = {
|
|
17
|
+
"institutes-one": "School",
|
|
18
|
+
"institutes-two": "Trust",
|
|
19
|
+
"careersHub": "Careers hub",
|
|
20
|
+
"careersSchool": "Hub school",
|
|
21
|
+
};
|
|
22
|
+
exports.BULK_ENGAGEMENT_PRODUCTS = ["wex", "employerEvents", "destinations"];
|
|
23
|
+
exports.BULK_ENGAGEMENT_PRODUCT_LABELS = {
|
|
24
|
+
wex: "Work experience",
|
|
25
|
+
employerEvents: "Employer events",
|
|
26
|
+
destinations: "Destinations",
|
|
27
|
+
};
|
|
28
|
+
/** Who the popup's "Send test" goes to. Fixed on the server, never taken from the request. */
|
|
29
|
+
exports.BULK_TEST_RECIPIENT = "tom@careerthread.co.uk";
|
|
30
|
+
/** How many schools' copies one test sends. Matches the cap in the callable's contract. */
|
|
31
|
+
exports.BULK_TEST_SCHOOLS = 3;
|
|
15
32
|
/** A school that had this email this recently isn't suggested it again. */
|
|
16
33
|
exports.RECENTLY_SENT_DAYS = 60;
|
|
17
34
|
/**
|
|
@@ -69,4 +86,16 @@ const bulkEngagementSuggestion = (templateKey, school) => {
|
|
|
69
86
|
return { suggested: true, reason: `Renews in ${days} days`, flags };
|
|
70
87
|
};
|
|
71
88
|
exports.bulkEngagementSuggestion = bulkEngagementSuggestion;
|
|
89
|
+
/**
|
|
90
|
+
* Whether a school passes the send popup's filters: its package is one of
|
|
91
|
+
* those ticked, and it has any of the products ticked. An empty filter
|
|
92
|
+
* matches everything.
|
|
93
|
+
*
|
|
94
|
+
* @param {object} school the school's package and products.
|
|
95
|
+
* @param {BulkEngagementFilters} filters what is ticked.
|
|
96
|
+
* @return {boolean} whether the school matches.
|
|
97
|
+
*/
|
|
98
|
+
const matchesBulkFilters = (school, { packages, products }) => (!packages.length || packages.includes(school.package)) &&
|
|
99
|
+
(!products.length || products.some((p) => school.products.includes(p)));
|
|
100
|
+
exports.matchesBulkFilters = matchesBulkFilters;
|
|
72
101
|
//# sourceMappingURL=bulkEngagement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulkEngagement.js","sourceRoot":"","sources":["../src/bulkEngagement.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bulkEngagement.js","sourceRoot":"","sources":["../src/bulkEngagement.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ jest.mock("./firebase/firebaseQuery", () => ({ __esModule: true, default: class
|
|
|
5
5
|
} }));
|
|
6
6
|
const productResolver_1 = require("./productResolver");
|
|
7
7
|
const bulkEngagement_1 = require("./bulkEngagement");
|
|
8
|
+
const engagement_1 = require("./callables/engagement");
|
|
8
9
|
const school = (renewalDate, overrides = {}) => ({
|
|
9
10
|
name: "Calder Park Academy",
|
|
10
11
|
package: "institutes-one",
|
|
@@ -60,4 +61,59 @@ describe("bulk engagement suggestions", () => {
|
|
|
60
61
|
expect(suggest("engagementPickFeatures", school(), "2026-11-04", { nextOnboardingTemplate: "engagementPlanYear" }).suggested).toBe(false);
|
|
61
62
|
});
|
|
62
63
|
});
|
|
64
|
+
describe("matchesBulkFilters", () => {
|
|
65
|
+
const trust = { package: "institutes-two", products: ["wex", "destinations"] };
|
|
66
|
+
const hub = { package: "careersHub", products: ["employerEvents"] };
|
|
67
|
+
const none = { package: "institutes-one", products: [] };
|
|
68
|
+
it("matches everything when nothing is ticked", () => {
|
|
69
|
+
[trust, hub, none].forEach((s) => expect((0, bulkEngagement_1.matchesBulkFilters)(s, { packages: [], products: [] })).toBe(true));
|
|
70
|
+
});
|
|
71
|
+
it("matches a package that is one of those ticked", () => {
|
|
72
|
+
const packages = ["institutes-two", "careersHub"];
|
|
73
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(trust, { packages, products: [] })).toBe(true);
|
|
74
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(hub, { packages, products: [] })).toBe(true);
|
|
75
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(none, { packages, products: [] })).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
it("matches a school with any of the products ticked, not all of them", () => {
|
|
78
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(trust, { packages: [], products: ["destinations", "employerEvents"] })).toBe(true);
|
|
79
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(trust, { packages: [], products: ["employerEvents"] })).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
it("never matches a school with no products once a product is ticked", () => {
|
|
82
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(none, { packages: [], products: ["wex"] })).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
it("needs both filters to pass", () => {
|
|
85
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(trust, { packages: ["institutes-two"], products: ["wex"] })).toBe(true);
|
|
86
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(trust, { packages: ["careersHub"], products: ["wex"] })).toBe(false);
|
|
87
|
+
expect((0, bulkEngagement_1.matchesBulkFilters)(trust, { packages: ["institutes-two"], products: ["employerEvents"] })).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
it("labels every package and product in sentence case", () => {
|
|
90
|
+
expect(bulkEngagement_1.BULK_ENGAGEMENT_PACKAGE_LABELS).toEqual({
|
|
91
|
+
"institutes-one": "School",
|
|
92
|
+
"institutes-two": "Trust",
|
|
93
|
+
"careersHub": "Careers hub",
|
|
94
|
+
"careersSchool": "Hub school",
|
|
95
|
+
});
|
|
96
|
+
expect(bulkEngagement_1.BULK_ENGAGEMENT_PRODUCTS.map((p) => bulkEngagement_1.BULK_ENGAGEMENT_PRODUCT_LABELS[p])).toEqual(["Work experience", "Employer events", "Destinations"]);
|
|
97
|
+
});
|
|
98
|
+
it("offers products that resolveProducts sets", () => {
|
|
99
|
+
const products = (0, productResolver_1.resolveProducts)({ package: "careersHub", workExperience: true });
|
|
100
|
+
expect(bulkEngagement_1.BULK_ENGAGEMENT_PRODUCTS.filter((p) => products[p])).toEqual(["employerEvents"]);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe("sendBulkEngagementTest contract", () => {
|
|
104
|
+
const request = (count) => ({
|
|
105
|
+
templateKey: "engagementRenewalDue",
|
|
106
|
+
oIds: Array.from({ length: count }, (_, i) => `school-${i}`),
|
|
107
|
+
subject: "Renewing",
|
|
108
|
+
body: [{ type: "paragraph" }],
|
|
109
|
+
});
|
|
110
|
+
const contract = engagement_1.engagementCallables["bulkEngagement-sendBulkEngagementTest"].request;
|
|
111
|
+
it("takes up to BULK_TEST_SCHOOLS schools and no more", () => {
|
|
112
|
+
expect(contract.safeParse(request(bulkEngagement_1.BULK_TEST_SCHOOLS)).success).toBe(true);
|
|
113
|
+
expect(contract.safeParse(request(bulkEngagement_1.BULK_TEST_SCHOOLS + 1)).success).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
it("has no way to name a recipient", () => {
|
|
116
|
+
expect(contract.parse({ ...request(1), to: "someone@school.sch.uk" })).not.toHaveProperty("to");
|
|
117
|
+
});
|
|
118
|
+
});
|
|
63
119
|
//# sourceMappingURL=bulkEngagement.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulkEngagement.test.js","sourceRoot":"","sources":["../src/bulkEngagement.test.ts"],"names":[],"mappings":";;AAAA,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,EAAC,CAAC,CAAC,CAAC;AAC5D,IAAI,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,CAAC,EAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE;KAAQ,EAAC,CAAC,CAAC,CAAC;AAGrF,uDAAkD;AAClD,
|
|
1
|
+
{"version":3,"file":"bulkEngagement.test.js","sourceRoot":"","sources":["../src/bulkEngagement.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,8 @@ export declare const engagementCallables: {
|
|
|
14
14
|
oId: z.ZodString;
|
|
15
15
|
name: z.ZodString;
|
|
16
16
|
package: z.ZodString;
|
|
17
|
+
/** The products the admin can filter this school by. */
|
|
18
|
+
products: z.ZodArray<z.ZodEnum<["wex", "employerEvents", "destinations"]>, "many">;
|
|
17
19
|
suggested: z.ZodBoolean;
|
|
18
20
|
reason: z.ZodOptional<z.ZodString>;
|
|
19
21
|
flags: z.ZodArray<z.ZodEnum<["noContacts", "noRenewalDate", "noQuote", "noFinanceContact", "sentRecently"]>, "many">;
|
|
@@ -30,6 +32,7 @@ export declare const engagementCallables: {
|
|
|
30
32
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
31
33
|
contacts: number;
|
|
32
34
|
params: Record<string, string>;
|
|
35
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
33
36
|
suggested: boolean;
|
|
34
37
|
reason?: string | undefined;
|
|
35
38
|
lastSent?: string | undefined;
|
|
@@ -40,6 +43,7 @@ export declare const engagementCallables: {
|
|
|
40
43
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
41
44
|
contacts: number;
|
|
42
45
|
params: Record<string, string>;
|
|
46
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
43
47
|
suggested: boolean;
|
|
44
48
|
reason?: string | undefined;
|
|
45
49
|
lastSent?: string | undefined;
|
|
@@ -52,6 +56,7 @@ export declare const engagementCallables: {
|
|
|
52
56
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
53
57
|
contacts: number;
|
|
54
58
|
params: Record<string, string>;
|
|
59
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
55
60
|
suggested: boolean;
|
|
56
61
|
reason?: string | undefined;
|
|
57
62
|
lastSent?: string | undefined;
|
|
@@ -64,6 +69,7 @@ export declare const engagementCallables: {
|
|
|
64
69
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
65
70
|
contacts: number;
|
|
66
71
|
params: Record<string, string>;
|
|
72
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
67
73
|
suggested: boolean;
|
|
68
74
|
reason?: string | undefined;
|
|
69
75
|
lastSent?: string | undefined;
|
|
@@ -120,6 +126,54 @@ export declare const engagementCallables: {
|
|
|
120
126
|
}>;
|
|
121
127
|
}>;
|
|
122
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* Sends each school's copy of the email to CareerThread's test address, so
|
|
131
|
+
* it can be read before the real send. Nothing is logged on the school or
|
|
132
|
+
* changed on it, and no follow-ups start. The address is set on the server.
|
|
133
|
+
*/
|
|
134
|
+
"bulkEngagement-sendBulkEngagementTest": {
|
|
135
|
+
request: z.ZodObject<{
|
|
136
|
+
templateKey: z.ZodString;
|
|
137
|
+
oIds: z.ZodArray<z.ZodString, "many">;
|
|
138
|
+
subject: z.ZodString;
|
|
139
|
+
body: z.ZodArray<z.ZodUnknown, "many">;
|
|
140
|
+
heroImage: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | undefined, string | null | undefined>;
|
|
141
|
+
}, "strip", z.ZodTypeAny, {
|
|
142
|
+
body: unknown[];
|
|
143
|
+
subject: string;
|
|
144
|
+
templateKey: string;
|
|
145
|
+
oIds: string[];
|
|
146
|
+
heroImage?: string | undefined;
|
|
147
|
+
}, {
|
|
148
|
+
body: unknown[];
|
|
149
|
+
subject: string;
|
|
150
|
+
templateKey: string;
|
|
151
|
+
oIds: string[];
|
|
152
|
+
heroImage?: string | null | undefined;
|
|
153
|
+
}>;
|
|
154
|
+
response: z.ZodObject<{
|
|
155
|
+
results: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
156
|
+
sent: z.ZodArray<z.ZodString, "many">;
|
|
157
|
+
error: z.ZodOptional<z.ZodString>;
|
|
158
|
+
}, "strip", z.ZodTypeAny, {
|
|
159
|
+
sent: string[];
|
|
160
|
+
error?: string | undefined;
|
|
161
|
+
}, {
|
|
162
|
+
sent: string[];
|
|
163
|
+
error?: string | undefined;
|
|
164
|
+
}>>;
|
|
165
|
+
}, "strip", z.ZodTypeAny, {
|
|
166
|
+
results: Record<string, {
|
|
167
|
+
sent: string[];
|
|
168
|
+
error?: string | undefined;
|
|
169
|
+
}>;
|
|
170
|
+
}, {
|
|
171
|
+
results: Record<string, {
|
|
172
|
+
sent: string[];
|
|
173
|
+
error?: string | undefined;
|
|
174
|
+
}>;
|
|
175
|
+
}>;
|
|
176
|
+
};
|
|
123
177
|
/** One-off: removes the open renewal email tasks the old automatic schedule made. */
|
|
124
178
|
"bulkEngagement-clearRenewalEmailTasks": {
|
|
125
179
|
request: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
|
|
@@ -12,6 +12,7 @@ const types_1 = require("./types");
|
|
|
12
12
|
* an email interaction on the school. All of them are admin-only.
|
|
13
13
|
*/
|
|
14
14
|
const flag = zod_1.z.enum(["noContacts", "noRenewalDate", "noQuote", "noFinanceContact", "sentRecently"]);
|
|
15
|
+
const product = zod_1.z.enum(["wex", "employerEvents", "destinations"]);
|
|
15
16
|
exports.engagementCallables = {
|
|
16
17
|
"bulkEngagement-getBulkEngagementSchools": {
|
|
17
18
|
request: zod_1.z.object({
|
|
@@ -23,6 +24,8 @@ exports.engagementCallables = {
|
|
|
23
24
|
oId: zod_1.z.string(),
|
|
24
25
|
name: zod_1.z.string(),
|
|
25
26
|
package: zod_1.z.string(),
|
|
27
|
+
/** The products the admin can filter this school by. */
|
|
28
|
+
products: zod_1.z.array(product),
|
|
26
29
|
suggested: zod_1.z.boolean(),
|
|
27
30
|
reason: zod_1.z.string().optional(),
|
|
28
31
|
flags: zod_1.z.array(flag),
|
|
@@ -52,6 +55,23 @@ exports.engagementCallables = {
|
|
|
52
55
|
results: zod_1.z.record(zod_1.z.string(), zod_1.z.object({ sent: zod_1.z.array(zod_1.z.string()), error: zod_1.z.string().optional() })),
|
|
53
56
|
}),
|
|
54
57
|
},
|
|
58
|
+
/**
|
|
59
|
+
* Sends each school's copy of the email to CareerThread's test address, so
|
|
60
|
+
* it can be read before the real send. Nothing is logged on the school or
|
|
61
|
+
* changed on it, and no follow-ups start. The address is set on the server.
|
|
62
|
+
*/
|
|
63
|
+
"bulkEngagement-sendBulkEngagementTest": {
|
|
64
|
+
request: zod_1.z.object({
|
|
65
|
+
templateKey: zod_1.z.string().min(1),
|
|
66
|
+
oIds: zod_1.z.array(zod_1.z.string().min(1)).min(1, "Pick at least one school.").max(3),
|
|
67
|
+
subject: zod_1.z.string().trim().min(1, "Give it a subject."),
|
|
68
|
+
body: zod_1.z.array(zod_1.z.unknown()).min(1),
|
|
69
|
+
heroImage: (0, types_1.optionalField)(zod_1.z.string()),
|
|
70
|
+
}),
|
|
71
|
+
response: zod_1.z.object({
|
|
72
|
+
results: zod_1.z.record(zod_1.z.string(), zod_1.z.object({ sent: zod_1.z.array(zod_1.z.string()), error: zod_1.z.string().optional() })),
|
|
73
|
+
}),
|
|
74
|
+
},
|
|
55
75
|
/** One-off: removes the open renewal email tasks the old automatic schedule made. */
|
|
56
76
|
"bulkEngagement-clearRenewalEmailTasks": {
|
|
57
77
|
request: zod_1.z.object({}).optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engagement.js","sourceRoot":"","sources":["../../src/callables/engagement.ts"],"names":[],"mappings":";;;AAAA,6BAAsB;AACtB,mCAAqD;AAErD;;;;;;;GAOG;AAEH,MAAM,IAAI,GAAG,OAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,EAAE,cAAc,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"engagement.js","sourceRoot":"","sources":["../../src/callables/engagement.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@ export declare const allCallables: {
|
|
|
24
24
|
oId: z.ZodString;
|
|
25
25
|
name: z.ZodString;
|
|
26
26
|
package: z.ZodString;
|
|
27
|
+
products: z.ZodArray<z.ZodEnum<["wex", "employerEvents", "destinations"]>, "many">;
|
|
27
28
|
suggested: z.ZodBoolean;
|
|
28
29
|
reason: z.ZodOptional<z.ZodString>;
|
|
29
30
|
flags: z.ZodArray<z.ZodEnum<["noContacts", "noRenewalDate", "noQuote", "noFinanceContact", "sentRecently"]>, "many">;
|
|
@@ -37,6 +38,7 @@ export declare const allCallables: {
|
|
|
37
38
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
38
39
|
contacts: number;
|
|
39
40
|
params: Record<string, string>;
|
|
41
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
40
42
|
suggested: boolean;
|
|
41
43
|
reason?: string | undefined;
|
|
42
44
|
lastSent?: string | undefined;
|
|
@@ -47,6 +49,7 @@ export declare const allCallables: {
|
|
|
47
49
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
48
50
|
contacts: number;
|
|
49
51
|
params: Record<string, string>;
|
|
52
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
50
53
|
suggested: boolean;
|
|
51
54
|
reason?: string | undefined;
|
|
52
55
|
lastSent?: string | undefined;
|
|
@@ -59,6 +62,7 @@ export declare const allCallables: {
|
|
|
59
62
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
60
63
|
contacts: number;
|
|
61
64
|
params: Record<string, string>;
|
|
65
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
62
66
|
suggested: boolean;
|
|
63
67
|
reason?: string | undefined;
|
|
64
68
|
lastSent?: string | undefined;
|
|
@@ -71,6 +75,7 @@ export declare const allCallables: {
|
|
|
71
75
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
72
76
|
contacts: number;
|
|
73
77
|
params: Record<string, string>;
|
|
78
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
74
79
|
suggested: boolean;
|
|
75
80
|
reason?: string | undefined;
|
|
76
81
|
lastSent?: string | undefined;
|
|
@@ -123,6 +128,49 @@ export declare const allCallables: {
|
|
|
123
128
|
}>;
|
|
124
129
|
}>;
|
|
125
130
|
};
|
|
131
|
+
"bulkEngagement-sendBulkEngagementTest": {
|
|
132
|
+
request: z.ZodObject<{
|
|
133
|
+
templateKey: z.ZodString;
|
|
134
|
+
oIds: z.ZodArray<z.ZodString, "many">;
|
|
135
|
+
subject: z.ZodString;
|
|
136
|
+
body: z.ZodArray<z.ZodUnknown, "many">;
|
|
137
|
+
heroImage: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | undefined, string | null | undefined>;
|
|
138
|
+
}, "strip", z.ZodTypeAny, {
|
|
139
|
+
body: unknown[];
|
|
140
|
+
subject: string;
|
|
141
|
+
templateKey: string;
|
|
142
|
+
oIds: string[];
|
|
143
|
+
heroImage?: string | undefined;
|
|
144
|
+
}, {
|
|
145
|
+
body: unknown[];
|
|
146
|
+
subject: string;
|
|
147
|
+
templateKey: string;
|
|
148
|
+
oIds: string[];
|
|
149
|
+
heroImage?: string | null | undefined;
|
|
150
|
+
}>;
|
|
151
|
+
response: z.ZodObject<{
|
|
152
|
+
results: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
153
|
+
sent: z.ZodArray<z.ZodString, "many">;
|
|
154
|
+
error: z.ZodOptional<z.ZodString>;
|
|
155
|
+
}, "strip", z.ZodTypeAny, {
|
|
156
|
+
sent: string[];
|
|
157
|
+
error?: string | undefined;
|
|
158
|
+
}, {
|
|
159
|
+
sent: string[];
|
|
160
|
+
error?: string | undefined;
|
|
161
|
+
}>>;
|
|
162
|
+
}, "strip", z.ZodTypeAny, {
|
|
163
|
+
results: Record<string, {
|
|
164
|
+
sent: string[];
|
|
165
|
+
error?: string | undefined;
|
|
166
|
+
}>;
|
|
167
|
+
}, {
|
|
168
|
+
results: Record<string, {
|
|
169
|
+
sent: string[];
|
|
170
|
+
error?: string | undefined;
|
|
171
|
+
}>;
|
|
172
|
+
}>;
|
|
173
|
+
};
|
|
126
174
|
"bulkEngagement-clearRenewalEmailTasks": {
|
|
127
175
|
request: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
|
|
128
176
|
response: z.ZodObject<{
|
|
@@ -7999,6 +8047,7 @@ export declare const callableGroups: {
|
|
|
7999
8047
|
oId: z.ZodString;
|
|
8000
8048
|
name: z.ZodString;
|
|
8001
8049
|
package: z.ZodString;
|
|
8050
|
+
products: z.ZodArray<z.ZodEnum<["wex", "employerEvents", "destinations"]>, "many">;
|
|
8002
8051
|
suggested: z.ZodBoolean;
|
|
8003
8052
|
reason: z.ZodOptional<z.ZodString>;
|
|
8004
8053
|
flags: z.ZodArray<z.ZodEnum<["noContacts", "noRenewalDate", "noQuote", "noFinanceContact", "sentRecently"]>, "many">;
|
|
@@ -8012,6 +8061,7 @@ export declare const callableGroups: {
|
|
|
8012
8061
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
8013
8062
|
contacts: number;
|
|
8014
8063
|
params: Record<string, string>;
|
|
8064
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
8015
8065
|
suggested: boolean;
|
|
8016
8066
|
reason?: string | undefined;
|
|
8017
8067
|
lastSent?: string | undefined;
|
|
@@ -8022,6 +8072,7 @@ export declare const callableGroups: {
|
|
|
8022
8072
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
8023
8073
|
contacts: number;
|
|
8024
8074
|
params: Record<string, string>;
|
|
8075
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
8025
8076
|
suggested: boolean;
|
|
8026
8077
|
reason?: string | undefined;
|
|
8027
8078
|
lastSent?: string | undefined;
|
|
@@ -8034,6 +8085,7 @@ export declare const callableGroups: {
|
|
|
8034
8085
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
8035
8086
|
contacts: number;
|
|
8036
8087
|
params: Record<string, string>;
|
|
8088
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
8037
8089
|
suggested: boolean;
|
|
8038
8090
|
reason?: string | undefined;
|
|
8039
8091
|
lastSent?: string | undefined;
|
|
@@ -8046,6 +8098,7 @@ export declare const callableGroups: {
|
|
|
8046
8098
|
flags: ("noContacts" | "noRenewalDate" | "noQuote" | "noFinanceContact" | "sentRecently")[];
|
|
8047
8099
|
contacts: number;
|
|
8048
8100
|
params: Record<string, string>;
|
|
8101
|
+
products: ("employerEvents" | "wex" | "destinations")[];
|
|
8049
8102
|
suggested: boolean;
|
|
8050
8103
|
reason?: string | undefined;
|
|
8051
8104
|
lastSent?: string | undefined;
|
|
@@ -8098,6 +8151,49 @@ export declare const callableGroups: {
|
|
|
8098
8151
|
}>;
|
|
8099
8152
|
}>;
|
|
8100
8153
|
};
|
|
8154
|
+
"bulkEngagement-sendBulkEngagementTest": {
|
|
8155
|
+
request: z.ZodObject<{
|
|
8156
|
+
templateKey: z.ZodString;
|
|
8157
|
+
oIds: z.ZodArray<z.ZodString, "many">;
|
|
8158
|
+
subject: z.ZodString;
|
|
8159
|
+
body: z.ZodArray<z.ZodUnknown, "many">;
|
|
8160
|
+
heroImage: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | undefined, string | null | undefined>;
|
|
8161
|
+
}, "strip", z.ZodTypeAny, {
|
|
8162
|
+
body: unknown[];
|
|
8163
|
+
subject: string;
|
|
8164
|
+
templateKey: string;
|
|
8165
|
+
oIds: string[];
|
|
8166
|
+
heroImage?: string | undefined;
|
|
8167
|
+
}, {
|
|
8168
|
+
body: unknown[];
|
|
8169
|
+
subject: string;
|
|
8170
|
+
templateKey: string;
|
|
8171
|
+
oIds: string[];
|
|
8172
|
+
heroImage?: string | null | undefined;
|
|
8173
|
+
}>;
|
|
8174
|
+
response: z.ZodObject<{
|
|
8175
|
+
results: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
8176
|
+
sent: z.ZodArray<z.ZodString, "many">;
|
|
8177
|
+
error: z.ZodOptional<z.ZodString>;
|
|
8178
|
+
}, "strip", z.ZodTypeAny, {
|
|
8179
|
+
sent: string[];
|
|
8180
|
+
error?: string | undefined;
|
|
8181
|
+
}, {
|
|
8182
|
+
sent: string[];
|
|
8183
|
+
error?: string | undefined;
|
|
8184
|
+
}>>;
|
|
8185
|
+
}, "strip", z.ZodTypeAny, {
|
|
8186
|
+
results: Record<string, {
|
|
8187
|
+
sent: string[];
|
|
8188
|
+
error?: string | undefined;
|
|
8189
|
+
}>;
|
|
8190
|
+
}, {
|
|
8191
|
+
results: Record<string, {
|
|
8192
|
+
sent: string[];
|
|
8193
|
+
error?: string | undefined;
|
|
8194
|
+
}>;
|
|
8195
|
+
}>;
|
|
8196
|
+
};
|
|
8101
8197
|
"bulkEngagement-clearRenewalEmailTasks": {
|
|
8102
8198
|
request: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
|
|
8103
8199
|
response: z.ZodObject<{
|
package/package.json
CHANGED
|
@@ -3,7 +3,15 @@ jest.mock("./firebase/firebaseQuery", () => ({__esModule: true, default: class {
|
|
|
3
3
|
|
|
4
4
|
import {InstituteData} from "./typeDefinitions";
|
|
5
5
|
import {resolveProducts} from "./productResolver";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
BULK_ENGAGEMENT_PACKAGE_LABELS,
|
|
8
|
+
BULK_ENGAGEMENT_PRODUCTS,
|
|
9
|
+
BULK_ENGAGEMENT_PRODUCT_LABELS,
|
|
10
|
+
BULK_TEST_SCHOOLS,
|
|
11
|
+
bulkEngagementSuggestion,
|
|
12
|
+
matchesBulkFilters,
|
|
13
|
+
} from "./bulkEngagement";
|
|
14
|
+
import {engagementCallables} from "./callables/engagement";
|
|
7
15
|
|
|
8
16
|
const school = (renewalDate?: string, overrides: Partial<InstituteData> = {}): InstituteData => ({
|
|
9
17
|
name: "Calder Park Academy",
|
|
@@ -70,3 +78,69 @@ describe("bulk engagement suggestions", () => {
|
|
|
70
78
|
expect(suggest("engagementPickFeatures", school(), "2026-11-04", {nextOnboardingTemplate: "engagementPlanYear"}).suggested).toBe(false);
|
|
71
79
|
});
|
|
72
80
|
});
|
|
81
|
+
|
|
82
|
+
describe("matchesBulkFilters", () => {
|
|
83
|
+
const trust = {package: "institutes-two", products: ["wex", "destinations"]};
|
|
84
|
+
const hub = {package: "careersHub", products: ["employerEvents"]};
|
|
85
|
+
const none = {package: "institutes-one", products: []};
|
|
86
|
+
|
|
87
|
+
it("matches everything when nothing is ticked", () => {
|
|
88
|
+
[trust, hub, none].forEach((s) => expect(matchesBulkFilters(s, {packages: [], products: []})).toBe(true));
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("matches a package that is one of those ticked", () => {
|
|
92
|
+
const packages = ["institutes-two", "careersHub"];
|
|
93
|
+
expect(matchesBulkFilters(trust, {packages, products: []})).toBe(true);
|
|
94
|
+
expect(matchesBulkFilters(hub, {packages, products: []})).toBe(true);
|
|
95
|
+
expect(matchesBulkFilters(none, {packages, products: []})).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("matches a school with any of the products ticked, not all of them", () => {
|
|
99
|
+
expect(matchesBulkFilters(trust, {packages: [], products: ["destinations", "employerEvents"]})).toBe(true);
|
|
100
|
+
expect(matchesBulkFilters(trust, {packages: [], products: ["employerEvents"]})).toBe(false);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("never matches a school with no products once a product is ticked", () => {
|
|
104
|
+
expect(matchesBulkFilters(none, {packages: [], products: ["wex"]})).toBe(false);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("needs both filters to pass", () => {
|
|
108
|
+
expect(matchesBulkFilters(trust, {packages: ["institutes-two"], products: ["wex"]})).toBe(true);
|
|
109
|
+
expect(matchesBulkFilters(trust, {packages: ["careersHub"], products: ["wex"]})).toBe(false);
|
|
110
|
+
expect(matchesBulkFilters(trust, {packages: ["institutes-two"], products: ["employerEvents"]})).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("labels every package and product in sentence case", () => {
|
|
114
|
+
expect(BULK_ENGAGEMENT_PACKAGE_LABELS).toEqual({
|
|
115
|
+
"institutes-one": "School",
|
|
116
|
+
"institutes-two": "Trust",
|
|
117
|
+
"careersHub": "Careers hub",
|
|
118
|
+
"careersSchool": "Hub school",
|
|
119
|
+
});
|
|
120
|
+
expect(BULK_ENGAGEMENT_PRODUCTS.map((p) => BULK_ENGAGEMENT_PRODUCT_LABELS[p])).toEqual(["Work experience", "Employer events", "Destinations"]);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("offers products that resolveProducts sets", () => {
|
|
124
|
+
const products = resolveProducts({package: "careersHub", workExperience: true});
|
|
125
|
+
expect(BULK_ENGAGEMENT_PRODUCTS.filter((p) => products[p])).toEqual(["employerEvents"]);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe("sendBulkEngagementTest contract", () => {
|
|
130
|
+
const request = (count: number) => ({
|
|
131
|
+
templateKey: "engagementRenewalDue",
|
|
132
|
+
oIds: Array.from({length: count}, (_, i) => `school-${i}`),
|
|
133
|
+
subject: "Renewing",
|
|
134
|
+
body: [{type: "paragraph"}],
|
|
135
|
+
});
|
|
136
|
+
const contract = engagementCallables["bulkEngagement-sendBulkEngagementTest"].request;
|
|
137
|
+
|
|
138
|
+
it("takes up to BULK_TEST_SCHOOLS schools and no more", () => {
|
|
139
|
+
expect(contract.safeParse(request(BULK_TEST_SCHOOLS)).success).toBe(true);
|
|
140
|
+
expect(contract.safeParse(request(BULK_TEST_SCHOOLS + 1)).success).toBe(false);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("has no way to name a recipient", () => {
|
|
144
|
+
expect(contract.parse({...request(1), to: "someone@school.sch.uk"})).not.toHaveProperty("to");
|
|
145
|
+
});
|
|
146
|
+
});
|
package/src/bulkEngagement.ts
CHANGED
|
@@ -25,6 +25,34 @@ export const BULK_ENGAGEMENT_FLAG_LABELS: Record<BulkEngagementFlag, string> = {
|
|
|
25
25
|
/** Flags that stop a school being sent the email at all. */
|
|
26
26
|
export const BULK_ENGAGEMENT_BLOCKING_FLAGS: BulkEngagementFlag[] = ["noContacts"];
|
|
27
27
|
|
|
28
|
+
/** The account types the send popup filters by, and what it calls them. */
|
|
29
|
+
export const BULK_ENGAGEMENT_PACKAGE_LABELS: {[pkg: string]: string} = {
|
|
30
|
+
"institutes-one": "School",
|
|
31
|
+
"institutes-two": "Trust",
|
|
32
|
+
"careersHub": "Careers hub",
|
|
33
|
+
"careersSchool": "Hub school",
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** The products the send popup filters by. Flags on ResolvedProducts. */
|
|
37
|
+
export type BulkEngagementProduct = "wex"|"employerEvents"|"destinations";
|
|
38
|
+
|
|
39
|
+
export const BULK_ENGAGEMENT_PRODUCTS: BulkEngagementProduct[] = ["wex", "employerEvents", "destinations"];
|
|
40
|
+
|
|
41
|
+
export const BULK_ENGAGEMENT_PRODUCT_LABELS: Record<BulkEngagementProduct, string> = {
|
|
42
|
+
wex: "Work experience",
|
|
43
|
+
employerEvents: "Employer events",
|
|
44
|
+
destinations: "Destinations",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** What the admin has ticked in the send popup's filters. Empty means any. */
|
|
48
|
+
export type BulkEngagementFilters = {packages: string[], products: string[]};
|
|
49
|
+
|
|
50
|
+
/** Who the popup's "Send test" goes to. Fixed on the server, never taken from the request. */
|
|
51
|
+
export const BULK_TEST_RECIPIENT = "tom@careerthread.co.uk";
|
|
52
|
+
|
|
53
|
+
/** How many schools' copies one test sends. Matches the cap in the callable's contract. */
|
|
54
|
+
export const BULK_TEST_SCHOOLS = 3;
|
|
55
|
+
|
|
28
56
|
/** A school that had this email this recently isn't suggested it again. */
|
|
29
57
|
export const RECENTLY_SENT_DAYS = 60;
|
|
30
58
|
|
|
@@ -98,3 +126,19 @@ export const bulkEngagementSuggestion = (templateKey: string, school: BulkEngage
|
|
|
98
126
|
if (days === undefined || days < window[0] || days > window[1]) return none;
|
|
99
127
|
return {suggested: true, reason: `Renews in ${days} days`, flags};
|
|
100
128
|
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Whether a school passes the send popup's filters: its package is one of
|
|
132
|
+
* those ticked, and it has any of the products ticked. An empty filter
|
|
133
|
+
* matches everything.
|
|
134
|
+
*
|
|
135
|
+
* @param {object} school the school's package and products.
|
|
136
|
+
* @param {BulkEngagementFilters} filters what is ticked.
|
|
137
|
+
* @return {boolean} whether the school matches.
|
|
138
|
+
*/
|
|
139
|
+
export const matchesBulkFilters = (
|
|
140
|
+
school: {package: string, products: string[]},
|
|
141
|
+
{packages, products}: BulkEngagementFilters,
|
|
142
|
+
): boolean =>
|
|
143
|
+
(!packages.length || packages.includes(school.package)) &&
|
|
144
|
+
(!products.length || products.some((p) => school.products.includes(p)));
|
|
@@ -11,6 +11,7 @@ import {CallableGroup, optionalField} from "./types";
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
const flag = z.enum(["noContacts", "noRenewalDate", "noQuote", "noFinanceContact", "sentRecently"]);
|
|
14
|
+
const product = z.enum(["wex", "employerEvents", "destinations"]);
|
|
14
15
|
|
|
15
16
|
export const engagementCallables = {
|
|
16
17
|
"bulkEngagement-getBulkEngagementSchools": {
|
|
@@ -23,6 +24,8 @@ export const engagementCallables = {
|
|
|
23
24
|
oId: z.string(),
|
|
24
25
|
name: z.string(),
|
|
25
26
|
package: z.string(),
|
|
27
|
+
/** The products the admin can filter this school by. */
|
|
28
|
+
products: z.array(product),
|
|
26
29
|
suggested: z.boolean(),
|
|
27
30
|
reason: z.string().optional(),
|
|
28
31
|
flags: z.array(flag),
|
|
@@ -52,6 +55,23 @@ export const engagementCallables = {
|
|
|
52
55
|
results: z.record(z.string(), z.object({sent: z.array(z.string()), error: z.string().optional()})),
|
|
53
56
|
}),
|
|
54
57
|
},
|
|
58
|
+
/**
|
|
59
|
+
* Sends each school's copy of the email to CareerThread's test address, so
|
|
60
|
+
* it can be read before the real send. Nothing is logged on the school or
|
|
61
|
+
* changed on it, and no follow-ups start. The address is set on the server.
|
|
62
|
+
*/
|
|
63
|
+
"bulkEngagement-sendBulkEngagementTest": {
|
|
64
|
+
request: z.object({
|
|
65
|
+
templateKey: z.string().min(1),
|
|
66
|
+
oIds: z.array(z.string().min(1)).min(1, "Pick at least one school.").max(3),
|
|
67
|
+
subject: z.string().trim().min(1, "Give it a subject."),
|
|
68
|
+
body: z.array(z.unknown()).min(1),
|
|
69
|
+
heroImage: optionalField(z.string()),
|
|
70
|
+
}),
|
|
71
|
+
response: z.object({
|
|
72
|
+
results: z.record(z.string(), z.object({sent: z.array(z.string()), error: z.string().optional()})),
|
|
73
|
+
}),
|
|
74
|
+
},
|
|
55
75
|
/** One-off: removes the open renewal email tasks the old automatic schedule made. */
|
|
56
76
|
"bulkEngagement-clearRenewalEmailTasks": {
|
|
57
77
|
request: z.object({}).optional(),
|