placementt-core 1.400.1143 → 1.400.1144
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/checks.d.ts +4 -4
- package/lib/callables/registry.d.ts +358 -12
- package/lib/callables/surveys.d.ts +2 -2
- package/lib/callables/wonde.d.ts +187 -1
- package/lib/callables/wonde.js +47 -1
- package/lib/callables/wonde.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/letters.d.ts +22 -0
- package/lib/letters.js +75 -0
- package/lib/letters.js.map +1 -0
- package/lib/typeDefinitions.d.ts +8 -0
- package/lib/typeDefinitions.js.map +1 -1
- package/package.json +1 -1
- package/src/callables/wonde.ts +47 -1
- package/src/index.ts +1 -0
- package/src/letters.ts +91 -0
- package/src/typeDefinitions.ts +6 -0
|
@@ -31,12 +31,12 @@ export declare const checksCallables: {
|
|
|
31
31
|
}, "strip", z.ZodTypeAny, {
|
|
32
32
|
label: string;
|
|
33
33
|
done?: boolean | undefined;
|
|
34
|
-
owner?: "
|
|
34
|
+
owner?: "student" | "staff" | undefined;
|
|
35
35
|
dueDate?: string | undefined;
|
|
36
36
|
}, {
|
|
37
37
|
label: string;
|
|
38
38
|
done?: boolean | undefined;
|
|
39
|
-
owner?: "
|
|
39
|
+
owner?: "student" | "staff" | undefined;
|
|
40
40
|
dueDate?: string | undefined;
|
|
41
41
|
}>, "many">>;
|
|
42
42
|
concern: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -48,7 +48,7 @@ export declare const checksCallables: {
|
|
|
48
48
|
actions?: {
|
|
49
49
|
label: string;
|
|
50
50
|
done?: boolean | undefined;
|
|
51
|
-
owner?: "
|
|
51
|
+
owner?: "student" | "staff" | undefined;
|
|
52
52
|
dueDate?: string | undefined;
|
|
53
53
|
}[] | undefined;
|
|
54
54
|
staffNotes?: string | undefined;
|
|
@@ -63,7 +63,7 @@ export declare const checksCallables: {
|
|
|
63
63
|
actions?: {
|
|
64
64
|
label: string;
|
|
65
65
|
done?: boolean | undefined;
|
|
66
|
-
owner?: "
|
|
66
|
+
owner?: "student" | "staff" | undefined;
|
|
67
67
|
dueDate?: string | undefined;
|
|
68
68
|
}[] | undefined;
|
|
69
69
|
staffNotes?: string | undefined;
|
|
@@ -804,6 +804,179 @@ export declare const allCallables: {
|
|
|
804
804
|
taskId: string;
|
|
805
805
|
}>;
|
|
806
806
|
};
|
|
807
|
+
"wonde-findDualRegistrations": {
|
|
808
|
+
request: z.ZodObject<{
|
|
809
|
+
oId: z.ZodString;
|
|
810
|
+
}, "strip", z.ZodTypeAny, {
|
|
811
|
+
oId: string;
|
|
812
|
+
}, {
|
|
813
|
+
oId: string;
|
|
814
|
+
}>;
|
|
815
|
+
response: z.ZodObject<{
|
|
816
|
+
trustId: z.ZodString;
|
|
817
|
+
schools: z.ZodArray<z.ZodObject<{
|
|
818
|
+
oId: z.ZodString;
|
|
819
|
+
name: z.ZodString;
|
|
820
|
+
rosterSize: z.ZodNumber;
|
|
821
|
+
missingUpn: z.ZodNumber;
|
|
822
|
+
enrolmentStatuses: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
823
|
+
}, "strip", z.ZodTypeAny, {
|
|
824
|
+
name: string;
|
|
825
|
+
oId: string;
|
|
826
|
+
rosterSize: number;
|
|
827
|
+
missingUpn: number;
|
|
828
|
+
enrolmentStatuses: Record<string, number>;
|
|
829
|
+
}, {
|
|
830
|
+
name: string;
|
|
831
|
+
oId: string;
|
|
832
|
+
rosterSize: number;
|
|
833
|
+
missingUpn: number;
|
|
834
|
+
enrolmentStatuses: Record<string, number>;
|
|
835
|
+
}>, "many">;
|
|
836
|
+
skipped: z.ZodArray<z.ZodObject<{
|
|
837
|
+
oId: z.ZodString;
|
|
838
|
+
name: z.ZodString;
|
|
839
|
+
reason: z.ZodString;
|
|
840
|
+
}, "strip", z.ZodTypeAny, {
|
|
841
|
+
name: string;
|
|
842
|
+
reason: string;
|
|
843
|
+
oId: string;
|
|
844
|
+
}, {
|
|
845
|
+
name: string;
|
|
846
|
+
reason: string;
|
|
847
|
+
oId: string;
|
|
848
|
+
}>, "many">;
|
|
849
|
+
matches: z.ZodArray<z.ZodObject<{
|
|
850
|
+
matchedOn: z.ZodEnum<["upn", "nameDob"]>;
|
|
851
|
+
upn: z.ZodNullable<z.ZodString>;
|
|
852
|
+
forename: z.ZodString;
|
|
853
|
+
surname: z.ZodString;
|
|
854
|
+
dateOfBirth: z.ZodNullable<z.ZodString>;
|
|
855
|
+
enrolments: z.ZodArray<z.ZodObject<{
|
|
856
|
+
oId: z.ZodString;
|
|
857
|
+
schoolName: z.ZodString;
|
|
858
|
+
wondeId: z.ZodString;
|
|
859
|
+
email: z.ZodNullable<z.ZodString>;
|
|
860
|
+
year: z.ZodNullable<z.ZodString>;
|
|
861
|
+
formGroup: z.ZodNullable<z.ZodString>;
|
|
862
|
+
enrolmentStatus: z.ZodNullable<z.ZodString>;
|
|
863
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
864
|
+
}, "strip", z.ZodTypeAny, {
|
|
865
|
+
email: string | null;
|
|
866
|
+
year: string | null;
|
|
867
|
+
oId: string;
|
|
868
|
+
userId: string | null;
|
|
869
|
+
schoolName: string;
|
|
870
|
+
wondeId: string;
|
|
871
|
+
formGroup: string | null;
|
|
872
|
+
enrolmentStatus: string | null;
|
|
873
|
+
}, {
|
|
874
|
+
email: string | null;
|
|
875
|
+
year: string | null;
|
|
876
|
+
oId: string;
|
|
877
|
+
userId: string | null;
|
|
878
|
+
schoolName: string;
|
|
879
|
+
wondeId: string;
|
|
880
|
+
formGroup: string | null;
|
|
881
|
+
enrolmentStatus: string | null;
|
|
882
|
+
}>, "many">;
|
|
883
|
+
}, "strip", z.ZodTypeAny, {
|
|
884
|
+
upn: string | null;
|
|
885
|
+
matchedOn: "upn" | "nameDob";
|
|
886
|
+
forename: string;
|
|
887
|
+
surname: string;
|
|
888
|
+
dateOfBirth: string | null;
|
|
889
|
+
enrolments: {
|
|
890
|
+
email: string | null;
|
|
891
|
+
year: string | null;
|
|
892
|
+
oId: string;
|
|
893
|
+
userId: string | null;
|
|
894
|
+
schoolName: string;
|
|
895
|
+
wondeId: string;
|
|
896
|
+
formGroup: string | null;
|
|
897
|
+
enrolmentStatus: string | null;
|
|
898
|
+
}[];
|
|
899
|
+
}, {
|
|
900
|
+
upn: string | null;
|
|
901
|
+
matchedOn: "upn" | "nameDob";
|
|
902
|
+
forename: string;
|
|
903
|
+
surname: string;
|
|
904
|
+
dateOfBirth: string | null;
|
|
905
|
+
enrolments: {
|
|
906
|
+
email: string | null;
|
|
907
|
+
year: string | null;
|
|
908
|
+
oId: string;
|
|
909
|
+
userId: string | null;
|
|
910
|
+
schoolName: string;
|
|
911
|
+
wondeId: string;
|
|
912
|
+
formGroup: string | null;
|
|
913
|
+
enrolmentStatus: string | null;
|
|
914
|
+
}[];
|
|
915
|
+
}>, "many">;
|
|
916
|
+
}, "strip", z.ZodTypeAny, {
|
|
917
|
+
skipped: {
|
|
918
|
+
name: string;
|
|
919
|
+
reason: string;
|
|
920
|
+
oId: string;
|
|
921
|
+
}[];
|
|
922
|
+
matches: {
|
|
923
|
+
upn: string | null;
|
|
924
|
+
matchedOn: "upn" | "nameDob";
|
|
925
|
+
forename: string;
|
|
926
|
+
surname: string;
|
|
927
|
+
dateOfBirth: string | null;
|
|
928
|
+
enrolments: {
|
|
929
|
+
email: string | null;
|
|
930
|
+
year: string | null;
|
|
931
|
+
oId: string;
|
|
932
|
+
userId: string | null;
|
|
933
|
+
schoolName: string;
|
|
934
|
+
wondeId: string;
|
|
935
|
+
formGroup: string | null;
|
|
936
|
+
enrolmentStatus: string | null;
|
|
937
|
+
}[];
|
|
938
|
+
}[];
|
|
939
|
+
schools: {
|
|
940
|
+
name: string;
|
|
941
|
+
oId: string;
|
|
942
|
+
rosterSize: number;
|
|
943
|
+
missingUpn: number;
|
|
944
|
+
enrolmentStatuses: Record<string, number>;
|
|
945
|
+
}[];
|
|
946
|
+
trustId: string;
|
|
947
|
+
}, {
|
|
948
|
+
skipped: {
|
|
949
|
+
name: string;
|
|
950
|
+
reason: string;
|
|
951
|
+
oId: string;
|
|
952
|
+
}[];
|
|
953
|
+
matches: {
|
|
954
|
+
upn: string | null;
|
|
955
|
+
matchedOn: "upn" | "nameDob";
|
|
956
|
+
forename: string;
|
|
957
|
+
surname: string;
|
|
958
|
+
dateOfBirth: string | null;
|
|
959
|
+
enrolments: {
|
|
960
|
+
email: string | null;
|
|
961
|
+
year: string | null;
|
|
962
|
+
oId: string;
|
|
963
|
+
userId: string | null;
|
|
964
|
+
schoolName: string;
|
|
965
|
+
wondeId: string;
|
|
966
|
+
formGroup: string | null;
|
|
967
|
+
enrolmentStatus: string | null;
|
|
968
|
+
}[];
|
|
969
|
+
}[];
|
|
970
|
+
schools: {
|
|
971
|
+
name: string;
|
|
972
|
+
oId: string;
|
|
973
|
+
rosterSize: number;
|
|
974
|
+
missingUpn: number;
|
|
975
|
+
enrolmentStatuses: Record<string, number>;
|
|
976
|
+
}[];
|
|
977
|
+
trustId: string;
|
|
978
|
+
}>;
|
|
979
|
+
};
|
|
807
980
|
"e2e-redeemSignInLink": {
|
|
808
981
|
request: z.ZodObject<{
|
|
809
982
|
token: z.ZodString;
|
|
@@ -1499,12 +1672,12 @@ export declare const allCallables: {
|
|
|
1499
1672
|
}, "strip", z.ZodTypeAny, {
|
|
1500
1673
|
label: string;
|
|
1501
1674
|
done?: boolean | undefined;
|
|
1502
|
-
owner?: "
|
|
1675
|
+
owner?: "student" | "staff" | undefined;
|
|
1503
1676
|
dueDate?: string | undefined;
|
|
1504
1677
|
}, {
|
|
1505
1678
|
label: string;
|
|
1506
1679
|
done?: boolean | undefined;
|
|
1507
|
-
owner?: "
|
|
1680
|
+
owner?: "student" | "staff" | undefined;
|
|
1508
1681
|
dueDate?: string | undefined;
|
|
1509
1682
|
}>, "many">>;
|
|
1510
1683
|
concern: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1516,7 +1689,7 @@ export declare const allCallables: {
|
|
|
1516
1689
|
actions?: {
|
|
1517
1690
|
label: string;
|
|
1518
1691
|
done?: boolean | undefined;
|
|
1519
|
-
owner?: "
|
|
1692
|
+
owner?: "student" | "staff" | undefined;
|
|
1520
1693
|
dueDate?: string | undefined;
|
|
1521
1694
|
}[] | undefined;
|
|
1522
1695
|
staffNotes?: string | undefined;
|
|
@@ -1531,7 +1704,7 @@ export declare const allCallables: {
|
|
|
1531
1704
|
actions?: {
|
|
1532
1705
|
label: string;
|
|
1533
1706
|
done?: boolean | undefined;
|
|
1534
|
-
owner?: "
|
|
1707
|
+
owner?: "student" | "staff" | undefined;
|
|
1535
1708
|
dueDate?: string | undefined;
|
|
1536
1709
|
}[] | undefined;
|
|
1537
1710
|
staffNotes?: string | undefined;
|
|
@@ -2076,14 +2249,14 @@ export declare const allCallables: {
|
|
|
2076
2249
|
requestId: string;
|
|
2077
2250
|
token?: string | undefined;
|
|
2078
2251
|
response?: unknown;
|
|
2079
|
-
submittedBy?: "parent" | "
|
|
2252
|
+
submittedBy?: "parent" | "employer" | "student" | "staff" | "trustedContact" | undefined;
|
|
2080
2253
|
rater?: "students" | "parents" | "trustedContact" | "employers" | undefined;
|
|
2081
2254
|
noChange?: boolean | undefined;
|
|
2082
2255
|
}, {
|
|
2083
2256
|
requestId: string;
|
|
2084
2257
|
token?: string | undefined;
|
|
2085
2258
|
response?: unknown;
|
|
2086
|
-
submittedBy?: "parent" | "
|
|
2259
|
+
submittedBy?: "parent" | "employer" | "student" | "staff" | "trustedContact" | undefined;
|
|
2087
2260
|
rater?: "students" | "parents" | "trustedContact" | "employers" | undefined;
|
|
2088
2261
|
noChange?: boolean | undefined;
|
|
2089
2262
|
}>;
|
|
@@ -2862,14 +3035,14 @@ export declare const callableGroups: {
|
|
|
2862
3035
|
requestId: string;
|
|
2863
3036
|
token?: string | undefined;
|
|
2864
3037
|
response?: unknown;
|
|
2865
|
-
submittedBy?: "parent" | "
|
|
3038
|
+
submittedBy?: "parent" | "employer" | "student" | "staff" | "trustedContact" | undefined;
|
|
2866
3039
|
rater?: "students" | "parents" | "trustedContact" | "employers" | undefined;
|
|
2867
3040
|
noChange?: boolean | undefined;
|
|
2868
3041
|
}, {
|
|
2869
3042
|
requestId: string;
|
|
2870
3043
|
token?: string | undefined;
|
|
2871
3044
|
response?: unknown;
|
|
2872
|
-
submittedBy?: "parent" | "
|
|
3045
|
+
submittedBy?: "parent" | "employer" | "student" | "staff" | "trustedContact" | undefined;
|
|
2873
3046
|
rater?: "students" | "parents" | "trustedContact" | "employers" | undefined;
|
|
2874
3047
|
noChange?: boolean | undefined;
|
|
2875
3048
|
}>;
|
|
@@ -2900,12 +3073,12 @@ export declare const callableGroups: {
|
|
|
2900
3073
|
}, "strip", z.ZodTypeAny, {
|
|
2901
3074
|
label: string;
|
|
2902
3075
|
done?: boolean | undefined;
|
|
2903
|
-
owner?: "
|
|
3076
|
+
owner?: "student" | "staff" | undefined;
|
|
2904
3077
|
dueDate?: string | undefined;
|
|
2905
3078
|
}, {
|
|
2906
3079
|
label: string;
|
|
2907
3080
|
done?: boolean | undefined;
|
|
2908
|
-
owner?: "
|
|
3081
|
+
owner?: "student" | "staff" | undefined;
|
|
2909
3082
|
dueDate?: string | undefined;
|
|
2910
3083
|
}>, "many">>;
|
|
2911
3084
|
concern: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -2917,7 +3090,7 @@ export declare const callableGroups: {
|
|
|
2917
3090
|
actions?: {
|
|
2918
3091
|
label: string;
|
|
2919
3092
|
done?: boolean | undefined;
|
|
2920
|
-
owner?: "
|
|
3093
|
+
owner?: "student" | "staff" | undefined;
|
|
2921
3094
|
dueDate?: string | undefined;
|
|
2922
3095
|
}[] | undefined;
|
|
2923
3096
|
staffNotes?: string | undefined;
|
|
@@ -2932,7 +3105,7 @@ export declare const callableGroups: {
|
|
|
2932
3105
|
actions?: {
|
|
2933
3106
|
label: string;
|
|
2934
3107
|
done?: boolean | undefined;
|
|
2935
|
-
owner?: "
|
|
3108
|
+
owner?: "student" | "staff" | undefined;
|
|
2936
3109
|
dueDate?: string | undefined;
|
|
2937
3110
|
}[] | undefined;
|
|
2938
3111
|
staffNotes?: string | undefined;
|
|
@@ -3669,6 +3842,179 @@ export declare const callableGroups: {
|
|
|
3669
3842
|
taskId: string;
|
|
3670
3843
|
}>;
|
|
3671
3844
|
};
|
|
3845
|
+
"wonde-findDualRegistrations": {
|
|
3846
|
+
request: z.ZodObject<{
|
|
3847
|
+
oId: z.ZodString;
|
|
3848
|
+
}, "strip", z.ZodTypeAny, {
|
|
3849
|
+
oId: string;
|
|
3850
|
+
}, {
|
|
3851
|
+
oId: string;
|
|
3852
|
+
}>;
|
|
3853
|
+
response: z.ZodObject<{
|
|
3854
|
+
trustId: z.ZodString;
|
|
3855
|
+
schools: z.ZodArray<z.ZodObject<{
|
|
3856
|
+
oId: z.ZodString;
|
|
3857
|
+
name: z.ZodString;
|
|
3858
|
+
rosterSize: z.ZodNumber;
|
|
3859
|
+
missingUpn: z.ZodNumber;
|
|
3860
|
+
enrolmentStatuses: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
3861
|
+
}, "strip", z.ZodTypeAny, {
|
|
3862
|
+
name: string;
|
|
3863
|
+
oId: string;
|
|
3864
|
+
rosterSize: number;
|
|
3865
|
+
missingUpn: number;
|
|
3866
|
+
enrolmentStatuses: Record<string, number>;
|
|
3867
|
+
}, {
|
|
3868
|
+
name: string;
|
|
3869
|
+
oId: string;
|
|
3870
|
+
rosterSize: number;
|
|
3871
|
+
missingUpn: number;
|
|
3872
|
+
enrolmentStatuses: Record<string, number>;
|
|
3873
|
+
}>, "many">;
|
|
3874
|
+
skipped: z.ZodArray<z.ZodObject<{
|
|
3875
|
+
oId: z.ZodString;
|
|
3876
|
+
name: z.ZodString;
|
|
3877
|
+
reason: z.ZodString;
|
|
3878
|
+
}, "strip", z.ZodTypeAny, {
|
|
3879
|
+
name: string;
|
|
3880
|
+
reason: string;
|
|
3881
|
+
oId: string;
|
|
3882
|
+
}, {
|
|
3883
|
+
name: string;
|
|
3884
|
+
reason: string;
|
|
3885
|
+
oId: string;
|
|
3886
|
+
}>, "many">;
|
|
3887
|
+
matches: z.ZodArray<z.ZodObject<{
|
|
3888
|
+
matchedOn: z.ZodEnum<["upn", "nameDob"]>;
|
|
3889
|
+
upn: z.ZodNullable<z.ZodString>;
|
|
3890
|
+
forename: z.ZodString;
|
|
3891
|
+
surname: z.ZodString;
|
|
3892
|
+
dateOfBirth: z.ZodNullable<z.ZodString>;
|
|
3893
|
+
enrolments: z.ZodArray<z.ZodObject<{
|
|
3894
|
+
oId: z.ZodString;
|
|
3895
|
+
schoolName: z.ZodString;
|
|
3896
|
+
wondeId: z.ZodString;
|
|
3897
|
+
email: z.ZodNullable<z.ZodString>;
|
|
3898
|
+
year: z.ZodNullable<z.ZodString>;
|
|
3899
|
+
formGroup: z.ZodNullable<z.ZodString>;
|
|
3900
|
+
enrolmentStatus: z.ZodNullable<z.ZodString>;
|
|
3901
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
3902
|
+
}, "strip", z.ZodTypeAny, {
|
|
3903
|
+
email: string | null;
|
|
3904
|
+
year: string | null;
|
|
3905
|
+
oId: string;
|
|
3906
|
+
userId: string | null;
|
|
3907
|
+
schoolName: string;
|
|
3908
|
+
wondeId: string;
|
|
3909
|
+
formGroup: string | null;
|
|
3910
|
+
enrolmentStatus: string | null;
|
|
3911
|
+
}, {
|
|
3912
|
+
email: string | null;
|
|
3913
|
+
year: string | null;
|
|
3914
|
+
oId: string;
|
|
3915
|
+
userId: string | null;
|
|
3916
|
+
schoolName: string;
|
|
3917
|
+
wondeId: string;
|
|
3918
|
+
formGroup: string | null;
|
|
3919
|
+
enrolmentStatus: string | null;
|
|
3920
|
+
}>, "many">;
|
|
3921
|
+
}, "strip", z.ZodTypeAny, {
|
|
3922
|
+
upn: string | null;
|
|
3923
|
+
matchedOn: "upn" | "nameDob";
|
|
3924
|
+
forename: string;
|
|
3925
|
+
surname: string;
|
|
3926
|
+
dateOfBirth: string | null;
|
|
3927
|
+
enrolments: {
|
|
3928
|
+
email: string | null;
|
|
3929
|
+
year: string | null;
|
|
3930
|
+
oId: string;
|
|
3931
|
+
userId: string | null;
|
|
3932
|
+
schoolName: string;
|
|
3933
|
+
wondeId: string;
|
|
3934
|
+
formGroup: string | null;
|
|
3935
|
+
enrolmentStatus: string | null;
|
|
3936
|
+
}[];
|
|
3937
|
+
}, {
|
|
3938
|
+
upn: string | null;
|
|
3939
|
+
matchedOn: "upn" | "nameDob";
|
|
3940
|
+
forename: string;
|
|
3941
|
+
surname: string;
|
|
3942
|
+
dateOfBirth: string | null;
|
|
3943
|
+
enrolments: {
|
|
3944
|
+
email: string | null;
|
|
3945
|
+
year: string | null;
|
|
3946
|
+
oId: string;
|
|
3947
|
+
userId: string | null;
|
|
3948
|
+
schoolName: string;
|
|
3949
|
+
wondeId: string;
|
|
3950
|
+
formGroup: string | null;
|
|
3951
|
+
enrolmentStatus: string | null;
|
|
3952
|
+
}[];
|
|
3953
|
+
}>, "many">;
|
|
3954
|
+
}, "strip", z.ZodTypeAny, {
|
|
3955
|
+
skipped: {
|
|
3956
|
+
name: string;
|
|
3957
|
+
reason: string;
|
|
3958
|
+
oId: string;
|
|
3959
|
+
}[];
|
|
3960
|
+
matches: {
|
|
3961
|
+
upn: string | null;
|
|
3962
|
+
matchedOn: "upn" | "nameDob";
|
|
3963
|
+
forename: string;
|
|
3964
|
+
surname: string;
|
|
3965
|
+
dateOfBirth: string | null;
|
|
3966
|
+
enrolments: {
|
|
3967
|
+
email: string | null;
|
|
3968
|
+
year: string | null;
|
|
3969
|
+
oId: string;
|
|
3970
|
+
userId: string | null;
|
|
3971
|
+
schoolName: string;
|
|
3972
|
+
wondeId: string;
|
|
3973
|
+
formGroup: string | null;
|
|
3974
|
+
enrolmentStatus: string | null;
|
|
3975
|
+
}[];
|
|
3976
|
+
}[];
|
|
3977
|
+
schools: {
|
|
3978
|
+
name: string;
|
|
3979
|
+
oId: string;
|
|
3980
|
+
rosterSize: number;
|
|
3981
|
+
missingUpn: number;
|
|
3982
|
+
enrolmentStatuses: Record<string, number>;
|
|
3983
|
+
}[];
|
|
3984
|
+
trustId: string;
|
|
3985
|
+
}, {
|
|
3986
|
+
skipped: {
|
|
3987
|
+
name: string;
|
|
3988
|
+
reason: string;
|
|
3989
|
+
oId: string;
|
|
3990
|
+
}[];
|
|
3991
|
+
matches: {
|
|
3992
|
+
upn: string | null;
|
|
3993
|
+
matchedOn: "upn" | "nameDob";
|
|
3994
|
+
forename: string;
|
|
3995
|
+
surname: string;
|
|
3996
|
+
dateOfBirth: string | null;
|
|
3997
|
+
enrolments: {
|
|
3998
|
+
email: string | null;
|
|
3999
|
+
year: string | null;
|
|
4000
|
+
oId: string;
|
|
4001
|
+
userId: string | null;
|
|
4002
|
+
schoolName: string;
|
|
4003
|
+
wondeId: string;
|
|
4004
|
+
formGroup: string | null;
|
|
4005
|
+
enrolmentStatus: string | null;
|
|
4006
|
+
}[];
|
|
4007
|
+
}[];
|
|
4008
|
+
schools: {
|
|
4009
|
+
name: string;
|
|
4010
|
+
oId: string;
|
|
4011
|
+
rosterSize: number;
|
|
4012
|
+
missingUpn: number;
|
|
4013
|
+
enrolmentStatuses: Record<string, number>;
|
|
4014
|
+
}[];
|
|
4015
|
+
trustId: string;
|
|
4016
|
+
}>;
|
|
4017
|
+
};
|
|
3672
4018
|
};
|
|
3673
4019
|
misSyncCallables: {
|
|
3674
4020
|
"misSync-saveConfig": {
|
|
@@ -580,14 +580,14 @@ export declare const surveyCallables: {
|
|
|
580
580
|
requestId: string;
|
|
581
581
|
token?: string | undefined;
|
|
582
582
|
response?: unknown;
|
|
583
|
-
submittedBy?: "parent" | "
|
|
583
|
+
submittedBy?: "parent" | "employer" | "student" | "staff" | "trustedContact" | undefined;
|
|
584
584
|
rater?: "students" | "parents" | "trustedContact" | "employers" | undefined;
|
|
585
585
|
noChange?: boolean | undefined;
|
|
586
586
|
}, {
|
|
587
587
|
requestId: string;
|
|
588
588
|
token?: string | undefined;
|
|
589
589
|
response?: unknown;
|
|
590
|
-
submittedBy?: "parent" | "
|
|
590
|
+
submittedBy?: "parent" | "employer" | "student" | "staff" | "trustedContact" | undefined;
|
|
591
591
|
rater?: "students" | "parents" | "trustedContact" | "employers" | undefined;
|
|
592
592
|
noChange?: boolean | undefined;
|
|
593
593
|
}>;
|
package/lib/callables/wonde.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
/**
|
|
3
|
-
* Contracts for the Wonde connection request
|
|
3
|
+
* Contracts for the Wonde connection request and the dual registration check
|
|
4
4
|
* (`Placementt-Backend/functions/src/wonde.ts`).
|
|
5
5
|
*
|
|
6
6
|
* Wonde only approves a connection once the school's IT manager signs it off, so
|
|
@@ -32,4 +32,190 @@ export declare const wondeCallables: {
|
|
|
32
32
|
taskId: string;
|
|
33
33
|
}>;
|
|
34
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Admin only, read only. Pulls the full Wonde roster of every connected school
|
|
37
|
+
* in the trust `oId` belongs to (or is) and lists the pupils on more than one,
|
|
38
|
+
* such as a SEND school's pupils based in satellite centres at other schools.
|
|
39
|
+
* Writes nothing, so it is safe to run against a live trust.
|
|
40
|
+
*/
|
|
41
|
+
"wonde-findDualRegistrations": {
|
|
42
|
+
request: z.ZodObject<{
|
|
43
|
+
/** The trust, or any school in it. */
|
|
44
|
+
oId: z.ZodString;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
oId: string;
|
|
47
|
+
}, {
|
|
48
|
+
oId: string;
|
|
49
|
+
}>;
|
|
50
|
+
response: z.ZodObject<{
|
|
51
|
+
trustId: z.ZodString;
|
|
52
|
+
schools: z.ZodArray<z.ZodObject<{
|
|
53
|
+
oId: z.ZodString;
|
|
54
|
+
name: z.ZodString;
|
|
55
|
+
rosterSize: z.ZodNumber;
|
|
56
|
+
/** Pupils Wonde returned with no UPN, matched on name and date of birth instead. */
|
|
57
|
+
missingUpn: z.ZodNumber;
|
|
58
|
+
/** Distinct `extended_details.enrolment_status` values on the roster, with counts. */
|
|
59
|
+
enrolmentStatuses: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
60
|
+
}, "strip", z.ZodTypeAny, {
|
|
61
|
+
name: string;
|
|
62
|
+
oId: string;
|
|
63
|
+
rosterSize: number;
|
|
64
|
+
missingUpn: number;
|
|
65
|
+
enrolmentStatuses: Record<string, number>;
|
|
66
|
+
}, {
|
|
67
|
+
name: string;
|
|
68
|
+
oId: string;
|
|
69
|
+
rosterSize: number;
|
|
70
|
+
missingUpn: number;
|
|
71
|
+
enrolmentStatuses: Record<string, number>;
|
|
72
|
+
}>, "many">;
|
|
73
|
+
/** Trust schools left out, and why. */
|
|
74
|
+
skipped: z.ZodArray<z.ZodObject<{
|
|
75
|
+
oId: z.ZodString;
|
|
76
|
+
name: z.ZodString;
|
|
77
|
+
reason: z.ZodString;
|
|
78
|
+
}, "strip", z.ZodTypeAny, {
|
|
79
|
+
name: string;
|
|
80
|
+
reason: string;
|
|
81
|
+
oId: string;
|
|
82
|
+
}, {
|
|
83
|
+
name: string;
|
|
84
|
+
reason: string;
|
|
85
|
+
oId: string;
|
|
86
|
+
}>, "many">;
|
|
87
|
+
matches: z.ZodArray<z.ZodObject<{
|
|
88
|
+
/** What the pupils were matched on. */
|
|
89
|
+
matchedOn: z.ZodEnum<["upn", "nameDob"]>;
|
|
90
|
+
upn: z.ZodNullable<z.ZodString>;
|
|
91
|
+
forename: z.ZodString;
|
|
92
|
+
surname: z.ZodString;
|
|
93
|
+
dateOfBirth: z.ZodNullable<z.ZodString>;
|
|
94
|
+
/** One per school the pupil is on roll at. */
|
|
95
|
+
enrolments: z.ZodArray<z.ZodObject<{
|
|
96
|
+
oId: z.ZodString;
|
|
97
|
+
schoolName: z.ZodString;
|
|
98
|
+
wondeId: z.ZodString;
|
|
99
|
+
email: z.ZodNullable<z.ZodString>;
|
|
100
|
+
year: z.ZodNullable<z.ZodString>;
|
|
101
|
+
formGroup: z.ZodNullable<z.ZodString>;
|
|
102
|
+
enrolmentStatus: z.ZodNullable<z.ZodString>;
|
|
103
|
+
/** The CareerThread student at this school, if we hold one. */
|
|
104
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
105
|
+
}, "strip", z.ZodTypeAny, {
|
|
106
|
+
email: string | null;
|
|
107
|
+
year: string | null;
|
|
108
|
+
oId: string;
|
|
109
|
+
userId: string | null;
|
|
110
|
+
schoolName: string;
|
|
111
|
+
wondeId: string;
|
|
112
|
+
formGroup: string | null;
|
|
113
|
+
enrolmentStatus: string | null;
|
|
114
|
+
}, {
|
|
115
|
+
email: string | null;
|
|
116
|
+
year: string | null;
|
|
117
|
+
oId: string;
|
|
118
|
+
userId: string | null;
|
|
119
|
+
schoolName: string;
|
|
120
|
+
wondeId: string;
|
|
121
|
+
formGroup: string | null;
|
|
122
|
+
enrolmentStatus: string | null;
|
|
123
|
+
}>, "many">;
|
|
124
|
+
}, "strip", z.ZodTypeAny, {
|
|
125
|
+
upn: string | null;
|
|
126
|
+
matchedOn: "upn" | "nameDob";
|
|
127
|
+
forename: string;
|
|
128
|
+
surname: string;
|
|
129
|
+
dateOfBirth: string | null;
|
|
130
|
+
enrolments: {
|
|
131
|
+
email: string | null;
|
|
132
|
+
year: string | null;
|
|
133
|
+
oId: string;
|
|
134
|
+
userId: string | null;
|
|
135
|
+
schoolName: string;
|
|
136
|
+
wondeId: string;
|
|
137
|
+
formGroup: string | null;
|
|
138
|
+
enrolmentStatus: string | null;
|
|
139
|
+
}[];
|
|
140
|
+
}, {
|
|
141
|
+
upn: string | null;
|
|
142
|
+
matchedOn: "upn" | "nameDob";
|
|
143
|
+
forename: string;
|
|
144
|
+
surname: string;
|
|
145
|
+
dateOfBirth: string | null;
|
|
146
|
+
enrolments: {
|
|
147
|
+
email: string | null;
|
|
148
|
+
year: string | null;
|
|
149
|
+
oId: string;
|
|
150
|
+
userId: string | null;
|
|
151
|
+
schoolName: string;
|
|
152
|
+
wondeId: string;
|
|
153
|
+
formGroup: string | null;
|
|
154
|
+
enrolmentStatus: string | null;
|
|
155
|
+
}[];
|
|
156
|
+
}>, "many">;
|
|
157
|
+
}, "strip", z.ZodTypeAny, {
|
|
158
|
+
skipped: {
|
|
159
|
+
name: string;
|
|
160
|
+
reason: string;
|
|
161
|
+
oId: string;
|
|
162
|
+
}[];
|
|
163
|
+
matches: {
|
|
164
|
+
upn: string | null;
|
|
165
|
+
matchedOn: "upn" | "nameDob";
|
|
166
|
+
forename: string;
|
|
167
|
+
surname: string;
|
|
168
|
+
dateOfBirth: string | null;
|
|
169
|
+
enrolments: {
|
|
170
|
+
email: string | null;
|
|
171
|
+
year: string | null;
|
|
172
|
+
oId: string;
|
|
173
|
+
userId: string | null;
|
|
174
|
+
schoolName: string;
|
|
175
|
+
wondeId: string;
|
|
176
|
+
formGroup: string | null;
|
|
177
|
+
enrolmentStatus: string | null;
|
|
178
|
+
}[];
|
|
179
|
+
}[];
|
|
180
|
+
schools: {
|
|
181
|
+
name: string;
|
|
182
|
+
oId: string;
|
|
183
|
+
rosterSize: number;
|
|
184
|
+
missingUpn: number;
|
|
185
|
+
enrolmentStatuses: Record<string, number>;
|
|
186
|
+
}[];
|
|
187
|
+
trustId: string;
|
|
188
|
+
}, {
|
|
189
|
+
skipped: {
|
|
190
|
+
name: string;
|
|
191
|
+
reason: string;
|
|
192
|
+
oId: string;
|
|
193
|
+
}[];
|
|
194
|
+
matches: {
|
|
195
|
+
upn: string | null;
|
|
196
|
+
matchedOn: "upn" | "nameDob";
|
|
197
|
+
forename: string;
|
|
198
|
+
surname: string;
|
|
199
|
+
dateOfBirth: string | null;
|
|
200
|
+
enrolments: {
|
|
201
|
+
email: string | null;
|
|
202
|
+
year: string | null;
|
|
203
|
+
oId: string;
|
|
204
|
+
userId: string | null;
|
|
205
|
+
schoolName: string;
|
|
206
|
+
wondeId: string;
|
|
207
|
+
formGroup: string | null;
|
|
208
|
+
enrolmentStatus: string | null;
|
|
209
|
+
}[];
|
|
210
|
+
}[];
|
|
211
|
+
schools: {
|
|
212
|
+
name: string;
|
|
213
|
+
oId: string;
|
|
214
|
+
rosterSize: number;
|
|
215
|
+
missingUpn: number;
|
|
216
|
+
enrolmentStatuses: Record<string, number>;
|
|
217
|
+
}[];
|
|
218
|
+
trustId: string;
|
|
219
|
+
}>;
|
|
220
|
+
};
|
|
35
221
|
};
|
package/lib/callables/wonde.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.wondeCallables = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
/**
|
|
6
|
-
* Contracts for the Wonde connection request
|
|
6
|
+
* Contracts for the Wonde connection request and the dual registration check
|
|
7
7
|
* (`Placementt-Backend/functions/src/wonde.ts`).
|
|
8
8
|
*
|
|
9
9
|
* Wonde only approves a connection once the school's IT manager signs it off, so
|
|
@@ -23,5 +23,51 @@ exports.wondeCallables = {
|
|
|
23
23
|
taskId: zod_1.z.string(),
|
|
24
24
|
}),
|
|
25
25
|
},
|
|
26
|
+
/**
|
|
27
|
+
* Admin only, read only. Pulls the full Wonde roster of every connected school
|
|
28
|
+
* in the trust `oId` belongs to (or is) and lists the pupils on more than one,
|
|
29
|
+
* such as a SEND school's pupils based in satellite centres at other schools.
|
|
30
|
+
* Writes nothing, so it is safe to run against a live trust.
|
|
31
|
+
*/
|
|
32
|
+
"wonde-findDualRegistrations": {
|
|
33
|
+
request: zod_1.z.object({
|
|
34
|
+
/** The trust, or any school in it. */
|
|
35
|
+
oId: zod_1.z.string().min(1),
|
|
36
|
+
}),
|
|
37
|
+
response: zod_1.z.object({
|
|
38
|
+
trustId: zod_1.z.string(),
|
|
39
|
+
schools: zod_1.z.array(zod_1.z.object({
|
|
40
|
+
oId: zod_1.z.string(),
|
|
41
|
+
name: zod_1.z.string(),
|
|
42
|
+
rosterSize: zod_1.z.number(),
|
|
43
|
+
/** Pupils Wonde returned with no UPN, matched on name and date of birth instead. */
|
|
44
|
+
missingUpn: zod_1.z.number(),
|
|
45
|
+
/** Distinct `extended_details.enrolment_status` values on the roster, with counts. */
|
|
46
|
+
enrolmentStatuses: zod_1.z.record(zod_1.z.string(), zod_1.z.number()),
|
|
47
|
+
})),
|
|
48
|
+
/** Trust schools left out, and why. */
|
|
49
|
+
skipped: zod_1.z.array(zod_1.z.object({ oId: zod_1.z.string(), name: zod_1.z.string(), reason: zod_1.z.string() })),
|
|
50
|
+
matches: zod_1.z.array(zod_1.z.object({
|
|
51
|
+
/** What the pupils were matched on. */
|
|
52
|
+
matchedOn: zod_1.z.enum(["upn", "nameDob"]),
|
|
53
|
+
upn: zod_1.z.string().nullable(),
|
|
54
|
+
forename: zod_1.z.string(),
|
|
55
|
+
surname: zod_1.z.string(),
|
|
56
|
+
dateOfBirth: zod_1.z.string().nullable(),
|
|
57
|
+
/** One per school the pupil is on roll at. */
|
|
58
|
+
enrolments: zod_1.z.array(zod_1.z.object({
|
|
59
|
+
oId: zod_1.z.string(),
|
|
60
|
+
schoolName: zod_1.z.string(),
|
|
61
|
+
wondeId: zod_1.z.string(),
|
|
62
|
+
email: zod_1.z.string().nullable(),
|
|
63
|
+
year: zod_1.z.string().nullable(),
|
|
64
|
+
formGroup: zod_1.z.string().nullable(),
|
|
65
|
+
enrolmentStatus: zod_1.z.string().nullable(),
|
|
66
|
+
/** The CareerThread student at this school, if we hold one. */
|
|
67
|
+
userId: zod_1.z.string().nullable(),
|
|
68
|
+
})),
|
|
69
|
+
})),
|
|
70
|
+
}),
|
|
71
|
+
},
|
|
26
72
|
};
|
|
27
73
|
//# sourceMappingURL=wonde.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wonde.js","sourceRoot":"","sources":["../../src/callables/wonde.ts"],"names":[],"mappings":";;;AAAA,6BAAsB;AAGtB;;;;;;;GAOG;AACU,QAAA,cAAc,GAAG;IAC1B,yBAAyB,EAAE;QACvB,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC;YACd,wCAAwC;YACxC,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACtB,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;YAChD,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;SACrD,CAAC;QACF,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,4DAA4D;YAC5D,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;SACrB,CAAC;KACL;CACoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"wonde.js","sourceRoot":"","sources":["../../src/callables/wonde.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export * from "./benchmarkAggregate";
|
|
|
44
44
|
export * from "./portfolioAggregate";
|
|
45
45
|
export * from "./tutorialTips";
|
|
46
46
|
export * from "./constants";
|
|
47
|
+
export * from "./letters";
|
|
47
48
|
export * from "./dataViewerReload";
|
|
48
49
|
export * from "./hooks";
|
|
49
50
|
export * from "./workflowBands";
|
package/lib/index.js
CHANGED
|
@@ -64,6 +64,7 @@ __exportStar(require("./benchmarkAggregate"), exports);
|
|
|
64
64
|
__exportStar(require("./portfolioAggregate"), exports);
|
|
65
65
|
__exportStar(require("./tutorialTips"), exports);
|
|
66
66
|
__exportStar(require("./constants"), exports);
|
|
67
|
+
__exportStar(require("./letters"), exports);
|
|
67
68
|
__exportStar(require("./dataViewerReload"), exports);
|
|
68
69
|
__exportStar(require("./hooks"), exports);
|
|
69
70
|
__exportStar(require("./workflowBands"), exports);
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AACA,sDAAoC;AACpC,gEAA8C;AAC9C,0DAAwC;AACxC,2DAAyC;AACzC,kDAAgC;AAChC,uDAAqC;AACrC,4DAA0C;AAC1C,2DAAyC;AAEzC,oDAAkC;AAClC,8CAA4B;AAC5B,kDAAgC;AAChC,kDAAgC;AAChC,qDAAmC;AACnC,mDAAiC;AACjC,qDAAmC;AACnC,qDAAmC;AACnC,sDAAoC;AACpC,kDAAgC;AAChC,mDAAiC;AACjC,+CAA6B;AAC7B,oDAAkC;AAClC,iDAA+B;AAC/B,qDAAmC;AACnC,uDAAqC;AACrC,gDAA8B;AAC9B,4CAA0B;AAC1B,wCAAsB;AACtB,kDAAgC;AAChC,6CAA2B;AAC3B,8CAA4B;AAC5B,oDAAkC;AAClC,4CAA0B;AAC1B,8CAA4B;AAC5B,2CAAyB;AACzB,wDAAsC;AACtC,kDAAgC;AAChC,uDAAqC;AACrC,oDAAkC;AAClC,kDAAgC;AAChC,0DAAwC;AACxC,iDAA+B;AAC/B,2DAAyC;AACzC,uDAAqC;AACrC,uDAAqC;AACrC,iDAA+B;AAC/B,8CAA4B;AAC5B,qDAAmC;AACnC,0CAAwB;AACxB,kDAAgC;AAChC,yCAAuB;AACvB,4DAA0C;AAC1C,kDAAgC;AAChC,iDAA+B;AAC/B,2CAAyB;AACzB,4DAA0C;AAC1C,oEAAiD;AACjD,yEAAuD;AACvD,kEAAgD;AAChD,kEAAgD;AAChD,oEAAkD;AAClD,yGAAuF;AACvF,0GAAwF;AACxF,+FAA6E;AAC7E,4DAA0C;AAC1C,oEAAkD;AAClD,iEAA+C;AAC/C,gEAA8C;AAC9C,2EAAyD;AACzD,6CAA2B;AAC3B,+CAA6B;AAC7B,8CAA4B;AAC5B,4CAA0B;AAC1B,6DAAuE;AAA9D,2IAAA,OAAO,OAAuB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AACA,sDAAoC;AACpC,gEAA8C;AAC9C,0DAAwC;AACxC,2DAAyC;AACzC,kDAAgC;AAChC,uDAAqC;AACrC,4DAA0C;AAC1C,2DAAyC;AAEzC,oDAAkC;AAClC,8CAA4B;AAC5B,kDAAgC;AAChC,kDAAgC;AAChC,qDAAmC;AACnC,mDAAiC;AACjC,qDAAmC;AACnC,qDAAmC;AACnC,sDAAoC;AACpC,kDAAgC;AAChC,mDAAiC;AACjC,+CAA6B;AAC7B,oDAAkC;AAClC,iDAA+B;AAC/B,qDAAmC;AACnC,uDAAqC;AACrC,gDAA8B;AAC9B,4CAA0B;AAC1B,wCAAsB;AACtB,kDAAgC;AAChC,6CAA2B;AAC3B,8CAA4B;AAC5B,oDAAkC;AAClC,4CAA0B;AAC1B,8CAA4B;AAC5B,2CAAyB;AACzB,wDAAsC;AACtC,kDAAgC;AAChC,uDAAqC;AACrC,oDAAkC;AAClC,kDAAgC;AAChC,0DAAwC;AACxC,iDAA+B;AAC/B,2DAAyC;AACzC,uDAAqC;AACrC,uDAAqC;AACrC,iDAA+B;AAC/B,8CAA4B;AAC5B,4CAA0B;AAC1B,qDAAmC;AACnC,0CAAwB;AACxB,kDAAgC;AAChC,yCAAuB;AACvB,4DAA0C;AAC1C,kDAAgC;AAChC,iDAA+B;AAC/B,2CAAyB;AACzB,4DAA0C;AAC1C,oEAAiD;AACjD,yEAAuD;AACvD,kEAAgD;AAChD,kEAAgD;AAChD,oEAAkD;AAClD,yGAAuF;AACvF,0GAAwF;AACxF,+FAA6E;AAC7E,4DAA0C;AAC1C,oEAAkD;AAClD,iEAA+C;AAC/C,gEAA8C;AAC9C,2EAAyD;AACzD,6CAA2B;AAC3B,+CAA6B;AAC7B,8CAA4B;AAC5B,4CAA0B;AAC1B,6DAAuE;AAA9D,2IAAA,OAAO,OAAuB"}
|
package/lib/letters.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Descendant } from "slate";
|
|
2
|
+
import type { ProductTag } from "./typeDefinitions";
|
|
3
|
+
export type WexLetterKey = "employer" | "parent" | "student";
|
|
4
|
+
export type WexLetterOverride = {
|
|
5
|
+
body: Descendant[];
|
|
6
|
+
updated: string;
|
|
7
|
+
updatedBy?: string;
|
|
8
|
+
};
|
|
9
|
+
export type WexLetterConfig = {
|
|
10
|
+
name: string;
|
|
11
|
+
audience: "employers" | "parents" | "students";
|
|
12
|
+
description: string;
|
|
13
|
+
productTag: ProductTag;
|
|
14
|
+
body: Descendant[];
|
|
15
|
+
};
|
|
16
|
+
export declare const wexLetterParams: string[];
|
|
17
|
+
export declare const wexLetters: {
|
|
18
|
+
[key in WexLetterKey]: WexLetterConfig;
|
|
19
|
+
};
|
|
20
|
+
export declare function fillLetterParams(text: string, values: {
|
|
21
|
+
[key: string]: string | undefined;
|
|
22
|
+
}): string;
|
package/lib/letters.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wexLetters = exports.wexLetterParams = void 0;
|
|
4
|
+
exports.fillLetterParams = fillLetterParams;
|
|
5
|
+
// Params available in every letter. Filled in when the letter is previewed or downloaded.
|
|
6
|
+
exports.wexLetterParams = ["instituteName", "academicYear", "cohortName", "placementStart", "placementEnd", "staffName", "staffEmail"];
|
|
7
|
+
// Builds Slate content from lines. "# " and "## " start headings, **text** is bold, {{param}} becomes a param node.
|
|
8
|
+
function toLetterBody(lines) {
|
|
9
|
+
return lines.map((line) => {
|
|
10
|
+
const type = line.startsWith("# ") ? "heading-one" : line.startsWith("## ") ? "heading-two" : "paragraph";
|
|
11
|
+
const text = type === "heading-one" ? line.slice(2) : type === "heading-two" ? line.slice(3) : line;
|
|
12
|
+
const children = text.split(/(\*\*[^*]+\*\*|\{\{\w+\}\})/).filter(Boolean).map((part) => {
|
|
13
|
+
if (part.startsWith("**"))
|
|
14
|
+
return { text: part.slice(2, -2), bold: true };
|
|
15
|
+
if (part.startsWith("{{"))
|
|
16
|
+
return { text: part, param: true };
|
|
17
|
+
return { text: part };
|
|
18
|
+
});
|
|
19
|
+
return { type, children: children.length ? children : [{ text: "" }] };
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const signOff = ["Kind regards,", "", "Thomas Barton", "Founder, Director", "tom@careerthread.co.uk", "CareerThread"];
|
|
23
|
+
exports.wexLetters = {
|
|
24
|
+
employer: {
|
|
25
|
+
name: "Employer letter",
|
|
26
|
+
audience: "employers",
|
|
27
|
+
description: "Introduces CareerThread to businesses hosting a student, and what we will ask them for.",
|
|
28
|
+
productTag: "wex",
|
|
29
|
+
body: toLetterBody([
|
|
30
|
+
"# Employer Guidance",
|
|
31
|
+
"{{instituteName}} are using CareerThread through the academic year {{academicYear}} to support their students in managing work experience.",
|
|
32
|
+
"CareerThread helps students find placements, manages administrative sign-off and provides tools for schools to build lasting connections to businesses. As you are hosting a work experience student, we will contact you over the next few months to request additional information. This is to ensure students have all the information they need to prepare effectively for their placement.",
|
|
33
|
+
"We aim to build a community of businesses willing to support work experience at the school and the surrounding area. If you would like to advertise additional placements this year or in the future, please contact the school. Likewise, if you would like any support on hosting a student, please get in touch.",
|
|
34
|
+
"All automated correspondence from CareerThread will be sent from admin@careerthread.co.uk. If you have any questions specific to your placement, please contact the school. If you have any questions regarding CareerThread, please contact Tom at tom@careerthread.co.uk.",
|
|
35
|
+
"Thank you for agreeing to host a student for work experience. We hope it will be an enriching experience for you and your student.",
|
|
36
|
+
...signOff,
|
|
37
|
+
]),
|
|
38
|
+
},
|
|
39
|
+
parent: {
|
|
40
|
+
name: "Parent letter",
|
|
41
|
+
audience: "parents",
|
|
42
|
+
description: "Explains to parents how work experience is managed and what we will email them about.",
|
|
43
|
+
productTag: "wex",
|
|
44
|
+
body: toLetterBody([
|
|
45
|
+
"# Parent Guidance",
|
|
46
|
+
"{{instituteName}} is using CareerThread to manage your child's work experience. CareerThread helps secondary schools to coordinate work experience placements while supporting students with daily reflections and post-placement feedback, ensuring a meaningful and structured experience.",
|
|
47
|
+
"While CareerThread supports secondary schools in managing work experience, we do not currently find placements for your child. The students remain responsible for organising placements directly with an employer.",
|
|
48
|
+
"Your school will securely upload your email address to our platform so we can keep you informed about your child's placement and any potential issues. If you have any concerns or would prefer not to share your email, please contact the school.",
|
|
49
|
+
"Once your child has uploaded details of their work experience, we will retrieve necessary documentation from the employer. We may also email you requesting sign-off on the placement. This is necessary for us to go ahead with the placement.",
|
|
50
|
+
"During your child's work experience, you can view placement details and feedback through the email links we send you, so you can monitor your child's progress.",
|
|
51
|
+
"If you have any questions on how CareerThread works, please get in touch by emailing Tom at tom@careerthread.co.uk.",
|
|
52
|
+
...signOff,
|
|
53
|
+
]),
|
|
54
|
+
},
|
|
55
|
+
student: {
|
|
56
|
+
name: "Student guide",
|
|
57
|
+
audience: "students",
|
|
58
|
+
description: "Helps students prepare for their placement once it has been confirmed.",
|
|
59
|
+
productTag: "wex",
|
|
60
|
+
body: toLetterBody([
|
|
61
|
+
"# Preparing for Your Work Experience Placement",
|
|
62
|
+
"Congratulations on finding a placement! Now it's time to make the most of the opportunity. Good preparation can make all the difference, and this guide will walk you through some key steps to help you feel confident and ready to thrive.",
|
|
63
|
+
"**Confirm Details:** Once your placement has been verified on our portal, you'll see key information like your responsibilities, dress code, working hours, and any required preparation on your placement page. Review these carefully, and don't hesitate to contact the business if anything is unclear.",
|
|
64
|
+
"**Research the Company:** Take time to explore the business's website and any recent news or updates about them. Get familiar with their mission and the sector they work in. Think of a few questions you'd like to ask your new colleagues - it's a great way to learn and show your interest.",
|
|
65
|
+
"**Sharpen Your Skills:** Consider what skills might be useful during your placement. These could be technical skills (like using a specific type of software) or general ones like teamwork or communication. Practising these beforehand will help you feel ready and confident.",
|
|
66
|
+
"**Plan Your Travel:** Punctuality is key to a great first impression. Aim to arrive 15 minutes before your start time. Don't be too early, as your contact may not be ready for you. Before you start your placement, plan your travel route. If necessary, do a trial commute to make sure you will be on time.",
|
|
67
|
+
"**Pack Your Essentials:** Bring everything you'll need to feel prepared - this might include a notebook, pen, water bottle, lunch, or anything specific the business has asked you to bring. If you're unsure, ask ahead. Being well-prepared shows you're reliable, enthusiastic, and organised.",
|
|
68
|
+
]),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
// Replaces {{param}} text with its value. Unknown params are left as they are, so a missing value is visible rather than blank.
|
|
72
|
+
function fillLetterParams(text, values) {
|
|
73
|
+
return text.replace(/\{\{(\w+)\}\}/g, (match, key) => values[key] ?? match);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=letters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"letters.js","sourceRoot":"","sources":["../src/letters.ts"],"names":[],"mappings":"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"}
|
package/lib/typeDefinitions.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { StudentTaskConfigMap, SurveyKind, SurveySendPolicyMap, SurveySlot
|
|
|
7
7
|
import type { InstitutePricing } from "./pricing";
|
|
8
8
|
import type { CompassActivityType, CompassCareersPartnerType, CompassDeliveryMethod } from "./compassTemplate";
|
|
9
9
|
import type { MisColumnMapping } from "./misSync";
|
|
10
|
+
import type { WexLetterKey, WexLetterOverride } from "./letters";
|
|
10
11
|
export type FilterObject = {
|
|
11
12
|
[key: string]: {
|
|
12
13
|
label: string;
|
|
@@ -1078,6 +1079,10 @@ export type EmployerField = {
|
|
|
1078
1079
|
/** The areas of the staff platform that each own part of the careers year. */
|
|
1079
1080
|
export type CareersSetupArea = "development" | "destinations";
|
|
1080
1081
|
export type InstituteData = {
|
|
1082
|
+
/** The school's own edited versions of our work experience letters. Missing keys use our default. */
|
|
1083
|
+
wexLetters?: {
|
|
1084
|
+
[key in WexLetterKey]?: WexLetterOverride;
|
|
1085
|
+
};
|
|
1081
1086
|
/** MIS file sync. `mapping` holds the college's own header for any field not named exactly as we specify. */
|
|
1082
1087
|
mis?: {
|
|
1083
1088
|
mapping?: MisColumnMapping;
|
|
@@ -1277,6 +1282,9 @@ export type InstituteData = {
|
|
|
1277
1282
|
* screen shown before the platform on first sign-in. Registration sets it false;
|
|
1278
1283
|
* absent means the account predates the screen and is never asked. */
|
|
1279
1284
|
featureSetupComplete?: boolean;
|
|
1285
|
+
/** Every feature ticked on that screen, including those with no flag of their own yet
|
|
1286
|
+
* (aspirations, leavers, careersLibrary), so the platform knows what to show. */
|
|
1287
|
+
selectedFeatures?: string[];
|
|
1280
1288
|
deactivated?: boolean;
|
|
1281
1289
|
isTest?: boolean;
|
|
1282
1290
|
cohortFilters?: {
|
|
@@ -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":";;;AAynIA,sDASC;AAeD,oDAKC;AAaD,0CAEC;AAjoED;;;;;kFAKkF;AACrE,QAAA,qBAAqB,GAAG,SAAS,CAAC;AAClC,QAAA,iBAAiB,GAAG,OAAO,CAAC;AA6iEzC;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
package/src/callables/wonde.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {z} from "zod";
|
|
|
2
2
|
import {CallableGroup} from "./types";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Contracts for the Wonde connection request
|
|
5
|
+
* Contracts for the Wonde connection request and the dual registration check
|
|
6
6
|
* (`Placementt-Backend/functions/src/wonde.ts`).
|
|
7
7
|
*
|
|
8
8
|
* Wonde only approves a connection once the school's IT manager signs it off, so
|
|
@@ -22,4 +22,50 @@ export const wondeCallables = {
|
|
|
22
22
|
taskId: z.string(),
|
|
23
23
|
}),
|
|
24
24
|
},
|
|
25
|
+
/**
|
|
26
|
+
* Admin only, read only. Pulls the full Wonde roster of every connected school
|
|
27
|
+
* in the trust `oId` belongs to (or is) and lists the pupils on more than one,
|
|
28
|
+
* such as a SEND school's pupils based in satellite centres at other schools.
|
|
29
|
+
* Writes nothing, so it is safe to run against a live trust.
|
|
30
|
+
*/
|
|
31
|
+
"wonde-findDualRegistrations": {
|
|
32
|
+
request: z.object({
|
|
33
|
+
/** The trust, or any school in it. */
|
|
34
|
+
oId: z.string().min(1),
|
|
35
|
+
}),
|
|
36
|
+
response: z.object({
|
|
37
|
+
trustId: z.string(),
|
|
38
|
+
schools: z.array(z.object({
|
|
39
|
+
oId: z.string(),
|
|
40
|
+
name: z.string(),
|
|
41
|
+
rosterSize: z.number(),
|
|
42
|
+
/** Pupils Wonde returned with no UPN, matched on name and date of birth instead. */
|
|
43
|
+
missingUpn: z.number(),
|
|
44
|
+
/** Distinct `extended_details.enrolment_status` values on the roster, with counts. */
|
|
45
|
+
enrolmentStatuses: z.record(z.string(), z.number()),
|
|
46
|
+
})),
|
|
47
|
+
/** Trust schools left out, and why. */
|
|
48
|
+
skipped: z.array(z.object({oId: z.string(), name: z.string(), reason: z.string()})),
|
|
49
|
+
matches: z.array(z.object({
|
|
50
|
+
/** What the pupils were matched on. */
|
|
51
|
+
matchedOn: z.enum(["upn", "nameDob"]),
|
|
52
|
+
upn: z.string().nullable(),
|
|
53
|
+
forename: z.string(),
|
|
54
|
+
surname: z.string(),
|
|
55
|
+
dateOfBirth: z.string().nullable(),
|
|
56
|
+
/** One per school the pupil is on roll at. */
|
|
57
|
+
enrolments: z.array(z.object({
|
|
58
|
+
oId: z.string(),
|
|
59
|
+
schoolName: z.string(),
|
|
60
|
+
wondeId: z.string(),
|
|
61
|
+
email: z.string().nullable(),
|
|
62
|
+
year: z.string().nullable(),
|
|
63
|
+
formGroup: z.string().nullable(),
|
|
64
|
+
enrolmentStatus: z.string().nullable(),
|
|
65
|
+
/** The CareerThread student at this school, if we hold one. */
|
|
66
|
+
userId: z.string().nullable(),
|
|
67
|
+
})),
|
|
68
|
+
})),
|
|
69
|
+
}),
|
|
70
|
+
},
|
|
25
71
|
} satisfies CallableGroup;
|
package/src/index.ts
CHANGED
|
@@ -46,6 +46,7 @@ export * from "./benchmarkAggregate";
|
|
|
46
46
|
export * from "./portfolioAggregate";
|
|
47
47
|
export * from "./tutorialTips";
|
|
48
48
|
export * from "./constants";
|
|
49
|
+
export * from "./letters";
|
|
49
50
|
export * from "./dataViewerReload";
|
|
50
51
|
export * from "./hooks";
|
|
51
52
|
export * from "./workflowBands";
|
package/src/letters.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {Descendant} from "slate";
|
|
2
|
+
import type {ProductTag} from "./typeDefinitions";
|
|
3
|
+
|
|
4
|
+
// Work experience letters schools hand to employers, parents and students. We provide the defaults below.
|
|
5
|
+
// A school can edit a letter once, saved to InstituteData.wexLetters[key], and that version is used for all their cohorts.
|
|
6
|
+
// Cohort specific details (name, dates) come in through params, so one school version suits every cohort.
|
|
7
|
+
|
|
8
|
+
export type WexLetterKey = "employer"|"parent"|"student";
|
|
9
|
+
|
|
10
|
+
export type WexLetterOverride = {body: Descendant[], updated: string, updatedBy?: string};
|
|
11
|
+
|
|
12
|
+
export type WexLetterConfig = {
|
|
13
|
+
name: string,
|
|
14
|
+
audience: "employers"|"parents"|"students",
|
|
15
|
+
description: string,
|
|
16
|
+
productTag: ProductTag,
|
|
17
|
+
body: Descendant[],
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Params available in every letter. Filled in when the letter is previewed or downloaded.
|
|
21
|
+
export const wexLetterParams = ["instituteName", "academicYear", "cohortName", "placementStart", "placementEnd", "staffName", "staffEmail"];
|
|
22
|
+
|
|
23
|
+
// Builds Slate content from lines. "# " and "## " start headings, **text** is bold, {{param}} becomes a param node.
|
|
24
|
+
function toLetterBody(lines: string[]): Descendant[] {
|
|
25
|
+
return lines.map((line) => {
|
|
26
|
+
const type = line.startsWith("# ") ? "heading-one" : line.startsWith("## ") ? "heading-two" : "paragraph";
|
|
27
|
+
const text = type === "heading-one" ? line.slice(2) : type === "heading-two" ? line.slice(3) : line;
|
|
28
|
+
const children = text.split(/(\*\*[^*]+\*\*|\{\{\w+\}\})/).filter(Boolean).map((part) => {
|
|
29
|
+
if (part.startsWith("**")) return {text: part.slice(2, -2), bold: true};
|
|
30
|
+
if (part.startsWith("{{")) return {text: part, param: true};
|
|
31
|
+
return {text: part};
|
|
32
|
+
});
|
|
33
|
+
return {type, children: children.length ? children : [{text: ""}]} as unknown as Descendant;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const signOff = ["Kind regards,", "", "Thomas Barton", "Founder, Director", "tom@careerthread.co.uk", "CareerThread"];
|
|
38
|
+
|
|
39
|
+
export const wexLetters: {[key in WexLetterKey]: WexLetterConfig} = {
|
|
40
|
+
employer: {
|
|
41
|
+
name: "Employer letter",
|
|
42
|
+
audience: "employers",
|
|
43
|
+
description: "Introduces CareerThread to businesses hosting a student, and what we will ask them for.",
|
|
44
|
+
productTag: "wex",
|
|
45
|
+
body: toLetterBody([
|
|
46
|
+
"# Employer Guidance",
|
|
47
|
+
"{{instituteName}} are using CareerThread through the academic year {{academicYear}} to support their students in managing work experience.",
|
|
48
|
+
"CareerThread helps students find placements, manages administrative sign-off and provides tools for schools to build lasting connections to businesses. As you are hosting a work experience student, we will contact you over the next few months to request additional information. This is to ensure students have all the information they need to prepare effectively for their placement.",
|
|
49
|
+
"We aim to build a community of businesses willing to support work experience at the school and the surrounding area. If you would like to advertise additional placements this year or in the future, please contact the school. Likewise, if you would like any support on hosting a student, please get in touch.",
|
|
50
|
+
"All automated correspondence from CareerThread will be sent from admin@careerthread.co.uk. If you have any questions specific to your placement, please contact the school. If you have any questions regarding CareerThread, please contact Tom at tom@careerthread.co.uk.",
|
|
51
|
+
"Thank you for agreeing to host a student for work experience. We hope it will be an enriching experience for you and your student.",
|
|
52
|
+
...signOff,
|
|
53
|
+
]),
|
|
54
|
+
},
|
|
55
|
+
parent: {
|
|
56
|
+
name: "Parent letter",
|
|
57
|
+
audience: "parents",
|
|
58
|
+
description: "Explains to parents how work experience is managed and what we will email them about.",
|
|
59
|
+
productTag: "wex",
|
|
60
|
+
body: toLetterBody([
|
|
61
|
+
"# Parent Guidance",
|
|
62
|
+
"{{instituteName}} is using CareerThread to manage your child's work experience. CareerThread helps secondary schools to coordinate work experience placements while supporting students with daily reflections and post-placement feedback, ensuring a meaningful and structured experience.",
|
|
63
|
+
"While CareerThread supports secondary schools in managing work experience, we do not currently find placements for your child. The students remain responsible for organising placements directly with an employer.",
|
|
64
|
+
"Your school will securely upload your email address to our platform so we can keep you informed about your child's placement and any potential issues. If you have any concerns or would prefer not to share your email, please contact the school.",
|
|
65
|
+
"Once your child has uploaded details of their work experience, we will retrieve necessary documentation from the employer. We may also email you requesting sign-off on the placement. This is necessary for us to go ahead with the placement.",
|
|
66
|
+
"During your child's work experience, you can view placement details and feedback through the email links we send you, so you can monitor your child's progress.",
|
|
67
|
+
"If you have any questions on how CareerThread works, please get in touch by emailing Tom at tom@careerthread.co.uk.",
|
|
68
|
+
...signOff,
|
|
69
|
+
]),
|
|
70
|
+
},
|
|
71
|
+
student: {
|
|
72
|
+
name: "Student guide",
|
|
73
|
+
audience: "students",
|
|
74
|
+
description: "Helps students prepare for their placement once it has been confirmed.",
|
|
75
|
+
productTag: "wex",
|
|
76
|
+
body: toLetterBody([
|
|
77
|
+
"# Preparing for Your Work Experience Placement",
|
|
78
|
+
"Congratulations on finding a placement! Now it's time to make the most of the opportunity. Good preparation can make all the difference, and this guide will walk you through some key steps to help you feel confident and ready to thrive.",
|
|
79
|
+
"**Confirm Details:** Once your placement has been verified on our portal, you'll see key information like your responsibilities, dress code, working hours, and any required preparation on your placement page. Review these carefully, and don't hesitate to contact the business if anything is unclear.",
|
|
80
|
+
"**Research the Company:** Take time to explore the business's website and any recent news or updates about them. Get familiar with their mission and the sector they work in. Think of a few questions you'd like to ask your new colleagues - it's a great way to learn and show your interest.",
|
|
81
|
+
"**Sharpen Your Skills:** Consider what skills might be useful during your placement. These could be technical skills (like using a specific type of software) or general ones like teamwork or communication. Practising these beforehand will help you feel ready and confident.",
|
|
82
|
+
"**Plan Your Travel:** Punctuality is key to a great first impression. Aim to arrive 15 minutes before your start time. Don't be too early, as your contact may not be ready for you. Before you start your placement, plan your travel route. If necessary, do a trial commute to make sure you will be on time.",
|
|
83
|
+
"**Pack Your Essentials:** Bring everything you'll need to feel prepared - this might include a notebook, pen, water bottle, lunch, or anything specific the business has asked you to bring. If you're unsure, ask ahead. Being well-prepared shows you're reliable, enthusiastic, and organised.",
|
|
84
|
+
]),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Replaces {{param}} text with its value. Unknown params are left as they are, so a missing value is visible rather than blank.
|
|
89
|
+
export function fillLetterParams(text: string, values: {[key: string]: string|undefined}) {
|
|
90
|
+
return text.replace(/\{\{(\w+)\}\}/g, (match, key) => values[key] ?? match);
|
|
91
|
+
}
|
package/src/typeDefinitions.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {StudentTaskConfigMap, SurveyKind, SurveySendPolicyMap, SurveySlot}
|
|
|
7
7
|
import type {InstitutePricing} from "./pricing";
|
|
8
8
|
import type {CompassActivityType, CompassCareersPartnerType, CompassDeliveryMethod} from "./compassTemplate";
|
|
9
9
|
import type {MisColumnMapping} from "./misSync";
|
|
10
|
+
import type {WexLetterKey, WexLetterOverride} from "./letters";
|
|
10
11
|
|
|
11
12
|
export type FilterObject = {
|
|
12
13
|
[key: string]: {
|
|
@@ -1125,6 +1126,8 @@ export type EmployerField = {
|
|
|
1125
1126
|
export type CareersSetupArea = "development"|"destinations";
|
|
1126
1127
|
|
|
1127
1128
|
export type InstituteData = {
|
|
1129
|
+
/** The school's own edited versions of our work experience letters. Missing keys use our default. */
|
|
1130
|
+
wexLetters?: {[key in WexLetterKey]?: WexLetterOverride},
|
|
1128
1131
|
/** MIS file sync. `mapping` holds the college's own header for any field not named exactly as we specify. */
|
|
1129
1132
|
mis?: {mapping?: MisColumnMapping},
|
|
1130
1133
|
students: number,
|
|
@@ -1305,6 +1308,9 @@ export type InstituteData = {
|
|
|
1305
1308
|
* screen shown before the platform on first sign-in. Registration sets it false;
|
|
1306
1309
|
* absent means the account predates the screen and is never asked. */
|
|
1307
1310
|
featureSetupComplete?: boolean,
|
|
1311
|
+
/** Every feature ticked on that screen, including those with no flag of their own yet
|
|
1312
|
+
* (aspirations, leavers, careersLibrary), so the platform knows what to show. */
|
|
1313
|
+
selectedFeatures?: string[],
|
|
1308
1314
|
deactivated?: boolean,
|
|
1309
1315
|
isTest?: boolean,
|
|
1310
1316
|
cohortFilters?: {
|