placementt-core 1.400.933 → 1.400.935

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.
@@ -19,7 +19,53 @@ export type ChecklistItem = {
19
19
  oId: string;
20
20
  name: string;
21
21
  status: ChecklistItemStatus;
22
+ packageFormat?: OnboardingPackFormat;
23
+ packageItems?: string[];
24
+ productTypes?: OnboardingProductType[];
25
+ address?: string;
22
26
  };
27
+ export type OnboardingPackFormat = "box" | "A4 letter";
28
+ export type OnboardingProductType = "careersHub" | "careersHubSchool" | "trust" | "workExperience" | "employerEvents" | "destinations";
29
+ export type OnboardingProductPack = {
30
+ format: OnboardingPackFormat;
31
+ /** Product-specific items only — universal items are added automatically. */
32
+ items: string[];
33
+ };
34
+ export declare const ONBOARDING_BOX_UNIVERSAL_ITEMS: string[];
35
+ export declare const ONBOARDING_LETTER_UNIVERSAL_ITEMS: string[];
36
+ export declare const onboardingPackConfig: Record<OnboardingProductType, OnboardingProductPack>;
37
+ export type OnboardingInstituteInput = {
38
+ package?: string;
39
+ workExperience?: boolean;
40
+ employerEvents?: boolean;
41
+ destinationTracking?: boolean;
42
+ careersHubLinks?: {
43
+ [oId: string]: {
44
+ status?: string;
45
+ };
46
+ };
47
+ ["address-line1"]?: string;
48
+ ["address-line2"]?: string;
49
+ locality?: string;
50
+ postal_code?: string;
51
+ country?: string;
52
+ };
53
+ /** Which onboarding product types a given institute holds. */
54
+ export declare function getOnboardingProductTypes(ins: OnboardingInstituteInput): OnboardingProductType[];
55
+ export type OnboardingPackage = {
56
+ format: OnboardingPackFormat;
57
+ productTypes: OnboardingProductType[];
58
+ items: string[];
59
+ };
60
+ /**
61
+ * Build the single onboarding package for an institute.
62
+ * Returns null if the institute holds no relevant products.
63
+ * "Box wins": any box product upgrades the whole package to a box and the A4
64
+ * items (e.g. the hub one-pager) are merged in, de-duplicated.
65
+ */
66
+ export declare function buildOnboardingPackage(ins: OnboardingInstituteInput): OnboardingPackage | null;
67
+ /** Human-readable single-line address from institute fields. */
68
+ export declare function formatInstituteAddress(ins: OnboardingInstituteInput): string;
23
69
  export type PhoneCheckInCategory = "careersHub" | "trust" | "workExperience" | "employerEvents" | null;
