placementt-core 1.400.995 → 1.400.997

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.
@@ -9,6 +9,10 @@
9
9
  * A rule is year-agnostic; it resolves into a concrete date for a given academic
10
10
  * year (each September) via surveyRuleToMMDD / surveyRuleToDate.
11
11
  *
12
+ * It also answers WHICH academic year to resolve against — programmeStartYear, at the
13
+ * foot of this file. Provisioning and the staff year tabs both ask it, so they cannot
14
+ * disagree about the year a school is on.
15
+ *
12
16
  * ── One academic-year boundary: 1 September ───────────────────────────────────
13
17
  * Everything here derives the academic year the same way — currentAcademicStartYear,
14
18
  * and academicYearOf which labels it. September to August is one academic year.
@@ -24,8 +28,8 @@
24
28
  * • the two legacy derivations must be replaced by academicYearOf when their
25
29
  * callers move onto the engine, so new writes agree with migrated ones.
26
30
  */
27
- import type { SurveyDateRule, SurveyOrdinal, SurveyWeekday } from "../typeDefinitions";
28
- import type { SurveySlot } from "./types";
31
+ import type { DestinationsConfig, InstituteData, SurveyDateRule, SurveyOrdinal, SurveyWeekday } from "../typeDefinitions";
32
+ import type { SurveyCohortScope, SurveyKind, SurveySlot } from "./types";
29
33
  /** "MM-DD" for a date, in local time — the format survey slots are stored in. */
30
34
  export declare const toMMDD: (date?: Date) => string;
31
35
  /**
@@ -100,3 +104,61 @@ export declare const resolveSlotsForYear: (slots: SurveySlot[] | undefined, acad
100
104
  * provisioned) — whether it SENDS is the cycle's autoSend flag, checked by the cron.
101
105
  */
102
106
  export declare const isSlotDueOn: (slot: SurveySlot, date?: Date) => boolean;
107
+ /** One leaver leg resolved for one year group in one academic year. */
108
+ export type ResolvedLeaverLeg = {
109
+ kind: SurveyKind;
110
+ yearGroup: string;
111
+ /** MM-DD the CONFIG resolves to — what provisioning keys its cycle id on, so a
112
+ * cycle staff have since rescheduled is not re-created. */
113
+ sendMMDD: string;
114
+ sendISO: string;
115
+ /** The leg's own academic start year: the year after for the Christmas leg. */
116
+ startYear: number;
117
+ /** Every student in these groups leaves (no internal sixth form). */
118
+ allStudentsLeave?: boolean;
119
+ };
120
+ /**
121
+ * A year group's leaver legs for one academic year, in send order — exactly the legs
122
+ * provisioning creates cycles for, so the disabled ones and any that don't resolve to
123
+ * a real date are already dropped.
124
+ *
125
+ * A per-year-group override REPLACES the shared leaver fields: Y11 and Y13 differ
126
+ * (GCSE vs A-level results days, sixth-form stayers).
127
+ */
128
+ export declare const resolveLeaverLegsForYearGroup: (cfg: DestinationsConfig["leavers"], yearGroup: string, academicStartYear: number) => ResolvedLeaverLeg[];
129
+ /** The parts of an institute that schedule surveys — all these helpers read. */
130
+ export type SurveyProgrammeConfig = Pick<InstituteData, "destinationsConfig" | "skillsAssessments" | "skillsSurveys" | "skillsMappings">;
131
+ /**
132
+ * Every send date one programme is configured to fire in one academic year, ISO, in
133
+ * order. Empty when the programme is off or has no schedule — which is not the same as
134
+ * "finished", and callers treat it as "nothing to say".
135
+ *
136
+ * @param {SurveyProgrammeConfig} institute the school's setup.
137
+ * @param {SurveyCohortScope} scope which programme.
138
+ * @param {number} academicStartYear the year the academic year starts in.
139
+ * @return {string[]} ISO send datetimes, earliest first.
140
+ */
141
+ export declare const programmeSendDatesForYear: (institute: SurveyProgrammeConfig, scope: SurveyCohortScope, academicStartYear: number) => string[];
142
+ /**
143
+ * The academic year a programme should be laid out for, as its start year: the current
144
+ * one while any of its sends is still to come, the next one once they have all gone by.
145
+ *
146
+ * A programme with nothing configured stays on the current year — there is nothing to
147
+ * roll forward to, and the current year is still the one staff are working in.
148
+ *
149
+ * @param {SurveyProgrammeConfig} institute the school's setup.
150
+ * @param {SurveyCohortScope} scope which programme.
151
+ * @param {Date} [now] the moment to judge "still to come" against.
152
+ * @return {number} the year the academic year to provision starts in.
153
+ */
154
+ export declare const programmeStartYear: (institute: SurveyProgrammeConfig, scope: SurveyCohortScope, now?: Date) => number;
155
+ /**
156
+ * The academic-year LABEL a programme is on, hyphen form — what the staff year tabs
157
+ * key on. See programmeStartYear.
158
+ *
159
+ * @param {SurveyProgrammeConfig} institute the school's setup.
160
+ * @param {SurveyCohortScope} scope which programme.
161
+ * @param {Date} [now] the moment to judge "still to come" against.
162
+ * @return {string} e.g. "2026-27".
163
+ */
164
+ export declare const programmeAcademicYear: (institute: SurveyProgrammeConfig, scope: SurveyCohortScope, now?: Date) => string;
@@ -10,6 +10,10 @@
10
10
  * A rule is year-agnostic; it resolves into a concrete date for a given academic
