placementt-core 1.400.1117 → 1.400.1119
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/he.d.ts +41 -0
- package/lib/callables/he.js +23 -1
- package/lib/callables/he.js.map +1 -1
- package/lib/callables/misSync.d.ts +0 -3
- package/lib/callables/registry.d.ts +38 -6
- package/lib/heMappings.d.ts +77 -0
- package/lib/heMappings.js +266 -0
- package/lib/heMappings.js.map +1 -0
- package/lib/heMappings.test.d.ts +1 -0
- package/lib/heMappings.test.js +62 -0
- package/lib/heMappings.test.js.map +1 -0
- package/lib/heRanking.d.ts +337 -0
- package/lib/heRanking.js +767 -0
- package/lib/heRanking.js.map +1 -0
- package/lib/heRanking.test.d.ts +1 -0
- package/lib/heRanking.test.js +197 -0
- package/lib/heRanking.test.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/misSync.d.ts +14 -19
- package/lib/misSync.js +21 -32
- package/lib/misSync.js.map +1 -1
- package/lib/misSync.test.js +16 -13
- package/lib/misSync.test.js.map +1 -1
- package/lib/typeDefinitions.d.ts +283 -2
- package/lib/typeDefinitions.js.map +1 -1
- package/package.json +1 -1
- package/src/callables/he.ts +23 -0
- package/src/heMappings.test.ts +72 -0
- package/src/heMappings.ts +259 -0
- package/src/heRanking.test.ts +229 -0
- package/src/heRanking.ts +821 -0
- package/src/index.ts +2 -0
- package/src/misSync.test.ts +18 -15
- package/src/misSync.ts +24 -35
- package/src/typeDefinitions.ts +254 -2
package/lib/callables/he.d.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Contracts for the `he` backend module
|
|
4
|
+
* (`Placementt-Backend/functions/src/heImport.ts`).
|
|
5
|
+
*
|
|
6
|
+
* Admin-only controls for the weekly mirror of the HESA Discover Uni dataset
|
|
7
|
+
* into `heCourses` / `heProviders`. The status document (`heMeta/status`) is
|
|
8
|
+
* the source of truth the admin card reads live, so the responses only echo
|
|
9
|
+
* enough to confirm the call landed - an import can outlive the client's
|
|
10
|
+
* callable deadline and the card still resolves.
|
|
11
|
+
*/
|
|
12
|
+
/** Every enrichment source, in the order the admin card lists them. The
|
|
13
|
+
* orchestrator runs "areas" first (the city sources key on its output) and
|
|
14
|
+
* "finalise" last. */
|
|
15
|
+
export declare const HE_ENRICHMENT_SOURCES: readonly ["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation", "openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"];
|
|
2
16
|
export declare const heCallables: {
|
|
3
17
|
/** Run a full import now. `storagePath` names a zip already uploaded to
|
|
4
18
|
* Cloud Storage (`heImports/<file>.zip`) to use instead of the URL in
|
|
@@ -79,6 +93,33 @@ export declare const heCallables: {
|
|
|
79
93
|
};
|
|
80
94
|
}>;
|
|
81
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* Run the university enrichment: one status entry per source in
|
|
98
|
+
* `heMeta/enrichmentStatus`, one Cloud Task per source, then a finalise
|
|
99
|
+
* task that computes provider / area percentiles and reapplies course
|
|
100
|
+
* percentiles. `sources` limits the run to those sources (a retry of the
|
|
101
|
+
* ones that failed); omitted, every source runs. Returns as soon as the
|
|
102
|
+
* tasks are queued; the admin card follows the status document.
|
|
103
|
+
*/
|
|
104
|
+
"he-runEnrichment": {
|
|
105
|
+
request: z.ZodObject<{
|
|
106
|
+
sources: z.ZodOptional<z.ZodArray<z.ZodEnum<["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation", "openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"]>, "many">>;
|
|
107
|
+
}, "strip", z.ZodTypeAny, {
|
|
108
|
+
sources?: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[] | undefined;
|
|
109
|
+
}, {
|
|
110
|
+
sources?: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[] | undefined;
|
|
111
|
+
}>;
|
|
112
|
+
response: z.ZodObject<{
|
|
113
|
+
runId: z.ZodString;
|
|
114
|
+
queued: z.ZodArray<z.ZodEnum<["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation", "openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"]>, "many">;
|
|
115
|
+
}, "strip", z.ZodTypeAny, {
|
|
116
|
+
runId: string;
|
|
117
|
+
queued: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[];
|
|
118
|
+
}, {
|
|
119
|
+
runId: string;
|
|
120
|
+
queued: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[];
|
|
121
|
+
}>;
|
|
122
|
+
};
|
|
82
123
|
/** Clear a stuck "running" state. The mirror and its manifest are left
|
|
83
124
|
* alone. */
|
|
84
125
|
"he-resetRun": {
|
package/lib/callables/he.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.heCallables = void 0;
|
|
3
|
+
exports.heCallables = exports.HE_ENRICHMENT_SOURCES = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
/**
|
|
6
6
|
* Contracts for the `he` backend module
|
|
@@ -12,6 +12,11 @@ const zod_1 = require("zod");
|
|
|
12
12
|
* enough to confirm the call landed - an import can outlive the client's
|
|
13
13
|
* callable deadline and the card still resolves.
|
|
14
14
|
*/
|
|
15
|
+
/** Every enrichment source, in the order the admin card lists them. The
|
|
16
|
+
* orchestrator runs "areas" first (the city sources key on its output) and
|
|
17
|
+
* "finalise" last. */
|
|
18
|
+
exports.HE_ENRICHMENT_SOURCES = ["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation",
|
|
19
|
+
"openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"];
|
|
15
20
|
const importCounts = zod_1.z.object({
|
|
16
21
|
coursesAssembled: zod_1.z.number(),
|
|
17
22
|
coursesWritten: zod_1.z.number(),
|
|
@@ -39,6 +44,23 @@ exports.heCallables = {
|
|
|
39
44
|
counts: importCounts,
|
|
40
45
|
}),
|
|
41
46
|
},
|
|
47
|
+
/**
|
|
48
|
+
* Run the university enrichment: one status entry per source in
|
|
49
|
+
* `heMeta/enrichmentStatus`, one Cloud Task per source, then a finalise
|
|
50
|
+
* task that computes provider / area percentiles and reapplies course
|
|
51
|
+
* percentiles. `sources` limits the run to those sources (a retry of the
|
|
52
|
+
* ones that failed); omitted, every source runs. Returns as soon as the
|
|
53
|
+
* tasks are queued; the admin card follows the status document.
|
|
54
|
+
*/
|
|
55
|
+
"he-runEnrichment": {
|
|
56
|
+
request: zod_1.z.object({
|
|
57
|
+
sources: zod_1.z.array(zod_1.z.enum(exports.HE_ENRICHMENT_SOURCES)).optional(),
|
|
58
|
+
}),
|
|
59
|
+
response: zod_1.z.object({
|
|
60
|
+
runId: zod_1.z.string(),
|
|
61
|
+
queued: zod_1.z.array(zod_1.z.enum(exports.HE_ENRICHMENT_SOURCES)),
|
|
62
|
+
}),
|
|
63
|
+
},
|
|
42
64
|
/** Clear a stuck "running" state. The mirror and its manifest are left
|
|
43
65
|
* alone. */
|
|
44
66
|
"he-resetRun": {
|
package/lib/callables/he.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"he.js","sourceRoot":"","sources":["../../src/callables/he.ts"],"names":[],"mappings":";;;AAAA,6BAAsB;AAGtB;;;;;;;;;GASG;AAEH,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,kBAAkB,EAAE,OAAC,CAAC,MAAM,EAAE;CACjC,CAAC,CAAC;AAEU,QAAA,WAAW,GAAG;IACvB;;;4BAGwB;IACxB,cAAc,EAAE;QACZ,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC;YACd,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SACrC,CAAC;QACF,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;YACjB,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;YAC1B,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;gBACb,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBAChC,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE;aAClB,CAAC;YACF,MAAM,EAAE,YAAY;SACvB,CAAC;KACL;IACD;gBACY;IACZ,aAAa,EAAE;QACX,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,EAAE,EAAE,OAAC,CAAC,OAAO,CAAC,IAAI,CAAC;SACtB,CAAC;KACL;CACoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"he.js","sourceRoot":"","sources":["../../src/callables/he.ts"],"names":[],"mappings":";;;AAAA,6BAAsB;AAGtB;;;;;;;;;GASG;AAEH;;sBAEsB;AACT,QAAA,qBAAqB,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,uBAAuB;IAC5G,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,CAAU,CAAC;AAEzG,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,kBAAkB,EAAE,OAAC,CAAC,MAAM,EAAE;CACjC,CAAC,CAAC;AAEU,QAAA,WAAW,GAAG;IACvB;;;4BAGwB;IACxB,cAAc,EAAE;QACZ,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC;YACd,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SACrC,CAAC;QACF,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;YACjB,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;YAC1B,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;gBACb,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBAChC,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE;aAClB,CAAC;YACF,MAAM,EAAE,YAAY;SACvB,CAAC;KACL;IACD;;;;;;;OAOG;IACH,kBAAkB,EAAE;QAChB,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC;YACd,OAAO,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,IAAI,CAAC,6BAAqB,CAAC,CAAC,CAAC,QAAQ,EAAE;SAC7D,CAAC;QACF,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;YACjB,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,IAAI,CAAC,6BAAqB,CAAC,CAAC;SACjD,CAAC;KACL;IACD;gBACY;IACZ,aAAa,EAAE;QACX,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,EAAE,EAAE,OAAC,CAAC,OAAO,CAAC,IAAI,CAAC;SACtB,CAAC;KACL;CACoB,CAAC"}
|
|
@@ -14,7 +14,6 @@ export declare const misSyncCallables: {
|
|
|
14
14
|
method: z.ZodEnum<["email", "api"]>;
|
|
15
15
|
allowedSenders: z.ZodArray<z.ZodEffects<z.ZodString, string, string>, "many">;
|
|
16
16
|
studentEmailDomains: z.ZodArray<z.ZodString, "many">;
|
|
17
|
-
columnMapping: z.ZodRecord<z.ZodEnum<["mis_student_id", "first_name", "last_name", "email", "year_group", "course", "tutor_group", "status", "start_date", "leave_date"]>, z.ZodString>;
|
|
18
17
|
inactiveStatuses: z.ZodArray<z.ZodString, "many">;
|
|
19
18
|
requireApproval: z.ZodBoolean;
|
|
20
19
|
maxArchivePercent: z.ZodNumber;
|
|
@@ -30,7 +29,6 @@ export declare const misSyncCallables: {
|
|
|
30
29
|
enabled: boolean;
|
|
31
30
|
allowedSenders: string[];
|
|
32
31
|
studentEmailDomains: string[];
|
|
33
|
-
columnMapping: Partial<Record<"email" | "status" | "mis_student_id" | "first_name" | "last_name" | "year_group" | "course" | "tutor_group" | "start_date" | "leave_date", string>>;
|
|
34
32
|
inactiveStatuses: string[];
|
|
35
33
|
requireApproval: boolean;
|
|
36
34
|
maxArchivePercent: number;
|
|
@@ -44,7 +42,6 @@ export declare const misSyncCallables: {
|
|
|
44
42
|
enabled: boolean;
|
|
45
43
|
allowedSenders: string[];
|
|
46
44
|
studentEmailDomains: string[];
|
|
47
|
-
columnMapping: Partial<Record<"email" | "status" | "mis_student_id" | "first_name" | "last_name" | "year_group" | "course" | "tutor_group" | "start_date" | "leave_date", string>>;
|
|
48
45
|
inactiveStatuses: string[];
|
|
49
46
|
requireApproval: boolean;
|
|
50
47
|
maxArchivePercent: number;
|
|
@@ -17,7 +17,6 @@ export declare const allCallables: {
|
|
|
17
17
|
method: z.ZodEnum<["email", "api"]>;
|
|
18
18
|
allowedSenders: z.ZodArray<z.ZodEffects<z.ZodString, string, string>, "many">;
|
|
19
19
|
studentEmailDomains: z.ZodArray<z.ZodString, "many">;
|
|
20
|
-
columnMapping: z.ZodRecord<z.ZodEnum<["mis_student_id", "first_name", "last_name", "email", "year_group", "course", "tutor_group", "status", "start_date", "leave_date"]>, z.ZodString>;
|
|
21
20
|
inactiveStatuses: z.ZodArray<z.ZodString, "many">;
|
|
22
21
|
requireApproval: z.ZodBoolean;
|
|
23
22
|
maxArchivePercent: z.ZodNumber;
|
|
@@ -33,7 +32,6 @@ export declare const allCallables: {
|
|
|
33
32
|
enabled: boolean;
|
|
34
33
|
allowedSenders: string[];
|
|
35
34
|
studentEmailDomains: string[];
|
|
36
|
-
columnMapping: Partial<Record<"email" | "status" | "mis_student_id" | "first_name" | "last_name" | "year_group" | "course" | "tutor_group" | "start_date" | "leave_date", string>>;
|
|
37
35
|
inactiveStatuses: string[];
|
|
38
36
|
requireApproval: boolean;
|
|
39
37
|
maxArchivePercent: number;
|
|
@@ -47,7 +45,6 @@ export declare const allCallables: {
|
|
|
47
45
|
enabled: boolean;
|
|
48
46
|
allowedSenders: string[];
|
|
49
47
|
studentEmailDomains: string[];
|
|
50
|
-
columnMapping: Partial<Record<"email" | "status" | "mis_student_id" | "first_name" | "last_name" | "year_group" | "course" | "tutor_group" | "start_date" | "leave_date", string>>;
|
|
51
48
|
inactiveStatuses: string[];
|
|
52
49
|
requireApproval: boolean;
|
|
53
50
|
maxArchivePercent: number;
|
|
@@ -621,6 +618,25 @@ export declare const allCallables: {
|
|
|
621
618
|
};
|
|
622
619
|
}>;
|
|
623
620
|
};
|
|
621
|
+
"he-runEnrichment": {
|
|
622
|
+
request: z.ZodObject<{
|
|
623
|
+
sources: z.ZodOptional<z.ZodArray<z.ZodEnum<["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation", "openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"]>, "many">>;
|
|
624
|
+
}, "strip", z.ZodTypeAny, {
|
|
625
|
+
sources?: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[] | undefined;
|
|
626
|
+
}, {
|
|
627
|
+
sources?: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[] | undefined;
|
|
628
|
+
}>;
|
|
629
|
+
response: z.ZodObject<{
|
|
630
|
+
runId: z.ZodString;
|
|
631
|
+
queued: z.ZodArray<z.ZodEnum<["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation", "openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"]>, "many">;
|
|
632
|
+
}, "strip", z.ZodTypeAny, {
|
|
633
|
+
runId: string;
|
|
634
|
+
queued: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[];
|
|
635
|
+
}, {
|
|
636
|
+
runId: string;
|
|
637
|
+
queued: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[];
|
|
638
|
+
}>;
|
|
639
|
+
};
|
|
624
640
|
"he-resetRun": {
|
|
625
641
|
request: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
626
642
|
response: z.ZodObject<{
|
|
@@ -2357,6 +2373,25 @@ export declare const callableGroups: {
|
|
|
2357
2373
|
};
|
|
2358
2374
|
}>;
|
|
2359
2375
|
};
|
|
2376
|
+
"he-runEnrichment": {
|
|
2377
|
+
request: z.ZodObject<{
|
|
2378
|
+
sources: z.ZodOptional<z.ZodArray<z.ZodEnum<["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation", "openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"]>, "many">>;
|
|
2379
|
+
}, "strip", z.ZodTypeAny, {
|
|
2380
|
+
sources?: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[] | undefined;
|
|
2381
|
+
}, {
|
|
2382
|
+
sources?: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[] | undefined;
|
|
2383
|
+
}>;
|
|
2384
|
+
response: z.ZodObject<{
|
|
2385
|
+
runId: z.ZodString;
|
|
2386
|
+
queued: z.ZodArray<z.ZodEnum<["areas", "hesaSsr", "hesaFinance", "hesaStudents", "wideningParticipation", "openAlex", "rent", "crime", "localJobs", "weather", "amenities", "population", "finalise"]>, "many">;
|
|
2387
|
+
}, "strip", z.ZodTypeAny, {
|
|
2388
|
+
runId: string;
|
|
2389
|
+
queued: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[];
|
|
2390
|
+
}, {
|
|
2391
|
+
runId: string;
|
|
2392
|
+
queued: ("areas" | "hesaSsr" | "hesaFinance" | "hesaStudents" | "wideningParticipation" | "openAlex" | "rent" | "crime" | "localJobs" | "weather" | "amenities" | "population" | "finalise")[];
|
|
2393
|
+
}>;
|
|
2394
|
+
};
|
|
2360
2395
|
"he-resetRun": {
|
|
2361
2396
|
request: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
2362
2397
|
response: z.ZodObject<{
|
|
@@ -2765,7 +2800,6 @@ export declare const callableGroups: {
|
|
|
2765
2800
|
method: z.ZodEnum<["email", "api"]>;
|
|
2766
2801
|
allowedSenders: z.ZodArray<z.ZodEffects<z.ZodString, string, string>, "many">;
|
|
2767
2802
|
studentEmailDomains: z.ZodArray<z.ZodString, "many">;
|
|
2768
|
-
columnMapping: z.ZodRecord<z.ZodEnum<["mis_student_id", "first_name", "last_name", "email", "year_group", "course", "tutor_group", "status", "start_date", "leave_date"]>, z.ZodString>;
|
|
2769
2803
|
inactiveStatuses: z.ZodArray<z.ZodString, "many">;
|
|
2770
2804
|
requireApproval: z.ZodBoolean;
|
|
2771
2805
|
maxArchivePercent: z.ZodNumber;
|
|
@@ -2781,7 +2815,6 @@ export declare const callableGroups: {
|
|
|
2781
2815
|
enabled: boolean;
|
|
2782
2816
|
allowedSenders: string[];
|
|
2783
2817
|
studentEmailDomains: string[];
|
|
2784
|
-
columnMapping: Partial<Record<"email" | "status" | "mis_student_id" | "first_name" | "last_name" | "year_group" | "course" | "tutor_group" | "start_date" | "leave_date", string>>;
|
|
2785
2818
|
inactiveStatuses: string[];
|
|
2786
2819
|
requireApproval: boolean;
|
|
2787
2820
|
maxArchivePercent: number;
|
|
@@ -2795,7 +2828,6 @@ export declare const callableGroups: {
|
|
|
2795
2828
|
enabled: boolean;
|
|
2796
2829
|
allowedSenders: string[];
|
|
2797
2830
|
studentEmailDomains: string[];
|
|
2798
|
-
columnMapping: Partial<Record<"email" | "status" | "mis_student_id" | "first_name" | "last_name" | "year_group" | "course" | "tutor_group" | "start_date" | "leave_date", string>>;
|
|
2799
2831
|
inactiveStatuses: string[];
|
|
2800
2832
|
requireApproval: boolean;
|
|
2801
2833
|
maxArchivePercent: number;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lookup tables joining Discover Uni courses to the other HE sources.
|
|
3
|
+
*
|
|
4
|
+
* A course carries CAH subject codes (Common Aggregation Hierarchy, e.g.
|
|
5
|
+
* "CAH10-01-02"). The HESA finance and staff tables are published by cost
|
|
6
|
+
* centre instead, so each CAH code is mapped to the cost centre that teaches
|
|
7
|
+
* it, most specific match first: a level-3 code, then its level-2 parent
|
|
8
|
+
* ("CAH10-01"), then its level-1 parent ("CAH10").
|
|
9
|
+
*
|
|
10
|
+
* The CAH -> cost centre table follows HESA's own CAH/cost-centre guidance at
|
|
11
|
+
* the grain a student would recognise. It is deliberately coarse: a cost
|
|
12
|
+
* centre is a budget line, not a course, so any mapping is an approximation
|
|
13
|
+
* and every surface says the figure is for the subject area at that
|
|
14
|
+
* university.
|
|
15
|
+
*/
|
|
16
|
+
/** HESA cost centres (2019/20 onward) by code. */
|
|
17
|
+
export declare const HESA_COST_CENTRES: {
|
|
18
|
+
[code: string]: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* CAH code (level 1, 2 or 3) -> HESA cost centre. Looked up most specific
|
|
22
|
+
* first by `costCentreForCah`. CAH23 (combined and general studies) has no
|
|
23
|
+
* cost centre, so courses under it carry no subject stats.
|
|
24
|
+
*/
|
|
25
|
+
export declare const CAH_TO_COST_CENTRE: {
|
|
26
|
+
[cah: string]: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The CAH level-1, level-2 and level-3 codes of a subject, most specific
|
|
30
|
+
* first. A malformed code yields just itself.
|
|
31
|
+
*
|
|
32
|
+
* @param {string} cah a CAH code at any level, e.g. "CAH10-01-02".
|
|
33
|
+
* @return {string[]} e.g. ["CAH10-01-02", "CAH10-01", "CAH10"].
|
|
34
|
+
*/
|
|
35
|
+
export declare function cahAncestors(cah: string): string[];
|
|
36
|
+
/**
|
|
37
|
+
* The HESA cost centre a CAH subject is taught under, most specific mapping
|
|
38
|
+
* first.
|
|
39
|
+
*
|
|
40
|
+
* @param {string|undefined} cah a CAH code at any level.
|
|
41
|
+
* @return {string|undefined} the cost centre code, or undefined when none
|
|
42
|
+
* applies (combined studies, or an unknown code).
|
|
43
|
+
*/
|
|
44
|
+
export declare function costCentreForCah(cah: string | undefined): string | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* BRES broad industrial groups, as Nomis labels them, keyed by a stable id.
|
|
47
|
+
* The ids are what `HeArea.jobsBySector` and the `jobs_<id>` percentile keys
|
|
48
|
+
* use.
|
|
49
|
+
*/
|
|
50
|
+
export declare const BRES_SECTORS: {
|
|
51
|
+
[id: string]: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Resolve a Nomis BRES industry label to its sector id. Nomis prefixes the
|
|
55
|
+
* labels with a number ("10 : Information & communication (J)") and the
|
|
56
|
+
* edition may swap "&" for "and", so the match ignores both.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} label the label as it appears in the CSV.
|
|
59
|
+
* @return {string|undefined} the sector id, or undefined.
|
|
60
|
+
*/
|
|
61
|
+
export declare function bresSectorForLabel(label: string): string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Careers library category -> the BRES sectors its jobs mostly sit in, so
|
|
64
|
+
* "jobs in the sector you're interested in near this university" can be
|
|
65
|
+
* scored from the student's interests.
|
|
66
|
+
*/
|
|
67
|
+
export declare const CAREER_CATEGORY_SECTORS: {
|
|
68
|
+
[category: string]: string[];
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* The BRES sectors for a set of career interest categories, de-duplicated in
|
|
72
|
+
* the order the categories were given.
|
|
73
|
+
*
|
|
74
|
+
* @param {string[]} categories careers library categories.
|
|
75
|
+
* @return {string[]} sector ids.
|
|
76
|
+
*/
|
|
77
|
+
export declare function sectorsForCategories(categories: string[]): string[];
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lookup tables joining Discover Uni courses to the other HE sources.
|
|
4
|
+
*
|
|
5
|
+
* A course carries CAH subject codes (Common Aggregation Hierarchy, e.g.
|
|
6
|
+
* "CAH10-01-02"). The HESA finance and staff tables are published by cost
|
|
7
|
+
* centre instead, so each CAH code is mapped to the cost centre that teaches
|
|
8
|
+
* it, most specific match first: a level-3 code, then its level-2 parent
|
|
9
|
+
* ("CAH10-01"), then its level-1 parent ("CAH10").
|
|
10
|
+
*
|
|
11
|
+
* The CAH -> cost centre table follows HESA's own CAH/cost-centre guidance at
|
|
12
|
+
* the grain a student would recognise. It is deliberately coarse: a cost
|
|
13
|
+
* centre is a budget line, not a course, so any mapping is an approximation
|
|
14
|
+
* and every surface says the figure is for the subject area at that
|
|
15
|
+
* university.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.CAREER_CATEGORY_SECTORS = exports.BRES_SECTORS = exports.CAH_TO_COST_CENTRE = exports.HESA_COST_CENTRES = void 0;
|
|
19
|
+
exports.cahAncestors = cahAncestors;
|
|
20
|
+
exports.costCentreForCah = costCentreForCah;
|
|
21
|
+
exports.bresSectorForLabel = bresSectorForLabel;
|
|
22
|
+
exports.sectorsForCategories = sectorsForCategories;
|
|
23
|
+
/** HESA cost centres (2019/20 onward) by code. */
|
|
24
|
+
exports.HESA_COST_CENTRES = {
|
|
25
|
+
"101": "Clinical medicine",
|
|
26
|
+
"102": "Clinical dentistry",
|
|
27
|
+
"103": "Nursing and allied health professions",
|
|
28
|
+
"104": "Psychology and behavioural sciences",
|
|
29
|
+
"105": "Health and community studies",
|
|
30
|
+
"106": "Anatomy and physiology",
|
|
31
|
+
"107": "Pharmacy and pharmacology",
|
|
32
|
+
"108": "Sports science and leisure studies",
|
|
33
|
+
"109": "Veterinary science",
|
|
34
|
+
"110": "Agriculture, forestry and food science",
|
|
35
|
+
"111": "Earth, marine and environmental sciences",
|
|
36
|
+
"112": "Biosciences",
|
|
37
|
+
"113": "Chemistry",
|
|
38
|
+
"114": "Physics",
|
|
39
|
+
"115": "General engineering",
|
|
40
|
+
"116": "Chemical engineering",
|
|
41
|
+
"117": "Mineral, metallurgy and materials engineering",
|
|
42
|
+
"118": "Civil engineering",
|
|
43
|
+
"119": "Electrical, electronic and computer engineering",
|
|
44
|
+
"120": "Mechanical, aero and production engineering",
|
|
45
|
+
"121": "IT, systems sciences and computer software engineering",
|
|
46
|
+
"122": "Mathematics",
|
|
47
|
+
"123": "Architecture, built environment and planning",
|
|
48
|
+
"124": "Geography and environmental studies",
|
|
49
|
+
"125": "Area studies",
|
|
50
|
+
"126": "Archaeology",
|
|
51
|
+
"127": "Anthropology and development studies",
|
|
52
|
+
"128": "Politics and international studies",
|
|
53
|
+
"129": "Economics and econometrics",
|
|
54
|
+
"130": "Law",
|
|
55
|
+
"131": "Social work and social policy",
|
|
56
|
+
"132": "Sociology",
|
|
57
|
+
"133": "Business and management studies",
|
|
58
|
+
"134": "Catering and hospitality management",
|
|
59
|
+
"135": "Education",
|
|
60
|
+
"136": "Continuing education",
|
|
61
|
+
"137": "Modern languages",
|
|
62
|
+
"138": "English language and literature",
|
|
63
|
+
"139": "History",
|
|
64
|
+
"140": "Classics",
|
|
65
|
+
"141": "Philosophy",
|
|
66
|
+
"142": "Theology and religious studies",
|
|
67
|
+
"143": "Art and design",
|
|
68
|
+
"144": "Music, dance, drama and performing arts",
|
|
69
|
+
"145": "Media studies",
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* CAH code (level 1, 2 or 3) -> HESA cost centre. Looked up most specific
|
|
73
|
+
* first by `costCentreForCah`. CAH23 (combined and general studies) has no
|
|
74
|
+
* cost centre, so courses under it carry no subject stats.
|
|
75
|
+
*/
|
|
76
|
+
exports.CAH_TO_COST_CENTRE = {
|
|
77
|
+
// Medicine and dentistry
|
|
78
|
+
"CAH01": "101",
|
|
79
|
+
"CAH01-01-04": "102",
|
|
80
|
+
// Subjects allied to medicine
|
|
81
|
+
"CAH02": "103",
|
|
82
|
+
"CAH02-01": "107",
|
|
83
|
+
"CAH02-02": "106",
|
|
84
|
+
// Biological and sport sciences
|
|
85
|
+
"CAH03": "112",
|
|
86
|
+
"CAH03-02": "108",
|
|
87
|
+
// Psychology
|
|
88
|
+
"CAH04": "104",
|
|
89
|
+
// Veterinary sciences
|
|
90
|
+
"CAH05": "109",
|
|
91
|
+
// Agriculture, food and related studies
|
|
92
|
+
"CAH06": "110",
|
|
93
|
+
// Physical sciences
|
|
94
|
+
"CAH07": "114",
|
|
95
|
+
"CAH07-01": "114",
|
|
96
|
+
"CAH07-02": "113",
|
|
97
|
+
// Mathematical sciences
|
|
98
|
+
"CAH09": "122",
|
|
99
|
+
// Engineering and technology
|
|
100
|
+
"CAH10": "115",
|
|
101
|
+
"CAH10-01-01": "115",
|
|
102
|
+
"CAH10-01-02": "120",
|
|
103
|
+
"CAH10-01-03": "120",
|
|
104
|
+
"CAH10-01-04": "120",
|
|
105
|
+
"CAH10-01-05": "120",
|
|
106
|
+
"CAH10-01-06": "115",
|
|
107
|
+
"CAH10-01-07": "118",
|
|
108
|
+
"CAH10-01-08": "119",
|
|
109
|
+
"CAH10-01-09": "116",
|
|
110
|
+
"CAH10-03": "117",
|
|
111
|
+
// Computing
|
|
112
|
+
"CAH11": "121",
|
|
113
|
+
// Architecture, building and planning
|
|
114
|
+
"CAH13": "123",
|
|
115
|
+
// Social sciences
|
|
116
|
+
"CAH15": "132",
|
|
117
|
+
"CAH15-01": "132",
|
|
118
|
+
"CAH15-02": "129",
|
|
119
|
+
"CAH15-03": "128",
|
|
120
|
+
"CAH15-04": "131",
|
|
121
|
+
// Law
|
|
122
|
+
"CAH16": "130",
|
|
123
|
+
// Business and management
|
|
124
|
+
"CAH17": "133",
|
|
125
|
+
// Language and area studies
|
|
126
|
+
"CAH19": "137",
|
|
127
|
+
"CAH19-01": "138",
|
|
128
|
+
// Historical, philosophical and religious studies
|
|
129
|
+
"CAH20": "139",
|
|
130
|
+
"CAH20-01": "139",
|
|
131
|
+
"CAH20-02": "141",
|
|
132
|
+
// Education and teaching
|
|
133
|
+
"CAH22": "135",
|
|
134
|
+
// Media, journalism and communications
|
|
135
|
+
"CAH24": "145",
|
|
136
|
+
// Design, and creative and performing arts
|
|
137
|
+
"CAH25": "143",
|
|
138
|
+
"CAH25-01": "143",
|
|
139
|
+
"CAH25-02": "144",
|
|
140
|
+
// Geography, earth and environmental studies
|
|
141
|
+
"CAH26": "124",
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* The CAH level-1, level-2 and level-3 codes of a subject, most specific
|
|
145
|
+
* first. A malformed code yields just itself.
|
|
146
|
+
*
|
|
147
|
+
* @param {string} cah a CAH code at any level, e.g. "CAH10-01-02".
|
|
148
|
+
* @return {string[]} e.g. ["CAH10-01-02", "CAH10-01", "CAH10"].
|
|
149
|
+
*/
|
|
150
|
+
function cahAncestors(cah) {
|
|
151
|
+
const code = (cah || "").trim().toUpperCase();
|
|
152
|
+
const m = /^(CAH\d{2})(?:-(\d{2}))?(?:-(\d{2}))?$/.exec(code);
|
|
153
|
+
if (!m)
|
|
154
|
+
return code ? [code] : [];
|
|
155
|
+
const out = [];
|
|
156
|
+
if (m[3])
|
|
157
|
+
out.push(`${m[1]}-${m[2]}-${m[3]}`);
|
|
158
|
+
if (m[2])
|
|
159
|
+
out.push(`${m[1]}-${m[2]}`);
|
|
160
|
+
out.push(m[1]);
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* The HESA cost centre a CAH subject is taught under, most specific mapping
|
|
165
|
+
* first.
|
|
166
|
+
*
|
|
167
|
+
* @param {string|undefined} cah a CAH code at any level.
|
|
168
|
+
* @return {string|undefined} the cost centre code, or undefined when none
|
|
169
|
+
* applies (combined studies, or an unknown code).
|
|
170
|
+
*/
|
|
171
|
+
function costCentreForCah(cah) {
|
|
172
|
+
if (!cah)
|
|
173
|
+
return undefined;
|
|
174
|
+
for (const code of cahAncestors(cah)) {
|
|
175
|
+
const cc = exports.CAH_TO_COST_CENTRE[code];
|
|
176
|
+
if (cc)
|
|
177
|
+
return cc;
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* BRES broad industrial groups, as Nomis labels them, keyed by a stable id.
|
|
183
|
+
* The ids are what `HeArea.jobsBySector` and the `jobs_<id>` percentile keys
|
|
184
|
+
* use.
|
|
185
|
+
*/
|
|
186
|
+
exports.BRES_SECTORS = {
|
|
187
|
+
agriculture: "Agriculture, forestry & fishing",
|
|
188
|
+
utilities: "Mining, quarrying & utilities",
|
|
189
|
+
manufacturing: "Manufacturing",
|
|
190
|
+
construction: "Construction",
|
|
191
|
+
motor: "Motor trades",
|
|
192
|
+
wholesale: "Wholesale",
|
|
193
|
+
retail: "Retail",
|
|
194
|
+
transport: "Transport & storage (inc postal)",
|
|
195
|
+
hospitality: "Accommodation & food services",
|
|
196
|
+
ict: "Information & communication",
|
|
197
|
+
finance: "Financial & insurance",
|
|
198
|
+
property: "Property",
|
|
199
|
+
professional: "Professional, scientific & technical",
|
|
200
|
+
business: "Business administration & support services",
|
|
201
|
+
publicAdmin: "Public administration & defence",
|
|
202
|
+
education: "Education",
|
|
203
|
+
health: "Health",
|
|
204
|
+
arts: "Arts, entertainment, recreation & other services",
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* Resolve a Nomis BRES industry label to its sector id. Nomis prefixes the
|
|
208
|
+
* labels with a number ("10 : Information & communication (J)") and the
|
|
209
|
+
* edition may swap "&" for "and", so the match ignores both.
|
|
210
|
+
*
|
|
211
|
+
* @param {string} label the label as it appears in the CSV.
|
|
212
|
+
* @return {string|undefined} the sector id, or undefined.
|
|
213
|
+
*/
|
|
214
|
+
function bresSectorForLabel(label) {
|
|
215
|
+
const norm = (s) => s.toLowerCase()
|
|
216
|
+
.replace(/^\s*\d+\s*:\s*/, "")
|
|
217
|
+
.replace(/\([a-z,\s-]+\)\s*$/i, "")
|
|
218
|
+
.replace(/\band\b/g, "&")
|
|
219
|
+
.replace(/[^a-z&]+/g, "");
|
|
220
|
+
const target = norm(label);
|
|
221
|
+
if (!target)
|
|
222
|
+
return undefined;
|
|
223
|
+
return Object.keys(exports.BRES_SECTORS).find((id) => norm(exports.BRES_SECTORS[id]) === target);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Careers library category -> the BRES sectors its jobs mostly sit in, so
|
|
227
|
+
* "jobs in the sector you're interested in near this university" can be
|
|
228
|
+
* scored from the student's interests.
|
|
229
|
+
*/
|
|
230
|
+
exports.CAREER_CATEGORY_SECTORS = {
|
|
231
|
+
"Technology & Computing": ["ict"],
|
|
232
|
+
"Engineering & Manufacturing": ["manufacturing", "utilities"],
|
|
233
|
+
"Science & Research": ["professional"],
|
|
234
|
+
"Medicine & Healthcare": ["health"],
|
|
235
|
+
"Education & Training": ["education"],
|
|
236
|
+
"Business & Finance": ["finance", "business"],
|
|
237
|
+
"Law & Public Services": ["publicAdmin", "professional"],
|
|
238
|
+
"Creative Arts & Design": ["arts", "professional"],
|
|
239
|
+
"Media & Communications": ["ict", "arts"],
|
|
240
|
+
"Sport & Leisure": ["arts"],
|
|
241
|
+
"Hospitality & Tourism": ["hospitality"],
|
|
242
|
+
"Construction & Property": ["construction", "property"],
|
|
243
|
+
"Agriculture & Environment": ["agriculture"],
|
|
244
|
+
"Social Care & Charity": ["health"],
|
|
245
|
+
"Armed Forces & Emergency Services": ["publicAdmin"],
|
|
246
|
+
"Retail & Sales": ["retail", "wholesale"],
|
|
247
|
+
"Transport & Logistics": ["transport", "motor"],
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* The BRES sectors for a set of career interest categories, de-duplicated in
|
|
251
|
+
* the order the categories were given.
|
|
252
|
+
*
|
|
253
|
+
* @param {string[]} categories careers library categories.
|
|
254
|
+
* @return {string[]} sector ids.
|
|
255
|
+
*/
|
|
256
|
+
function sectorsForCategories(categories) {
|
|
257
|
+
const out = [];
|
|
258
|
+
for (const c of categories) {
|
|
259
|
+
for (const s of exports.CAREER_CATEGORY_SECTORS[c] ?? []) {
|
|
260
|
+
if (!out.includes(s))
|
|
261
|
+
out.push(s);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return out;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=heMappings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heMappings.js","sourceRoot":"","sources":["../src/heMappings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const heMappings_1 = require("./heMappings");
|
|
4
|
+
const lmiCategories_1 = require("./lmiCategories");
|
|
5
|
+
describe("cahAncestors", () => {
|
|
6
|
+
it("lists a level-3 code's parents, most specific first", () => {
|
|
7
|
+
expect((0, heMappings_1.cahAncestors)("CAH10-01-02")).toEqual(["CAH10-01-02", "CAH10-01", "CAH10"]);
|
|
8
|
+
});
|
|
9
|
+
it("handles level-2 and level-1 codes and normalises case", () => {
|
|
10
|
+
expect((0, heMappings_1.cahAncestors)("cah10-01")).toEqual(["CAH10-01", "CAH10"]);
|
|
11
|
+
expect((0, heMappings_1.cahAncestors)("CAH11")).toEqual(["CAH11"]);
|
|
12
|
+
});
|
|
13
|
+
it("returns a malformed code as itself and nothing for blank", () => {
|
|
14
|
+
expect((0, heMappings_1.cahAncestors)("X1")).toEqual(["X1"]);
|
|
15
|
+
expect((0, heMappings_1.cahAncestors)("")).toEqual([]);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe("costCentreForCah", () => {
|
|
19
|
+
it("prefers the most specific mapping", () => {
|
|
20
|
+
expect((0, heMappings_1.costCentreForCah)("CAH10-01-07")).toBe("118");
|
|
21
|
+
expect((0, heMappings_1.costCentreForCah)("CAH10-02-01")).toBe("115");
|
|
22
|
+
expect((0, heMappings_1.costCentreForCah)("CAH15-02-01")).toBe("129");
|
|
23
|
+
});
|
|
24
|
+
it("falls back to the level-1 mapping", () => {
|
|
25
|
+
expect((0, heMappings_1.costCentreForCah)("CAH11-01-05")).toBe("121");
|
|
26
|
+
});
|
|
27
|
+
it("has no cost centre for combined studies or unknown codes", () => {
|
|
28
|
+
expect((0, heMappings_1.costCentreForCah)("CAH23-01-01")).toBeUndefined();
|
|
29
|
+
expect((0, heMappings_1.costCentreForCah)(undefined)).toBeUndefined();
|
|
30
|
+
expect((0, heMappings_1.costCentreForCah)("CAH99")).toBeUndefined();
|
|
31
|
+
});
|
|
32
|
+
it("maps only to cost centres that exist", () => {
|
|
33
|
+
Object.values(heMappings_1.CAH_TO_COST_CENTRE).forEach((cc) => expect(heMappings_1.HESA_COST_CENTRES[cc]).toBeDefined());
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe("bresSectorForLabel", () => {
|
|
37
|
+
it("matches Nomis labels with their numeric prefix and SIC letters", () => {
|
|
38
|
+
expect((0, heMappings_1.bresSectorForLabel)("10 : Information & communication (J)")).toBe("ict");
|
|
39
|
+
expect((0, heMappings_1.bresSectorForLabel)("18 : Arts, entertainment, recreation & other services (R,S,T and U)")).toBe("arts");
|
|
40
|
+
expect((0, heMappings_1.bresSectorForLabel)("Transport & storage (inc postal)")).toBe("transport");
|
|
41
|
+
});
|
|
42
|
+
it("treats 'and' like '&'", () => {
|
|
43
|
+
expect((0, heMappings_1.bresSectorForLabel)("Agriculture, forestry and fishing")).toBe("agriculture");
|
|
44
|
+
});
|
|
45
|
+
it("is undefined for anything else", () => {
|
|
46
|
+
expect((0, heMappings_1.bresSectorForLabel)("Total")).toBeUndefined();
|
|
47
|
+
expect((0, heMappings_1.bresSectorForLabel)("")).toBeUndefined();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe("career category sectors", () => {
|
|
51
|
+
it("covers every careers library category with known sectors", () => {
|
|
52
|
+
lmiCategories_1.CAREER_LIBRARY_CATEGORIES.forEach((c) => {
|
|
53
|
+
expect(heMappings_1.CAREER_CATEGORY_SECTORS[c]?.length).toBeGreaterThan(0);
|
|
54
|
+
heMappings_1.CAREER_CATEGORY_SECTORS[c].forEach((s) => expect(heMappings_1.BRES_SECTORS[s]).toBeDefined());
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
it("de-duplicates in order", () => {
|
|
58
|
+
expect((0, heMappings_1.sectorsForCategories)(["Technology & Computing", "Media & Communications"])).toEqual(["ict", "arts"]);
|
|
59
|
+
expect((0, heMappings_1.sectorsForCategories)(["Unknown"])).toEqual([]);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=heMappings.test.js.map
|