24
70
  export type CustomerCareConfig = {
25
71
  seasonalTasks: SeasonalTaskConfig[];
@@ -1,9 +1,115 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.customerCareConfig = void 0;
3
+ exports.customerCareConfig = exports.onboardingPackConfig = exports.ONBOARDING_LETTER_UNIVERSAL_ITEMS = exports.ONBOARDING_BOX_UNIVERSAL_ITEMS = void 0;
4
+ exports.getOnboardingProductTypes = getOnboardingProductTypes;
5
+ exports.buildOnboardingPackage = buildOnboardingPackage;
6
+ exports.formatInstituteAddress = formatInstituteAddress;
4
7
  exports.resolveSeasonalDates = resolveSeasonalDates;
5
8
  exports.isInBlackout = isInBlackout;
6
9
  exports.getCheckInCategory = getCheckInCategory;
10
+ // Universal items every BOX contains, regardless of product.
11
+ exports.ONBOARDING_BOX_UNIVERSAL_ITEMS = [
12
+ "Handwritten A6 card",
13
+ "Sticky notes",
14
+ "Highlighter",
15
+ "2 pens",
16
+ "Sticker",
17
+ ];
18
+ // Universal items every A4 LETTER contains, regardless of product.
19
+ exports.ONBOARDING_LETTER_UNIVERSAL_ITEMS = [
20
+ "Handwritten A6 card",
21
+ ];
22
+ // TODO(customer-success): refine the exact leaflet names/contents per product.
23
+ exports.onboardingPackConfig = {
24
+ careersHubSchool: {
25
+ format: "A4 letter",
26
+ // Hub schools are just users of the hub product → information one-pager.
27
+ items: ["Careers Hub platform one-pager"],
28
+ },
29
+ careersHub: {
30
+ format: "box",
31
+ items: ["Careers Hub platform guide leaflet", "New features leaflet"],
32
+ },
33
+ trust: {
34
+ format: "box",
35
+ items: ["Trust platform guide leaflet", "New features leaflet"],
36
+ },
37
+ workExperience: {
38
+ format: "box",
39
+ items: ["Work Experience platform guide leaflet", "New features leaflet"],
40
+ },
41
+ employerEvents: {
42
+ format: "box",
43
+ items: ["Employer Events platform guide leaflet", "New features leaflet"],
44
+ },
45
+ destinations: {
46
+ format: "box",
47
+ items: ["Destinations platform guide leaflet", "New features leaflet"],
48
+ },
49
+ };
50
+ /** Which onboarding product types a given institute holds. */
51
+ function getOnboardingProductTypes(ins) {
52
+ const types = [];
53
+ if (ins.package === "careersHub")
54
+ types.push("careersHub");
55
+ const isHubSchool = ins.package === "careersSchool" ||
56
+ Object.values(ins.careersHubLinks || {}).some((l) => l.status === "approved");
57
+ if (isHubSchool)
58
+ types.push("careersHubSchool");
59
+ if (ins.package === "institutes-two")
60
+ types.push("trust");
61
+ // Add-on products apply whenever the flag is set (institutes-one or trusts).
62
+ if (ins.workExperience)
63
+ types.push("workExperience");
64
+ if (ins.employerEvents)
65
+ types.push("employerEvents");
66
+ if (ins.destinationTracking)
67
+ types.push("destinations");
68
+ return types;
69
+ }
70
+ // Case-insensitive, order-preserving de-duplication.
71
+ function dedupeItems(items) {
72
+ const seen = new Set();
73
+ const out = [];
74
+ for (const item of items) {
75
+ const key = item.trim().toLowerCase();
76
+ if (seen.has(key))
77
+ continue;
78
+ seen.add(key);
79
+ out.push(item);
80
+ }
81
+ return out;
82
+ }
83
+ /**
84
+ * Build the single onboarding package for an institute.
85
+ * Returns null if the institute holds no relevant products.
86
+ * "Box wins": any box product upgrades the whole package to a box and the A4
87
+ * items (e.g. the hub one-pager) are merged in, de-duplicated.
88
+ */
89
+ function buildOnboardingPackage(ins) {
90
+ const productTypes = getOnboardingProductTypes(ins);
91
+ if (productTypes.length === 0)
92
+ return null;
93
+ const isBox = productTypes.some((t) => exports.onboardingPackConfig[t].format === "box");
94
+ const format = isBox ? "box" : "A4 letter";
95
+ const universal = isBox ? exports.ONBOARDING_BOX_UNIVERSAL_ITEMS : exports.ONBOARDING_LETTER_UNIVERSAL_ITEMS;
96
+ const productItems = productTypes.flatMap((t) => exports.onboardingPackConfig[t].items);
97
+ return {
98
+ format,
99
+ productTypes,
100
+ items: dedupeItems([...universal, ...productItems]),
101
+ };
102
+ }
103
+ /** Human-readable single-line address from institute fields. */
104
+ function formatInstituteAddress(ins) {
105
+ return [
106
+ ins["address-line1"],
107
+ ins["address-line2"],
108
+ ins.locality,
109
+ ins.postal_code,
110
+ ins.country,
111
+ ].filter(Boolean).join(", ");
112
+ }
7
113
  exports.customerCareConfig = {
8
114
  seasonalTasks: [
9
115
  {
@@ -21,6 +127,15 @@ exports.customerCareConfig = {
21
127
  createAtMMDD: "03-09",
22
128
  description: "Send Easter eggs to admin staff at every active school.",
23
129
  },
130
+ {
131
+ // Start-of-year onboarding packs. Created at the start of August so
132
+ // there's time to prepare; should be sent by the start of term.
133
+ id: "onboardingPacks",
134
+ name: "Onboarding Packs",
135
+ deadlineMMDD: "09-15",
136
+ createAtMMDD: "08-01",
137
+ description: "Send the start-of-year onboarding pack (box or A4 letter) to every active customer. Each school's exact contents and format are listed against it.",
138
+ },
24
139
  ],
25
140
  phoneCheckIn: {
26
141
  careersHub: { intervalDays: 42, label: "Careers Hub" },
@@ -1 +1 @@
1
- {"version":3,"file":"customerCareConfig.js","sourceRoot":"","sources":["../src/customerCareConfig.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"customerCareConfig.js","sourceRoot":"","sources":["../src/customerCareConfig.ts"],"names":[],"mappings":"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"}
@@ -397,6 +397,7 @@ export type UserData = {
397
397
  groupData?: UserGroupData;
398
398
  staffRoles: string[];
399
399
  flags?: FlagCodes[];
400
+ keyContact?: boolean;
400
401
  cohortRequests: {
401
402
  [oId: string]: string[];
402
403
  };
@@ -525,6 +526,7 @@ export type DataViewerFilterView = {
525
526
  sort?: string;
526
527
  filters?: FilterObject;
527
528
  columns?: string[];
529
+ viewType?: "list" | "table";
528
530
  permanent?: boolean;
529
531
  };
530
532
  export type AnalyticsItem = {
@@ -3037,7 +3039,7 @@ export type SupportTask = {
3037
3039
  assignee: string;
3038
3040
  commId?: string;
3039
3041
  commType?: "leads" | "users";
3040
- source?: "customerQuery" | "general" | "seasonalTask";
3042
+ source?: "customerQuery" | "general" | "seasonalTask" | "onboardingPack";
3041
3043
  dueAt: string;
3042
3044
  inbox?: SupportInbox;
3043
3045
  messageId?: string;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "private": false,
3
3
  "name": "placementt-core",
4
4
  "author": "Placementt",
5
- "version": "1.400.933",
5
+ "version": "1.400.935",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
8
8
  "scripts": {
@@ -25,8 +25,178 @@ export type ChecklistItem = {
25
25
  oId: string;
26
26
  name: string;
27
27
  status: ChecklistItemStatus;
28
+ // ── Onboarding-pack extras (only populated on onboardingPack tasks) ──
29
+ // The package contents are baked in at task-creation time so the
30
+ // customer-success team always sees exactly what to pack, even if the
31
+ // institute's products change later.
32
+ packageFormat?: OnboardingPackFormat;
33
+ packageItems?: string[];
34
+ productTypes?: OnboardingProductType[];
35
+ address?: string;
28
36
  };
29
37
 
38
+ // ─── Onboarding packs ─────────────────────────────────────────────────────────
39
+ // Hardcoded definition of what goes into each customer's onboarding pack.
40
+ // Keyed by product type; each entry declares the package format and the
41
+ // product-specific items (universal items are added by buildOnboardingPackage).
42
+ //
43
+ // Rules (see buildOnboardingPackage):
44
+ // - "box" always wins: if a school holds any box product, it gets a single box
45
+ // and every product's specific items are merged in (de-duplicated).
46
+ // - A school that is *only* a hub-linked school gets an A4 letter. The moment
47
+ // they hold any higher package it becomes a box, and the A4 hub one-pager is
48
+ // folded into the box (de-duplicated).
49
+
50
+ export type OnboardingPackFormat = "box" | "A4 letter";
51
+
52
+ // The six product types a customer can hold for onboarding-pack purposes.
53
+ // (Distinct from CustomerProductType because it also covers "destinations".)
54
+ export type OnboardingProductType =
55
+ | "careersHub" // package === "careersHub" (the hub itself)
56
+ | "careersHubSchool" // careersHubLinks approved (a school using a hub)
57
+ | "trust" // package === "institutes-two"
58
+ | "workExperience" // workExperience flag
59
+ | "employerEvents" // employerEvents flag
60
+ | "destinations"; // destinationTracking flag
61
+
62
+ export type OnboardingProductPack = {
63
+ format: OnboardingPackFormat;
64
+ /** Product-specific items only — universal items are added automatically. */
65
+ items: string[];
66
+ };
67
+
68
+ // Universal items every BOX contains, regardless of product.
69
+ export const ONBOARDING_BOX_UNIVERSAL_ITEMS: string[] = [
70
+ "Handwritten A6 card",
71
+ "Sticky notes",
72
+ "Highlighter",
73
+ "2 pens",
74
+ "Sticker",
75
+ ];
76
+
77
+ // Universal items every A4 LETTER contains, regardless of product.
78
+ export const ONBOARDING_LETTER_UNIVERSAL_ITEMS: string[] = [
79
+ "Handwritten A6 card",
80
+ ];
81
+
82
+ // TODO(customer-success): refine the exact leaflet names/contents per product.
83
+ export const onboardingPackConfig: Record<OnboardingProductType, OnboardingProductPack> = {
84
+ careersHubSchool: {
85
+ format: "A4 letter",
86
+ // Hub schools are just users of the hub product → information one-pager.
87
+ items: ["Careers Hub platform one-pager"],
88
+ },
89
+ careersHub: {
90
+ format: "box",
91
+ items: ["Careers Hub platform guide leaflet", "New features leaflet"],
92
+ },
93
+ trust: {
94
+ format: "box",
95
+ items: ["Trust platform guide leaflet", "New features leaflet"],
96
+ },
97
+ workExperience: {
98
+ format: "box",
99
+ items: ["Work Experience platform guide leaflet", "New features leaflet"],
100
+ },
101
+ employerEvents: {
102
+ format: "box",
103
+ items: ["Employer Events platform guide leaflet", "New features leaflet"],
104
+ },
105
+ destinations: {
106
+ format: "box",
107
+ items: ["Destinations platform guide leaflet", "New features leaflet"],
108
+ },
109
+ };
110
+
111
+ // Minimal shape of the institute fields we read — declared locally to avoid a
112
+ // circular import with typeDefinitions (which imports ChecklistItem from here).
113
+ export type OnboardingInstituteInput = {
114
+ package?: string;
115
+ workExperience?: boolean;
116
+ employerEvents?: boolean;
117
+ destinationTracking?: boolean;
118
+ careersHubLinks?: {[oId: string]: {status?: string}};
119
+ ["address-line1"]?: string;
120
+ ["address-line2"]?: string;
121
+ locality?: string;
122
+ postal_code?: string;
123
+ country?: string;
124
+ };
125
+
126
+ /** Which onboarding product types a given institute holds. */
127
+ export function getOnboardingProductTypes(ins: OnboardingInstituteInput): OnboardingProductType[] {
128
+ const types: OnboardingProductType[] = [];
129
+
130
+ if (ins.package === "careersHub") types.push("careersHub");
131
+
132
+ const isHubSchool =
133
+ ins.package === "careersSchool" ||
134
+ Object.values(ins.careersHubLinks || {}).some((l) => l.status === "approved");
135
+ if (isHubSchool) types.push("careersHubSchool");
136
+
137
+ if (ins.package === "institutes-two") types.push("trust");
138
+
139
+ // Add-on products apply whenever the flag is set (institutes-one or trusts).
140
+ if (ins.workExperience) types.push("workExperience");
141
+ if (ins.employerEvents) types.push("employerEvents");
142
+ if (ins.destinationTracking) types.push("destinations");
143
+
144
+ return types;
145
+ }
146
+
147
+ // Case-insensitive, order-preserving de-duplication.
148
+ function dedupeItems(items: string[]): string[] {
149
+ const seen = new Set<string>();
150
+ const out: string[] = [];
151
+ for (const item of items) {
152
+ const key = item.trim().toLowerCase();
153
+ if (seen.has(key)) continue;
154
+ seen.add(key);
155
+ out.push(item);
156
+ }
157
+ return out;
158
+ }
159
+
160
+ export type OnboardingPackage = {
161
+ format: OnboardingPackFormat;
162
+ productTypes: OnboardingProductType[];
163
+ items: string[];
164
+ };
165
+
166
+ /**
167
+ * Build the single onboarding package for an institute.
168
+ * Returns null if the institute holds no relevant products.
169
+ * "Box wins": any box product upgrades the whole package to a box and the A4
170
+ * items (e.g. the hub one-pager) are merged in, de-duplicated.
171
+ */
172
+ export function buildOnboardingPackage(ins: OnboardingInstituteInput): OnboardingPackage | null {
173
+ const productTypes = getOnboardingProductTypes(ins);
174
+ if (productTypes.length === 0) return null;
175
+
176
+ const isBox = productTypes.some((t) => onboardingPackConfig[t].format === "box");
177
+ const format: OnboardingPackFormat = isBox ? "box" : "A4 letter";
178
+
179
+ const universal = isBox ? ONBOARDING_BOX_UNIVERSAL_ITEMS : ONBOARDING_LETTER_UNIVERSAL_ITEMS;
180
+ const productItems = productTypes.flatMap((t) => onboardingPackConfig[t].items);
181
+
182
+ return {
183
+ format,
184
+ productTypes,
185
+ items: dedupeItems([...universal, ...productItems]),
186
+ };
187
+ }
188
+
189
+ /** Human-readable single-line address from institute fields. */
190
+ export function formatInstituteAddress(ins: OnboardingInstituteInput): string {
191
+ return [
192
+ ins["address-line1"],
193
+ ins["address-line2"],
194
+ ins.locality,
195
+ ins.postal_code,
196
+ ins.country,
197
+ ].filter(Boolean).join(", ");
198
+ }
199
+
30
200
  export type PhoneCheckInCategory = "careersHub" | "trust" | "workExperience" | "employerEvents" | null;
31
201
 
32
202
  export type CustomerCareConfig = {
@@ -57,6 +227,15 @@ export const customerCareConfig: CustomerCareConfig = {
57
227
  createAtMMDD: "03-09",
58
228
  description: "Send Easter eggs to admin staff at every active school.",
59
229
  },
230
+ {
231
+ // Start-of-year onboarding packs. Created at the start of August so
232
+ // there's time to prepare; should be sent by the start of term.
233
+ id: "onboardingPacks",
234
+ name: "Onboarding Packs",
235
+ deadlineMMDD: "09-15",
236
+ createAtMMDD: "08-01",
237
+ description: "Send the start-of-year onboarding pack (box or A4 letter) to every active customer. Each school's exact contents and format are listed against it.",
238
+ },
60
239
  ],
61
240
  phoneCheckIn: {
62
241
  careersHub: {intervalDays: 42, label: "Careers Hub"},
@@ -407,6 +407,7 @@ export type UserData = {
407
407
  groupData?: UserGroupData,
408
408
  staffRoles: string[],
409
409
  flags?: FlagCodes[],
410
+ keyContact?: boolean, // Staff member who should receive customer-success packages (e.g. onboarding packs)
410
411
  cohortRequests: {[oId: string]: string[]},
411
412
  cohorts: {[oId: string]: string[]},
412
413
  analytics?: AnalyticsItem,
@@ -523,6 +524,7 @@ export type DataViewerFilterView = {
523
524
  sort?: string,
524
525
  filters?: FilterObject,
525
526
  columns?: string[],
527
+ viewType?: "list"|"table",
526
528
  permanent?: boolean,
527
529
  }
528
530
 
@@ -3017,7 +3019,7 @@ export type SupportTask = {
3017
3019
  assignee: string; // uid of the assigned team member
3018
3020
  commId?: string; // optional link to a Communication doc
3019
3021
  commType?: "leads" | "users"; // collection the comm lives in
3020
- source?: "customerQuery" | "general" | "seasonalTask";
3022
+ source?: "customerQuery" | "general" | "seasonalTask" | "onboardingPack";
3021
3023
  dueAt: string; // ISO string
3022
3024
  inbox?: SupportInbox; // which task inbox triggered this (absent for non-email tasks)
3023
3025
  messageId?: string; // Graph message ID — used to prevent duplicates