11
11
  * year (each September) via surveyRuleToMMDD / surveyRuleToDate.
12
12
  *
13
+ * It also answers WHICH academic year to resolve against — programmeStartYear, at the
14
+ * foot of this file. Provisioning and the staff year tabs both ask it, so they cannot
15
+ * disagree about the year a school is on.
16
+ *
13
17
  * ── One academic-year boundary: 1 September ───────────────────────────────────
14
18
  * Everything here derives the academic year the same way — currentAcademicStartYear,
15
19
  * and academicYearOf which labels it. September to August is one academic year.
@@ -26,7 +30,7 @@
26
30
  * callers move onto the engine, so new writes agree with migrated ones.
27
31
  */
28
32
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.isSlotDueOn = exports.resolveSlotsForYear = exports.slotMMDDForYear = exports.mmddToISO = exports.surveyRuleToMMDD = exports.surveyRuleToDate = exports.resolveNthWeekday = exports.normaliseAcademicYear = exports.academicYearSlashLabel = exports.academicYearOf = exports.academicYearLabel = exports.currentAcademicStartYear = exports.academicCalendarYear = exports.toMMDD = void 0;
33
+ exports.programmeAcademicYear = exports.programmeStartYear = exports.programmeSendDatesForYear = exports.resolveLeaverLegsForYearGroup = exports.isSlotDueOn = exports.resolveSlotsForYear = exports.slotMMDDForYear = exports.mmddToISO = exports.surveyRuleToMMDD = exports.surveyRuleToDate = exports.resolveNthWeekday = exports.normaliseAcademicYear = exports.academicYearSlashLabel = exports.academicYearOf = exports.academicYearLabel = exports.currentAcademicStartYear = exports.academicCalendarYear = exports.toMMDD = void 0;
30
34
  const pad2 = (n) => String(n).padStart(2, "0");
31
35
  /** "MM-DD" for a date, in local time — the format survey slots are stored in. */
