placementt-core 1.400.1269 → 1.400.1271

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.
@@ -21,7 +21,7 @@ exports.exportTransformers = {
21
21
  if (!cohort?.workflowId)
22
22
  return value;
23
23
  const workflowConfig = await fetcher.getDocData(["workflows", cohort.workflowId]).catch(() => null);
24
- return (0, workflows_1.applyWorkflowOverrides)(workflowConfig?.workflow || [], cohort.workflowOverrides).find(s => s.id === value)?.name ?? value;
24
+ return (0, workflows_1.applyWorkflowOverrides)(workflowConfig ?? undefined, cohort.workflowOverrides).find(s => s.id === value)?.name ?? value;
25
25
  },
26
26
  resolveActivityTitles: async (fetcher, value, item, params) => {
27
27
  const activityIds = value;
@@ -1 +1 @@
1
- {"version":3,"file":"exportTransformers.js","sourceRoot":"","sources":["../src/exportTransformers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"exportTransformers.js","sourceRoot":"","sources":["../src/exportTransformers.ts"],"names":[],"mappings":";;;AAAA,6CAAsE;AAEtE,2CAAmD;AACnD,+CAAmE;AAStD,QAAA,kBAAkB,GAAwC;IACnE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,IAAA,2BAAiB,EAAC,KAA6B,CAAC;IAE9F,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,IAAA,uBAAa,EAAC,KAA6B,CAAC;IAEzF,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAa,CAAC,SAAS,EAAE,KAAe,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACpG,OAAO,MAAM,EAAE,IAAI,IAAI,KAAK,CAAC;IACjC,CAAC;IAED,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAgB,CAAC;QACvC,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC7F,IAAI,CAAC,MAAM,EAAE,UAAU;YAAE,OAAO,KAAK,CAAC;QACtC,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,UAAU,CAAiB,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACpH,OAAO,IAAA,kCAAsB,EAAC,cAAc,IAAI,SAAS,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,IAAI,IAAI,KAAK,CAAC;IAClI,CAAC;IAED,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QAC1D,MAAM,WAAW,GAAG,KAAoC,CAAC;QACzD,IAAI,CAAC,WAAW,EAAE,MAAM;YAAE,OAAO,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,EAAE,GAAyB,CAAC;QAC9C,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAgB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9G,MAAM,SAAS,GAAG,MAAM,IAAA,kCAAqB,EAAC,SAAS,EACnD,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAgB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3F,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACzB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,UAAU,CAAmB,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACrG,OAAO,GAAG,IAAI,IAAA,8BAAiB,EAAC,EAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CACL,CAAC;QACF,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzE,CAAC;CACJ,CAAC"}
@@ -3358,7 +3358,10 @@ export type Alumni = {
3358
3358
  export type Parent = {
3359
3359
  forename: string;
3360
3360
  surname: string;
3361
+ /** Contact email. The parent can change it on sign-up, e.g. to a work address. */
3361
3362
  email: string;
3363
+ /** The email the school holds (student parentEmail or Wonde), kept when the parent changes email so later invite runs still match this record. */
3364
+ invitedEmail?: string;
3362
3365
  activities: string[];
3363
3366
  oId: string;
3364
3367
  uids: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"typeDefinitions.js","sourceRoot":"","sources":["../src/typeDefinitions.ts"],"names":[],"mappings":";;;AAq1IA,sDASC;AAeD,oDAKC;AAaD,0CAEC;AA1uED;;;;;kFAKkF;AACrE,QAAA,qBAAqB,GAAG,SAAS,CAAC;AAClC,QAAA,iBAAiB,GAAG,OAAO,CAAC;AAspEzC;yEACyE;AAC5D,QAAA,0BAA0B,GAA2C;IAC9E,gBAAgB,EAAE,2BAA2B;IAC7C,mBAAmB,EAAE,sBAAsB;IAC3C,cAAc,EAAE,iBAAiB;IACjC,kBAAkB,EAAE,qBAAqB;IACzC,UAAU,EAAE,oCAAoC;IAChD,aAAa,EAAE,yBAAyB;IACxC,aAAa,EAAE,wBAAwB;IACvC,KAAK,EAAE,OAAO;CACjB,CAAC;AAEW,QAAA,0BAA0B,GAA+C;IAClF,QAAQ,EAAE,WAAW;IACrB,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,OAAO;CACjB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,SAAgB,qBAAqB,CAAC,SAAsC;IACxE,QAAQ,SAAS,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC;QAC5B,KAAK,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC;QAC7B,KAAK,WAAW,CAAC;QACjB,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,OAAO,CAAC,CAAC,OAAO,UAAU,CAAC;IAC3B,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,oBAAoB,CAChC,IAAwC,EACxC,MAA6C;IAE7C,OAAO,IAAI,EAAE,WAAW,IAAI,MAAM,EAAE,YAAY,IAAI,KAAK,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,eAAe,CAAC,KAA6D;IACzF,OAAO,GAAG,KAAK,CAAC,cAAc,IAAI,EAAE,IAAI,KAAK,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AAC/E,CAAC"}
1
+ {"version":3,"file":"typeDefinitions.js","sourceRoot":"","sources":["../src/typeDefinitions.ts"],"names":[],"mappings":";;;AAw1IA,sDASC;AAeD,oDAKC;AAaD,0CAEC;AA7uED;;;;;kFAKkF;AACrE,QAAA,qBAAqB,GAAG,SAAS,CAAC;AAClC,QAAA,iBAAiB,GAAG,OAAO,CAAC;AAypEzC;yEACyE;AAC5D,QAAA,0BAA0B,GAA2C;IAC9E,gBAAgB,EAAE,2BAA2B;IAC7C,mBAAmB,EAAE,sBAAsB;IAC3C,cAAc,EAAE,iBAAiB;IACjC,kBAAkB,EAAE,qBAAqB;IACzC,UAAU,EAAE,oCAAoC;IAChD,aAAa,EAAE,yBAAyB;IACxC,aAAa,EAAE,wBAAwB;IACvC,KAAK,EAAE,OAAO;CACjB,CAAC;AAEW,QAAA,0BAA0B,GAA+C;IAClF,QAAQ,EAAE,WAAW;IACrB,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,OAAO;CACjB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,SAAgB,qBAAqB,CAAC,SAAsC;IACxE,QAAQ,SAAS,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC;QAC5B,KAAK,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC;QAC7B,KAAK,WAAW,CAAC;QACjB,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,OAAO,CAAC,CAAC,OAAO,UAAU,CAAC;IAC3B,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,oBAAoB,CAChC,IAAwC,EACxC,MAA6C;IAE7C,OAAO,IAAI,EAAE,WAAW,IAAI,MAAM,EAAE,YAAY,IAAI,KAAK,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,eAAe,CAAC,KAA6D;IACzF,OAAO,GAAG,KAAK,CAAC,cAAc,IAAI,EAAE,IAAI,KAAK,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AAC/E,CAAC"}
@@ -17,9 +17,25 @@ export declare const approvedTrustId: (institute?: Pick<InstituteData, "trustLin
17
17
  export declare const trustWorkflows: (workflows?: {
18
18
  [id: string]: WorkflowConfig;
19
19
  }, trustId?: string) => [string, WorkflowConfig][];
20
- export declare const workflowEditPolicy: (workflow?: WorkflowConfig) => WorkflowEditPolicy;
21
- /** Layer a school's per-stage forms/files deltas onto a base workflow. */
22
- export declare function applyWorkflowOverrides(workflow: WorkflowStage[], overrides?: WorkflowOverrides): WorkflowStage[];
20
+ export declare const workflowEditPolicy: (workflow?: Pick<WorkflowConfig, "trust" | "editPolicy">) => WorkflowEditPolicy;
21
+ /**
22
+ * Layer a school's per-stage forms/files overrides onto the workflow they were made on.
23
+ *
24
+ * Takes the workflow DOC, not its stages, because the trust's edit policy decides how an
25
+ * override combines with the stage, and it is applied here - every time the workflow is
26
+ * read - rather than only when the school saved. An override holds a stage's whole
27
+ * forms/files list as it stood then, so applying it as-is would let it outlive the
28
+ * trust's later edits: a form the trust adds to an "add only" stage would never reach a
29
+ * school that had added one of its own, and switching to "locked" would leave the
30
+ * school's additions in place. Through enforceEditPolicy, "add" is the trust's current
31
+ * list plus the school's own, "locked" is the trust's list alone, and "open" (and any
32
+ * workflow that isn't a trust's) is the school's list as saved.
33
+ *
34
+ * @param {Pick<WorkflowConfig, "workflow"|"trust"|"editPolicy">|undefined} config the workflow doc the overrides sit on.
35
+ * @param {WorkflowOverrides} overrides the cohort's or group's per-stage overrides.
36
+ * @return {WorkflowStage[]} the stages the cohort runs on.
37
+ */
38
+ export declare function applyWorkflowOverrides(config: Pick<WorkflowConfig, "workflow" | "trust" | "editPolicy"> | undefined, overrides?: WorkflowOverrides): WorkflowStage[];
23
39
  /** Reduce an edited workflow back to just the stages whose forms/files differ from the base. */
24
40
  export declare function diffWorkflowOverrides(base: WorkflowStage[], edited: WorkflowStage[]): WorkflowOverrides;
25
41
  /**
package/lib/workflows.js CHANGED
@@ -30,18 +30,36 @@ const trustWorkflows = (workflows, trustId) => Object.entries(workflows || {}).f
30
30
  exports.trustWorkflows = trustWorkflows;
31
31
  const workflowEditPolicy = (workflow) => (workflow?.trust ? workflow.editPolicy || "open" : "open");
32
32
  exports.workflowEditPolicy = workflowEditPolicy;
33
- /** Layer a school's per-stage forms/files deltas onto a base workflow. */
34
- function applyWorkflowOverrides(workflow, overrides) {
33
+ /**
34
+ * Layer a school's per-stage forms/files overrides onto the workflow they were made on.
35
+ *
36
+ * Takes the workflow DOC, not its stages, because the trust's edit policy decides how an
37
+ * override combines with the stage, and it is applied here - every time the workflow is
38
+ * read - rather than only when the school saved. An override holds a stage's whole
39
+ * forms/files list as it stood then, so applying it as-is would let it outlive the
40
+ * trust's later edits: a form the trust adds to an "add only" stage would never reach a
41
+ * school that had added one of its own, and switching to "locked" would leave the
42
+ * school's additions in place. Through enforceEditPolicy, "add" is the trust's current
43
+ * list plus the school's own, "locked" is the trust's list alone, and "open" (and any
44
+ * workflow that isn't a trust's) is the school's list as saved.
45
+ *
46
+ * @param {Pick<WorkflowConfig, "workflow"|"trust"|"editPolicy">|undefined} config the workflow doc the overrides sit on.
47
+ * @param {WorkflowOverrides} overrides the cohort's or group's per-stage overrides.
48
+ * @return {WorkflowStage[]} the stages the cohort runs on.
49
+ */
50
+ function applyWorkflowOverrides(config, overrides) {
51
+ const workflow = config?.workflow || [];
35
52
  if (!overrides || !Object.keys(overrides).length)
36
53
  return workflow;
54
+ const policy = (0, exports.workflowEditPolicy)(config);
37
55
  return workflow.map((stage) => {
38
56
  const override = overrides[String(stage.id)];
39
57
  if (!override)
40
58
  return stage;
41
59
  return {
42
60
  ...stage,
43
- ...(override.forms ? { forms: override.forms } : {}),
44
- ...(override.files ? { files: override.files } : {}),
61
+ ...(override.forms ? { forms: enforceEditPolicy(stage.forms, override.forms, policy) } : {}),
62
+ ...(override.files ? { files: enforceEditPolicy(stage.files, override.files, policy) } : {}),
45
63
  };
46
64
  });
47
65
  }
@@ -111,7 +129,7 @@ function resolveCohortWorkflow(cohort, workflows) {
111
129
  const config = workflows?.[cohort.workflowId];
112
130
  if (!config)
113
131
  return [];
114
- return applyWorkflowOverrides(config.workflow || [], cohort.workflowOverrides);
132
+ return applyWorkflowOverrides(config, cohort.workflowOverrides);
115
133
  }
116
134
  /** Fetch-and-resolve version of resolveCohortWorkflow, for callers without the
117
135
  * workflows collection already in memory. Returns [] when nothing is configured. */
@@ -121,7 +139,7 @@ async function fetchCohortWorkflow(cohort, firebaseQuery = new firebaseQuery_1.d
121
139
  const config = await firebaseQuery.getDocData(["workflows", cohort.workflowId]).catch(() => undefined);
122
140
  if (!config?.workflow?.length)
123
141
  return [];
124
- return applyWorkflowOverrides(config.workflow, cohort.workflowOverrides);
142
+ return applyWorkflowOverrides(config, cohort.workflowOverrides);
125
143
  }
126
144
  /** Whether a cohort has a usable workflow configured. */
127
145
  const cohortWorkflowConfigured = (cohort, workflows) => Boolean(cohort?.workflowId && workflows?.[cohort.workflowId]?.workflow?.length);
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../src/workflows.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../src/workflows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ jest.mock("./firebase/firebaseQuery", () => ({ __esModule: true, default: jest.fn() }));
4
+ const workflows_1 = require("./workflows");
5
+ describe("applyWorkflowOverrides", () => {
6
+ const stages = (forms) => [
7
+ { id: 1, name: "Staff review", userType: "Staff", forms },
8
+ { id: 2, name: "Parent review", userType: "Parent", forms: ["trustParent"] },
9
+ ];
10
+ const trustWorkflow = (editPolicy, forms = ["trustForm"]) => ({ trust: true, editPolicy, workflow: stages(forms) });
11
+ // Saved when the trust's stage held only trustForm, so it is the whole list as it stood then.
12
+ const overrides = { "1": { forms: ["trustForm", "schoolForm"] } };
13
+ it("keeps forms the trust adds after the school saved, under add only", () => {
14
+ const resolved = (0, workflows_1.applyWorkflowOverrides)(trustWorkflow("add", ["trustForm", "laterTrustForm"]), overrides);
15
+ expect(resolved[0].forms).toEqual(["trustForm", "laterTrustForm", "schoolForm"]);
16
+ expect(resolved[1].forms).toEqual(["trustParent"]);
17
+ });
18
+ it("keeps the trust's forms when the school's override dropped one, under add only", () => {
19
+ const resolved = (0, workflows_1.applyWorkflowOverrides)(trustWorkflow("add"), { "1": { forms: ["schoolForm"] } });
20
+ expect(resolved[0].forms).toEqual(["trustForm", "schoolForm"]);
21
+ });
22
+ it("ignores the school's additions once the trust locks the workflow", () => {
23
+ expect((0, workflows_1.applyWorkflowOverrides)(trustWorkflow("locked"), overrides)[0].forms).toEqual(["trustForm"]);
24
+ });
25
+ it("uses the school's list as saved under full editing", () => {
26
+ expect((0, workflows_1.applyWorkflowOverrides)(trustWorkflow("open"), { "1": { forms: ["schoolForm"] } })[0].forms).toEqual(["schoolForm"]);
27
+ });
28
+ it("uses the list as saved on a workflow that isn't a trust's", () => {
29
+ const own = { workflow: stages(["ownForm"]) };
30
+ expect((0, workflows_1.applyWorkflowOverrides)(own, { "1": { forms: ["other"] } })[0].forms).toEqual(["other"]);
31
+ });
32
+ it("returns no stages for a missing workflow", () => {
33
+ expect((0, workflows_1.applyWorkflowOverrides)(undefined, overrides)).toEqual([]);
34
+ });
35
+ });
36
+ //# sourceMappingURL=workflows.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.test.js","sourceRoot":"","sources":["../src/workflows.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.1269",
5
+ "version": "1.400.1271",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
8
8
  "scripts": {
@@ -27,7 +27,7 @@ export const exportTransformers: Record<string, ExportTransformerFn> = {
27
27
  const cohort = await fetcher.getDocData<CohortData>(["cohorts", cohortId]).catch(() => null);
28
28
  if (!cohort?.workflowId) return value;
29
29
  const workflowConfig = await fetcher.getDocData<WorkflowConfig>(["workflows", cohort.workflowId]).catch(() => null);
30
- return applyWorkflowOverrides(workflowConfig?.workflow || [], cohort.workflowOverrides).find(s => s.id === value)?.name ?? value;
30
+ return applyWorkflowOverrides(workflowConfig ?? undefined, cohort.workflowOverrides).find(s => s.id === value)?.name ?? value;
31
31
  },
32
32
 
33
33
  resolveActivityTitles: async (fetcher, value, item, params) => {
@@ -3346,7 +3346,10 @@ export type Alumni = {
3346
3346
  export type Parent = {
3347
3347
  forename: string,
3348
3348
  surname: string,
3349
+ /** Contact email. The parent can change it on sign-up, e.g. to a work address. */
3349
3350
  email: string,
3351
+ /** The email the school holds (student parentEmail or Wonde), kept when the parent changes email so later invite runs still match this record. */
3352
+ invitedEmail?: string,
3350
3353
  activities: string[],
3351
3354
  oId: string,
3352
3355
  uids: string[],
@@ -0,0 +1,44 @@
1
+ jest.mock("./firebase/firebaseQuery", () => ({__esModule: true, default: jest.fn()}));
2
+
3
+ import {applyWorkflowOverrides} from "./workflows";
4
+ import {WorkflowConfig, WorkflowEditPolicy, WorkflowStage} from "./typeDefinitions";
5
+
6
+ describe("applyWorkflowOverrides", () => {
7
+ const stages = (forms: string[]): WorkflowStage[] => [
8
+ {id: 1, name: "Staff review", userType: "Staff", forms} as WorkflowStage,
9
+ {id: 2, name: "Parent review", userType: "Parent", forms: ["trustParent"]} as WorkflowStage,
10
+ ];
11
+ const trustWorkflow = (editPolicy: WorkflowEditPolicy, forms = ["trustForm"]) =>
12
+ ({trust: true, editPolicy, workflow: stages(forms)}) as Pick<WorkflowConfig, "workflow"|"trust"|"editPolicy">;
13
+
14
+ // Saved when the trust's stage held only trustForm, so it is the whole list as it stood then.
15
+ const overrides = {"1": {forms: ["trustForm", "schoolForm"]}};
16
+
17
+ it("keeps forms the trust adds after the school saved, under add only", () => {
18
+ const resolved = applyWorkflowOverrides(trustWorkflow("add", ["trustForm", "laterTrustForm"]), overrides);
19
+ expect(resolved[0].forms).toEqual(["trustForm", "laterTrustForm", "schoolForm"]);
20
+ expect(resolved[1].forms).toEqual(["trustParent"]);
21
+ });
22
+
23
+ it("keeps the trust's forms when the school's override dropped one, under add only", () => {
24
+ const resolved = applyWorkflowOverrides(trustWorkflow("add"), {"1": {forms: ["schoolForm"]}});
25
+ expect(resolved[0].forms).toEqual(["trustForm", "schoolForm"]);
26
+ });
27
+
28
+ it("ignores the school's additions once the trust locks the workflow", () => {
29
+ expect(applyWorkflowOverrides(trustWorkflow("locked"), overrides)[0].forms).toEqual(["trustForm"]);
30
+ });
31
+
32
+ it("uses the school's list as saved under full editing", () => {
33
+ expect(applyWorkflowOverrides(trustWorkflow("open"), {"1": {forms: ["schoolForm"]}})[0].forms).toEqual(["schoolForm"]);
34
+ });
35
+
36
+ it("uses the list as saved on a workflow that isn't a trust's", () => {
37
+ const own = {workflow: stages(["ownForm"])} as Pick<WorkflowConfig, "workflow">;
38
+ expect(applyWorkflowOverrides(own, {"1": {forms: ["other"]}})[0].forms).toEqual(["other"]);
39
+ });
40
+
41
+ it("returns no stages for a missing workflow", () => {
42
+ expect(applyWorkflowOverrides(undefined, overrides)).toEqual([]);
43
+ });
44
+ });
package/src/workflows.ts CHANGED
@@ -21,19 +21,40 @@ export const approvedTrustId = (institute?: Pick<InstituteData, "trustLinks">) =
21
21
  export const trustWorkflows = (workflows?: {[id: string]: WorkflowConfig}, trustId?: string) =>
22
22
  Object.entries(workflows || {}).filter(([, w]) => w.trust && (!trustId || w.oId === trustId));
23
23
 
24
- export const workflowEditPolicy = (workflow?: WorkflowConfig): WorkflowEditPolicy =>
24
+ export const workflowEditPolicy = (workflow?: Pick<WorkflowConfig, "trust"|"editPolicy">): WorkflowEditPolicy =>
25
25
  (workflow?.trust ? workflow.editPolicy || "open" : "open");
26
26
 
27
- /** Layer a school's per-stage forms/files deltas onto a base workflow. */
28
- export function applyWorkflowOverrides(workflow: WorkflowStage[], overrides?: WorkflowOverrides): WorkflowStage[] {
27
+ /**
28
+ * Layer a school's per-stage forms/files overrides onto the workflow they were made on.
29
+ *
30
+ * Takes the workflow DOC, not its stages, because the trust's edit policy decides how an
31
+ * override combines with the stage, and it is applied here - every time the workflow is
32
+ * read - rather than only when the school saved. An override holds a stage's whole
33
+ * forms/files list as it stood then, so applying it as-is would let it outlive the
34
+ * trust's later edits: a form the trust adds to an "add only" stage would never reach a
35
+ * school that had added one of its own, and switching to "locked" would leave the
36
+ * school's additions in place. Through enforceEditPolicy, "add" is the trust's current
37
+ * list plus the school's own, "locked" is the trust's list alone, and "open" (and any
38
+ * workflow that isn't a trust's) is the school's list as saved.
39
+ *
40
+ * @param {Pick<WorkflowConfig, "workflow"|"trust"|"editPolicy">|undefined} config the workflow doc the overrides sit on.
41
+ * @param {WorkflowOverrides} overrides the cohort's or group's per-stage overrides.
42
+ * @return {WorkflowStage[]} the stages the cohort runs on.
43
+ */
44
+ export function applyWorkflowOverrides(
45
+ config: Pick<WorkflowConfig, "workflow"|"trust"|"editPolicy">|undefined,
46
+ overrides?: WorkflowOverrides,
47
+ ): WorkflowStage[] {
48
+ const workflow = config?.workflow || [];
29
49
  if (!overrides || !Object.keys(overrides).length) return workflow;
50
+ const policy = workflowEditPolicy(config);
30
51
  return workflow.map((stage) => {
31
52
  const override = overrides[String(stage.id)];
32
53
  if (!override) return stage;
33
54
  return {
34
55
  ...stage,
35
- ...(override.forms ? {forms: override.forms} : {}),
36
- ...(override.files ? {files: override.files} : {}),
56
+ ...(override.forms ? {forms: enforceEditPolicy(stage.forms, override.forms, policy)} : {}),
57
+ ...(override.files ? {files: enforceEditPolicy(stage.files, override.files, policy)} : {}),
37
58
  };
38
59
  });
39
60
  }
@@ -107,7 +128,7 @@ export function resolveCohortWorkflow(
107
128
  if (!cohort?.workflowId) return [];
108
129
  const config = workflows?.[cohort.workflowId];
109
130
  if (!config) return [];
110
- return applyWorkflowOverrides(config.workflow || [], cohort.workflowOverrides);
131
+ return applyWorkflowOverrides(config, cohort.workflowOverrides);
111
132
  }
112
133
 
113
134
  /** Fetch-and-resolve version of resolveCohortWorkflow, for callers without the
@@ -119,7 +140,7 @@ export async function fetchCohortWorkflow(
119
140
  if (!cohort?.workflowId) return [];
120
141
  const config = await firebaseQuery.getDocData(["workflows", cohort.workflowId]).catch(() => undefined) as WorkflowConfig|undefined;
121
142
  if (!config?.workflow?.length) return [];
122
- return applyWorkflowOverrides(config.workflow, cohort.workflowOverrides);
143
+ return applyWorkflowOverrides(config, cohort.workflowOverrides);
123
144
  }
124
145
 
125
146
  /** Whether a cohort has a usable workflow configured. */