placementt-core 1.400.1110 → 1.400.1112
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/callables/__tests__/registry.test.js +2 -1
- package/lib/callables/__tests__/registry.test.js.map +1 -1
- package/lib/callables/e2e.d.ts +33 -0
- package/lib/callables/e2e.js +27 -0
- package/lib/callables/e2e.js.map +1 -0
- package/lib/callables/index.d.ts +1 -0
- package/lib/callables/index.js +1 -0
- package/lib/callables/index.js.map +1 -1
- package/lib/callables/registry.d.ts +40 -0
- package/lib/callables/registry.js +3 -1
- package/lib/callables/registry.js.map +1 -1
- package/lib/typeDefinitions.d.ts +9 -0
- package/lib/typeDefinitions.js.map +1 -1
- package/package.json +1 -1
- package/src/callables/__tests__/registry.test.ts +2 -1
- package/src/callables/e2e.ts +25 -0
- package/src/callables/index.ts +1 -0
- package/src/callables/registry.ts +3 -1
- package/src/typeDefinitions.ts +8 -0
|
@@ -19,7 +19,8 @@ describe("callable registry", () => {
|
|
|
19
19
|
});
|
|
20
20
|
it("names every callable as `<module>-<export>`", () => {
|
|
21
21
|
for (const name of names) {
|
|
22
|
-
|
|
22
|
+
// Letters first; digits allowed after, for modules like `e2e`.
|
|
23
|
+
expect(name).toMatch(/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z][a-zA-Z0-9]*$/);
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
26
|
it("gives every callable a request and response zod schema", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../../src/callables/__tests__/registry.test.ts"],"names":[],"mappings":";;AAAA,6BAAsB;AACtB,0CAAyD;AAEzD;;;;;GAKG;AACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,uBAAY,CAAC,CAAC;IAExC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,yBAAc,CAAC;aAC9C,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChE,wEAAwE;QACxE,sEAAsE;QACtE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../../src/callables/__tests__/registry.test.ts"],"names":[],"mappings":";;AAAA,6BAAsB;AACtB,0CAAyD;AAEzD;;;;;GAKG;AACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,uBAAY,CAAC,CAAC;IAExC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,yBAAc,CAAC;aAC9C,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChE,wEAAwE;QACxE,sEAAsE;QACtE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,+DAA+D;YAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;QACxE,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,uBAAY,CAAC,IAAiC,CAAC,CAAC;YACjE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC;YACnD,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Contracts for the end-to-end and UX-audit harness
|
|
4
|
+
* (`Placementt-Backend/functions/src/e2e.ts`).
|
|
5
|
+
*
|
|
6
|
+
* `redeemSignInLink` is public: the token is the credential. Links are only
|
|
7
|
+
* ever minted by the harness (service account, straight into Firestore) and
|
|
8
|
+
* only ever sign in a reserved `e2e.*@careerthread.co.uk` user, so the UX audit
|
|
9
|
+
* can walk a registered school without anyone typing a password.
|
|
10
|
+
*/
|
|
11
|
+
export declare const e2eCallables: {
|
|
12
|
+
"e2e-redeemSignInLink": {
|
|
13
|
+
request: z.ZodObject<{
|
|
14
|
+
/** The raw token from `/e2eSignIn/:token`. Stored only as a SHA-256 hash. */
|
|
15
|
+
token: z.ZodString;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
token: string;
|
|
18
|
+
}, {
|
|
19
|
+
token: string;
|
|
20
|
+
}>;
|
|
21
|
+
response: z.ZodObject<{
|
|
22
|
+
code: z.ZodEnum<["ok", "notFound", "expired"]>;
|
|
23
|
+
/** Firebase custom token for the linked e2e user. Only set when code is "ok". */
|
|
24
|
+
authToken: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
code: "expired" | "ok" | "notFound";
|
|
27
|
+
authToken?: string | undefined;
|
|
28
|
+
}, {
|
|
29
|
+
code: "expired" | "ok" | "notFound";
|
|
30
|
+
authToken?: string | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.e2eCallables = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
/**
|
|
6
|
+
* Contracts for the end-to-end and UX-audit harness
|
|
7
|
+
* (`Placementt-Backend/functions/src/e2e.ts`).
|
|
8
|
+
*
|
|
9
|
+
* `redeemSignInLink` is public: the token is the credential. Links are only
|
|
10
|
+
* ever minted by the harness (service account, straight into Firestore) and
|
|
11
|
+
* only ever sign in a reserved `e2e.*@careerthread.co.uk` user, so the UX audit
|
|
12
|
+
* can walk a registered school without anyone typing a password.
|
|
13
|
+
*/
|
|
14
|
+
exports.e2eCallables = {
|
|
15
|
+
"e2e-redeemSignInLink": {
|
|
16
|
+
request: zod_1.z.object({
|
|
17
|
+
/** The raw token from `/e2eSignIn/:token`. Stored only as a SHA-256 hash. */
|
|
18
|
+
token: zod_1.z.string().min(32).max(128).regex(/^[A-Za-z0-9_-]+$/),
|
|
19
|
+
}),
|
|
20
|
+
response: zod_1.z.object({
|
|
21
|
+
code: zod_1.z.enum(["ok", "notFound", "expired"]),
|
|
22
|
+
/** Firebase custom token for the linked e2e user. Only set when code is "ok". */
|
|
23
|
+
authToken: zod_1.z.string().optional(),
|
|
24
|
+
}),
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=e2e.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e.js","sourceRoot":"","sources":["../../src/callables/e2e.ts"],"names":[],"mappings":";;;AAAA,6BAAsB;AAGtB;;;;;;;;GAQG;AACU,QAAA,YAAY,GAAG;IACxB,sBAAsB,EAAE;QACpB,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC;YACd,6EAA6E;YAC7E,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;SAC/D,CAAC;QACF,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YAC3C,iFAAiF;YACjF,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SACnC,CAAC;KACL;CACoB,CAAC"}
|
package/lib/callables/index.d.ts
CHANGED
package/lib/callables/index.js
CHANGED
|
@@ -25,4 +25,5 @@ __exportStar(require("./he"), exports);
|
|
|
25
25
|
__exportStar(require("./studentLaunches"), exports);
|
|
26
26
|
__exportStar(require("./billing"), exports);
|
|
27
27
|
__exportStar(require("./hubImpactReport"), exports);
|
|
28
|
+
__exportStar(require("./e2e"), exports);
|
|
28
29
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/callables/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,6CAA2B;AAC3B,uDAAqC;AACrC,8CAA4B;AAC5B,2CAAyB;AACzB,6CAA2B;AAC3B,oDAAkC;AAClC,uCAAqB;AACrB,oDAAkC;AAClC,4CAA0B;AAC1B,oDAAkC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/callables/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,6CAA2B;AAC3B,uDAAqC;AACrC,8CAA4B;AAC5B,2CAAyB;AACzB,6CAA2B;AAC3B,oDAAkC;AAClC,uCAAqB;AACrB,oDAAkC;AAClC,4CAA0B;AAC1B,oDAAkC;AAClC,wCAAsB"}
|
|
@@ -11,6 +11,25 @@ import { z } from "zod";
|
|
|
11
11
|
* equals the sum of the group key counts.
|
|
12
12
|
*/
|
|
13
13
|
export declare const allCallables: {
|
|
14
|
+
"e2e-redeemSignInLink": {
|
|
15
|
+
request: z.ZodObject<{
|
|
16
|
+
token: z.ZodString;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
token: string;
|
|
19
|
+
}, {
|
|
20
|
+
token: string;
|
|
21
|
+
}>;
|
|
22
|
+
response: z.ZodObject<{
|
|
23
|
+
code: z.ZodEnum<["ok", "notFound", "expired"]>;
|
|
24
|
+
authToken: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
code: "expired" | "ok" | "notFound";
|
|
27
|
+
authToken?: string | undefined;
|
|
28
|
+
}, {
|
|
29
|
+
code: "expired" | "ok" | "notFound";
|
|
30
|
+
authToken?: string | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
14
33
|
"hubImpactReport-createHubImpactReport": {
|
|
15
34
|
request: z.ZodObject<{
|
|
16
35
|
oId: z.ZodOptional<z.ZodString>;
|
|
@@ -2515,4 +2534,25 @@ export declare const callableGroups: {
|
|
|
2515
2534
|
response: z.ZodString;
|
|
2516
2535
|
};
|
|
2517
2536
|
};
|
|
2537
|
+
e2eCallables: {
|
|
2538
|
+
"e2e-redeemSignInLink": {
|
|
2539
|
+
request: z.ZodObject<{
|
|
2540
|
+
token: z.ZodString;
|
|
2541
|
+
}, "strip", z.ZodTypeAny, {
|
|
2542
|
+
token: string;
|
|
2543
|
+
}, {
|
|
2544
|
+
token: string;
|
|
2545
|
+
}>;
|
|
2546
|
+
response: z.ZodObject<{
|
|
2547
|
+
code: z.ZodEnum<["ok", "notFound", "expired"]>;
|
|
2548
|
+
authToken: z.ZodOptional<z.ZodString>;
|
|
2549
|
+
}, "strip", z.ZodTypeAny, {
|
|
2550
|
+
code: "expired" | "ok" | "notFound";
|
|
2551
|
+
authToken?: string | undefined;
|
|
2552
|
+
}, {
|
|
2553
|
+
code: "expired" | "ok" | "notFound";
|
|
2554
|
+
authToken?: string | undefined;
|
|
2555
|
+
}>;
|
|
2556
|
+
};
|
|
2557
|
+
};
|
|
2518
2558
|
};
|
|
@@ -13,6 +13,7 @@ const studentLaunches_1 = require("./studentLaunches");
|
|
|
13
13
|
const billing_1 = require("./billing");
|
|
14
14
|
const jobRoles_1 = require("./jobRoles");
|
|
15
15
|
const hubImpactReport_1 = require("./hubImpactReport");
|
|
16
|
+
const e2e_1 = require("./e2e");
|
|
16
17
|
/**
|
|
17
18
|
* The single source of truth for every typed callable. Add a feature group's
|
|
18
19
|
* spread here and its callables are automatically covered by:
|
|
@@ -37,7 +38,8 @@ exports.allCallables = {
|
|
|
37
38
|
...billing_1.billingCallables,
|
|
38
39
|
...jobRoles_1.jobRolesCallables,
|
|
39
40
|
...hubImpactReport_1.hubImpactReportCallables,
|
|
41
|
+
...e2e_1.e2eCallables,
|
|
40
42
|
};
|
|
41
43
|
/** The per-group maps, exported so tests can assert no key collisions. */
|
|
42
|
-
exports.callableGroups = { destinationsConfigCallables: destinationsConfig_1.destinationsConfigCallables, placementCallables: placement_1.placementCallables, eventsCallables: events_1.eventsCallables, surveyCallables: surveys_1.surveyCallables, checksCallables: checks_1.checksCallables, benchmarksCallables: benchmarks_1.benchmarksCallables, apprenticeshipsCallables: apprenticeships_1.apprenticeshipsCallables, heCallables: he_1.heCallables, studentLaunchCallables: studentLaunches_1.studentLaunchCallables, billingCallables: billing_1.billingCallables, jobRolesCallables: jobRoles_1.jobRolesCallables, hubImpactReportCallables: hubImpactReport_1.hubImpactReportCallables };
|
|
44
|
+
exports.callableGroups = { destinationsConfigCallables: destinationsConfig_1.destinationsConfigCallables, placementCallables: placement_1.placementCallables, eventsCallables: events_1.eventsCallables, surveyCallables: surveys_1.surveyCallables, checksCallables: checks_1.checksCallables, benchmarksCallables: benchmarks_1.benchmarksCallables, apprenticeshipsCallables: apprenticeships_1.apprenticeshipsCallables, heCallables: he_1.heCallables, studentLaunchCallables: studentLaunches_1.studentLaunchCallables, billingCallables: billing_1.billingCallables, jobRolesCallables: jobRoles_1.jobRolesCallables, hubImpactReportCallables: hubImpactReport_1.hubImpactReportCallables, e2eCallables: e2e_1.e2eCallables };
|
|
43
45
|
//# sourceMappingURL=registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/callables/registry.ts"],"names":[],"mappings":";;;AAEA,6DAAiE;AACjE,2CAA+C;AAC/C,qCAAyC;AACzC,uCAA0C;AAC1C,qCAAyC;AACzC,6CAAiD;AACjD,uDAA2D;AAC3D,6BAAiC;AACjC,uDAAyD;AACzD,uCAA2C;AAC3C,yCAA6C;AAC7C,uDAA2D;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/callables/registry.ts"],"names":[],"mappings":";;;AAEA,6DAAiE;AACjE,2CAA+C;AAC/C,qCAAyC;AACzC,uCAA0C;AAC1C,qCAAyC;AACzC,6CAAiD;AACjD,uDAA2D;AAC3D,6BAAiC;AACjC,uDAAyD;AACzD,uCAA2C;AAC3C,yCAA6C;AAC7C,uDAA2D;AAC3D,+BAAmC;AAEnC;;;;;;;;;;GAUG;AACU,QAAA,YAAY,GAAG;IACxB,GAAG,gDAA2B;IAC9B,GAAG,8BAAkB;IACrB,GAAG,wBAAe;IAClB,GAAG,yBAAe;IAClB,GAAG,wBAAe;IAClB,GAAG,gCAAmB;IACtB,GAAG,0CAAwB;IAC3B,GAAG,gBAAW;IACd,GAAG,wCAAsB;IACzB,GAAG,0BAAgB;IACnB,GAAG,4BAAiB;IACpB,GAAG,0CAAwB;IAC3B,GAAG,kBAAY;CACM,CAAC;AAiB1B,0EAA0E;AAC7D,QAAA,cAAc,GAAG,EAAC,2BAA2B,EAA3B,gDAA2B,EAAE,kBAAkB,EAAlB,8BAAkB,EAAE,eAAe,EAAf,wBAAe,EAAE,eAAe,EAAf,yBAAe,EAAE,eAAe,EAAf,wBAAe,EAAE,mBAAmB,EAAnB,gCAAmB,EAAE,wBAAwB,EAAxB,0CAAwB,EAAE,WAAW,EAAX,gBAAW,EAAE,sBAAsB,EAAtB,wCAAsB,EAAE,gBAAgB,EAAhB,0BAAgB,EAAE,iBAAiB,EAAjB,4BAAiB,EAAE,wBAAwB,EAAxB,0CAAwB,EAAE,YAAY,EAAZ,kBAAY,EAAC,CAAC"}
|
package/lib/typeDefinitions.d.ts
CHANGED
|
@@ -1045,6 +1045,8 @@ export type EmployerField = {
|
|
|
1045
1045
|
multiple?: boolean;
|
|
1046
1046
|
required?: boolean;
|
|
1047
1047
|
};
|
|
1048
|
+
/** The areas of the staff platform that each own part of the careers year. */
|
|
1049
|
+
export type CareersSetupArea = "development" | "destinations";
|
|
1048
1050
|
export type InstituteData = {
|
|
1049
1051
|
students: number;
|
|
1050
1052
|
staff: number;
|
|
@@ -1163,7 +1165,14 @@ export type InstituteData = {
|
|
|
1163
1165
|
};
|
|
1164
1166
|
destinationsConfig?: DestinationsConfig;
|
|
1165
1167
|
guidanceConfig?: GuidanceConfig;
|
|
1168
|
+
/** "Set up later" from the careers calendar's whole-year flow. Holds until the
|
|
1169
|
+
* next 1 September, so the year is offered again when it actually changes. */
|
|
1166
1170
|
careersYearSetupDeferredAt?: string;
|
|
1171
|
+
/** The same, said from inside one area's own flow. Development's "later" is no
|
|
1172
|
+
* answer about Destinations, so each area keeps its own. */
|
|
1173
|
+
careersAreaSetupDeferredAt?: {
|
|
1174
|
+
[area in CareersSetupArea]?: string;
|
|
1175
|
+
};
|
|
1167
1176
|
leaverDestinations?: {
|
|
1168
1177
|
[id: string]: LeaverDestination;
|
|
1169
1178
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typeDefinitions.js","sourceRoot":"","sources":["../src/typeDefinitions.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"typeDefinitions.js","sourceRoot":"","sources":["../src/typeDefinitions.ts"],"names":[],"mappings":";;;AA4iIA,sDASC;AAeD,oDAKC;AAaD,0CAEC;AA/nED;;;;;kFAKkF;AACrE,QAAA,qBAAqB,GAAG,SAAS,CAAC;AAClC,QAAA,iBAAiB,GAAG,OAAO,CAAC;AA2iEzC;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"}
|
package/package.json
CHANGED
|
@@ -20,7 +20,8 @@ describe("callable registry", () => {
|
|
|
20
20
|
|
|
21
21
|
it("names every callable as `<module>-<export>`", () => {
|
|
22
22
|
for (const name of names) {
|
|
23
|
-
|
|
23
|
+
// Letters first; digits allowed after, for modules like `e2e`.
|
|
24
|
+
expect(name).toMatch(/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z][a-zA-Z0-9]*$/);
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
27
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {z} from "zod";
|
|
2
|
+
import {CallableGroup} from "./types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Contracts for the end-to-end and UX-audit harness
|
|
6
|
+
* (`Placementt-Backend/functions/src/e2e.ts`).
|
|
7
|
+
*
|
|
8
|
+
* `redeemSignInLink` is public: the token is the credential. Links are only
|
|
9
|
+
* ever minted by the harness (service account, straight into Firestore) and
|
|
10
|
+
* only ever sign in a reserved `e2e.*@careerthread.co.uk` user, so the UX audit
|
|
11
|
+
* can walk a registered school without anyone typing a password.
|
|
12
|
+
*/
|
|
13
|
+
export const e2eCallables = {
|
|
14
|
+
"e2e-redeemSignInLink": {
|
|
15
|
+
request: z.object({
|
|
16
|
+
/** The raw token from `/e2eSignIn/:token`. Stored only as a SHA-256 hash. */
|
|
17
|
+
token: z.string().min(32).max(128).regex(/^[A-Za-z0-9_-]+$/),
|
|
18
|
+
}),
|
|
19
|
+
response: z.object({
|
|
20
|
+
code: z.enum(["ok", "notFound", "expired"]),
|
|
21
|
+
/** Firebase custom token for the linked e2e user. Only set when code is "ok". */
|
|
22
|
+
authToken: z.string().optional(),
|
|
23
|
+
}),
|
|
24
|
+
},
|
|
25
|
+
} satisfies CallableGroup;
|
package/src/callables/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {studentLaunchCallables} from "./studentLaunches";
|
|
|
12
12
|
import {billingCallables} from "./billing";
|
|
13
13
|
import {jobRolesCallables} from "./jobRoles";
|
|
14
14
|
import {hubImpactReportCallables} from "./hubImpactReport";
|
|
15
|
+
import {e2eCallables} from "./e2e";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* The single source of truth for every typed callable. Add a feature group's
|
|
@@ -37,6 +38,7 @@ export const allCallables = {
|
|
|
37
38
|
...billingCallables,
|
|
38
39
|
...jobRolesCallables,
|
|
39
40
|
...hubImpactReportCallables,
|
|
41
|
+
...e2eCallables,
|
|
40
42
|
} satisfies CallableGroup;
|
|
41
43
|
|
|
42
44
|
/** Every registered callable name. */
|
|
@@ -55,4 +57,4 @@ export type CallableContracts = {
|
|
|
55
57
|
};
|
|
56
58
|
|
|
57
59
|
/** The per-group maps, exported so tests can assert no key collisions. */
|
|
58
|
-
export const callableGroups = {destinationsConfigCallables, placementCallables, eventsCallables, surveyCallables, checksCallables, benchmarksCallables, apprenticeshipsCallables, heCallables, studentLaunchCallables, billingCallables, jobRolesCallables, hubImpactReportCallables};
|
|
60
|
+
export const callableGroups = {destinationsConfigCallables, placementCallables, eventsCallables, surveyCallables, checksCallables, benchmarksCallables, apprenticeshipsCallables, heCallables, studentLaunchCallables, billingCallables, jobRolesCallables, hubImpactReportCallables, e2eCallables};
|
package/src/typeDefinitions.ts
CHANGED
|
@@ -1086,6 +1086,9 @@ export type EmployerField = {
|
|
|
1086
1086
|
required?: boolean,
|
|
1087
1087
|
}
|
|
1088
1088
|
|
|
1089
|
+
/** The areas of the staff platform that each own part of the careers year. */
|
|
1090
|
+
export type CareersSetupArea = "development"|"destinations";
|
|
1091
|
+
|
|
1089
1092
|
export type InstituteData = {
|
|
1090
1093
|
students: number,
|
|
1091
1094
|
staff: number,
|
|
@@ -1193,7 +1196,12 @@ export type InstituteData = {
|
|
|
1193
1196
|
},
|
|
1194
1197
|
destinationsConfig?: DestinationsConfig,
|
|
1195
1198
|
guidanceConfig?: GuidanceConfig,
|
|
1199
|
+
/** "Set up later" from the careers calendar's whole-year flow. Holds until the
|
|
1200
|
+
* next 1 September, so the year is offered again when it actually changes. */
|
|
1196
1201
|
careersYearSetupDeferredAt?: string,
|
|
1202
|
+
/** The same, said from inside one area's own flow. Development's "later" is no
|
|
1203
|
+
* answer about Destinations, so each area keeps its own. */
|
|
1204
|
+
careersAreaSetupDeferredAt?: {[area in CareersSetupArea]?: string},
|
|
1197
1205
|
leaverDestinations?: {[id: string]: LeaverDestination},
|
|
1198
1206
|
trustPolicies?: {[feature in TrustPolicyFeature]?: TrustPolicy},
|
|
1199
1207
|
studentTasks?: StudentTaskConfigMap,
|