32
36
  const toMMDD = (date = new Date()) => `${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
@@ -145,4 +149,121 @@ exports.resolveSlotsForYear = resolveSlotsForYear;
145
149
  */
146
150
  const isSlotDueOn = (slot, date = new Date()) => (0, exports.slotMMDDForYear)(slot, (0, exports.currentAcademicStartYear)(date)) === (0, exports.toMMDD)(date);
147
151
  exports.isSlotDueOn = isSlotDueOn;
152
+ /**
153
+ * A year group's leaver legs for one academic year, in send order — exactly the legs
154
+ * provisioning creates cycles for, so the disabled ones and any that don't resolve to
155
+ * a real date are already dropped.
156
+ *
157
+ * A per-year-group override REPLACES the shared leaver fields: Y11 and Y13 differ
158
+ * (GCSE vs A-level results days, sixth-form stayers).
159
+ */
160
+ const resolveLeaverLegsForYearGroup = (cfg, yearGroup, academicStartYear) => {
161
+ const override = cfg.byYearGroup?.[String(yearGroup)];
162
+ const resultsCfg = override?.resultsDay ?? cfg.resultsDay;
163
+ const christmasCfg = override?.christmas ?? cfg.christmas;
164
+ const allStudentsLeave = override?.allStudentsLeave ?? cfg.allStudentsLeave;
165
+ const legs = [
166
+ {
167
+ kind: "leaverIntentions",
168
+ mmdd: override?.intentionsSendMMDD ?? cfg.intentionsSendMMDD,
169
+ rule: override?.intentionsRule ?? cfg.intentionsRule,
170
+ enabled: true,
171
+ },
172
+ { kind: "leaverResults", mmdd: resultsCfg?.sendMMDD ?? "", rule: resultsCfg?.rule, enabled: Boolean(resultsCfg?.enabled) },
173
+ { kind: "leaverChristmas", mmdd: christmasCfg?.sendMMDD ?? "", rule: christmasCfg?.rule, enabled: Boolean(christmasCfg?.enabled) },
174
+ ];
175
+ return legs.flatMap((leg) => {
176
+ // A 2026/27 cohort sits its exams in June 2027 and gets its results that August,
177
+ // but its Christmas check-in is December 2027 — the winter AFTER it leaves, which
178
+ // falls in the next academic year. Resolving it against this academic year would
179
+ // date it December 2026, six months BEFORE the intentions form. The cycle still
180
+ // carries the cohort's academic year, so the three legs stay one journey.
181
+ const startYear = leg.kind === "leaverChristmas" ? academicStartYear + 1 : academicStartYear;
182
+ // A rule is resolved against the leg's own year, so "third Thursday of August"
183
+ // lands on the right Thursday every year. The stored MM-DD is the fallback for
184
+ // configs written before leaver dates became rules.
185
+ const sendMMDD = leg.rule ? (0, exports.surveyRuleToMMDD)(leg.rule, startYear) : leg.mmdd;
186
+ if (!leg.enabled || !sendMMDD)
187
+ return [];
188
+ const sendISO = (0, exports.mmddToISO)(sendMMDD, startYear);
189
+ if (!sendISO)
190
+ return [];
191
+ return [{ kind: leg.kind, yearGroup, sendMMDD, sendISO, startYear, allStudentsLeave }];
192
+ });
193
+ };
194
+ exports.resolveLeaverLegsForYearGroup = resolveLeaverLegsForYearGroup;
195
+ /**
196
+ * Every send date one programme is configured to fire in one academic year, ISO, in
197
+ * order. Empty when the programme is off or has no schedule — which is not the same as
198
+ * "finished", and callers treat it as "nothing to say".
199
+ *
200
+ * @param {SurveyProgrammeConfig} institute the school's setup.
201
+ * @param {SurveyCohortScope} scope which programme.
202
+ * @param {number} academicStartYear the year the academic year starts in.
203
+ * @return {string[]} ISO send datetimes, earliest first.
204
+ */
205
+ const programmeSendDatesForYear = (institute, scope, academicStartYear) => {
206
+ const dates = [];
207
+ if (scope === "aspirations") {
208
+ const cfg = institute.destinationsConfig?.aspirations;
209
+ if (!cfg?.enabled || !cfg.yearGroups?.length)
210
+ return [];
211
+ for (const yearGroup of cfg.yearGroups) {
212
+ const slots = cfg.surveysByYearGroup?.[String(yearGroup)] ?? cfg.surveys ?? [];
213
+ dates.push(...(0, exports.resolveSlotsForYear)(slots, academicStartYear).map((s) => s.sendISO));
214
+ }
215
+ }
216
+ if (scope === "skills") {
217
+ if (!institute.skillsAssessments)
218
+ return [];
219
+ dates.push(...(0, exports.resolveSlotsForYear)(institute.skillsSurveys, academicStartYear).map((s) => s.sendISO));
220
+ for (const mapping of institute.skillsMappings ?? []) {
221
+ // A mapping with no filters matches nobody, so provisioning ignores it.
222
+ if (!Object.values(mapping.filters ?? {}).some((v) => v?.length))
223
+ continue;
224
+ dates.push(...(0, exports.resolveSlotsForYear)(mapping.surveys, academicStartYear).map((s) => s.sendISO));
225
+ }
226
+ }
227
+ if (scope === "leavers") {
228
+ const cfg = institute.destinationsConfig?.leavers;
229
+ if (!cfg?.enabled || !cfg.yearGroups?.length)
230
+ return [];
231
+ for (const yearGroup of cfg.yearGroups) {
232
+ dates.push(...(0, exports.resolveLeaverLegsForYearGroup)(cfg, String(yearGroup), academicStartYear).map((l) => l.sendISO));
233
+ }
234
+ }
235
+ return dates.sort((a, b) => a.localeCompare(b));
236
+ };
237
+ exports.programmeSendDatesForYear = programmeSendDatesForYear;
238
+ /**
239
+ * The academic year a programme should be laid out for, as its start year: the current
240
+ * one while any of its sends is still to come, the next one once they have all gone by.
241
+ *
242
+ * A programme with nothing configured stays on the current year — there is nothing to
243
+ * roll forward to, and the current year is still the one staff are working in.
244
+ *
245
+ * @param {SurveyProgrammeConfig} institute the school's setup.
246
+ * @param {SurveyCohortScope} scope which programme.
247
+ * @param {Date} [now] the moment to judge "still to come" against.
248
+ * @return {number} the year the academic year to provision starts in.
249
+ */
250
+ const programmeStartYear = (institute, scope, now = new Date()) => {
251
+ const startYear = (0, exports.currentAcademicStartYear)(now);
252
+ const dates = (0, exports.programmeSendDatesForYear)(institute, scope, startYear);
253
+ if (!dates.length)
254
+ return startYear;
255
+ return dates.some((iso) => new Date(iso) >= now) ? startYear : startYear + 1;
256
+ };
257
+ exports.programmeStartYear = programmeStartYear;
258
+ /**
259
+ * The academic-year LABEL a programme is on, hyphen form — what the staff year tabs
260
+ * key on. See programmeStartYear.
261
+ *
262
+ * @param {SurveyProgrammeConfig} institute the school's setup.
263
+ * @param {SurveyCohortScope} scope which programme.
264
+ * @param {Date} [now] the moment to judge "still to come" against.
265
+ * @return {string} e.g. "2026-27".
266
+ */
267
+ const programmeAcademicYear = (institute, scope, now = new Date()) => (0, exports.academicYearLabel)((0, exports.programmeStartYear)(institute, scope, now));
268
+ exports.programmeAcademicYear = programmeAcademicYear;
148
269
  //# sourceMappingURL=schedule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../src/surveys/schedule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../src/surveys/schedule.ts"],"names":[],"mappings":"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"}
@@ -128,6 +128,89 @@ describe("isSlotDueOn", () => {
128
128
  expect((0, schedule_1.isSlotDueOn)({ sendMMDD: (0, schedule_1.toMMDD)(date) }, date)).toEqual(true);
129
129
  });
130
130
  });
131
+ describe("resolveLeaverLegsForYearGroup", () => {
132
+ const leavers = {
133
+ enabled: true, yearGroups: ["13"], intentionsSendMMDD: "06-15",
134
+ resultsDay: { enabled: true, sendMMDD: "08-29" },
135
+ christmas: { enabled: true, sendMMDD: "12-08" },
136
+ };
137
+ it("dates the Christmas leg in the year AFTER the cohort leaves", () => {
138
+ expect((0, schedule_1.resolveLeaverLegsForYearGroup)(leavers, "13", 2026).map((l) => l.sendISO.slice(0, 10)))
139
+ .toEqual(["2027-06-15", "2027-08-29", "2027-12-08"]);
140
+ });
141
+ it("drops a checkpoint that is switched off", () => {
142
+ const cfg = { ...leavers, christmas: { enabled: false, sendMMDD: "12-08" } };
143
+ expect((0, schedule_1.resolveLeaverLegsForYearGroup)(cfg, "13", 2026).map((l) => l.kind))
144
+ .toEqual(["leaverIntentions", "leaverResults"]);
145
+ });
146
+ it("lets a year group's override replace the shared dates", () => {
147
+ // Y11 sits GCSEs, so its results day is a week before Y13's.
148
+ const cfg = { ...leavers, yearGroups: ["11", "13"], byYearGroup: {
149
+ "11": {
150
+ intentionsSendMMDD: "06-01",
151
+ resultsDay: { enabled: true, sendMMDD: "08-22" },
152
+ christmas: { enabled: false, sendMMDD: "" },
153
+ },
154
+ } };
155
+ expect((0, schedule_1.resolveLeaverLegsForYearGroup)(cfg, "11", 2026).map((l) => l.sendISO.slice(0, 10)))
156
+ .toEqual(["2027-06-01", "2027-08-22"]);
157
+ expect((0, schedule_1.resolveLeaverLegsForYearGroup)(cfg, "13", 2026)).toHaveLength(3);
158
+ });
159
+ it("resolves a rule against the leg's own year, ignoring a stale stored date", () => {
160
+ const cfg = { ...leavers, intentionsRule: { ordinal: "third", weekday: 5, month: 6 } };
161
+ // Third Friday of June 2027.
162
+ expect((0, schedule_1.resolveLeaverLegsForYearGroup)(cfg, "13", 2026)[0].sendISO.slice(0, 10)).toEqual("2027-06-18");
163
+ });
164
+ });
165
+ describe("programmeStartYear", () => {
166
+ // 2026-27: the academic year running 1 Sep 2026 → 31 Aug 2027.
167
+ const aspirations = (surveys) => ({
168
+ destinationsConfig: {
169
+ aspirations: { enabled: true, yearGroups: ["12"], surveys, closeAfterDays: 21 },
170
+ leavers: { enabled: false, yearGroups: [], intentionsSendMMDD: "", resultsDay: { enabled: false, sendMMDD: "" }, christmas: { enabled: false, sendMMDD: "" } },
171
+ alumni: { acceptingAlumni: false, approveAlumni: false, alumniConversations: false, visibleToStudents: false },
172
+ provisionMMDD: "09-01", setupCompletedAt: "2026-09-01T00:00:00.000Z", setupBy: "test",
173
+ },
174
+ });
175
+ it("stays on this year while a survey is still to come", () => {
176
+ const institute = aspirations([{ sendMMDD: "10-01" }, { sendMMDD: "03-01" }]);
177
+ // Mid-October: the autumn survey has gone, the spring one has not.
178
+ expect((0, schedule_1.programmeStartYear)(institute, "aspirations", new Date("2026-10-15T07:00:00.000Z"))).toEqual(2026);
179
+ });
180
+ it("rolls forward once this year's dates have all gone by", () => {
181
+ const institute = aspirations([{ sendMMDD: "10-01" }]);
182
+ expect((0, schedule_1.programmeStartYear)(institute, "aspirations", new Date("2027-07-20T07:00:00.000Z"))).toEqual(2027);
183
+ });
184
+ it("counts a survey due today as still to come, so the cron can create it", () => {
185
+ const institute = aspirations([{ sendMMDD: "10-01" }]);
186
+ // The cron runs at 07:00 and sends are stamped 08:00 — the day's own survey
187
+ // must not be treated as already gone.
188
+ expect((0, schedule_1.programmeStartYear)(institute, "aspirations", new Date("2026-10-01T07:00:00.000Z"))).toEqual(2026);
189
+ });
190
+ it("stays on this year when nothing is configured — there is nothing to roll to", () => {
191
+ expect((0, schedule_1.programmeStartYear)({}, "skills", new Date("2027-07-20T07:00:00.000Z"))).toEqual(2026);
192
+ expect((0, schedule_1.programmeStartYear)({}, "aspirations", new Date("2027-07-20T07:00:00.000Z"))).toEqual(2026);
193
+ });
194
+ it("judges each programme on its own dates", () => {
195
+ const institute = {
196
+ ...aspirations([{ sendMMDD: "10-01" }]),
197
+ skillsAssessments: true,
198
+ skillsSurveys: [{ sendMMDD: "03-01" }],
199
+ };
200
+ // Mid-October: aspirations are finished for the year, skills are not.
201
+ const now = new Date("2026-10-15T07:00:00.000Z");
202
+ expect((0, schedule_1.programmeStartYear)(institute, "aspirations", now)).toEqual(2027);
203
+ expect((0, schedule_1.programmeStartYear)(institute, "skills", now)).toEqual(2026);
204
+ });
205
+ it("ignores a skills group that filters on nothing, since it reaches nobody", () => {
206
+ const institute = {
207
+ skillsAssessments: true,
208
+ skillsSurveys: [],
209
+ skillsMappings: [{ id: "g1", filters: {}, skills: [], surveys: [{ sendMMDD: "03-01" }] }],
210
+ };
211
+ expect((0, schedule_1.programmeSendDatesForYear)(institute, "skills", 2026)).toEqual([]);
212
+ });
213
+ });
131
214
  describe("survey registry", () => {
132
215
  it("describes every kind", () => {
133
216
  expect(Object.keys(registry_1.SURVEY_KINDS).sort()).toEqual([...types_1.SURVEY_KINDS_LIST].sort());
@@ -1 +1 @@
1
- {"version":3,"file":"schedule.test.js","sourceRoot":"","sources":["../../src/surveys/schedule.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schedule.test.js","sourceRoot":"","sources":["../../src/surveys/schedule.test.ts"],"names":[],"mappings":"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"}
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.995",
5
+ "version": "1.400.997",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
8
8
  "scripts": {
@@ -1,8 +1,8 @@
1
1
  import {SURVEY_KINDS, SURVEY_THREADS, supersedingMessageTypes, supersedingSurveyKinds, surveyEmailCopy, legacySupersedingMessageTypes} from "./registry";
2
2
  import {
3
3
  academicCalendarYear, academicYearOf, academicYearLabel, academicYearSlashLabel, currentAcademicStartYear,
4
- isSlotDueOn, mmddToISO, normaliseAcademicYear, resolveNthWeekday, resolveSlotsForYear, surveyRuleToDate,
5
- surveyRuleToMMDD, toMMDD,
4
+ isSlotDueOn, mmddToISO, normaliseAcademicYear, programmeSendDatesForYear, programmeStartYear, resolveNthWeekday,
5
+ resolveLeaverLegsForYearGroup, resolveSlotsForYear, SurveyProgrammeConfig, surveyRuleToDate, surveyRuleToMMDD, toMMDD,
6
6
  } from "./schedule";
7
7
  import {SURVEY_KINDS_LIST, SurveyKind, SurveySlot} from "./types";
8
8
 
@@ -158,6 +158,101 @@ describe("isSlotDueOn", () => {
158
158
  });
159
159
  });
160
160
 
161
+ describe("resolveLeaverLegsForYearGroup", () => {
162
+ const leavers = {
163
+ enabled: true, yearGroups: ["13"], intentionsSendMMDD: "06-15",
164
+ resultsDay: {enabled: true, sendMMDD: "08-29"},
165
+ christmas: {enabled: true, sendMMDD: "12-08"},
166
+ };
167
+
168
+ it("dates the Christmas leg in the year AFTER the cohort leaves", () => {
169
+ expect(resolveLeaverLegsForYearGroup(leavers, "13", 2026).map((l) => l.sendISO.slice(0, 10)))
170
+ .toEqual(["2027-06-15", "2027-08-29", "2027-12-08"]);
171
+ });
172
+
173
+ it("drops a checkpoint that is switched off", () => {
174
+ const cfg = {...leavers, christmas: {enabled: false, sendMMDD: "12-08"}};
175
+ expect(resolveLeaverLegsForYearGroup(cfg, "13", 2026).map((l) => l.kind))
176
+ .toEqual(["leaverIntentions", "leaverResults"]);
177
+ });
178
+
179
+ it("lets a year group's override replace the shared dates", () => {
180
+ // Y11 sits GCSEs, so its results day is a week before Y13's.
181
+ const cfg = {...leavers, yearGroups: ["11", "13"], byYearGroup: {
182
+ "11": {
183
+ intentionsSendMMDD: "06-01",
184
+ resultsDay: {enabled: true, sendMMDD: "08-22"},
185
+ christmas: {enabled: false, sendMMDD: ""},
186
+ },
187
+ }};
188
+ expect(resolveLeaverLegsForYearGroup(cfg, "11", 2026).map((l) => l.sendISO.slice(0, 10)))
189
+ .toEqual(["2027-06-01", "2027-08-22"]);
190
+ expect(resolveLeaverLegsForYearGroup(cfg, "13", 2026)).toHaveLength(3);
191
+ });
192
+
193
+ it("resolves a rule against the leg's own year, ignoring a stale stored date", () => {
194
+ const cfg = {...leavers, intentionsRule: {ordinal: "third" as const, weekday: 5 as const, month: 6}};
195
+ // Third Friday of June 2027.
196
+ expect(resolveLeaverLegsForYearGroup(cfg, "13", 2026)[0].sendISO.slice(0, 10)).toEqual("2027-06-18");
197
+ });
198
+ });
199
+
200
+ describe("programmeStartYear", () => {
201
+ // 2026-27: the academic year running 1 Sep 2026 → 31 Aug 2027.
202
+ const aspirations = (surveys: SurveySlot[]): SurveyProgrammeConfig => ({
203
+ destinationsConfig: {
204
+ aspirations: {enabled: true, yearGroups: ["12"], surveys, closeAfterDays: 21},
205
+ leavers: {enabled: false, yearGroups: [], intentionsSendMMDD: "", resultsDay: {enabled: false, sendMMDD: ""}, christmas: {enabled: false, sendMMDD: ""}},
206
+ alumni: {acceptingAlumni: false, approveAlumni: false, alumniConversations: false, visibleToStudents: false},
207
+ provisionMMDD: "09-01", setupCompletedAt: "2026-09-01T00:00:00.000Z", setupBy: "test",
208
+ },
209
+ });
210
+
211
+ it("stays on this year while a survey is still to come", () => {
212
+ const institute = aspirations([{sendMMDD: "10-01"}, {sendMMDD: "03-01"}]);
213
+ // Mid-October: the autumn survey has gone, the spring one has not.
214
+ expect(programmeStartYear(institute, "aspirations", new Date("2026-10-15T07:00:00.000Z"))).toEqual(2026);
215
+ });
216
+
217
+ it("rolls forward once this year's dates have all gone by", () => {
218
+ const institute = aspirations([{sendMMDD: "10-01"}]);
219
+ expect(programmeStartYear(institute, "aspirations", new Date("2027-07-20T07:00:00.000Z"))).toEqual(2027);
220
+ });
221
+
222
+ it("counts a survey due today as still to come, so the cron can create it", () => {
223
+ const institute = aspirations([{sendMMDD: "10-01"}]);
224
+ // The cron runs at 07:00 and sends are stamped 08:00 — the day's own survey
225
+ // must not be treated as already gone.
226
+ expect(programmeStartYear(institute, "aspirations", new Date("2026-10-01T07:00:00.000Z"))).toEqual(2026);
227
+ });
228
+
229
+ it("stays on this year when nothing is configured — there is nothing to roll to", () => {
230
+ expect(programmeStartYear({}, "skills", new Date("2027-07-20T07:00:00.000Z"))).toEqual(2026);
231
+ expect(programmeStartYear({}, "aspirations", new Date("2027-07-20T07:00:00.000Z"))).toEqual(2026);
232
+ });
233
+
234
+ it("judges each programme on its own dates", () => {
235
+ const institute: SurveyProgrammeConfig = {
236
+ ...aspirations([{sendMMDD: "10-01"}]),
237
+ skillsAssessments: true,
238
+ skillsSurveys: [{sendMMDD: "03-01"}],
239
+ };
240
+ // Mid-October: aspirations are finished for the year, skills are not.
241
+ const now = new Date("2026-10-15T07:00:00.000Z");
242
+ expect(programmeStartYear(institute, "aspirations", now)).toEqual(2027);
243
+ expect(programmeStartYear(institute, "skills", now)).toEqual(2026);
244
+ });
245
+
246
+ it("ignores a skills group that filters on nothing, since it reaches nobody", () => {
247
+ const institute: SurveyProgrammeConfig = {
248
+ skillsAssessments: true,
249
+ skillsSurveys: [],
250
+ skillsMappings: [{id: "g1", filters: {}, skills: [], surveys: [{sendMMDD: "03-01"}]}],
251
+ };
252
+ expect(programmeSendDatesForYear(institute, "skills", 2026)).toEqual([]);
253
+ });
254
+ });
255
+
161
256
  describe("survey registry", () => {
162
257
  it("describes every kind", () => {
163
258
  expect(Object.keys(SURVEY_KINDS).sort()).toEqual([...SURVEY_KINDS_LIST].sort());
@@ -9,6 +9,10 @@
9
9
  * A rule is year-agnostic; it resolves into a concrete date for a given academic
10
10
  * year (each September) via surveyRuleToMMDD / surveyRuleToDate.
11
11
  *
12
+ * It also answers WHICH academic year to resolve against — programmeStartYear, at the
13
+ * foot of this file. Provisioning and the staff year tabs both ask it, so they cannot
14
+ * disagree about the year a school is on.
15
+ *
12
16
  * ── One academic-year boundary: 1 September ───────────────────────────────────
13
17
  * Everything here derives the academic year the same way — currentAcademicStartYear,
14
18
  * and academicYearOf which labels it. September to August is one academic year.
@@ -25,8 +29,8 @@
25
29
  * callers move onto the engine, so new writes agree with migrated ones.
26
30
  */
27
31
 
28
- import type {SurveyDateRule, SurveyOrdinal, SurveyWeekday} from "../typeDefinitions";
29
- import type {SurveySlot} from "./types";
32
+ import type {DestinationsConfig, InstituteData, SurveyDateRule, SurveyOrdinal, SurveyWeekday} from "../typeDefinitions";
33
+ import type {SurveyCohortScope, SurveyKind, SurveySlot} from "./types";
30
34
 
31
35
  const pad2 = (n: number) => String(n).padStart(2, "0");
32
36
 
@@ -166,3 +170,160 @@ export const resolveSlotsForYear = (
166
170
  */
167
171
  export const isSlotDueOn = (slot: SurveySlot, date = new Date()): boolean =>
168
172
  slotMMDDForYear(slot, currentAcademicStartYear(date)) === toMMDD(date);
173
+
174
+ // ─── The leaver thread's three legs ───────────────────────────────────────────
175
+
176
+ /** One leaver leg resolved for one year group in one academic year. */
177
+ export type ResolvedLeaverLeg = {
178
+ kind: SurveyKind,
179
+ yearGroup: string,
180
+ /** MM-DD the CONFIG resolves to — what provisioning keys its cycle id on, so a
181
+ * cycle staff have since rescheduled is not re-created. */
182
+ sendMMDD: string,
183
+ sendISO: string,
184
+ /** The leg's own academic start year: the year after for the Christmas leg. */
185
+ startYear: number,
186
+ /** Every student in these groups leaves (no internal sixth form). */
187
+ allStudentsLeave?: boolean,
188
+ };
189
+
190
+ /**
191
+ * A year group's leaver legs for one academic year, in send order — exactly the legs
192
+ * provisioning creates cycles for, so the disabled ones and any that don't resolve to
193
+ * a real date are already dropped.
194
+ *
195
+ * A per-year-group override REPLACES the shared leaver fields: Y11 and Y13 differ
196
+ * (GCSE vs A-level results days, sixth-form stayers).
197
+ */
198
+ export const resolveLeaverLegsForYearGroup = (
199
+ cfg: DestinationsConfig["leavers"], yearGroup: string, academicStartYear: number,
200
+ ): ResolvedLeaverLeg[] => {
201
+ const override = cfg.byYearGroup?.[String(yearGroup)];
202
+ const resultsCfg = override?.resultsDay ?? cfg.resultsDay;
203
+ const christmasCfg = override?.christmas ?? cfg.christmas;
204
+ const allStudentsLeave = override?.allStudentsLeave ?? cfg.allStudentsLeave;
205
+
206
+ const legs: {kind: SurveyKind, mmdd: string, rule?: SurveyDateRule, enabled: boolean}[] = [
207
+ {
208
+ kind: "leaverIntentions",
209
+ mmdd: override?.intentionsSendMMDD ?? cfg.intentionsSendMMDD,
210
+ rule: override?.intentionsRule ?? cfg.intentionsRule,
211
+ enabled: true,
212
+ },
213
+ {kind: "leaverResults", mmdd: resultsCfg?.sendMMDD ?? "", rule: resultsCfg?.rule, enabled: Boolean(resultsCfg?.enabled)},
214
+ {kind: "leaverChristmas", mmdd: christmasCfg?.sendMMDD ?? "", rule: christmasCfg?.rule, enabled: Boolean(christmasCfg?.enabled)},
215
+ ];
216
+
217
+ return legs.flatMap((leg) => {
218
+ // A 2026/27 cohort sits its exams in June 2027 and gets its results that August,
219
+ // but its Christmas check-in is December 2027 — the winter AFTER it leaves, which
220
+ // falls in the next academic year. Resolving it against this academic year would
221
+ // date it December 2026, six months BEFORE the intentions form. The cycle still
222
+ // carries the cohort's academic year, so the three legs stay one journey.
223
+ const startYear = leg.kind === "leaverChristmas" ? academicStartYear + 1 : academicStartYear;
224
+ // A rule is resolved against the leg's own year, so "third Thursday of August"
225
+ // lands on the right Thursday every year. The stored MM-DD is the fallback for
226
+ // configs written before leaver dates became rules.
227
+ const sendMMDD = leg.rule ? surveyRuleToMMDD(leg.rule, startYear) : leg.mmdd;
228
+ if (!leg.enabled || !sendMMDD) return [];
229
+ const sendISO = mmddToISO(sendMMDD, startYear);
230
+ if (!sendISO) return [];
231
+ return [{kind: leg.kind, yearGroup, sendMMDD, sendISO, startYear, allStudentsLeave}];
232
+ });
233
+ };
234
+
235
+ // ─── Which academic year a programme is currently on ──────────────────────────
236
+ //
237
+ // Provisioning used to lay out ONLY the academic year we are in, so a school whose
238
+ // dates for the year had all gone by got nothing at all: the nightly run resolved its
239
+ // slots, found every one of them in the past, skipped them, and simply stopped for the
240
+ // rest of the year — leaving a school that set its programme up in the summer term
241
+ // staring at an empty tab for a year that was already over.
242
+ //
243
+ // The year to lay out is the one the programme still has sends coming in: this one
244
+ // until its last date passes, the next one from that moment on. Backend provisioning
245
+ // and the staff year tabs both derive it here so they cannot disagree about which year
246
+ // a school is on.
247
+
248
+ /** The parts of an institute that schedule surveys — all these helpers read. */
249
+ export type SurveyProgrammeConfig = Pick<InstituteData,
250
+ "destinationsConfig"|"skillsAssessments"|"skillsSurveys"|"skillsMappings">;
251
+
252
+ /**
253
+ * Every send date one programme is configured to fire in one academic year, ISO, in
254
+ * order. Empty when the programme is off or has no schedule — which is not the same as
255
+ * "finished", and callers treat it as "nothing to say".
256
+ *
257
+ * @param {SurveyProgrammeConfig} institute the school's setup.
258
+ * @param {SurveyCohortScope} scope which programme.
259
+ * @param {number} academicStartYear the year the academic year starts in.
260
+ * @return {string[]} ISO send datetimes, earliest first.
261
+ */
262
+ export const programmeSendDatesForYear = (
263
+ institute: SurveyProgrammeConfig, scope: SurveyCohortScope, academicStartYear: number,
264
+ ): string[] => {
265
+ const dates: string[] = [];
266
+
267
+ if (scope === "aspirations") {
268
+ const cfg = institute.destinationsConfig?.aspirations;
269
+ if (!cfg?.enabled || !cfg.yearGroups?.length) return [];
270
+ for (const yearGroup of cfg.yearGroups) {
271
+ const slots = cfg.surveysByYearGroup?.[String(yearGroup)] ?? cfg.surveys ?? [];
272
+ dates.push(...resolveSlotsForYear(slots, academicStartYear).map((s) => s.sendISO));
273
+ }
274
+ }
275
+
276
+ if (scope === "skills") {
277
+ if (!institute.skillsAssessments) return [];
278
+ dates.push(...resolveSlotsForYear(institute.skillsSurveys, academicStartYear).map((s) => s.sendISO));
279
+ for (const mapping of institute.skillsMappings ?? []) {
280
+ // A mapping with no filters matches nobody, so provisioning ignores it.
281
+ if (!Object.values(mapping.filters ?? {}).some((v) => v?.length)) continue;
282
+ dates.push(...resolveSlotsForYear(mapping.surveys, academicStartYear).map((s) => s.sendISO));
283
+ }
284
+ }
285
+
286
+ if (scope === "leavers") {
287
+ const cfg = institute.destinationsConfig?.leavers;
288
+ if (!cfg?.enabled || !cfg.yearGroups?.length) return [];
289
+ for (const yearGroup of cfg.yearGroups) {
290
+ dates.push(...resolveLeaverLegsForYearGroup(cfg, String(yearGroup), academicStartYear).map((l) => l.sendISO));
291
+ }
292
+ }
293
+
294
+ return dates.sort((a, b) => a.localeCompare(b));
295
+ };
296
+
297
+ /**
298
+ * The academic year a programme should be laid out for, as its start year: the current
299
+ * one while any of its sends is still to come, the next one once they have all gone by.
300
+ *
301
+ * A programme with nothing configured stays on the current year — there is nothing to
302
+ * roll forward to, and the current year is still the one staff are working in.
303
+ *
304
+ * @param {SurveyProgrammeConfig} institute the school's setup.
305
+ * @param {SurveyCohortScope} scope which programme.
306
+ * @param {Date} [now] the moment to judge "still to come" against.
307
+ * @return {number} the year the academic year to provision starts in.
308
+ */
309
+ export const programmeStartYear = (
310
+ institute: SurveyProgrammeConfig, scope: SurveyCohortScope, now = new Date(),
311
+ ): number => {
312
+ const startYear = currentAcademicStartYear(now);
313
+ const dates = programmeSendDatesForYear(institute, scope, startYear);
314
+ if (!dates.length) return startYear;
315
+ return dates.some((iso) => new Date(iso) >= now) ? startYear : startYear + 1;
316
+ };
317
+
318
+ /**
319
+ * The academic-year LABEL a programme is on, hyphen form — what the staff year tabs
320
+ * key on. See programmeStartYear.
321
+ *
322
+ * @param {SurveyProgrammeConfig} institute the school's setup.
323
+ * @param {SurveyCohortScope} scope which programme.
324
+ * @param {Date} [now] the moment to judge "still to come" against.
325
+ * @return {string} e.g. "2026-27".
326
+ */
327
+ export const programmeAcademicYear = (
328
+ institute: SurveyProgrammeConfig, scope: SurveyCohortScope, now = new Date(),
329
+ ): string => academicYearLabel(programmeStartYear(institute, scope, now));