@thejob/schema 2.5.0 → 2.7.0

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/dist/index.cjs CHANGED
@@ -32,10 +32,14 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  AnswerChoiceType: () => AnswerChoiceType,
34
34
  ApplicationReceivePreference: () => ApplicationReceivePreference,
35
+ AuditFilterSchema: () => AuditFilterSchema,
36
+ AuditSchema: () => AuditSchema,
35
37
  BillingPeriod: () => BillingPeriod,
36
38
  BillingSubscriptionSchema: () => BillingSubscriptionSchema,
37
39
  BillingTransactionSchema: () => BillingTransactionSchema,
38
40
  CAMPAIGN_MAX_RECIPIENTS_CEILING: () => CAMPAIGN_MAX_RECIPIENTS_CEILING,
41
+ CONCEPT_ID_PATTERN: () => CONCEPT_ID_PATTERN,
42
+ CONCEPT_TYPE_PATTERN: () => CONCEPT_TYPE_PATTERN,
39
43
  CONSUME_MAX_UNITS: () => CONSUME_MAX_UNITS,
40
44
  CampaignDataSourceSchema: () => CampaignDataSourceSchema,
41
45
  CampaignEndKind: () => CampaignEndKind,
@@ -51,6 +55,11 @@ __export(index_exports, {
51
55
  Common: () => Common,
52
56
  CompensationType: () => CompensationType,
53
57
  CompletenessScoreSchema: () => CompletenessScoreSchema,
58
+ ConceptFilterSchema: () => ConceptFilterSchema,
59
+ ConceptMembershipSchema: () => ConceptMembershipSchema,
60
+ ConceptProposalFilterSchema: () => ConceptProposalFilterSchema,
61
+ ConceptProposalSchema: () => ConceptProposalSchema,
62
+ ConceptSchema: () => ConceptSchema,
54
63
  ContactTypes: () => ContactTypes,
55
64
  CoordinatorPageLinkSchema: () => CoordinatorPageLinkSchema,
56
65
  CountryFilterSchema: () => CountryFilterSchema,
@@ -116,6 +125,7 @@ __export(index_exports, {
116
125
  MailingListFilterSchema: () => MailingListFilterSchema,
117
126
  MailingListSchema: () => MailingListSchema,
118
127
  MoneySchema: () => MoneySchema,
128
+ NormalizeContextSchema: () => NormalizeContextSchema,
119
129
  NotificationType: () => NotificationType,
120
130
  OccurrenceStatus: () => OccurrenceStatus,
121
131
  PREFILL_MIRRORED_KEYS: () => PREFILL_MIRRORED_KEYS,
@@ -135,6 +145,8 @@ __export(index_exports, {
135
145
  PostSchema: () => PostSchema,
136
146
  PostStatus: () => PostStatus,
137
147
  ProficiencyLevel: () => ProficiencyLevel,
148
+ ProposalCandidateSchema: () => ProposalCandidateSchema,
149
+ ProposalMessageSchema: () => ProposalMessageSchema,
138
150
  PushSubscriptionSchema: () => PushSubscriptionSchema,
139
151
  QuestionSchema: () => QuestionSchema,
140
152
  QuestionType: () => QuestionType,
@@ -142,9 +154,15 @@ __export(index_exports, {
142
154
  ReadAndAcknowledgeQuestionSchema: () => ReadAndAcknowledgeQuestionSchema,
143
155
  RecruiterPageLinkSchema: () => RecruiterPageLinkSchema,
144
156
  ReferralSource: () => ReferralSource,
157
+ ReleaseFilterSchema: () => ReleaseFilterSchema,
158
+ ReleaseSchema: () => ReleaseSchema,
145
159
  ReportReason: () => ReportReason,
146
160
  ReportSchema: () => ReportSchema,
161
+ ResolverSettingsSchema: () => ResolverSettingsSchema,
162
+ ResolverVerificationSchema: () => ResolverVerificationSchema,
147
163
  ResourceType: () => ResourceType,
164
+ SCHEDULE_MAX_HOURS: () => SCHEDULE_MAX_HOURS,
165
+ SCHEDULE_MIN_HOURS: () => SCHEDULE_MIN_HOURS,
148
166
  SITEMAP_FORMAT: () => SITEMAP_FORMAT,
149
167
  SYSTEM_DATE_FORMAT: () => SYSTEM_DATE_FORMAT,
150
168
  SavedSearchSchema: () => SavedSearchSchema,
@@ -159,14 +177,17 @@ __export(index_exports, {
159
177
  StudentCompletenessSchema: () => StudentCompletenessSchema,
160
178
  StudyType: () => StudyType,
161
179
  SubscriptionStatus: () => SubscriptionStatus,
180
+ SuggestedHomeSchema: () => SuggestedHomeSchema,
162
181
  SupportedAnswerChoiceTypes: () => SupportedAnswerChoiceTypes,
163
182
  SupportedApplicationReceivePreferences: () => SupportedApplicationReceivePreferences,
183
+ SupportedAuditStatuses: () => SupportedAuditStatuses,
164
184
  SupportedBillingPeriods: () => SupportedBillingPeriods,
165
185
  SupportedCampaignEndKinds: () => SupportedCampaignEndKinds,
166
186
  SupportedCampaignIntervalUnits: () => SupportedCampaignIntervalUnits,
167
187
  SupportedCampaignStatuses: () => SupportedCampaignStatuses,
168
188
  SupportedCampaignTriggerKinds: () => SupportedCampaignTriggerKinds,
169
189
  SupportedCompensationTypes: () => SupportedCompensationTypes,
190
+ SupportedConceptSources: () => SupportedConceptSources,
170
191
  SupportedContactTypes: () => SupportedContactTypes,
171
192
  SupportedEducationLevels: () => SupportedEducationLevels,
172
193
  SupportedEmployeeCounts: () => SupportedEmployeeCounts,
@@ -191,6 +212,7 @@ __export(index_exports, {
191
212
  SupportedJobSearchUrgencies: () => SupportedJobSearchUrgencies,
192
213
  SupportedJobStatuses: () => SupportedJobStatuses,
193
214
  SupportedJobSubCategories: () => SupportedJobSubCategories,
215
+ SupportedMatchTypes: () => SupportedMatchTypes,
194
216
  SupportedNotificationTypes: () => SupportedNotificationTypes,
195
217
  SupportedOccurrenceStatuses: () => SupportedOccurrenceStatuses,
196
218
  SupportedPaddleEnvironments: () => SupportedPaddleEnvironments,
@@ -200,11 +222,19 @@ __export(index_exports, {
200
222
  SupportedPlanKinds: () => SupportedPlanKinds,
201
223
  SupportedPlanStatuses: () => SupportedPlanStatuses,
202
224
  SupportedPostStatuses: () => SupportedPostStatuses,
225
+ SupportedPrefilterRules: () => SupportedPrefilterRules,
203
226
  SupportedProficiencyLevels: () => SupportedProficiencyLevels,
227
+ SupportedProposalFilters: () => SupportedProposalFilters,
228
+ SupportedProposalKinds: () => SupportedProposalKinds,
229
+ SupportedProposalMessageRoles: () => SupportedProposalMessageRoles,
230
+ SupportedProposalStatuses: () => SupportedProposalStatuses,
204
231
  SupportedQuestionTypes: () => SupportedQuestionTypes,
205
232
  SupportedQuotaPeriods: () => SupportedQuotaPeriods,
206
233
  SupportedReferralSources: () => SupportedReferralSources,
234
+ SupportedReleaseKinds: () => SupportedReleaseKinds,
235
+ SupportedReleaseStatuses: () => SupportedReleaseStatuses,
207
236
  SupportedReportReasons: () => SupportedReportReasons,
237
+ SupportedResolverVerdicts: () => SupportedResolverVerdicts,
208
238
  SupportedResourceTypes: () => SupportedResourceTypes,
209
239
  SupportedSalaryCurrencies: () => SupportedSalaryCurrencies,
210
240
  SupportedSavedSearchStatuses: () => SupportedSavedSearchStatuses,
@@ -212,19 +242,31 @@ __export(index_exports, {
212
242
  SupportedSocialAccounts: () => SupportedSocialAccounts,
213
243
  SupportedStudyTypes: () => SupportedStudyTypes,
214
244
  SupportedSubscriptionStatuses: () => SupportedSubscriptionStatuses,
245
+ SupportedTaxonomyJobKinds: () => SupportedTaxonomyJobKinds,
246
+ SupportedTaxonomyJobStates: () => SupportedTaxonomyJobStates,
247
+ SupportedTaxonomyNodeKinds: () => SupportedTaxonomyNodeKinds,
248
+ SupportedTaxonomySources: () => SupportedTaxonomySources,
215
249
  SupportedTemplateVariableBindingKinds: () => SupportedTemplateVariableBindingKinds,
216
250
  SupportedTransactionStatuses: () => SupportedTransactionStatuses,
251
+ SupportedUnmatchedReasons: () => SupportedUnmatchedReasons,
252
+ SupportedUnmatchedResolutions: () => SupportedUnmatchedResolutions,
217
253
  SupportedUserProfileVisibilities: () => SupportedUserProfileVisibilities,
218
254
  SupportedUserRoles: () => SupportedUserRoles,
219
255
  SupportedUserStatuses: () => SupportedUserStatuses,
220
256
  SupportedWorkModes: () => SupportedWorkModes,
221
257
  TAXONOMY_LABELS: () => TAXONOMY_LABELS,
258
+ TAXONOMY_NODE_ID_PATTERN: () => TAXONOMY_NODE_ID_PATTERN,
259
+ TaxonomyNodeFilterSchema: () => TaxonomyNodeFilterSchema,
260
+ TaxonomyNodeSchema: () => TaxonomyNodeSchema,
261
+ TaxonomyScheduleSchema: () => TaxonomyScheduleSchema,
222
262
  TemplateVariableBindingKind: () => TemplateVariableBindingKind,
223
263
  TemplateVariableBindingSchema: () => TemplateVariableBindingSchema,
224
264
  TerminalCampaignStatuses: () => TerminalCampaignStatuses,
225
265
  TerminalGeoSyncStatuses: () => TerminalGeoSyncStatuses,
226
266
  TermsAcceptedSchema: () => TermsAcceptedSchema,
227
267
  TransactionStatus: () => TransactionStatus,
268
+ UnmatchedFilterSchema: () => UnmatchedFilterSchema,
269
+ UnmatchedTermSchema: () => UnmatchedTermSchema,
228
270
  UserAdditionalInfoSchema: () => UserAdditionalInfoSchema,
229
271
  UserCertificationSchema: () => UserCertificationSchema,
230
272
  UserCompletenessSchema: () => UserCompletenessSchema,
@@ -243,6 +285,9 @@ __export(index_exports, {
243
285
  UserSchema: () => UserSchema,
244
286
  UserSkillSchema: () => UserSkillSchema,
245
287
  UserStatus: () => UserStatus,
288
+ VOCABULARY_ID_PATTERN: () => VOCABULARY_ID_PATTERN,
289
+ VocabularySchema: () => VocabularySchema,
290
+ VocabularyTypeSchema: () => VocabularyTypeSchema,
246
291
  WorkExperienceSchema: () => WorkExperienceSchema,
247
292
  WorkMode: () => WorkMode,
248
293
  canTransitionCampaign: () => canTransitionCampaign,
@@ -640,7 +685,7 @@ var GroupFilterSchema = rejectUnknownKeys(
640
685
  );
641
686
 
642
687
  // src/job/job.schema.ts
643
- var import_yup20 = require("yup");
688
+ var import_yup21 = require("yup");
644
689
 
645
690
  // src/location/location.schema.ts
646
691
  var import_yup7 = require("yup");
@@ -859,6 +904,338 @@ var SkillSchema = (0, import_yup15.object)({
859
904
  tags: (0, import_yup15.array)().of((0, import_yup15.string)().max(50)).max(20).optional().label("Tags")
860
905
  }).concat(DbDefaultSchema).noUnknown().strict().label("Skill");
861
906
 
907
+ // src/taxonomy/taxonomy.schema.ts
908
+ var import_yup16 = require("yup");
909
+
910
+ // src/taxonomy/taxonomy.constant.ts
911
+ var SupportedConceptSources = ["seed", "manual", "import"];
912
+ var SupportedTaxonomySources = ["seed", "manual"];
913
+ var SupportedTaxonomyNodeKinds = ["category", "subcategory", "group"];
914
+ var SupportedPrefilterRules = [
915
+ "spoken_language",
916
+ "no_letters",
917
+ "url_or_email",
918
+ "fragment"
919
+ ];
920
+ var SupportedUnmatchedResolutions = ["pending", "added", "rejected"];
921
+ var SupportedUnmatchedReasons = ["ambiguous"];
922
+ var SupportedProposalKinds = ["concept", "alias", "placement"];
923
+ var SupportedProposalFilters = [...SupportedProposalKinds, "uncategorized"];
924
+ var SupportedProposalStatuses = ["draft", "approved", "discarded"];
925
+ var SupportedProposalMessageRoles = ["operator", "model"];
926
+ var SupportedResolverVerdicts = [
927
+ "same",
928
+ "narrower",
929
+ "broader",
930
+ "related",
931
+ "new_concept",
932
+ "out_of_scope"
933
+ ];
934
+ var SupportedAuditStatuses = ["pending", "correct", "wrong"];
935
+ var SupportedReleaseKinds = ["seed", "manual", "review", "auto"];
936
+ var SupportedReleaseStatuses = ["open", "rolled_back"];
937
+ var SupportedMatchTypes = ["exact", "canonical", "fuzzy", "none"];
938
+ var SupportedTaxonomyJobKinds = [
939
+ "describe-concepts",
940
+ "retype-concepts",
941
+ "generate-aliases",
942
+ "alias-backfill",
943
+ "close-gaps",
944
+ "propose-placements",
945
+ "place-unplaced",
946
+ "calibrate-placement",
947
+ "reseed",
948
+ "reindex",
949
+ "calibrate-resolver",
950
+ "golden",
951
+ "resolve-backlog"
952
+ ];
953
+ var SupportedTaxonomyJobStates = ["running", "succeeded", "failed", "cancelled"];
954
+ var CONCEPT_ID_PATTERN = /^[a-z][a-z0-9-]*_[a-z0-9-]+$/;
955
+ var VOCABULARY_ID_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;
956
+ var TAXONOMY_NODE_ID_PATTERN = /^[A-Za-z0-9_]{1,64}$/;
957
+ var CONCEPT_TYPE_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
958
+ var SCHEDULE_MIN_HOURS = 1;
959
+ var SCHEDULE_MAX_HOURS = 24 * 30;
960
+
961
+ // src/taxonomy/taxonomy.schema.ts
962
+ var conceptId = () => (0, import_yup16.string)().matches(CONCEPT_ID_PATTERN, "conceptId must look like <vocabulary>_<slug>");
963
+ var vocabularyId = () => (0, import_yup16.string)().matches(VOCABULARY_ID_PATTERN, "vocabulary must match [a-z][a-z0-9-]{0,31}");
964
+ var nodeId = () => (0, import_yup16.string)().matches(TAXONOMY_NODE_ID_PATTERN, "node ids look like CAT_01_TECH");
965
+ var strings = () => (0, import_yup16.array)((0, import_yup16.string)().trim().min(1).required());
966
+ var VocabularyTypeSchema = (0, import_yup16.object)({
967
+ id: (0, import_yup16.string)().matches(CONCEPT_TYPE_PATTERN, "type ids match [a-z][a-z0-9_]*").required().label("Type ID"),
968
+ /** Shown to the model when it classifies a concept; include examples. */
969
+ description: (0, import_yup16.string)().defined().label("Description")
970
+ }).label("Vocabulary Type");
971
+ var VocabularySchema = (0, import_yup16.object)({
972
+ vocabularyId: vocabularyId().required().label("Vocabulary ID"),
973
+ name: (0, import_yup16.string)().trim().min(1).required().label("Name"),
974
+ /** What one concept is called in prompts and messages: "skill", "role". */
975
+ noun: (0, import_yup16.string)().trim().min(1).required().label("Noun"),
976
+ nounPlural: (0, import_yup16.string)().trim().min(1).required().label("Noun (plural)"),
977
+ /** What belongs in this vocabulary, for prompts. */
978
+ description: (0, import_yup16.string)().trim().min(1).required().label("Description"),
979
+ /** Where its terms are written, for the "swap it in" test: "a job posting". */
980
+ appearsIn: (0, import_yup16.string)().trim().min(1).required().label("Appears In"),
981
+ /** Things that are NOT concepts of this vocabulary, for prompts. */
982
+ outOfScope: (0, import_yup16.string)().trim().min(1).required().label("Out of Scope"),
983
+ types: (0, import_yup16.array)(VocabularyTypeSchema.required()).min(1).required().test(
984
+ "unique-type-ids",
985
+ "type ids must be unique",
986
+ (types) => !types || new Set(types.map((t) => t.id)).size === types.length
987
+ ).label("Types"),
988
+ /** The type a concept gets when nothing more specific is known. One of `types`. */
989
+ defaultType: (0, import_yup16.string)().required().test("default-type-listed", "defaultType must be one of the type ids", function(value) {
990
+ const types = this.parent.types ?? [];
991
+ return types.some((t) => t.id === value);
992
+ }).label("Default Type"),
993
+ prefilter: (0, import_yup16.array)((0, import_yup16.string)().oneOf(SupportedPrefilterRules).required()).default([]).label("Prefilter"),
994
+ /**
995
+ * Words that qualify a term without changing what it names ("fluent",
996
+ * "native"), dropped from its canonical lookup form in THIS vocabulary only.
997
+ */
998
+ qualifiers: strings().optional().label("Qualifiers"),
999
+ /** Extra instructions per model task; each is optional. */
1000
+ guidance: (0, import_yup16.object)({
1001
+ describe: (0, import_yup16.string)().optional(),
1002
+ classify: (0, import_yup16.string)().optional(),
1003
+ aliases: (0, import_yup16.string)().optional(),
1004
+ verify: (0, import_yup16.string)().optional(),
1005
+ place: (0, import_yup16.string)().optional()
1006
+ }).label("Guidance"),
1007
+ source: (0, import_yup16.string)().oneOf(SupportedTaxonomySources).required().label("Source"),
1008
+ createdAt: (0, import_yup16.number)().required().label("Created At"),
1009
+ updatedAt: (0, import_yup16.number)().required().label("Updated At")
1010
+ }).label("Vocabulary");
1011
+ var TaxonomyNodeSchema = (0, import_yup16.object)({
1012
+ nodeId: nodeId().required().label("Node ID"),
1013
+ vocabulary: vocabularyId().required().label("Vocabulary"),
1014
+ kind: (0, import_yup16.string)().oneOf(SupportedTaxonomyNodeKinds).required().label("Kind"),
1015
+ name: (0, import_yup16.string)().trim().min(1).required().label("Name"),
1016
+ /** Groups carry a description; categories and subcategories usually do not. */
1017
+ description: (0, import_yup16.string)().optional().label("Description"),
1018
+ aliases: strings().default([]).label("Aliases"),
1019
+ /** null for categories (the roots). */
1020
+ parentId: (0, import_yup16.string)().nullable().defined().label("Parent ID"),
1021
+ /** Ancestor ids from the root down to and including this node. */
1022
+ path: (0, import_yup16.array)((0, import_yup16.string)().required()).default([]).label("Path"),
1023
+ source: (0, import_yup16.string)().oneOf(SupportedTaxonomySources).optional().label("Source"),
1024
+ createdAt: (0, import_yup16.number)().required().label("Created At"),
1025
+ updatedAt: (0, import_yup16.number)().required().label("Updated At")
1026
+ }).label("Taxonomy Node");
1027
+ var ConceptMembershipSchema = (0, import_yup16.object)({
1028
+ categoryId: (0, import_yup16.string)().required().label("Category ID"),
1029
+ categoryName: (0, import_yup16.string)().required().label("Category Name"),
1030
+ subcategoryId: (0, import_yup16.string)().required().label("Subcategory ID"),
1031
+ subcategoryName: (0, import_yup16.string)().required().label("Subcategory Name"),
1032
+ groupId: (0, import_yup16.string)().required().label("Group ID"),
1033
+ groupName: (0, import_yup16.string)().required().label("Group Name"),
1034
+ /** The source record this membership came from; '' when written by hand. */
1035
+ sourceId: (0, import_yup16.string)().default("").label("Source ID")
1036
+ }).label("Concept Membership");
1037
+ var ConceptSchema = (0, import_yup16.object)({
1038
+ /** `<vocabulary>_<slug>`, e.g. `skills_power-bi`. Primary key. */
1039
+ conceptId: conceptId().required().label("Concept ID"),
1040
+ vocabulary: vocabularyId().required().label("Vocabulary"),
1041
+ name: (0, import_yup16.string)().trim().min(1).max(200).required().label("Name"),
1042
+ /** One of the vocabulary's type ids; checked against the vocabulary by the service. */
1043
+ type: (0, import_yup16.string)().trim().matches(CONCEPT_TYPE_PATTERN, "type must be a type id").required().label("Type"),
1044
+ description: (0, import_yup16.string)().trim().max(2e3).default("").label("Description"),
1045
+ aliases: strings().default([]).label("Aliases"),
1046
+ memberships: (0, import_yup16.array)(ConceptMembershipSchema.required()).default([]).label("Memberships"),
1047
+ /** Always concepts of the same vocabulary. */
1048
+ relatedConceptIds: strings().default([]).label("Related Concepts"),
1049
+ source: (0, import_yup16.string)().oneOf(SupportedConceptSources).required().label("Source"),
1050
+ createdAt: (0, import_yup16.number)().required().label("Created At"),
1051
+ updatedAt: (0, import_yup16.number)().required().label("Updated At"),
1052
+ /** Resume marker of `retype-concepts`: set once the type was examined. */
1053
+ retypedAt: (0, import_yup16.number)().optional().label("Retyped At"),
1054
+ /** Resume marker of `generate-aliases`: set even when no alias was added. */
1055
+ aliasedAt: (0, import_yup16.number)().optional().label("Aliased At"),
1056
+ /** Set while `description` is a stand-in; removed once a real one is written. */
1057
+ descriptionPending: (0, import_yup16.boolean)().isTrue().optional().label("Description Pending")
1058
+ }).label("Concept");
1059
+ var UnmatchedTermSchema = (0, import_yup16.object)({
1060
+ vocabulary: vocabularyId().required().label("Vocabulary"),
1061
+ /** The raw input as first received. */
1062
+ term: (0, import_yup16.string)().required().label("Term"),
1063
+ /** The dedupe key, so "React JS" and "react.js" share a row. */
1064
+ normalizedTerm: (0, import_yup16.string)().required().label("Normalized Term"),
1065
+ count: (0, import_yup16.number)().integer().min(0).required().label("Count"),
1066
+ firstSeenAt: (0, import_yup16.number)().required().label("First Seen At"),
1067
+ lastSeenAt: (0, import_yup16.number)().required().label("Last Seen At"),
1068
+ /** Which callers sent it, capped. */
1069
+ sources: (0, import_yup16.array)(
1070
+ (0, import_yup16.object)({
1071
+ service: (0, import_yup16.string)().required(),
1072
+ context: (0, import_yup16.string)().optional()
1073
+ }).required()
1074
+ ).default([]).label("Sources"),
1075
+ resolution: (0, import_yup16.string)().oneOf(SupportedUnmatchedResolutions).required().label("Resolution"),
1076
+ resolvedConceptId: (0, import_yup16.string)().optional().label("Resolved Concept"),
1077
+ /** `ambiguous`: the concept exists; the caller gave no context that picked one. */
1078
+ reason: (0, import_yup16.string)().oneOf(SupportedUnmatchedReasons).optional().label("Reason"),
1079
+ /** The concepts an ambiguous term could mean. */
1080
+ candidates: (0, import_yup16.array)((0, import_yup16.string)().required()).optional().label("Candidates"),
1081
+ /** Who rejected it when it was not a human: `prefilter:<rule>` or `model`. */
1082
+ rejectedBy: (0, import_yup16.string)().optional().label("Rejected By")
1083
+ }).label("Unmatched Term");
1084
+ var ProposalCandidateSchema = (0, import_yup16.object)({
1085
+ groupId: (0, import_yup16.string)().required(),
1086
+ groupName: (0, import_yup16.string)().required(),
1087
+ subcategoryId: (0, import_yup16.string)().required(),
1088
+ subcategoryName: (0, import_yup16.string)().required(),
1089
+ categoryId: (0, import_yup16.string)().required(),
1090
+ categoryName: (0, import_yup16.string)().required(),
1091
+ score: (0, import_yup16.number)().required(),
1092
+ nearestMembers: (0, import_yup16.array)((0, import_yup16.string)().required()).default([])
1093
+ }).label("Proposal Candidate");
1094
+ var ProposalMessageSchema = (0, import_yup16.object)({
1095
+ role: (0, import_yup16.string)().oneOf(SupportedProposalMessageRoles).required(),
1096
+ /** The operator's instruction, or the model's note on what it changed and why. */
1097
+ content: (0, import_yup16.string)().defined(),
1098
+ /** Which model answered. Absent on operator turns. */
1099
+ model: (0, import_yup16.string)().optional(),
1100
+ at: (0, import_yup16.number)().required()
1101
+ }).label("Proposal Message");
1102
+ var SuggestedHomeSchema = (0, import_yup16.object)({
1103
+ categoryName: (0, import_yup16.string)().defined(),
1104
+ subcategoryName: (0, import_yup16.string)().defined(),
1105
+ groupName: (0, import_yup16.string)().defined()
1106
+ }).label("Suggested Home");
1107
+ var ResolverVerificationSchema = (0, import_yup16.object)({
1108
+ verdict: (0, import_yup16.string)().oneOf(SupportedResolverVerdicts).required(),
1109
+ /** The shown concept the verdict is about; null for `new_concept` / `out_of_scope`. */
1110
+ conceptId: (0, import_yup16.string)().nullable().defined(),
1111
+ evidence: (0, import_yup16.string)().defined(),
1112
+ /** What the judge took the term to mean, abbreviations expanded. */
1113
+ means: (0, import_yup16.string)().optional(),
1114
+ /** For `same`: did the independent confirm step agree? */
1115
+ consistent: (0, import_yup16.boolean)().optional(),
1116
+ confirm: (0, import_yup16.object)({
1117
+ answer: (0, import_yup16.string)().oneOf(["yes", "no"]).required(),
1118
+ evidence: (0, import_yup16.string)().defined()
1119
+ }).optional().default(void 0)
1120
+ }).label("Resolver Verification");
1121
+ var ConceptProposalSchema = (0, import_yup16.object)({
1122
+ proposalId: (0, import_yup16.string)().required().label("Proposal ID"),
1123
+ vocabulary: vocabularyId().required().label("Vocabulary"),
1124
+ /** The miss this closes; `normalizedTerm` links back to its unmatched row. */
1125
+ term: (0, import_yup16.string)().required().label("Term"),
1126
+ normalizedTerm: (0, import_yup16.string)().required().label("Normalized Term"),
1127
+ /** Demand at proposal time, so the queue ranks without a join. */
1128
+ count: (0, import_yup16.number)().integer().min(0).required().label("Count"),
1129
+ /** Other misses folded into this draft because they name the same new concept. */
1130
+ mergedTerms: (0, import_yup16.array)(
1131
+ (0, import_yup16.object)({
1132
+ term: (0, import_yup16.string)().required(),
1133
+ normalizedTerm: (0, import_yup16.string)().required(),
1134
+ count: (0, import_yup16.number)().integer().min(0).required()
1135
+ }).required()
1136
+ ).optional().label("Merged Terms"),
1137
+ /** Absent on drafts that predate the field: read as `concept`. */
1138
+ kind: (0, import_yup16.string)().oneOf(SupportedProposalKinds).optional().label("Kind"),
1139
+ /** For `alias`: the concept the term names. For `placement`: the concept to place. */
1140
+ targetConceptId: (0, import_yup16.string)().optional().label("Target Concept"),
1141
+ targetName: (0, import_yup16.string)().optional().label("Target Name"),
1142
+ // The draft concept, editable until approved. Empty strings are valid here:
1143
+ // an alias draft carries no draft concept of its own.
1144
+ name: (0, import_yup16.string)().defined().label("Name"),
1145
+ type: (0, import_yup16.string)().defined().label("Type"),
1146
+ description: (0, import_yup16.string)().defined().label("Description"),
1147
+ aliases: (0, import_yup16.array)((0, import_yup16.string)().required()).default([]).label("Aliases"),
1148
+ /** Empty when no group fits: approved that way, the concept goes live uncategorized. */
1149
+ memberships: (0, import_yup16.array)(ConceptMembershipSchema.required()).default([]).label("Memberships"),
1150
+ suggestedHome: SuggestedHomeSchema.nullable().optional().default(void 0).label("Suggested Home"),
1151
+ /** Resolved to concepts that exist; names that matched nothing are dropped. */
1152
+ relatedConceptIds: (0, import_yup16.array)((0, import_yup16.string)().required()).default([]).label("Related Concepts"),
1153
+ /** Every placement candidate considered, best first. */
1154
+ candidates: (0, import_yup16.array)(ProposalCandidateSchema.required()).default([]).label("Candidates"),
1155
+ needsReview: (0, import_yup16.boolean)().required().label("Needs Review"),
1156
+ reason: (0, import_yup16.string)().optional().label("Reason"),
1157
+ verification: ResolverVerificationSchema.optional().default(void 0).label("Verification"),
1158
+ /** What the auto-accept gate decided for an alias verdict. */
1159
+ autoAccept: (0, import_yup16.object)({
1160
+ accepted: (0, import_yup16.boolean)().required(),
1161
+ reason: (0, import_yup16.string)().optional(),
1162
+ tier: (0, import_yup16.string)().optional(),
1163
+ calibrationId: (0, import_yup16.string)().optional(),
1164
+ releaseId: (0, import_yup16.string)().optional()
1165
+ }).optional().default(void 0).label("Auto Accept"),
1166
+ /** Which model drafted it. */
1167
+ model: (0, import_yup16.string)().defined().label("Model"),
1168
+ /** The refinement conversation, oldest first. */
1169
+ messages: (0, import_yup16.array)(ProposalMessageSchema.required()).default([]).label("Messages"),
1170
+ status: (0, import_yup16.string)().oneOf(SupportedProposalStatuses).required().label("Status"),
1171
+ /** Set when approved: the concept this became. */
1172
+ resolvedConceptId: (0, import_yup16.string)().optional().label("Resolved Concept"),
1173
+ createdAt: (0, import_yup16.number)().required().label("Created At"),
1174
+ updatedAt: (0, import_yup16.number)().required().label("Updated At")
1175
+ }).label("Concept Proposal");
1176
+ var ReleaseSchema = (0, import_yup16.object)({
1177
+ releaseId: (0, import_yup16.string)().required().label("Release ID"),
1178
+ kind: (0, import_yup16.string)().oneOf(SupportedReleaseKinds).required().label("Kind"),
1179
+ status: (0, import_yup16.string)().oneOf(SupportedReleaseStatuses).required().label("Status"),
1180
+ createdBy: (0, import_yup16.string)().required().label("Created By"),
1181
+ createdAt: (0, import_yup16.number)().required().label("Created At"),
1182
+ note: (0, import_yup16.string)().optional().label("Note"),
1183
+ rolledBackAt: (0, import_yup16.number)().optional().label("Rolled Back At"),
1184
+ rolledBackBy: (0, import_yup16.string)().optional().label("Rolled Back By")
1185
+ }).label("Release");
1186
+ var AuditSchema = (0, import_yup16.object)({
1187
+ auditId: (0, import_yup16.string)().required().label("Audit ID"),
1188
+ releaseId: (0, import_yup16.string)().required().label("Release ID"),
1189
+ key: (0, import_yup16.string)().required().label("Key"),
1190
+ term: (0, import_yup16.string)().required().label("Term"),
1191
+ conceptId: (0, import_yup16.string)().required().label("Concept ID"),
1192
+ tier: (0, import_yup16.string)().optional().label("Tier"),
1193
+ status: (0, import_yup16.string)().oneOf(SupportedAuditStatuses).required().label("Status"),
1194
+ createdAt: (0, import_yup16.number)().required().label("Created At"),
1195
+ resolvedAt: (0, import_yup16.number)().optional().label("Resolved At"),
1196
+ resolvedBy: (0, import_yup16.string)().optional().label("Resolved By")
1197
+ }).label("Audit");
1198
+ var ResolverSettingsSchema = (0, import_yup16.object)({
1199
+ autoAccept: (0, import_yup16.object)({
1200
+ /** Stop switch for WRITING auto keys. Off until a calibration passes. */
1201
+ enabled: (0, import_yup16.boolean)().required(),
1202
+ /** Minimum calibrated precision (Wilson 95% lower bound) for a tier to auto-accept. */
1203
+ target: (0, import_yup16.number)().min(0.5).lessThan(1).required(),
1204
+ maxPerRun: (0, import_yup16.number)().integer().min(0).required(),
1205
+ maxPerDay: (0, import_yup16.number)().integer().min(0).required(),
1206
+ /** Share of each auto release sampled into the audit queue (0..1). */
1207
+ auditRate: (0, import_yup16.number)().min(0).max(1).required()
1208
+ }).label("Auto Accept"),
1209
+ /** Stop switch for SERVING auto keys: false hides them from lookups at once. */
1210
+ serveAutoKeys: (0, import_yup16.boolean)().required().label("Serve Auto Keys"),
1211
+ /** Minimum Meilisearch ranking score (0..1) for a fuzzy hit to be considered. */
1212
+ fuzzyMinScore: (0, import_yup16.number)().min(0).max(1).required().label("Fuzzy Min Score"),
1213
+ /** Per-client limit on public search, per minute per replica. 0 disables it. */
1214
+ searchRateLimitPerMin: (0, import_yup16.number)().integer().min(0).required().label("Search Rate Limit"),
1215
+ /** Master switch for scheduled maintenance jobs. */
1216
+ scheduledJobs: (0, import_yup16.boolean)().required().label("Scheduled Jobs"),
1217
+ updatedAt: (0, import_yup16.number)().optional().label("Updated At"),
1218
+ updatedBy: (0, import_yup16.string)().optional().label("Updated By"),
1219
+ /** Why auto-accept was last switched off automatically. */
1220
+ trippedReason: (0, import_yup16.string)().optional().label("Tripped Reason")
1221
+ }).label("Resolver Settings");
1222
+ var TaxonomyScheduleSchema = (0, import_yup16.object)({
1223
+ kind: (0, import_yup16.string)().oneOf(SupportedTaxonomyJobKinds).required().label("Job"),
1224
+ enabled: (0, import_yup16.boolean)().required().label("Enabled"),
1225
+ everyHours: (0, import_yup16.number)().min(SCHEDULE_MIN_HOURS).max(SCHEDULE_MAX_HOURS).required().label("Every (hours)"),
1226
+ /** Last time the scheduler fired this job. */
1227
+ lastRunAt: (0, import_yup16.number)().optional().label("Last Run At"),
1228
+ updatedAt: (0, import_yup16.number)().required().label("Updated At")
1229
+ }).label("Taxonomy Schedule");
1230
+ var NormalizeContextSchema = (0, import_yup16.object)({
1231
+ /** The title of the record the terms come from. */
1232
+ title: (0, import_yup16.string)().max(200).optional(),
1233
+ /** Backbone node ids (category, subcategory or group). */
1234
+ categoryIds: (0, import_yup16.array)(nodeId().required()).max(10).optional(),
1235
+ /** Other terms from the same record, in the same vocabulary. */
1236
+ siblings: (0, import_yup16.array)((0, import_yup16.string)().max(200).required()).max(50).optional()
1237
+ }).label("Normalize Context");
1238
+
862
1239
  // src/question/question.constant.ts
863
1240
  var QuestionType = /* @__PURE__ */ ((QuestionType2) => {
864
1241
  QuestionType2["Input"] = "input";
@@ -875,24 +1252,24 @@ var AnswerChoiceType = /* @__PURE__ */ ((AnswerChoiceType2) => {
875
1252
  var SupportedAnswerChoiceTypes = Object.values(AnswerChoiceType);
876
1253
 
877
1254
  // src/question/question.schema.ts
878
- var import_yup16 = require("yup");
879
- var QuestionSchema = (0, import_yup16.object)().shape({
880
- label: (0, import_yup16.string)().max(50).optional().label("Label"),
881
- default: (0, import_yup16.boolean)().optional().default(false).label("Default"),
882
- title: (0, import_yup16.string)().required().max(200).label("Title"),
883
- type: (0, import_yup16.string)().oneOf(SupportedQuestionTypes).required().label("Type"),
884
- isOptional: (0, import_yup16.boolean)().optional().label("Mark if the question is optional"),
885
- readonly: (0, import_yup16.boolean)().optional().label("Readonly"),
886
- isNew: (0, import_yup16.boolean)().optional().label("Is New")
1255
+ var import_yup17 = require("yup");
1256
+ var QuestionSchema = (0, import_yup17.object)().shape({
1257
+ label: (0, import_yup17.string)().max(50).optional().label("Label"),
1258
+ default: (0, import_yup17.boolean)().optional().default(false).label("Default"),
1259
+ title: (0, import_yup17.string)().required().max(200).label("Title"),
1260
+ type: (0, import_yup17.string)().oneOf(SupportedQuestionTypes).required().label("Type"),
1261
+ isOptional: (0, import_yup17.boolean)().optional().label("Mark if the question is optional"),
1262
+ readonly: (0, import_yup17.boolean)().optional().label("Readonly"),
1263
+ isNew: (0, import_yup17.boolean)().optional().label("Is New")
887
1264
  });
888
1265
 
889
1266
  // src/question/input-question.schema.ts
890
- var import_yup17 = require("yup");
1267
+ var import_yup18 = require("yup");
891
1268
  var InputQuestionSchema = QuestionSchema.concat(
892
- (0, import_yup17.object)().shape({
893
- type: (0, import_yup17.string)().oneOf(["input" /* Input */]).required().label("Question type"),
894
- preferredAnswer: (0, import_yup17.string)().max(100).optional().label("Preferred Answer"),
895
- answers: (0, import_yup17.string)().max(500).when("isOptional", {
1269
+ (0, import_yup18.object)().shape({
1270
+ type: (0, import_yup18.string)().oneOf(["input" /* Input */]).required().label("Question type"),
1271
+ preferredAnswer: (0, import_yup18.string)().max(100).optional().label("Preferred Answer"),
1272
+ answers: (0, import_yup18.string)().max(500).when("isOptional", {
896
1273
  is: (isOptional) => Boolean(isOptional),
897
1274
  then: (schema) => schema.optional(),
898
1275
  otherwise: (schema) => schema.required()
@@ -901,10 +1278,10 @@ var InputQuestionSchema = QuestionSchema.concat(
901
1278
  );
902
1279
 
903
1280
  // src/question/choice-question.schema.ts
904
- var import_yup18 = require("yup");
905
- var ChoicePreferredAnswerSchema = (label = "Preferred answer") => (0, import_yup18.mixed)().when("answerChoiceType", {
1281
+ var import_yup19 = require("yup");
1282
+ var ChoicePreferredAnswerSchema = (label = "Preferred answer") => (0, import_yup19.mixed)().when("answerChoiceType", {
906
1283
  is: (value) => value === "multiple" /* Multiple */,
907
- then: () => (0, import_yup18.array)((0, import_yup18.string)()).test(
1284
+ then: () => (0, import_yup19.array)((0, import_yup19.string)()).test(
908
1285
  "is-valid-option",
909
1286
  `${label} must be from the provided options`,
910
1287
  function(answer) {
@@ -915,7 +1292,7 @@ var ChoicePreferredAnswerSchema = (label = "Preferred answer") => (0, import_yup
915
1292
  return true;
916
1293
  }
917
1294
  ).optional().label(label),
918
- otherwise: () => (0, import_yup18.string)().test(
1295
+ otherwise: () => (0, import_yup19.string)().test(
919
1296
  "is-valid-option",
920
1297
  `${label} must be from the provided options`,
921
1298
  function(answer) {
@@ -926,20 +1303,20 @@ var ChoicePreferredAnswerSchema = (label = "Preferred answer") => (0, import_yup
926
1303
  });
927
1304
  var getChoiceAnswerSchema = (answerChoiceType, isOptional) => {
928
1305
  if (answerChoiceType === "multiple" /* Multiple */) {
929
- const multiAnswerSchema = (0, import_yup18.array)((0, import_yup18.string)().max(500));
1306
+ const multiAnswerSchema = (0, import_yup19.array)((0, import_yup19.string)().max(500));
930
1307
  return isOptional ? multiAnswerSchema.optional().default([]) : multiAnswerSchema.min(1, "Select at least one option.").required("Select at least one option.").default([]);
931
1308
  }
932
- const singleAnswerSchema = (0, import_yup18.string)().max(500);
1309
+ const singleAnswerSchema = (0, import_yup19.string)().max(500);
933
1310
  return isOptional ? singleAnswerSchema.optional() : singleAnswerSchema.required("Select an option.");
934
1311
  };
935
1312
  var ChoiceQuestionSchema = QuestionSchema.concat(
936
- (0, import_yup18.object)().shape({
937
- type: (0, import_yup18.string)().oneOf(["choice" /* Choice */]).required().label("Question type"),
938
- optionsFrom: (0, import_yup18.string)().oneOf(["skill" /* Skill */, "education_level" /* EducationLevel */, "experience_level" /* ExperienceLevel */]).optional().label("Option field"),
939
- options: (0, import_yup18.array)((0, import_yup18.string)().required()).min(1).required().label("Options"),
940
- answerChoiceType: (0, import_yup18.string)().oneOf(SupportedAnswerChoiceTypes).required().default("single" /* Single */).label("Type"),
1313
+ (0, import_yup19.object)().shape({
1314
+ type: (0, import_yup19.string)().oneOf(["choice" /* Choice */]).required().label("Question type"),
1315
+ optionsFrom: (0, import_yup19.string)().oneOf(["skill" /* Skill */, "education_level" /* EducationLevel */, "experience_level" /* ExperienceLevel */]).optional().label("Option field"),
1316
+ options: (0, import_yup19.array)((0, import_yup19.string)().required()).min(1).required().label("Options"),
1317
+ answerChoiceType: (0, import_yup19.string)().oneOf(SupportedAnswerChoiceTypes).required().default("single" /* Single */).label("Type"),
941
1318
  preferredAnswer: ChoicePreferredAnswerSchema("Preferred answer"),
942
- answers: (0, import_yup18.mixed)().when(
1319
+ answers: (0, import_yup19.mixed)().when(
943
1320
  ["answerChoiceType", "isOptional"],
944
1321
  ([answerChoiceType, isOptional]) => getChoiceAnswerSchema(answerChoiceType, isOptional)
945
1322
  )
@@ -947,12 +1324,12 @@ var ChoiceQuestionSchema = QuestionSchema.concat(
947
1324
  );
948
1325
 
949
1326
  // src/question/read-and-acknowledge.schema.ts
950
- var import_yup19 = require("yup");
951
- var AcknowledgeAnswerSchema = (0, import_yup19.string)().oneOf(["yes" /* Yes */, "no" /* No */]).required("This question must be acknowledged.");
1327
+ var import_yup20 = require("yup");
1328
+ var AcknowledgeAnswerSchema = (0, import_yup20.string)().oneOf(["yes" /* Yes */, "no" /* No */]).required("This question must be acknowledged.");
952
1329
  var ReadAndAcknowledgeQuestionSchema = QuestionSchema.concat(
953
- (0, import_yup19.object)().shape({
954
- type: (0, import_yup19.string)().oneOf(["readAndAcknowledge" /* ReadAndAcknowledge */]).required().label("Question type"),
955
- description: (0, import_yup19.string)().max(1e4).required().label("Content"),
1330
+ (0, import_yup20.object)().shape({
1331
+ type: (0, import_yup20.string)().oneOf(["readAndAcknowledge" /* ReadAndAcknowledge */]).required().label("Question type"),
1332
+ description: (0, import_yup20.string)().max(1e4).required().label("Content"),
956
1333
  preferredAnswer: AcknowledgeAnswerSchema.label("Preferred Answer"),
957
1334
  answers: AcknowledgeAnswerSchema.label("Answer")
958
1335
  })
@@ -1033,20 +1410,20 @@ var SupportedApplicationReceivePreferences = Object.values(
1033
1410
  );
1034
1411
 
1035
1412
  // src/job/job.schema.ts
1036
- var JobSchema = (0, import_yup20.object)({
1413
+ var JobSchema = (0, import_yup21.object)({
1037
1414
  /** Unique id usable by external systems to reference the job. */
1038
- uniqueId: (0, import_yup20.string)().optional().label("Unique ID"),
1415
+ uniqueId: (0, import_yup21.string)().optional().label("Unique ID"),
1039
1416
  /** Job title shown in listings and search. */
1040
- headline: (0, import_yup20.string)().required().min(5).max(150).label("Headline"),
1417
+ headline: (0, import_yup21.string)().required().min(5).max(150).label("Headline"),
1041
1418
  /** User-friendly, unique URL identifier. */
1042
- slug: (0, import_yup20.string)().required().max(250).label("Slug"),
1419
+ slug: (0, import_yup21.string)().required().max(250).label("Slug"),
1043
1420
  /** How applications are received (inbox vs external website). */
1044
- applicationReceivePreference: (0, import_yup20.mixed)().oneOf([
1421
+ applicationReceivePreference: (0, import_yup21.mixed)().oneOf([
1045
1422
  "inbox" /* Inbox */,
1046
1423
  "external_website" /* ExternalWebsite */
1047
1424
  ]).required().label("Preference"),
1048
1425
  /** Required when applicationReceivePreference is ExternalWebsite. */
1049
- externalApplyLink: (0, import_yup20.string)().when("applicationReceivePreference", {
1426
+ externalApplyLink: (0, import_yup21.string)().when("applicationReceivePreference", {
1050
1427
  is: (value) => value === "external_website" /* ExternalWebsite */,
1051
1428
  then: (schema) => schema.url().required().label("Apply for Job link"),
1052
1429
  otherwise: (schema) => schema.optional()
@@ -1054,35 +1431,44 @@ var JobSchema = (0, import_yup20.object)({
1054
1431
  /** Company the job belongs to (subset of PageSchema). */
1055
1432
  company: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company"),
1056
1433
  /** @deprecated kept for backwards compatibility. */
1057
- designation: (0, import_yup20.string)().optional().nullable().label("Designation"),
1058
- employmentType: (0, import_yup20.string)().required().label("Employment type"),
1059
- workMode: (0, import_yup20.string)().required().label("Work mode"),
1434
+ designation: (0, import_yup21.string)().optional().nullable().label("Designation"),
1435
+ employmentType: (0, import_yup21.string)().required().label("Employment type"),
1436
+ workMode: (0, import_yup21.string)().required().label("Work mode"),
1060
1437
  /**
1061
- * `conceptId`/`conceptName` carry the taxonomy-service normalization. They are
1062
- * picked here (not just `name`/`logo`) because SkillSchema is `.noUnknown()`:
1063
- * an unpicked field that is actually PRESENT fails validation, so omitting them
1064
- * would reject every normalized job.
1438
+ * `name` is the skill exactly as posted. `concept` is what thejob-taxonomy-service
1439
+ * resolved it to (`vocabulary: skills`), written by jobs-service, never by the
1440
+ * poster: enough of the concept to filter by id and display the canonical name
1441
+ * without a lookup. A copy, so it can go stale after a taxonomy release; see
1442
+ * `taxonomyVersion`.
1443
+ *
1444
+ * Additive, never authoritative: the raw `name` is always kept, so a wrong
1445
+ * match, a taxonomy release or an outage is recoverable by re-normalizing.
1446
+ * `concept` is absent when the term did not resolve (a normal outcome, logged
1447
+ * as a miss on the taxonomy side) or the job predates normalization, so read
1448
+ * `concept?.name ?? name`.
1065
1449
  */
1066
- skills: (0, import_yup20.array)().of(
1067
- SkillSchema.pick(["name", "logo", "conceptId", "conceptName"]).required().label("Skill")
1450
+ skills: (0, import_yup21.array)().of(
1451
+ SkillSchema.pick(["name", "logo"]).shape({
1452
+ concept: ConceptSchema.pick(["conceptId", "vocabulary", "name", "type"]).nullable().optional().default(void 0)
1453
+ }).required().label("Skill")
1068
1454
  ).nullable().optional().label("Skills"),
1069
- bookmarks: (0, import_yup20.array)().of(UserIdAndCreatedAtSchema).optional().label("Bookmarks"),
1070
- embedding: (0, import_yup20.object)({
1071
- vector: (0, import_yup20.array)((0, import_yup20.number)().required()).optional().label("Embedding vector"),
1072
- model: (0, import_yup20.string)().optional().label("Embedding model")
1455
+ bookmarks: (0, import_yup21.array)().of(UserIdAndCreatedAtSchema).optional().label("Bookmarks"),
1456
+ embedding: (0, import_yup21.object)({
1457
+ vector: (0, import_yup21.array)((0, import_yup21.number)().required()).optional().label("Embedding vector"),
1458
+ model: (0, import_yup21.string)().optional().label("Embedding model")
1073
1459
  }).nullable().optional().label("Embedding"),
1074
- applicants: (0, import_yup20.array)().of(UserIdAndCreatedAtSchema).optional().label("Applicants"),
1075
- applicantCount: (0, import_yup20.number)().optional().label("Applicant count"),
1076
- externalApplicationLinkClickCount: (0, import_yup20.number)().optional().label("External application link click count"),
1077
- description: (0, import_yup20.string)().required().min(100).max(5e4).label("Description"),
1078
- descriptionMarkdown: (0, import_yup20.string)().required().label("Description Markdown"),
1079
- descriptionHTML: (0, import_yup20.string)().optional().label("Description HTML"),
1460
+ applicants: (0, import_yup21.array)().of(UserIdAndCreatedAtSchema).optional().label("Applicants"),
1461
+ applicantCount: (0, import_yup21.number)().optional().label("Applicant count"),
1462
+ externalApplicationLinkClickCount: (0, import_yup21.number)().optional().label("External application link click count"),
1463
+ description: (0, import_yup21.string)().required().min(100).max(5e4).label("Description"),
1464
+ descriptionMarkdown: (0, import_yup21.string)().required().label("Description Markdown"),
1465
+ descriptionHTML: (0, import_yup21.string)().optional().label("Description HTML"),
1080
1466
  /**
1081
1467
  * Job locations. Required even for remote roles (compliance/legal). Defaults
1082
1468
  * to an empty array; min(1) is intentionally not enforced yet.
1083
1469
  */
1084
- locations: (0, import_yup20.array)().of(LocationSchema).default([]).label("Location"),
1085
- educationLevel: (0, import_yup20.array)((0, import_yup20.string)().oneOf(SupportedEducationLevels)).required().min(1).label("Educational level"),
1470
+ locations: (0, import_yup21.array)().of(LocationSchema).default([]).label("Location"),
1471
+ educationLevel: (0, import_yup21.array)((0, import_yup21.string)().oneOf(SupportedEducationLevels)).required().min(1).label("Educational level"),
1086
1472
  /** Posting validity window (start/expiry). */
1087
1473
  validity: DurationSchema({
1088
1474
  format: SYSTEM_DATE_FORMAT,
@@ -1095,22 +1481,22 @@ var JobSchema = (0, import_yup20.object)({
1095
1481
  * has no `validity.endDate` and must be verified by crawling its page. Guards
1096
1482
  * re-check cadence so the same job is not re-crawled on every sweep.
1097
1483
  */
1098
- lastExpiryCheckAt: (0, import_yup20.number)().optional().nullable().label("Last expiry check at"),
1484
+ lastExpiryCheckAt: (0, import_yup21.number)().optional().nullable().label("Last expiry check at"),
1099
1485
  /**
1100
1486
  * When this job transitioned to `status: closed` (epoch ms). Server-owned
1101
1487
  * operational field: stamped by every jobs-service close path (expiry
1102
1488
  * auto-close and the dated lapse sweep). Distinct from `updatedAt` so a later
1103
1489
  * edit to a closed job does not move it.
1104
1490
  */
1105
- closedAt: (0, import_yup20.number)().optional().nullable().label("Closed at"),
1106
- experienceLevel: (0, import_yup20.string)().oneOf(SupportedExperienceLevels).nullable().optional().label("Experience level"),
1107
- contactEmail: (0, import_yup20.string)().email().nullable().optional().label("Contact email"),
1108
- workingHoursPerWeek: (0, import_yup20.number)().nullable().optional().min(1).max(24 * 7).label("Working hours per week"),
1109
- tags: (0, import_yup20.array)().max(50).optional().label("Tags"),
1491
+ closedAt: (0, import_yup21.number)().optional().nullable().label("Closed at"),
1492
+ experienceLevel: (0, import_yup21.string)().oneOf(SupportedExperienceLevels).nullable().optional().label("Experience level"),
1493
+ contactEmail: (0, import_yup21.string)().email().nullable().optional().label("Contact email"),
1494
+ workingHoursPerWeek: (0, import_yup21.number)().nullable().optional().min(1).max(24 * 7).label("Working hours per week"),
1495
+ tags: (0, import_yup21.array)().max(50).optional().label("Tags"),
1110
1496
  /** Direct/Quick-apply questionnaire. Each item is validated against the
1111
1497
  * concrete question schema for its `type`, with the stored `answers` omitted. */
1112
- questionnaire: (0, import_yup20.array)().of(
1113
- (0, import_yup20.lazy)((question) => {
1498
+ questionnaire: (0, import_yup21.array)().of(
1499
+ (0, import_yup21.lazy)((question) => {
1114
1500
  const schema = getSchemaByQuestion(question.type);
1115
1501
  if (question.type === "input" /* Input */) {
1116
1502
  return schema.omit([
@@ -1126,12 +1512,12 @@ var JobSchema = (0, import_yup20.object)({
1126
1512
  return schema;
1127
1513
  })
1128
1514
  ).label("Questionnaire"),
1129
- status: (0, import_yup20.string)().oneOf(SupportedJobStatuses).default("draft" /* Draft */).required().label("Status"),
1130
- seoTags: (0, import_yup20.object)({
1131
- description: (0, import_yup20.string)().optional().label("Description"),
1132
- keywords: (0, import_yup20.array)().of((0, import_yup20.string)()).optional().label("Keywords")
1515
+ status: (0, import_yup21.string)().oneOf(SupportedJobStatuses).default("draft" /* Draft */).required().label("Status"),
1516
+ seoTags: (0, import_yup21.object)({
1517
+ description: (0, import_yup21.string)().optional().label("Description"),
1518
+ keywords: (0, import_yup21.array)().of((0, import_yup21.string)()).optional().label("Keywords")
1133
1519
  }).nullable().optional().label("SEO Tags"),
1134
- jdSummary: (0, import_yup20.string)().optional().label("JD Summary"),
1520
+ jdSummary: (0, import_yup21.string)().optional().label("JD Summary"),
1135
1521
  /**
1136
1522
  * Structured, model-extracted sections of the posting, re-organized into clean
1137
1523
  * bullet points. This is our OWN unique presentation of the job (rendered as the
@@ -1140,28 +1526,28 @@ var JobSchema = (0, import_yup20.object)({
1140
1526
  * optional: absent on jobs not yet (re-)enriched, and any section is `[]`/omitted
1141
1527
  * when the posting genuinely has none.
1142
1528
  */
1143
- jobHighlights: (0, import_yup20.object)({
1144
- responsibilities: (0, import_yup20.array)().of((0, import_yup20.string)()).optional().label("Responsibilities"),
1145
- requirements: (0, import_yup20.array)().of((0, import_yup20.string)()).optional().label("Requirements"),
1146
- benefits: (0, import_yup20.array)().of((0, import_yup20.string)()).optional().label("Benefits"),
1147
- qualifications: (0, import_yup20.array)().of((0, import_yup20.string)()).optional().label("Qualifications")
1529
+ jobHighlights: (0, import_yup21.object)({
1530
+ responsibilities: (0, import_yup21.array)().of((0, import_yup21.string)()).optional().label("Responsibilities"),
1531
+ requirements: (0, import_yup21.array)().of((0, import_yup21.string)()).optional().label("Requirements"),
1532
+ benefits: (0, import_yup21.array)().of((0, import_yup21.string)()).optional().label("Benefits"),
1533
+ qualifications: (0, import_yup21.array)().of((0, import_yup21.string)()).optional().label("Qualifications")
1148
1534
  }).nullable().optional().label("Job Highlights"),
1149
- canCreateAlert: (0, import_yup20.boolean)().optional().label("Can create alert"),
1150
- canDirectApply: (0, import_yup20.boolean)().optional().label("Can direct apply"),
1151
- hasApplied: (0, import_yup20.boolean)().optional().label("Has applied"),
1152
- isOwner: (0, import_yup20.boolean)().optional().label("Is owner"),
1153
- hasBookmarked: (0, import_yup20.boolean)().optional().label("Has bookmarked"),
1154
- hasReported: (0, import_yup20.boolean)().optional().label("Has reported"),
1155
- ratePerHour: (0, import_yup20.number)().optional().min(0).label("Rate per hour"),
1156
- isPromoted: (0, import_yup20.boolean)().optional().label("Is promoted"),
1157
- salaryRange: (0, import_yup20.object)({
1158
- currency: (0, import_yup20.string)().required().label("Currency").default("USD"),
1159
- min: (0, import_yup20.number)().nullable().optional().min(0).label("Minimum Salary"),
1160
- max: (0, import_yup20.number)().nullable().optional().min(0).label("Maximum Salary"),
1161
- compensationType: (0, import_yup20.string)().oneOf(SupportedCompensationTypes).nullable().optional().label("Compensation Type"),
1162
- isNegotiable: (0, import_yup20.boolean)().nullable().optional().default(true).label("Is Negotiable")
1535
+ canCreateAlert: (0, import_yup21.boolean)().optional().label("Can create alert"),
1536
+ canDirectApply: (0, import_yup21.boolean)().optional().label("Can direct apply"),
1537
+ hasApplied: (0, import_yup21.boolean)().optional().label("Has applied"),
1538
+ isOwner: (0, import_yup21.boolean)().optional().label("Is owner"),
1539
+ hasBookmarked: (0, import_yup21.boolean)().optional().label("Has bookmarked"),
1540
+ hasReported: (0, import_yup21.boolean)().optional().label("Has reported"),
1541
+ ratePerHour: (0, import_yup21.number)().optional().min(0).label("Rate per hour"),
1542
+ isPromoted: (0, import_yup21.boolean)().optional().label("Is promoted"),
1543
+ salaryRange: (0, import_yup21.object)({
1544
+ currency: (0, import_yup21.string)().required().label("Currency").default("USD"),
1545
+ min: (0, import_yup21.number)().nullable().optional().min(0).label("Minimum Salary"),
1546
+ max: (0, import_yup21.number)().nullable().optional().min(0).label("Maximum Salary"),
1547
+ compensationType: (0, import_yup21.string)().oneOf(SupportedCompensationTypes).nullable().optional().label("Compensation Type"),
1548
+ isNegotiable: (0, import_yup21.boolean)().nullable().optional().default(true).label("Is Negotiable")
1163
1549
  }).nullable().optional().label("Salary Range"),
1164
- reports: (0, import_yup20.array)().of(UserIdAndCreatedAtSchema).optional().label("Reports"),
1550
+ reports: (0, import_yup21.array)().of(UserIdAndCreatedAtSchema).optional().label("Reports"),
1165
1551
  // Taxonomy fields are constants (see job-taxonomy.constant.ts), stored as slugs and
1166
1552
  // translated for display. They are deliberately NOT `oneOf`-constrained here: a value
1167
1553
  // outside the taxonomy must be DROPPED, never a reason to reject the posting. Yup
@@ -1174,17 +1560,25 @@ var JobSchema = (0, import_yup20.object)({
1174
1560
  // time (values get renamed, retired, added), so stored jobs will always outlive the
1175
1561
  // enum — being lenient here is what lets the taxonomy evolve without a migration
1176
1562
  // gate on every write.
1177
- category: (0, import_yup20.string)().nullable().optional().label("Category"),
1178
- industry: (0, import_yup20.string)().nullable().optional().label("Industry"),
1179
- subCategories: (0, import_yup20.array)().of((0, import_yup20.string)().trim().required()).nullable().optional().label("Sub Categories"),
1180
- termsAccepted: (0, import_yup20.boolean)().oneOf([true], "Accept terms before proceeding").required("Accept terms before proceeding").label("Terms accepted"),
1181
- isFeatured: (0, import_yup20.boolean)().optional().default(false).label("Is featured"),
1563
+ category: (0, import_yup21.string)().nullable().optional().label("Category"),
1564
+ industry: (0, import_yup21.string)().nullable().optional().label("Industry"),
1565
+ subCategories: (0, import_yup21.array)().of((0, import_yup21.string)().trim().required()).nullable().optional().label("Sub Categories"),
1566
+ /**
1567
+ * The taxonomy state `skills[].concept` was resolved against (the service's
1568
+ * `taxonomyVersion`, bumped by every release and rollback); behind the current
1569
+ * version means the concepts may be stale. Written by jobs-service with every
1570
+ * skills write: `null` when that write could not be normalized (taxonomy down
1571
+ * or unconfigured), absent on jobs that predate normalization.
1572
+ */
1573
+ taxonomyVersion: (0, import_yup21.number)().integer().min(0).nullable().optional().label("Taxonomy Version"),
1574
+ termsAccepted: (0, import_yup21.boolean)().oneOf([true], "Accept terms before proceeding").required("Accept terms before proceeding").label("Terms accepted"),
1575
+ isFeatured: (0, import_yup21.boolean)().optional().default(false).label("Is featured"),
1182
1576
  /** Market country codes to feature this job in; empty = global. */
1183
- featuredMarkets: (0, import_yup20.array)().of((0, import_yup20.string)().required()).optional().default([]).label("Featured markets")
1577
+ featuredMarkets: (0, import_yup21.array)().of((0, import_yup21.string)().required()).optional().default([]).label("Featured markets")
1184
1578
  }).concat(DbDefaultSchema).noUnknown().label("Job");
1185
1579
 
1186
1580
  // src/job/job-filter.schema.ts
1187
- var import_yup21 = require("yup");
1581
+ var import_yup22 = require("yup");
1188
1582
 
1189
1583
  // src/user/user.constant.ts
1190
1584
  var UserRole = /* @__PURE__ */ ((UserRole2) => {
@@ -2372,7 +2766,7 @@ var TAXONOMY_LABELS = {
2372
2766
 
2373
2767
  // src/job/job-filter.schema.ts
2374
2768
  var GEO_GROUP = "Geo";
2375
- var JobFilterShape = (0, import_yup21.object)({
2769
+ var JobFilterShape = (0, import_yup22.object)({
2376
2770
  // ── Classification ──────────────────────────────────────────────────────────
2377
2771
  // Closed vocabularies, sent verbatim and matched exactly: a partial match
2378
2772
  // would make "remote" also match a hypothetical "remote_first".
@@ -2515,8 +2909,8 @@ var JobFilterShape = (0, import_yup21.object)({
2515
2909
  // ── Flags ───────────────────────────────────────────────────────────────────
2516
2910
  // No `.default(false)`: an unchecked box must mean "no constraint", not "only
2517
2911
  // the non-featured ones", so absent simply omits the clause.
2518
- isFeatured: (0, import_yup21.boolean)().optional().label("Featured Only"),
2519
- isPromoted: (0, import_yup21.boolean)().optional().label("Promoted Only"),
2912
+ isFeatured: (0, import_yup22.boolean)().optional().label("Featured Only"),
2913
+ isPromoted: (0, import_yup22.boolean)().optional().label("Promoted Only"),
2520
2914
  featuredMarkets: tokens("Featured Markets"),
2521
2915
  // ── Ranges ──────────────────────────────────────────────────────────────────
2522
2916
  /**
@@ -2527,10 +2921,10 @@ var JobFilterShape = (0, import_yup21.object)({
2527
2921
  // can be selected and a bound is meaningless across them. Here the currency is
2528
2922
  // a single sibling field, so the bound is plain and the currency simply
2529
2923
  // narrows which jobs are compared.
2530
- salary: (0, import_yup21.object)({
2531
- min: (0, import_yup21.number)().integer().min(0).optional().default(void 0).label("Salary \u2265"),
2532
- max: (0, import_yup21.number)().integer().min(0).optional().default(void 0).label("Salary \u2264"),
2533
- currency: (0, import_yup21.string)().oneOf(SupportedSalaryCurrencies).optional().label("Currency")
2924
+ salary: (0, import_yup22.object)({
2925
+ min: (0, import_yup22.number)().integer().min(0).optional().default(void 0).label("Salary \u2265"),
2926
+ max: (0, import_yup22.number)().integer().min(0).optional().default(void 0).label("Salary \u2264"),
2927
+ currency: (0, import_yup22.string)().oneOf(SupportedSalaryCurrencies).optional().label("Currency")
2534
2928
  }).optional().default(void 0).label("Salary"),
2535
2929
  /** Posted within this many days. Relative, so a saved filter does not rot. */
2536
2930
  postedWithinDays: days("Posted Within (days)"),
@@ -2539,7 +2933,7 @@ var JobFilterShape = (0, import_yup21.object)({
2539
2933
  * relative `postedWithinDays`. EPOCH MS, matching how the field is stored — a
2540
2934
  * coerced date string would not compare.
2541
2935
  */
2542
- createdAt: (0, import_yup21.object)({
2936
+ createdAt: (0, import_yup22.object)({
2543
2937
  min: epoch("Posted After"),
2544
2938
  max: epoch("Posted Before")
2545
2939
  }).optional().default(void 0).label("Posted Between")
@@ -2593,7 +2987,7 @@ function deriveIndustry(category, subCategories) {
2593
2987
  }
2594
2988
 
2595
2989
  // src/post/post.schema.ts
2596
- var import_yup22 = require("yup");
2990
+ var import_yup23 = require("yup");
2597
2991
 
2598
2992
  // src/post/post.constant.ts
2599
2993
  var PostStatus = /* @__PURE__ */ ((PostStatus2) => {
@@ -2605,41 +2999,41 @@ var PostStatus = /* @__PURE__ */ ((PostStatus2) => {
2605
2999
  var SupportedPostStatuses = Object.values(PostStatus);
2606
3000
 
2607
3001
  // src/post/post.schema.ts
2608
- var PostSchema = (0, import_yup22.object)({
3002
+ var PostSchema = (0, import_yup23.object)({
2609
3003
  /** Headline shown in listings and at the top of the post. */
2610
- title: (0, import_yup22.string)().required().min(5).max(200).label("Title"),
3004
+ title: (0, import_yup23.string)().required().min(5).max(200).label("Title"),
2611
3005
  /** User-friendly, unique URL identifier. */
2612
- slug: (0, import_yup22.string)().required().max(250).label("Slug"),
3006
+ slug: (0, import_yup23.string)().required().max(250).label("Slug"),
2613
3007
  /** Short summary used in listings and meta description fallback. */
2614
- excerpt: (0, import_yup22.string)().max(500).optional().label("Excerpt"),
3008
+ excerpt: (0, import_yup23.string)().max(500).optional().label("Excerpt"),
2615
3009
  /** Rendered HTML source of truth for the post body (sanitized on write/render).
2616
3010
  * Supports rich formatting markdown can't express (image size/alignment, etc). */
2617
- bodyHTML: (0, import_yup22.string)().required().min(1).label("Body (HTML)"),
3011
+ bodyHTML: (0, import_yup23.string)().required().min(1).label("Body (HTML)"),
2618
3012
  /** Optional Markdown mirror of the body (portable text / search fallback).
2619
3013
  * Kept for back-compat and plain-text derivation; bodyHTML is authoritative. */
2620
- bodyMarkdown: (0, import_yup22.string)().optional().label("Body (Markdown)"),
3014
+ bodyMarkdown: (0, import_yup23.string)().optional().label("Body (Markdown)"),
2621
3015
  /** Cover/hero image URL. Not `.url()`-validated: the value is either an
2622
3016
  * uploaded file URL served by this platform (which may be a bare host like
2623
3017
  * `http://localhost:3082/...` in dev, that yup's `.url()` wrongly rejects) or
2624
3018
  * an admin-pasted link. Kept as a plain string; empty ⇒ null. */
2625
- coverImage: (0, import_yup22.string)().nullable().optional().label("Cover image"),
3019
+ coverImage: (0, import_yup23.string)().nullable().optional().label("Cover image"),
2626
3020
  /** Author (user id). */
2627
- authorId: (0, import_yup22.string)().required().label("Author ID"),
3021
+ authorId: (0, import_yup23.string)().required().label("Author ID"),
2628
3022
  /** Free-form tags for filtering and related-posts. */
2629
- tags: (0, import_yup22.array)().of((0, import_yup22.string)().trim().required()).default([]).label("Tags"),
3023
+ tags: (0, import_yup23.array)().of((0, import_yup23.string)().trim().required()).default([]).label("Tags"),
2630
3024
  /** Estimated reading time in minutes (server-derived from body length). */
2631
- readingTimeMinutes: (0, import_yup22.number)().min(0).optional().label("Reading time (minutes)"),
3025
+ readingTimeMinutes: (0, import_yup23.number)().min(0).optional().label("Reading time (minutes)"),
2632
3026
  /** SEO overrides. */
2633
- seoTags: (0, import_yup22.object)({
2634
- description: (0, import_yup22.string)().optional().label("Description"),
2635
- keywords: (0, import_yup22.array)().of((0, import_yup22.string)().required()).optional().label("Keywords")
3027
+ seoTags: (0, import_yup23.object)({
3028
+ description: (0, import_yup23.string)().optional().label("Description"),
3029
+ keywords: (0, import_yup23.array)().of((0, import_yup23.string)().required()).optional().label("Keywords")
2636
3030
  }).nullable().optional().label("SEO Tags"),
2637
3031
  /** When the post was first published (epoch ms). Server-owned. */
2638
- publishedAt: (0, import_yup22.number)().nullable().optional().label("Published at"),
3032
+ publishedAt: (0, import_yup23.number)().nullable().optional().label("Published at"),
2639
3033
  /** Whether the post is featured in the blog listing. */
2640
- isFeatured: (0, import_yup22.boolean)().default(false).optional().label("Is featured"),
3034
+ isFeatured: (0, import_yup23.boolean)().default(false).optional().label("Is featured"),
2641
3035
  /** Publication state. */
2642
- status: (0, import_yup22.string)().oneOf(SupportedPostStatuses).default("draft" /* Draft */).required().label("Status")
3036
+ status: (0, import_yup23.string)().oneOf(SupportedPostStatuses).default("draft" /* Draft */).required().label("Status")
2643
3037
  }).concat(DbDefaultSchema).noUnknown().label("Post");
2644
3038
 
2645
3039
  // src/geo/geo.constant.ts
@@ -2689,11 +3083,11 @@ var GEO_COLLECTIONS = {
2689
3083
  var GEO_SEARCH_MAX = 64;
2690
3084
 
2691
3085
  // src/geo/country.schema.ts
2692
- var import_yup23 = require("yup");
2693
- var CountrySchema = (0, import_yup23.object)({
3086
+ var import_yup24 = require("yup");
3087
+ var CountrySchema = (0, import_yup24.object)({
2694
3088
  /** The upstream dr5hn id. Stable, and the key every upsert matches on. */
2695
- id: (0, import_yup23.number)().integer().required().label("ID"),
2696
- name: (0, import_yup23.string)().trim().required().label("Name"),
3089
+ id: (0, import_yup24.number)().integer().required().label("ID"),
3090
+ name: (0, import_yup24.string)().trim().required().label("Name"),
2697
3091
  /**
2698
3092
  * ISO 3166-1 alpha-2, UPPERCASE (`IN`, `SE`).
2699
3093
  *
@@ -2702,34 +3096,34 @@ var CountrySchema = (0, import_yup23.object)({
2702
3096
  * already clean uppercase alpha-2. A lowercase value here would compare
2703
3097
  * unequal to all of them and silently match nothing.
2704
3098
  */
2705
- countryCode: (0, import_yup23.string)().trim().uppercase().length(2).required().label("Country Code"),
2706
- iso3: (0, import_yup23.string)().trim().uppercase().length(3).optional().nullable().label("ISO3"),
2707
- numericCode: (0, import_yup23.string)().trim().optional().nullable().label("Numeric Code"),
2708
- phonecode: (0, import_yup23.string)().trim().optional().nullable().label("Phone Code"),
2709
- capital: (0, import_yup23.string)().trim().optional().nullable().label("Capital"),
2710
- currency: (0, import_yup23.string)().trim().optional().nullable().label("Currency"),
2711
- currencyName: (0, import_yup23.string)().trim().optional().nullable().label("Currency Name"),
2712
- currencySymbol: (0, import_yup23.string)().trim().optional().nullable().label("Currency Symbol"),
2713
- tld: (0, import_yup23.string)().trim().optional().nullable().label("TLD"),
3099
+ countryCode: (0, import_yup24.string)().trim().uppercase().length(2).required().label("Country Code"),
3100
+ iso3: (0, import_yup24.string)().trim().uppercase().length(3).optional().nullable().label("ISO3"),
3101
+ numericCode: (0, import_yup24.string)().trim().optional().nullable().label("Numeric Code"),
3102
+ phonecode: (0, import_yup24.string)().trim().optional().nullable().label("Phone Code"),
3103
+ capital: (0, import_yup24.string)().trim().optional().nullable().label("Capital"),
3104
+ currency: (0, import_yup24.string)().trim().optional().nullable().label("Currency"),
3105
+ currencyName: (0, import_yup24.string)().trim().optional().nullable().label("Currency Name"),
3106
+ currencySymbol: (0, import_yup24.string)().trim().optional().nullable().label("Currency Symbol"),
3107
+ tld: (0, import_yup24.string)().trim().optional().nullable().label("TLD"),
2714
3108
  /** The name in its own script, e.g. "भारत". Stored, but NOT searchable; see `searchByLocale`. */
2715
- native: (0, import_yup23.string)().trim().optional().nullable().label("Native Name"),
2716
- population: (0, import_yup23.number)().optional().nullable().label("Population"),
2717
- gdp: (0, import_yup23.number)().optional().nullable().label("GDP"),
2718
- region: (0, import_yup23.string)().trim().optional().nullable().label("Region"),
2719
- regionId: (0, import_yup23.number)().integer().optional().nullable().label("Region ID"),
2720
- subregion: (0, import_yup23.string)().trim().optional().nullable().label("Subregion"),
2721
- subregionId: (0, import_yup23.number)().integer().optional().nullable().label("Subregion ID"),
2722
- nationality: (0, import_yup23.string)().trim().optional().nullable().label("Nationality"),
2723
- areaSqKm: (0, import_yup23.number)().optional().nullable().label("Area (sq km)"),
2724
- postalCodeFormat: (0, import_yup23.string)().trim().optional().nullable().label("Postal Code Format"),
2725
- postalCodeRegex: (0, import_yup23.string)().optional().nullable().label("Postal Code Regex"),
2726
- timezones: (0, import_yup23.array)().of(
2727
- (0, import_yup23.object)({
2728
- zoneName: (0, import_yup23.string)().optional().nullable().label("Zone Name"),
2729
- gmtOffset: (0, import_yup23.number)().optional().nullable().label("GMT Offset"),
2730
- gmtOffsetName: (0, import_yup23.string)().optional().nullable().label("GMT Offset Name"),
2731
- abbreviation: (0, import_yup23.string)().optional().nullable().label("Abbreviation"),
2732
- tzName: (0, import_yup23.string)().optional().nullable().label("TZ Name")
3109
+ native: (0, import_yup24.string)().trim().optional().nullable().label("Native Name"),
3110
+ population: (0, import_yup24.number)().optional().nullable().label("Population"),
3111
+ gdp: (0, import_yup24.number)().optional().nullable().label("GDP"),
3112
+ region: (0, import_yup24.string)().trim().optional().nullable().label("Region"),
3113
+ regionId: (0, import_yup24.number)().integer().optional().nullable().label("Region ID"),
3114
+ subregion: (0, import_yup24.string)().trim().optional().nullable().label("Subregion"),
3115
+ subregionId: (0, import_yup24.number)().integer().optional().nullable().label("Subregion ID"),
3116
+ nationality: (0, import_yup24.string)().trim().optional().nullable().label("Nationality"),
3117
+ areaSqKm: (0, import_yup24.number)().optional().nullable().label("Area (sq km)"),
3118
+ postalCodeFormat: (0, import_yup24.string)().trim().optional().nullable().label("Postal Code Format"),
3119
+ postalCodeRegex: (0, import_yup24.string)().optional().nullable().label("Postal Code Regex"),
3120
+ timezones: (0, import_yup24.array)().of(
3121
+ (0, import_yup24.object)({
3122
+ zoneName: (0, import_yup24.string)().optional().nullable().label("Zone Name"),
3123
+ gmtOffset: (0, import_yup24.number)().optional().nullable().label("GMT Offset"),
3124
+ gmtOffsetName: (0, import_yup24.string)().optional().nullable().label("GMT Offset Name"),
3125
+ abbreviation: (0, import_yup24.string)().optional().nullable().label("Abbreviation"),
3126
+ tzName: (0, import_yup24.string)().optional().nullable().label("TZ Name")
2733
3127
  })
2734
3128
  ).optional().nullable().label("Timezones"),
2735
3129
  /**
@@ -2738,7 +3132,7 @@ var CountrySchema = (0, import_yup23.object)({
2738
3132
  * declaring it here would turn a new locale into a validation failure. The
2739
3133
  * VALUES are split per-locale into `searchByLocale`.
2740
3134
  */
2741
- translations: (0, import_yup23.object)().optional().nullable().label("Translations"),
3135
+ translations: (0, import_yup24.object)().optional().nullable().label("Translations"),
2742
3136
  /**
2743
3137
  * Coordinates as NUMBERS.
2744
3138
  *
@@ -2747,10 +3141,10 @@ var CountrySchema = (0, import_yup23.object)({
2747
3141
  * `"9" > "10"` is true, so a bounding-box filter would be quietly wrong rather
2748
3142
  * than failing loudly.
2749
3143
  */
2750
- latitude: (0, import_yup23.number)().optional().nullable().label("Latitude"),
2751
- longitude: (0, import_yup23.number)().optional().nullable().label("Longitude"),
2752
- emoji: (0, import_yup23.string)().optional().nullable().label("Emoji"),
2753
- emojiU: (0, import_yup23.string)().optional().nullable().label("Emoji Unicode"),
3144
+ latitude: (0, import_yup24.number)().optional().nullable().label("Latitude"),
3145
+ longitude: (0, import_yup24.number)().optional().nullable().label("Longitude"),
3146
+ emoji: (0, import_yup24.string)().optional().nullable().label("Emoji"),
3147
+ emojiU: (0, import_yup24.string)().optional().nullable().label("Emoji Unicode"),
2754
3148
  /**
2755
3149
  * The name field searched for the DEFAULT (English) locale: the canonical
2756
3150
  * `name`, and nothing else.
@@ -2760,7 +3154,7 @@ var CountrySchema = (0, import_yup23.object)({
2760
3154
  * field would make every locale's search implicitly a search of all 19
2761
3155
  * languages: a French UI searching "Inde" would also match German "Indien".
2762
3156
  */
2763
- searchDefault: (0, import_yup23.array)().of((0, import_yup23.string)().required()).optional().default([]).label("Search Default"),
3157
+ searchDefault: (0, import_yup24.array)().of((0, import_yup24.string)().required()).optional().default([]).label("Search Default"),
2764
3158
  /**
2765
3159
  * Per-locale name fields, keyed by lowercased BCP-47 tag (`de`, `pt-br`).
2766
3160
  * Each carries ONLY that locale's translation, which is what makes
@@ -2778,21 +3172,21 @@ var CountrySchema = (0, import_yup23.object)({
2778
3172
  * it, zh-CN, tr, ru, uk, pl, hi, ar. **`sv` is absent**, so a Swedish search
2779
3173
  * matches nothing. That is the accepted cost of strict scoping.
2780
3174
  */
2781
- searchByLocale: (0, import_yup23.object)().optional().nullable().label("Search By Locale"),
3175
+ searchByLocale: (0, import_yup24.object)().optional().nullable().label("Search By Locale"),
2782
3176
  /** Epoch ms of the run that last wrote this row. Drives the stale-row prune. */
2783
- syncedAt: (0, import_yup23.number)().optional().nullable().label("Synced At")
3177
+ syncedAt: (0, import_yup24.number)().optional().nullable().label("Synced At")
2784
3178
  }).label("Country");
2785
3179
 
2786
3180
  // src/geo/state.schema.ts
2787
- var import_yup24 = require("yup");
2788
- var StateSchema = (0, import_yup24.object)({
3181
+ var import_yup25 = require("yup");
3182
+ var StateSchema = (0, import_yup25.object)({
2789
3183
  /** The upstream dr5hn id. Stable, and the key every upsert matches on. */
2790
- id: (0, import_yup24.number)().integer().required().label("ID"),
2791
- name: (0, import_yup24.string)().trim().required().label("Name"),
2792
- countryId: (0, import_yup24.number)().integer().optional().nullable().label("Country ID"),
3184
+ id: (0, import_yup25.number)().integer().required().label("ID"),
3185
+ name: (0, import_yup25.string)().trim().required().label("Name"),
3186
+ countryId: (0, import_yup25.number)().integer().optional().nullable().label("Country ID"),
2793
3187
  /** ISO 3166-1 alpha-2 of the parent, UPPERCASE. See `CountrySchema.countryCode`. */
2794
- countryCode: (0, import_yup24.string)().trim().uppercase().length(2).required().label("Country Code"),
2795
- countryName: (0, import_yup24.string)().trim().optional().nullable().label("Country Name"),
3188
+ countryCode: (0, import_yup25.string)().trim().uppercase().length(2).required().label("Country Code"),
3189
+ countryName: (0, import_yup25.string)().trim().optional().nullable().label("Country Name"),
2796
3190
  /**
2797
3191
  * The BARE subdivision code, e.g. `KA` (upstream `iso2`).
2798
3192
  *
@@ -2804,22 +3198,22 @@ var StateSchema = (0, import_yup24.object)({
2804
3198
  * both are stored so the migration has its destination present before any
2805
3199
  * consumer moves.
2806
3200
  */
2807
- stateCode: (0, import_yup24.string)().trim().uppercase().optional().nullable().label("State Code"),
3201
+ stateCode: (0, import_yup25.string)().trim().uppercase().optional().nullable().label("State Code"),
2808
3202
  /** Fully-qualified ISO 3166-2, e.g. `IN-KA` (upstream `iso3166_2`). */
2809
- stateCodeIso: (0, import_yup24.string)().trim().uppercase().optional().nullable().label("ISO 3166-2 Code"),
2810
- fipsCode: (0, import_yup24.string)().trim().optional().nullable().label("FIPS Code"),
3203
+ stateCodeIso: (0, import_yup25.string)().trim().uppercase().optional().nullable().label("ISO 3166-2 Code"),
3204
+ fipsCode: (0, import_yup25.string)().trim().optional().nullable().label("FIPS Code"),
2811
3205
  /** Upstream's own word for the subdivision: "province", "state", "district", … */
2812
- type: (0, import_yup24.string)().trim().optional().nullable().label("Type"),
2813
- level: (0, import_yup24.number)().integer().optional().nullable().label("Level"),
2814
- parentId: (0, import_yup24.number)().integer().optional().nullable().label("Parent ID"),
3206
+ type: (0, import_yup25.string)().trim().optional().nullable().label("Type"),
3207
+ level: (0, import_yup25.number)().integer().optional().nullable().label("Level"),
3208
+ parentId: (0, import_yup25.number)().integer().optional().nullable().label("Parent ID"),
2815
3209
  /** The name in its own script. Stored, but NOT searchable; see `searchByLocale`. */
2816
- native: (0, import_yup24.string)().trim().optional().nullable().label("Native Name"),
3210
+ native: (0, import_yup25.string)().trim().optional().nullable().label("Native Name"),
2817
3211
  /** Numbers, not the strings upstream ships. See `CountrySchema.latitude`. */
2818
- latitude: (0, import_yup24.number)().optional().nullable().label("Latitude"),
2819
- longitude: (0, import_yup24.number)().optional().nullable().label("Longitude"),
2820
- timezone: (0, import_yup24.string)().trim().optional().nullable().label("Timezone"),
3212
+ latitude: (0, import_yup25.number)().optional().nullable().label("Latitude"),
3213
+ longitude: (0, import_yup25.number)().optional().nullable().label("Longitude"),
3214
+ timezone: (0, import_yup25.string)().trim().optional().nullable().label("Timezone"),
2821
3215
  /** Localized names keyed by locale. Unshaped; see `CountrySchema.translations`. */
2822
- translations: (0, import_yup24.object)().optional().nullable().label("Translations"),
3216
+ translations: (0, import_yup25.object)().optional().nullable().label("Translations"),
2823
3217
  /**
2824
3218
  * The name field searched for the DEFAULT (English) locale: the canonical
2825
3219
  * `name`, and nothing else.
@@ -2829,7 +3223,7 @@ var StateSchema = (0, import_yup24.object)({
2829
3223
  * field would make every locale's search implicitly a search of all 19
2830
3224
  * languages: a French UI searching "Inde" would also match German "Indien".
2831
3225
  */
2832
- searchDefault: (0, import_yup24.array)().of((0, import_yup24.string)().required()).optional().default([]).label("Search Default"),
3226
+ searchDefault: (0, import_yup25.array)().of((0, import_yup25.string)().required()).optional().default([]).label("Search Default"),
2833
3227
  /**
2834
3228
  * Per-locale name fields, keyed by lowercased BCP-47 tag (`de`, `pt-br`).
2835
3229
  * Each carries ONLY that locale's translation, which is what makes
@@ -2847,20 +3241,20 @@ var StateSchema = (0, import_yup24.object)({
2847
3241
  * it, zh-CN, tr, ru, uk, pl, hi, ar. **`sv` is absent**, so a Swedish search
2848
3242
  * matches nothing. That is the accepted cost of strict scoping.
2849
3243
  */
2850
- searchByLocale: (0, import_yup24.object)().optional().nullable().label("Search By Locale"),
3244
+ searchByLocale: (0, import_yup25.object)().optional().nullable().label("Search By Locale"),
2851
3245
  /** Epoch ms of the run that last wrote this row. Drives the stale-row prune. */
2852
- syncedAt: (0, import_yup24.number)().optional().nullable().label("Synced At")
3246
+ syncedAt: (0, import_yup25.number)().optional().nullable().label("Synced At")
2853
3247
  }).label("State");
2854
3248
 
2855
3249
  // src/geo/city.schema.ts
2856
- var import_yup25 = require("yup");
2857
- var CitySchema = (0, import_yup25.object)({
3250
+ var import_yup26 = require("yup");
3251
+ var CitySchema = (0, import_yup26.object)({
2858
3252
  /** The upstream dr5hn id. Stable, and the key every upsert matches on. */
2859
- id: (0, import_yup25.number)().integer().required().label("ID"),
2860
- name: (0, import_yup25.string)().trim().required().label("Name"),
2861
- stateId: (0, import_yup25.number)().integer().optional().nullable().label("State ID"),
3253
+ id: (0, import_yup26.number)().integer().required().label("ID"),
3254
+ name: (0, import_yup26.string)().trim().required().label("Name"),
3255
+ stateId: (0, import_yup26.number)().integer().optional().nullable().label("State ID"),
2862
3256
  /** The BARE subdivision code. Only meaningful paired with `countryCode`; see `StateSchema`. */
2863
- stateCode: (0, import_yup25.string)().trim().uppercase().optional().nullable().label("State Code"),
3257
+ stateCode: (0, import_yup26.string)().trim().uppercase().optional().nullable().label("State Code"),
2864
3258
  /**
2865
3259
  * Fully-qualified ISO 3166-2, e.g. `IN-KA`.
2866
3260
  *
@@ -2870,29 +3264,29 @@ var CitySchema = (0, import_yup25.object)({
2870
3264
  * migration can re-point the cities route without a 153k-row re-ingest.
2871
3265
  * Null when either half is missing.
2872
3266
  */
2873
- stateCodeIso: (0, import_yup25.string)().trim().uppercase().optional().nullable().label("ISO 3166-2 Code"),
2874
- stateName: (0, import_yup25.string)().trim().optional().nullable().label("State Name"),
2875
- countryId: (0, import_yup25.number)().integer().optional().nullable().label("Country ID"),
3267
+ stateCodeIso: (0, import_yup26.string)().trim().uppercase().optional().nullable().label("ISO 3166-2 Code"),
3268
+ stateName: (0, import_yup26.string)().trim().optional().nullable().label("State Name"),
3269
+ countryId: (0, import_yup26.number)().integer().optional().nullable().label("Country ID"),
2876
3270
  /** ISO 3166-1 alpha-2 of the parent, UPPERCASE. See `CountrySchema.countryCode`. */
2877
- countryCode: (0, import_yup25.string)().trim().uppercase().length(2).required().label("Country Code"),
2878
- countryName: (0, import_yup25.string)().trim().optional().nullable().label("Country Name"),
3271
+ countryCode: (0, import_yup26.string)().trim().uppercase().length(2).required().label("Country Code"),
3272
+ countryName: (0, import_yup26.string)().trim().optional().nullable().label("Country Name"),
2879
3273
  /** Numbers, not the strings upstream ships. See `CountrySchema.latitude`. */
2880
- latitude: (0, import_yup25.number)().optional().nullable().label("Latitude"),
2881
- longitude: (0, import_yup25.number)().optional().nullable().label("Longitude"),
3274
+ latitude: (0, import_yup26.number)().optional().nullable().label("Latitude"),
3275
+ longitude: (0, import_yup26.number)().optional().nullable().label("Longitude"),
2882
3276
  /** The name in its own script. Stored, but NOT searchable; see `searchByLocale`. */
2883
- native: (0, import_yup25.string)().trim().optional().nullable().label("Native Name"),
2884
- type: (0, import_yup25.string)().trim().optional().nullable().label("Type"),
2885
- level: (0, import_yup25.number)().integer().optional().nullable().label("Level"),
2886
- parentId: (0, import_yup25.number)().integer().optional().nullable().label("Parent ID"),
3277
+ native: (0, import_yup26.string)().trim().optional().nullable().label("Native Name"),
3278
+ type: (0, import_yup26.string)().trim().optional().nullable().label("Type"),
3279
+ level: (0, import_yup26.number)().integer().optional().nullable().label("Level"),
3280
+ parentId: (0, import_yup26.number)().integer().optional().nullable().label("Parent ID"),
2887
3281
  /**
2888
3282
  * Null on most rows. Worth keeping (it is a good relevance signal when
2889
3283
  * present) but never worth SORTING by alone, since a null-heavy sort buries
2890
3284
  * every city upstream has no figure for.
2891
3285
  */
2892
- population: (0, import_yup25.number)().optional().nullable().label("Population"),
2893
- timezone: (0, import_yup25.string)().trim().optional().nullable().label("Timezone"),
3286
+ population: (0, import_yup26.number)().optional().nullable().label("Population"),
3287
+ timezone: (0, import_yup26.string)().trim().optional().nullable().label("Timezone"),
2894
3288
  /** Localized names keyed by locale. Unshaped; see `CountrySchema.translations`. */
2895
- translations: (0, import_yup25.object)().optional().nullable().label("Translations"),
3289
+ translations: (0, import_yup26.object)().optional().nullable().label("Translations"),
2896
3290
  /**
2897
3291
  * The name field searched for the DEFAULT (English) locale: the canonical
2898
3292
  * `name`, and nothing else.
@@ -2902,7 +3296,7 @@ var CitySchema = (0, import_yup25.object)({
2902
3296
  * field would make every locale's search implicitly a search of all 19
2903
3297
  * languages: a French UI searching "Inde" would also match German "Indien".
2904
3298
  */
2905
- searchDefault: (0, import_yup25.array)().of((0, import_yup25.string)().required()).optional().default([]).label("Search Default"),
3299
+ searchDefault: (0, import_yup26.array)().of((0, import_yup26.string)().required()).optional().default([]).label("Search Default"),
2906
3300
  /**
2907
3301
  * Per-locale name fields, keyed by lowercased BCP-47 tag (`de`, `pt-br`).
2908
3302
  * Each carries ONLY that locale's translation, which is what makes
@@ -2920,14 +3314,14 @@ var CitySchema = (0, import_yup25.object)({
2920
3314
  * it, zh-CN, tr, ru, uk, pl, hi, ar. **`sv` is absent**, so a Swedish search
2921
3315
  * matches nothing. That is the accepted cost of strict scoping.
2922
3316
  */
2923
- searchByLocale: (0, import_yup25.object)().optional().nullable().label("Search By Locale"),
3317
+ searchByLocale: (0, import_yup26.object)().optional().nullable().label("Search By Locale"),
2924
3318
  /** Epoch ms of the run that last wrote this row. Drives the stale-row prune. */
2925
- syncedAt: (0, import_yup25.number)().optional().nullable().label("Synced At")
3319
+ syncedAt: (0, import_yup26.number)().optional().nullable().label("Synced At")
2926
3320
  }).label("City");
2927
3321
 
2928
3322
  // src/geo/country-filter.schema.ts
2929
- var import_yup26 = require("yup");
2930
- var CountryFilterShape = (0, import_yup26.object)({
3323
+ var import_yup27 = require("yup");
3324
+ var CountryFilterShape = (0, import_yup27.object)({
2931
3325
  /** ISO 3166-1 alpha-2 codes, e.g. `IN`. Uppercased, matching how they are stored. */
2932
3326
  countryCodes: codeTokens("Country Codes"),
2933
3327
  /** ISO 3166-1 alpha-3 codes, e.g. `IND`. */
@@ -2947,8 +3341,8 @@ var CountryFilterSchema = rejectUnknownKeys(
2947
3341
  );
2948
3342
 
2949
3343
  // src/geo/state-filter.schema.ts
2950
- var import_yup27 = require("yup");
2951
- var StateFilterShape = (0, import_yup27.object)({
3344
+ var import_yup28 = require("yup");
3345
+ var StateFilterShape = (0, import_yup28.object)({
2952
3346
  /** ISO 3166-1 alpha-2 of the parent country, e.g. `IN`. */
2953
3347
  countryCodes: codeTokens("Country Codes"),
2954
3348
  /**
@@ -2978,8 +3372,8 @@ var StateFilterSchema = rejectUnknownKeys(
2978
3372
  );
2979
3373
 
2980
3374
  // src/geo/city-filter.schema.ts
2981
- var import_yup28 = require("yup");
2982
- var CityFilterShape = (0, import_yup28.object)({
3375
+ var import_yup29 = require("yup");
3376
+ var CityFilterShape = (0, import_yup29.object)({
2983
3377
  /** ISO 3166-1 alpha-2 of the parent country, e.g. `IN`. */
2984
3378
  countryCodes: codeTokens("Country Codes"),
2985
3379
  /**
@@ -2996,28 +3390,28 @@ var CityFilterSchema = rejectUnknownKeys(
2996
3390
  );
2997
3391
 
2998
3392
  // src/geo/geo-sync.schema.ts
2999
- var import_yup29 = require("yup");
3000
- var GeoSyncCountsSchema = (0, import_yup29.object)({
3001
- read: (0, import_yup29.number)().integer().min(0).default(0).label("Read"),
3002
- upserted: (0, import_yup29.number)().integer().min(0).default(0).label("Upserted"),
3003
- modified: (0, import_yup29.number)().integer().min(0).default(0).label("Modified"),
3004
- matched: (0, import_yup29.number)().integer().min(0).default(0).label("Matched"),
3393
+ var import_yup30 = require("yup");
3394
+ var GeoSyncCountsSchema = (0, import_yup30.object)({
3395
+ read: (0, import_yup30.number)().integer().min(0).default(0).label("Read"),
3396
+ upserted: (0, import_yup30.number)().integer().min(0).default(0).label("Upserted"),
3397
+ modified: (0, import_yup30.number)().integer().min(0).default(0).label("Modified"),
3398
+ matched: (0, import_yup30.number)().integer().min(0).default(0).label("Matched"),
3005
3399
  /** Rows removed because upstream dropped them. See `prunedSkipped`. */
3006
- pruned: (0, import_yup29.number)().integer().min(0).default(0).label("Pruned"),
3400
+ pruned: (0, import_yup30.number)().integer().min(0).default(0).label("Pruned"),
3007
3401
  /**
3008
3402
  * True when the stale-row prune was REFUSED because it would have removed more
3009
3403
  * than its safety threshold of the collection. A partial fetch that looked
3010
3404
  * like a success must not be able to empty the table, so the run reports the
3011
3405
  * refusal rather than acting on it.
3012
3406
  */
3013
- prunedSkipped: (0, import_yup29.boolean)().default(false).label("Prune Skipped")
3407
+ prunedSkipped: (0, import_yup30.boolean)().default(false).label("Prune Skipped")
3014
3408
  }).label("Sync Counts");
3015
- var GeoSyncRunSchema = (0, import_yup29.object)({
3016
- jobId: (0, import_yup29.string)().required().label("Job ID"),
3017
- status: (0, import_yup29.mixed)().oneOf(SupportedGeoSyncStatuses).required().label("Status"),
3018
- trigger: (0, import_yup29.mixed)().oneOf(SupportedGeoSyncTriggers).optional().label("Trigger"),
3409
+ var GeoSyncRunSchema = (0, import_yup30.object)({
3410
+ jobId: (0, import_yup30.string)().required().label("Job ID"),
3411
+ status: (0, import_yup30.mixed)().oneOf(SupportedGeoSyncStatuses).required().label("Status"),
3412
+ trigger: (0, import_yup30.mixed)().oneOf(SupportedGeoSyncTriggers).optional().label("Trigger"),
3019
3413
  /** Whether the caller asked to run even though the release tag was unchanged. */
3020
- force: (0, import_yup29.boolean)().default(false).label("Force"),
3414
+ force: (0, import_yup30.boolean)().default(false).label("Force"),
3021
3415
  /**
3022
3416
  * The upstream release tag this run fetched, e.g. `v3.2-export.7`.
3023
3417
  *
@@ -3025,13 +3419,13 @@ var GeoSyncRunSchema = (0, import_yup29.object)({
3025
3419
  * cannot tell what version it is fetching is otherwise a failure, not a
3026
3420
  * refresh, so it is not allowed to proceed unattended.
3027
3421
  */
3028
- releaseTag: (0, import_yup29.string)().optional().nullable().label("Release Tag"),
3422
+ releaseTag: (0, import_yup30.string)().optional().nullable().label("Release Tag"),
3029
3423
  /** The tag of the last successful run, i.e. what this one is replacing. */
3030
- previousReleaseTag: (0, import_yup29.string)().optional().nullable().label("Previous Release Tag"),
3031
- startedAt: (0, import_yup29.number)().required().label("Started At"),
3032
- finishedAt: (0, import_yup29.number)().optional().nullable().label("Finished At"),
3033
- durationMs: (0, import_yup29.number)().optional().nullable().label("Duration (ms)"),
3034
- phase: (0, import_yup29.mixed)().oneOf(SupportedGeoSyncPhases).optional().nullable().label("Phase"),
3424
+ previousReleaseTag: (0, import_yup30.string)().optional().nullable().label("Previous Release Tag"),
3425
+ startedAt: (0, import_yup30.number)().required().label("Started At"),
3426
+ finishedAt: (0, import_yup30.number)().optional().nullable().label("Finished At"),
3427
+ durationMs: (0, import_yup30.number)().optional().nullable().label("Duration (ms)"),
3428
+ phase: (0, import_yup30.mixed)().oneOf(SupportedGeoSyncPhases).optional().nullable().label("Phase"),
3035
3429
  /**
3036
3430
  * Live progress for the dashboard bar.
3037
3431
  *
@@ -3039,25 +3433,25 @@ var GeoSyncRunSchema = (0, import_yup29.object)({
3039
3433
  * collection, or a hardcoded fallback on the very first run, since the true
3040
3434
  * total is not known until the stream ends. The UI should render it as one.
3041
3435
  */
3042
- progress: (0, import_yup29.object)({
3043
- collection: (0, import_yup29.string)().optional().nullable().label("Collection"),
3044
- processed: (0, import_yup29.number)().integer().min(0).default(0).label("Processed"),
3045
- total: (0, import_yup29.number)().integer().min(0).optional().nullable().label("Total")
3436
+ progress: (0, import_yup30.object)({
3437
+ collection: (0, import_yup30.string)().optional().nullable().label("Collection"),
3438
+ processed: (0, import_yup30.number)().integer().min(0).default(0).label("Processed"),
3439
+ total: (0, import_yup30.number)().integer().min(0).optional().nullable().label("Total")
3046
3440
  }).optional().nullable().label("Progress"),
3047
- counts: (0, import_yup29.object)({
3441
+ counts: (0, import_yup30.object)({
3048
3442
  countries: GeoSyncCountsSchema.optional().nullable().label("Countries"),
3049
3443
  states: GeoSyncCountsSchema.optional().nullable().label("States"),
3050
3444
  cities: GeoSyncCountsSchema.optional().nullable().label("Cities")
3051
3445
  }).optional().nullable().label("Counts"),
3052
3446
  /** Why a `skipped` run was skipped, in words the dashboard can show verbatim. */
3053
- reason: (0, import_yup29.string)().optional().nullable().label("Reason"),
3447
+ reason: (0, import_yup30.string)().optional().nullable().label("Reason"),
3054
3448
  /** The failure message on a `failed` run. Surfaced verbatim to the admin. */
3055
- error: (0, import_yup29.string)().optional().nullable().label("Error")
3449
+ error: (0, import_yup30.string)().optional().nullable().label("Error")
3056
3450
  }).label("Geo Sync Run");
3057
3451
 
3058
3452
  // src/language/language-filter.schema.ts
3059
- var import_yup30 = require("yup");
3060
- var LanguageFilterShape = (0, import_yup30.object)({
3453
+ var import_yup31 = require("yup");
3454
+ var LanguageFilterShape = (0, import_yup31.object)({
3061
3455
  /** Language names, matched exactly. Free-text matching is `?search=`. */
3062
3456
  names: tokens("Names")
3063
3457
  }).label("Language Filter");
@@ -3067,8 +3461,8 @@ var LanguageFilterSchema = rejectUnknownKeys(
3067
3461
  );
3068
3462
 
3069
3463
  // src/page/page-filter.schema.ts
3070
- var import_yup31 = require("yup");
3071
- var PageFilterShape = (0, import_yup31.object)({
3464
+ var import_yup32 = require("yup");
3465
+ var PageFilterShape = (0, import_yup32.object)({
3072
3466
  /**
3073
3467
  * `type`, NOT `pageType`.
3074
3468
  *
@@ -3088,7 +3482,7 @@ var PageFilterShape = (0, import_yup31.object)({
3088
3482
  // No `.default(false)`: absent means no constraint. Note `isFeatured` is
3089
3483
  // present on only 55 documents, so combining it with `status: ['published']`
3090
3484
  // leaves 11 pages — a legitimate filter that returns almost nothing.
3091
- isFeatured: (0, import_yup31.boolean)().optional().label("Featured Only"),
3485
+ isFeatured: (0, import_yup32.boolean)().optional().label("Featured Only"),
3092
3486
  /** Lowercase (`in`, `se`, `ww`), like groups. See `GroupFilterSchema`. */
3093
3487
  featuredMarkets: tokens("Featured Markets"),
3094
3488
  /** Page SLUGS. A company is matched by slug: a display name breaks on rename. */
@@ -3101,7 +3495,7 @@ var PageFilterSchema = rejectUnknownKeys(
3101
3495
  );
3102
3496
 
3103
3497
  // src/marketing/marketing.schema.ts
3104
- var import_yup33 = require("yup");
3498
+ var import_yup34 = require("yup");
3105
3499
 
3106
3500
  // src/marketing/marketing.constant.ts
3107
3501
  var CampaignStatus = /* @__PURE__ */ ((CampaignStatus2) => {
@@ -3178,8 +3572,8 @@ var SupportedOccurrenceStatuses = Object.values(OccurrenceStatus);
3178
3572
  var CAMPAIGN_MAX_RECIPIENTS_CEILING = 5e3;
3179
3573
 
3180
3574
  // src/user/user-filter.schema.ts
3181
- var import_yup32 = require("yup");
3182
- var UserFilterBranchShape = (0, import_yup32.object)({
3575
+ var import_yup33 = require("yup");
3576
+ var UserFilterBranchShape = (0, import_yup33.object)({
3183
3577
  /**
3184
3578
  * Exact email addresses. An IDENTITY lookup, not a search.
3185
3579
  *
@@ -3199,7 +3593,7 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3199
3593
  * the input keeps the match an indexed equality instead of a regex that would
3200
3594
  * put the scan straight back.
3201
3595
  */
3202
- emails: (0, import_yup32.array)().of((0, import_yup32.string)().required()).optional().default([]).label("Email Addresses"),
3596
+ emails: (0, import_yup33.array)().of((0, import_yup33.string)().required()).optional().default([]).label("Email Addresses"),
3203
3597
  /**
3204
3598
  * Better Auth account ids. An IDENTITY lookup like `emails`, and for the same
3205
3599
  * reason: the caller already knows the exact value.
@@ -3218,9 +3612,9 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3218
3612
  * The admin filter panel builds its controls explicitly rather than from this
3219
3613
  * shape, so declaring it here does not put an account-id box in the UI.
3220
3614
  */
3221
- authAccountIds: (0, import_yup32.array)().of((0, import_yup32.string)().required()).optional().default([]).label("Auth Account IDs"),
3615
+ authAccountIds: (0, import_yup33.array)().of((0, import_yup33.string)().required()).optional().default([]).label("Auth Account IDs"),
3222
3616
  // ── Enum facets (closed vocabularies, chip pickers) ─────────────────────────
3223
- countries: (0, import_yup32.array)().of((0, import_yup32.string)().required()).optional().default([]).label("Countries"),
3617
+ countries: (0, import_yup33.array)().of((0, import_yup33.string)().required()).optional().default([]).label("Countries"),
3224
3618
  roles: enumFacet(SupportedUserRoles, "Roles"),
3225
3619
  // The user's own current seniority (UserSchema.experienceLevel).
3226
3620
  experienceLevels: enumFacet(SupportedExperienceLevels, "Experience Levels"),
@@ -3353,12 +3747,12 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3353
3747
  // it, so the dependency is stated rather than assumed.
3354
3748
  minSalaryFloor: currencyBound("Min Salary \u2265", "salaryCurrencies"),
3355
3749
  minSalaryCeil: currencyBound("Min Salary \u2264", "salaryCurrencies"),
3356
- openToWorkOnly: (0, import_yup32.boolean)().optional().default(false).label("Open to Work Only"),
3357
- remoteExperienceOnly: (0, import_yup32.boolean)().optional().default(false).label("Has Remote Experience"),
3358
- hasResumeOnly: (0, import_yup32.boolean)().optional().default(false).label("Has Resume"),
3359
- onboardingCompletedOnly: (0, import_yup32.boolean)().optional().default(false).label("Onboarding Completed"),
3360
- emailVerifiedOnly: (0, import_yup32.boolean)().optional().default(false).label("Email Verified Only"),
3361
- mobileVerifiedOnly: (0, import_yup32.boolean)().optional().default(false).label("Mobile Verified Only"),
3750
+ openToWorkOnly: (0, import_yup33.boolean)().optional().default(false).label("Open to Work Only"),
3751
+ remoteExperienceOnly: (0, import_yup33.boolean)().optional().default(false).label("Has Remote Experience"),
3752
+ hasResumeOnly: (0, import_yup33.boolean)().optional().default(false).label("Has Resume"),
3753
+ onboardingCompletedOnly: (0, import_yup33.boolean)().optional().default(false).label("Onboarding Completed"),
3754
+ emailVerifiedOnly: (0, import_yup33.boolean)().optional().default(false).label("Email Verified Only"),
3755
+ mobileVerifiedOnly: (0, import_yup33.boolean)().optional().default(false).label("Mobile Verified Only"),
3362
3756
  // ── Lifecycle windows ───────────────────────────────────────────────────────
3363
3757
  // Relative, because a saved list is resolved fresh on every send: a stored
3364
3758
  // absolute epoch would freeze at authoring time and the audience would decay
@@ -3386,10 +3780,10 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3386
3780
  // Radius search around a point, against location.geo. All three required
3387
3781
  // together; validated as a group rather than field-by-field so a half-filled
3388
3782
  // radius cannot silently match everyone.
3389
- withinRadius: (0, import_yup32.object)({
3390
- lat: (0, import_yup32.number)().min(-90).max(90).required().label("Latitude"),
3391
- lng: (0, import_yup32.number)().min(-180).max(180).required().label("Longitude"),
3392
- km: (0, import_yup32.number)().moreThan(0).max(2e4).required().label("Radius (km)")
3783
+ withinRadius: (0, import_yup33.object)({
3784
+ lat: (0, import_yup33.number)().min(-90).max(90).required().label("Latitude"),
3785
+ lng: (0, import_yup33.number)().min(-180).max(180).required().label("Longitude"),
3786
+ km: (0, import_yup33.number)().moreThan(0).max(2e4).required().label("Radius (km)")
3393
3787
  }).optional().default(void 0).label("Within Radius"),
3394
3788
  // ── Signup context (immutable market / locale) ──────────────────────────────
3395
3789
  signupCountries: tokens("Signup Countries"),
@@ -3412,7 +3806,7 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3412
3806
  // materialise the second case on every list that never chose it.
3413
3807
  //
3414
3808
  // @todo CONSENT-FILTER-ENFORCEMENT — nothing enforces consent anywhere now.
3415
- marketingSubscribed: (0, import_yup32.boolean)().optional().label("Marketing Subscribed"),
3809
+ marketingSubscribed: (0, import_yup33.boolean)().optional().label("Marketing Subscribed"),
3416
3810
  jobAlertFrequencies: enumFacet(
3417
3811
  SupportedJobAlertFrequencies,
3418
3812
  "Job Alert Frequency"
@@ -3433,7 +3827,7 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3433
3827
  ),
3434
3828
  // ── Tenure / recency ────────────────────────────────────────────────────────
3435
3829
  // Against workExperiences[].duration and educations[].duration ("YYYY-MM").
3436
- currentlyEmployed: (0, import_yup32.boolean)().optional().default(false).label("Currently Employed"),
3830
+ currentlyEmployed: (0, import_yup33.boolean)().optional().default(false).label("Currently Employed"),
3437
3831
  graduatedWithinMonths: months("Graduated Within (months)"),
3438
3832
  skillUsedWithinMonths: months("Skill Used Within (months)"),
3439
3833
  // The ABSOLUTE bounds the three relative windows above resolve into
@@ -3446,13 +3840,13 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3446
3840
  // meaning that forever, while "within 18 months" keeps meaning what the admin
3447
3841
  // intended. They are declared because the vocabulary must be complete, not
3448
3842
  // because a list should store one.
3449
- graduatedAfter: (0, import_yup32.string)().trim().optional().label("Graduated After"),
3450
- skillUsedAfter: (0, import_yup32.string)().trim().optional().label("Skill Used After"),
3843
+ graduatedAfter: (0, import_yup33.string)().trim().optional().label("Graduated After"),
3844
+ skillUsedAfter: (0, import_yup33.string)().trim().optional().label("Skill Used After"),
3451
3845
  // ── Profile richness ────────────────────────────────────────────────────────
3452
- hasImage: (0, import_yup32.boolean)().optional().default(false).label("Has Photo"),
3453
- hasHeadline: (0, import_yup32.boolean)().optional().default(false).label("Has Headline"),
3454
- hasAboutMe: (0, import_yup32.boolean)().optional().default(false).label("Has About Me"),
3455
- hasMobile: (0, import_yup32.boolean)().optional().default(false).label("Has Mobile Number"),
3846
+ hasImage: (0, import_yup33.boolean)().optional().default(false).label("Has Photo"),
3847
+ hasHeadline: (0, import_yup33.boolean)().optional().default(false).label("Has Headline"),
3848
+ hasAboutMe: (0, import_yup33.boolean)().optional().default(false).label("Has About Me"),
3849
+ hasMobile: (0, import_yup33.boolean)().optional().default(false).label("Has Mobile Number"),
3456
3850
  // Segment by WHICH profile section is missing (profileCompleteness.missing[]),
3457
3851
  // rather than only by the overall percentage.
3458
3852
  missingSections: tokens("Missing Profile Sections"),
@@ -3464,8 +3858,8 @@ var UserFilterBranchShape = (0, import_yup32.object)({
3464
3858
  // data lives in other services' collections. Tri-state: `false` is a real
3465
3859
  // filter ("has NO job alert"), which is the audience an alert nudge wants, so
3466
3860
  // these are `undefined` when unset rather than defaulting to false.
3467
- hasJobAlert: (0, import_yup32.boolean)().optional().default(void 0).label("Has a Job Alert"),
3468
- hasApplied: (0, import_yup32.boolean)().optional().default(void 0).label("Has Applied"),
3861
+ hasJobAlert: (0, import_yup33.boolean)().optional().default(void 0).label("Has a Job Alert"),
3862
+ hasApplied: (0, import_yup33.boolean)().optional().default(void 0).label("Has Applied"),
3469
3863
  appliedWithinDays: days("Applied Within (days)")
3470
3864
  // `search` is NOT here. It is free text over name/email, not a facet: it names
3471
3865
  // no field on a user document, user-service treats it as a RESERVED PARAM
@@ -3478,25 +3872,25 @@ var BRANCH_KEYS = Object.keys(UserFilterBranchShape.fields);
3478
3872
  var UserFilterBranch = rejectUnknownKeys(UserFilterBranchShape, () => BRANCH_KEYS);
3479
3873
  var UserFilterSchema = rejectUnknownKeys(
3480
3874
  UserFilterBranchShape.shape({
3481
- or: (0, import_yup32.array)().of(UserFilterBranch).optional().default([]).label("Or Any Of")
3875
+ or: (0, import_yup33.array)().of(UserFilterBranch).optional().default([]).label("Or Any Of")
3482
3876
  }).label("User Filter"),
3483
3877
  () => [...BRANCH_KEYS, "or"]
3484
3878
  );
3485
3879
 
3486
3880
  // src/marketing/marketing.schema.ts
3487
3881
  var MailingListFilterSchema = UserFilterSchema;
3488
- var MailingListSchema = (0, import_yup33.object)({
3489
- name: (0, import_yup33.string)().required().min(1).max(120).label("Name"),
3490
- description: (0, import_yup33.string)().optional().max(500).label("Description"),
3882
+ var MailingListSchema = (0, import_yup34.object)({
3883
+ name: (0, import_yup34.string)().required().min(1).max(120).label("Name"),
3884
+ description: (0, import_yup34.string)().optional().max(500).label("Description"),
3491
3885
  filter: MailingListFilterSchema.default(
3492
3886
  () => MailingListFilterSchema.getDefault()
3493
3887
  )
3494
3888
  }).label("Mailing List");
3495
- var CampaignTriggerSchema = (0, import_yup33.object)({
3496
- kind: (0, import_yup33.string)().oneOf(SupportedCampaignTriggerKinds).required().default("manual" /* Manual */).label("Trigger"),
3889
+ var CampaignTriggerSchema = (0, import_yup34.object)({
3890
+ kind: (0, import_yup34.string)().oneOf(SupportedCampaignTriggerKinds).required().default("manual" /* Manual */).label("Trigger"),
3497
3891
  // IANA zone, e.g. "Asia/Kolkata". Local wall-clock times are interpreted in it,
3498
3892
  // so occurrences land at the intended hour across DST rather than drifting.
3499
- timezone: (0, import_yup33.string)().optional().default("UTC").label("Timezone").when("kind", {
3893
+ timezone: (0, import_yup34.string)().optional().default("UTC").label("Timezone").when("kind", {
3500
3894
  is: (k) => k !== "manual" /* Manual */,
3501
3895
  then: (s) => s.required()
3502
3896
  }),
@@ -3510,26 +3904,26 @@ var CampaignTriggerSchema = (0, import_yup33.object)({
3510
3904
  is: "schedule" /* Schedule */,
3511
3905
  then: (s) => s.required()
3512
3906
  }),
3513
- interval: (0, import_yup33.object)({
3514
- every: (0, import_yup33.number)().integer().min(1).max(365).required().label("Every"),
3515
- unit: (0, import_yup33.string)().oneOf(SupportedCampaignIntervalUnits).required().label("Unit")
3907
+ interval: (0, import_yup34.object)({
3908
+ every: (0, import_yup34.number)().integer().min(1).max(365).required().label("Every"),
3909
+ unit: (0, import_yup34.string)().oneOf(SupportedCampaignIntervalUnits).required().label("Unit")
3516
3910
  }).optional().default(void 0).label("Repeats").when("kind", {
3517
3911
  is: "schedule" /* Schedule */,
3518
3912
  then: (s) => s.required()
3519
3913
  }),
3520
3914
  /** Local wall-clock send time, "HH:mm" in `timezone`. */
3521
- timeOfDay: (0, import_yup33.string)().matches(/^([01]\d|2[0-3]):[0-5]\d$/, "Use HH:mm").optional().default("09:00").label("Time of Day"),
3915
+ timeOfDay: (0, import_yup34.string)().matches(/^([01]\d|2[0-3]):[0-5]\d$/, "Use HH:mm").optional().default("09:00").label("Time of Day"),
3522
3916
  /** For weekly intervals: ISO weekdays, 1 = Monday .. 7 = Sunday. */
3523
- byWeekday: (0, import_yup33.array)().of((0, import_yup33.number)().integer().min(1).max(7).required()).optional().default([]).label("On Days"),
3917
+ byWeekday: (0, import_yup34.array)().of((0, import_yup34.number)().integer().min(1).max(7).required()).optional().default([]).label("On Days"),
3524
3918
  /**
3525
3919
  * For monthly intervals: 1-31, or -1 meaning "last day of the month". A month
3526
3920
  * shorter than the chosen day is clamped to its last day, so 31 in February
3527
3921
  * fires on the 28th/29th rather than being skipped.
3528
3922
  */
3529
- byMonthday: (0, import_yup33.number)().integer().min(-1).max(31).notOneOf([0]).optional().default(void 0).label("Day of Month"),
3530
- end: (0, import_yup33.object)({
3531
- kind: (0, import_yup33.string)().oneOf(SupportedCampaignEndKinds).required().label("Ends"),
3532
- occurrences: (0, import_yup33.number)().integer().min(1).max(1e4).optional().default(void 0).label("After N Sends").when("kind", {
3923
+ byMonthday: (0, import_yup34.number)().integer().min(-1).max(31).notOneOf([0]).optional().default(void 0).label("Day of Month"),
3924
+ end: (0, import_yup34.object)({
3925
+ kind: (0, import_yup34.string)().oneOf(SupportedCampaignEndKinds).required().label("Ends"),
3926
+ occurrences: (0, import_yup34.number)().integer().min(1).max(1e4).optional().default(void 0).label("After N Sends").when("kind", {
3533
3927
  is: "afterOccurrences" /* AfterOccurrences */,
3534
3928
  then: (s) => s.required()
3535
3929
  }),
@@ -3539,8 +3933,8 @@ var CampaignTriggerSchema = (0, import_yup33.object)({
3539
3933
  })
3540
3934
  }).optional().default(() => ({ kind: "never" /* Never */ })).label("End Condition")
3541
3935
  }).label("Trigger");
3542
- var CampaignDataSourceSchema = (0, import_yup33.object)({
3543
- id: (0, import_yup33.string)().required().label("Data Source"),
3936
+ var CampaignDataSourceSchema = (0, import_yup34.object)({
3937
+ id: (0, import_yup34.string)().required().label("Data Source"),
3544
3938
  /**
3545
3939
  * Derive this source's filter per recipient from their profile, instead of
3546
3940
  * using the admin-entered `params` for everyone.
@@ -3555,7 +3949,7 @@ var CampaignDataSourceSchema = (0, import_yup33.object)({
3555
3949
  * un-personalised. Whether a source can honour it at all is declared by the
3556
3950
  * source itself (`supportsPersonalisation`), which this package cannot see.
3557
3951
  */
3558
- personalised: (0, import_yup33.boolean)().optional().label("Personalised"),
3952
+ personalised: (0, import_yup34.boolean)().optional().label("Personalised"),
3559
3953
  /**
3560
3954
  * A free-form bag whose keys are defined by the chosen source's OWN
3561
3955
  * `paramsSchema`, which this package cannot see. Same `lazy` treatment as
@@ -3568,22 +3962,22 @@ var CampaignDataSourceSchema = (0, import_yup33.object)({
3568
3962
  * them against the real source schema in `checkCampaignConfig`, which is the
3569
3963
  * only place that knows what a given source accepts.
3570
3964
  */
3571
- params: (0, import_yup33.lazy)((value) => {
3965
+ params: (0, import_yup34.lazy)((value) => {
3572
3966
  const keys = value && typeof value === "object" ? Object.keys(value) : [];
3573
- return (0, import_yup33.object)(
3574
- Object.fromEntries(keys.map((k) => [k, (0, import_yup33.mixed)().optional()]))
3967
+ return (0, import_yup34.object)(
3968
+ Object.fromEntries(keys.map((k) => [k, (0, import_yup34.mixed)().optional()]))
3575
3969
  ).optional().default(() => ({})).label("Parameters");
3576
3970
  })
3577
3971
  }).label("Data Source");
3578
- var TemplateVariableBindingSchema = (0, import_yup33.object)({
3579
- kind: (0, import_yup33.string)().oneOf(SupportedTemplateVariableBindingKinds).required().label("Source"),
3580
- value: (0, import_yup33.string)().required().min(1).max(2e3).label("Value")
3972
+ var TemplateVariableBindingSchema = (0, import_yup34.object)({
3973
+ kind: (0, import_yup34.string)().oneOf(SupportedTemplateVariableBindingKinds).required().label("Source"),
3974
+ value: (0, import_yup34.string)().required().min(1).max(2e3).label("Value")
3581
3975
  }).label("Template Variable Binding");
3582
- var CampaignSchema = (0, import_yup33.object)({
3583
- name: (0, import_yup33.string)().required().min(1).max(200).label("Campaign Name"),
3976
+ var CampaignSchema = (0, import_yup34.object)({
3977
+ name: (0, import_yup34.string)().required().min(1).max(200).label("Campaign Name"),
3584
3978
  // The template renders its own subject; an override is only needed for the
3585
3979
  // inline-HTML path, hence not required when a template is chosen.
3586
- subject: (0, import_yup33.string)().optional().max(255).label("Subject").when("templateKey", {
3980
+ subject: (0, import_yup34.string)().optional().max(255).label("Subject").when("templateKey", {
3587
3981
  is: (v) => !v,
3588
3982
  then: (s) => s.required().min(1)
3589
3983
  }),
@@ -3594,12 +3988,12 @@ var CampaignSchema = (0, import_yup33.object)({
3594
3988
  * one with a compliance-checked footer and a render test,
3595
3989
  * and hand-pasted HTML that repeats forever is a mistake that repeats forever.
3596
3990
  */
3597
- html: (0, import_yup33.string)().optional().label("HTML Body").when("templateKey", {
3991
+ html: (0, import_yup34.string)().optional().label("HTML Body").when("templateKey", {
3598
3992
  is: (v) => !v,
3599
3993
  then: (s) => s.required().min(1)
3600
3994
  }),
3601
- text: (0, import_yup33.string)().optional().label("Plain-text Body"),
3602
- listId: (0, import_yup33.string)().required().label("Mailing List"),
3995
+ text: (0, import_yup34.string)().optional().label("Plain-text Body"),
3996
+ listId: (0, import_yup34.string)().required().label("Mailing List"),
3603
3997
  /**
3604
3998
  * Where the campaign is in its life. See `CampaignStatus` for the transitions.
3605
3999
  *
@@ -3608,9 +4002,9 @@ var CampaignSchema = (0, import_yup33.object)({
3608
4002
  * value the enum never contained (`scheduled`) reached production rows and
3609
4003
  * rendered in the admin list as though it were real.
3610
4004
  */
3611
- status: (0, import_yup33.string)().oneOf(SupportedCampaignStatuses).optional().default("draft" /* Draft */).label("Status"),
4005
+ status: (0, import_yup34.string)().oneOf(SupportedCampaignStatuses).optional().default("draft" /* Draft */).label("Status"),
3612
4006
  /** Key from email-service's template registry. Mutually exclusive with `html`. */
3613
- templateKey: (0, import_yup33.string)().optional().label("Email Template"),
4007
+ templateKey: (0, import_yup34.string)().optional().label("Email Template"),
3614
4008
  /**
3615
4009
  * One entry per variable the chosen template declares. Validated at save time
3616
4010
  * against the template's own `variables`, so a missing required binding is a
@@ -3625,9 +4019,9 @@ var CampaignSchema = (0, import_yup33.object)({
3625
4019
  * whose required variables all appear unbound. Shaping each entry also means a
3626
4020
  * malformed binding is rejected here rather than at send time.
3627
4021
  */
3628
- bindings: (0, import_yup33.lazy)((value) => {
4022
+ bindings: (0, import_yup34.lazy)((value) => {
3629
4023
  const keys = value && typeof value === "object" ? Object.keys(value) : [];
3630
- return (0, import_yup33.object)(
4024
+ return (0, import_yup34.object)(
3631
4025
  Object.fromEntries(keys.map((k) => [k, TemplateVariableBindingSchema.required()]))
3632
4026
  ).optional().default(() => ({})).label("Template Data");
3633
4027
  }),
@@ -3639,7 +4033,7 @@ var CampaignSchema = (0, import_yup33.object)({
3639
4033
  * `groups.groupCount`), so two sources providing the same name cannot
3640
4034
  * overwrite each other and a template says which one it means.
3641
4035
  */
3642
- dataSources: (0, import_yup33.array)().of(CampaignDataSourceSchema).optional().default(void 0).label("Data Sources"),
4036
+ dataSources: (0, import_yup34.array)().of(CampaignDataSourceSchema).optional().default(void 0).label("Data Sources"),
3643
4037
  trigger: CampaignTriggerSchema.default(
3644
4038
  () => CampaignTriggerSchema.getDefault()
3645
4039
  ),
@@ -3654,7 +4048,7 @@ var CampaignSchema = (0, import_yup33.object)({
3654
4048
  * representable, and the admin list showed exactly that. Activation is a
3655
4049
  * state transition, so it belongs in the state.
3656
4050
  */
3657
- dryRun: (0, import_yup33.boolean)().optional().default(true).label("Dry Run"),
4051
+ dryRun: (0, import_yup34.boolean)().optional().default(true).label("Dry Run"),
3658
4052
  /**
3659
4053
  * Re-eligibility: when someone this campaign already mailed may get it again.
3660
4054
  *
@@ -3662,23 +4056,23 @@ var CampaignSchema = (0, import_yup33.object)({
3662
4056
  * person. `N`: again only after N days. Opt-in, because most recurring
3663
4057
  * campaigns exist to mail the same people repeatedly.
3664
4058
  */
3665
- resendAfterDays: (0, import_yup33.number)().integer().min(0).max(365).nullable().optional().default(void 0).label("Resend After (days)"),
3666
- maxRecipients: (0, import_yup33.number)().integer().min(1).max(CAMPAIGN_MAX_RECIPIENTS_CEILING).optional().default(void 0).label("Max Recipients"),
3667
- utm: (0, import_yup33.object)({
3668
- campaign: (0, import_yup33.string)().optional().max(120).label("utm_campaign"),
3669
- content: (0, import_yup33.string)().optional().max(120).label("utm_content")
4059
+ resendAfterDays: (0, import_yup34.number)().integer().min(0).max(365).nullable().optional().default(void 0).label("Resend After (days)"),
4060
+ maxRecipients: (0, import_yup34.number)().integer().min(1).max(CAMPAIGN_MAX_RECIPIENTS_CEILING).optional().default(void 0).label("Max Recipients"),
4061
+ utm: (0, import_yup34.object)({
4062
+ campaign: (0, import_yup34.string)().optional().max(120).label("utm_campaign"),
4063
+ content: (0, import_yup34.string)().optional().max(120).label("utm_content")
3670
4064
  }).optional().default(void 0).label("Link Tagging")
3671
4065
  }).label("Campaign");
3672
4066
 
3673
4067
  // src/pagination/pagination.schema.ts
3674
- var import_yup34 = require("yup");
3675
- var PaginationSchema = (0, import_yup34.object)().shape({
3676
- page: (0, import_yup34.number)().required().min(1).label("Page").default(1),
3677
- limit: (0, import_yup34.number)().required().min(1).max(100).label("Limit").default(10),
3678
- sortBy: (0, import_yup34.string)().notOneOf([""]).optional().label("SortBy"),
3679
- nextPage: (0, import_yup34.string)().optional().label("Next Page Token"),
3680
- prevPage: (0, import_yup34.string)().optional().label("Previous Page Token"),
3681
- sortDirection: (0, import_yup34.string)().oneOf(["asc", "desc"]).optional().label("Sort Direction")
4068
+ var import_yup35 = require("yup");
4069
+ var PaginationSchema = (0, import_yup35.object)().shape({
4070
+ page: (0, import_yup35.number)().required().min(1).label("Page").default(1),
4071
+ limit: (0, import_yup35.number)().required().min(1).max(100).label("Limit").default(10),
4072
+ sortBy: (0, import_yup35.string)().notOneOf([""]).optional().label("SortBy"),
4073
+ nextPage: (0, import_yup35.string)().optional().label("Next Page Token"),
4074
+ prevPage: (0, import_yup35.string)().optional().label("Previous Page Token"),
4075
+ sortDirection: (0, import_yup35.string)().oneOf(["asc", "desc"]).optional().label("Sort Direction")
3682
4076
  });
3683
4077
 
3684
4078
  // src/pagination/pagination.constant.ts
@@ -3694,7 +4088,7 @@ var DefaultPaginationOptions = {
3694
4088
  };
3695
4089
 
3696
4090
  // src/saved-search/saved-search.schema.ts
3697
- var import_yup35 = require("yup");
4091
+ var import_yup36 = require("yup");
3698
4092
 
3699
4093
  // src/saved-search/saved-search.constant.ts
3700
4094
  var SavedSearchStatus = /* @__PURE__ */ ((SavedSearchStatus2) => {
@@ -3705,21 +4099,21 @@ var SavedSearchStatus = /* @__PURE__ */ ((SavedSearchStatus2) => {
3705
4099
  var SupportedSavedSearchStatuses = Object.values(SavedSearchStatus);
3706
4100
 
3707
4101
  // src/saved-search/saved-search.schema.ts
3708
- var SavedSearchSchema = (0, import_yup35.object)({
4102
+ var SavedSearchSchema = (0, import_yup36.object)({
3709
4103
  /** Public identifier. Server-assigned. */
3710
- shortId: (0, import_yup35.string)().trim().label("Short Id"),
4104
+ shortId: (0, import_yup36.string)().trim().label("Short Id"),
3711
4105
  /**
3712
4106
  * Owner's Better Auth account id. Server-assigned from the verified token,
3713
4107
  * never accepted from a request body.
3714
4108
  */
3715
- ownerUserId: (0, import_yup35.string)().trim().label("Owner"),
4109
+ ownerUserId: (0, import_yup36.string)().trim().label("Owner"),
3716
4110
  /** What the user calls this search, e.g. "Remote React roles". */
3717
- label: (0, import_yup35.string)().trim().max(120).required().label("Label"),
4111
+ label: (0, import_yup36.string)().trim().max(120).required().label("Label"),
3718
4112
  /**
3719
4113
  * The free-text query. Optional because a search can be filters-only ("all
3720
4114
  * remote jobs in Sweden"), which is a legitimate alert to want.
3721
4115
  */
3722
- search: (0, import_yup35.string)().trim().max(500).optional().label("Search Text"),
4116
+ search: (0, import_yup36.string)().trim().max(500).optional().label("Search Text"),
3723
4117
  /**
3724
4118
  * Field filters, in the same `{ field: values }` shape the search endpoint
3725
4119
  * parses from `filter[field]=a,b`. Held as a free-form object rather than a
@@ -3727,7 +4121,7 @@ var SavedSearchSchema = (0, import_yup35.object)({
3727
4121
  * change independently; validating them here would put this package in the
3728
4122
  * business of tracking that vocabulary.
3729
4123
  */
3730
- filter: (0, import_yup35.object)().optional().default({}).label("Filters"),
4124
+ filter: (0, import_yup36.object)().optional().default({}).label("Filters"),
3731
4125
  /**
3732
4126
  * How often to mail matches. `off` keeps the search saved but silent, which is
3733
4127
  * the difference between "I don't want mail" and "delete my search".
@@ -3736,26 +4130,26 @@ var SavedSearchSchema = (0, import_yup35.object)({
3736
4130
  * than defining a second one: two vocabularies for the same concept is how
3737
4131
  * they drift.
3738
4132
  */
3739
- frequency: (0, import_yup35.string)().oneOf(SupportedJobAlertFrequencies).default("off" /* Off */).label("Alert Frequency"),
3740
- status: (0, import_yup35.string)().oneOf(SupportedSavedSearchStatuses).default("active" /* Active */).label("Status"),
4133
+ frequency: (0, import_yup36.string)().oneOf(SupportedJobAlertFrequencies).default("off" /* Off */).label("Alert Frequency"),
4134
+ status: (0, import_yup36.string)().oneOf(SupportedSavedSearchStatuses).default("active" /* Active */).label("Status"),
3741
4135
  /**
3742
4136
  * Epoch ms of the last alert sent for this search. The matching sweep reads it
3743
4137
  * to decide whether the cadence is due, and writes it only AFTER a successful
3744
4138
  * publish, so a failed run retries next tick rather than silently skipping a
3745
4139
  * period.
3746
4140
  */
3747
- lastNotifiedAt: (0, import_yup35.number)().optional().label("Last Notified At"),
4141
+ lastNotifiedAt: (0, import_yup36.number)().optional().label("Last Notified At"),
3748
4142
  /**
3749
4143
  * Epoch ms high-water mark: only jobs created after this are "new" for the
3750
4144
  * next alert. Kept separate from `lastNotifiedAt` because a run that finds no
3751
4145
  * matches should still advance what counts as new, without implying mail was
3752
4146
  * sent.
3753
4147
  */
3754
- lastMatchedAt: (0, import_yup35.number)().optional().label("Last Matched At")
4148
+ lastMatchedAt: (0, import_yup36.number)().optional().label("Last Matched At")
3755
4149
  }).noUnknown().strict();
3756
4150
 
3757
4151
  // src/report/report.schema.ts
3758
- var import_yup36 = require("yup");
4152
+ var import_yup37 = require("yup");
3759
4153
 
3760
4154
  // src/report/report.constant.ts
3761
4155
  var ResourceType = /* @__PURE__ */ ((ResourceType3) => {
@@ -3779,15 +4173,15 @@ var ReportReason = /* @__PURE__ */ ((ReportReason3) => {
3779
4173
  var SupportedReportReasons = Object.values(ReportReason);
3780
4174
 
3781
4175
  // src/report/report.schema.ts
3782
- var ReportSchema = (0, import_yup36.object)({
3783
- type: (0, import_yup36.mixed)().oneOf(SupportedResourceTypes).required().label("Type"),
3784
- resourceId: (0, import_yup36.string)().required().label("Resource ID"),
3785
- reason: (0, import_yup36.mixed)().oneOf(SupportedReportReasons).required("Please choose a reason").label("Reason"),
3786
- comment: (0, import_yup36.string)().max(1e3).optional().label("Comment")
4176
+ var ReportSchema = (0, import_yup37.object)({
4177
+ type: (0, import_yup37.mixed)().oneOf(SupportedResourceTypes).required().label("Type"),
4178
+ resourceId: (0, import_yup37.string)().required().label("Resource ID"),
4179
+ reason: (0, import_yup37.mixed)().oneOf(SupportedReportReasons).required("Please choose a reason").label("Reason"),
4180
+ comment: (0, import_yup37.string)().max(1e3).optional().label("Comment")
3787
4181
  }).label("Report Schema");
3788
4182
 
3789
4183
  // src/feedback/feedback-filter.schema.ts
3790
- var import_yup37 = require("yup");
4184
+ var import_yup38 = require("yup");
3791
4185
 
3792
4186
  // src/feedback/feedback.constant.ts
3793
4187
  var FeedbackType = /* @__PURE__ */ ((FeedbackType3) => {
@@ -3810,7 +4204,7 @@ var SupportedFeedbackStatuses = Object.values(FeedbackStatus);
3810
4204
  var FEEDBACK_MESSAGE_MAX = 4e3;
3811
4205
 
3812
4206
  // src/feedback/feedback-filter.schema.ts
3813
- var FeedbackFilterShape = (0, import_yup37.object)({
4207
+ var FeedbackFilterShape = (0, import_yup38.object)({
3814
4208
  type: enumFacet(SupportedFeedbackTypes, "Type"),
3815
4209
  status: enumFacet(SupportedFeedbackStatuses, "Status")
3816
4210
  }).label("Feedback Filter");
@@ -3820,18 +4214,18 @@ var FeedbackFilterSchema = rejectUnknownKeys(
3820
4214
  );
3821
4215
 
3822
4216
  // src/feedback/feedback.schema.ts
3823
- var import_yup38 = require("yup");
3824
- var FeedbackSchema = (0, import_yup38.object)({
3825
- type: (0, import_yup38.mixed)().oneOf(SupportedFeedbackTypes).required().label("Type"),
3826
- message: (0, import_yup38.string)().trim().required("Please enter a message").max(FEEDBACK_MESSAGE_MAX).label("Message"),
3827
- email: (0, import_yup38.string)().email().optional().label("Email"),
3828
- pageUrl: (0, import_yup38.string)().optional().label("Page URL"),
3829
- status: (0, import_yup38.mixed)().oneOf(SupportedFeedbackStatuses).optional().label("Status")
4217
+ var import_yup39 = require("yup");
4218
+ var FeedbackSchema = (0, import_yup39.object)({
4219
+ type: (0, import_yup39.mixed)().oneOf(SupportedFeedbackTypes).required().label("Type"),
4220
+ message: (0, import_yup39.string)().trim().required("Please enter a message").max(FEEDBACK_MESSAGE_MAX).label("Message"),
4221
+ email: (0, import_yup39.string)().email().optional().label("Email"),
4222
+ pageUrl: (0, import_yup39.string)().optional().label("Page URL"),
4223
+ status: (0, import_yup39.mixed)().oneOf(SupportedFeedbackStatuses).optional().label("Status")
3830
4224
  }).label("Feedback Schema");
3831
4225
 
3832
4226
  // src/skill/skill-filter.schema.ts
3833
- var import_yup39 = require("yup");
3834
- var SkillFilterShape = (0, import_yup39.object)({
4227
+ var import_yup40 = require("yup");
4228
+ var SkillFilterShape = (0, import_yup40.object)({
3835
4229
  /** Display names, matched exactly. Free-text matching is `?search=`. */
3836
4230
  names: tokens("Names"),
3837
4231
  /**
@@ -3849,7 +4243,7 @@ var SkillFilterSchema = rejectUnknownKeys(
3849
4243
  );
3850
4244
 
3851
4245
  // src/billing/billing.schema.ts
3852
- var import_yup40 = require("yup");
4246
+ var import_yup41 = require("yup");
3853
4247
 
3854
4248
  // src/billing/billing.constant.ts
3855
4249
  var PlanKind = /* @__PURE__ */ ((PlanKind2) => {
@@ -3952,60 +4346,60 @@ var GRANT_MAX_LIMIT = 1e5;
3952
4346
  var CONSUME_MAX_UNITS = 1e3;
3953
4347
 
3954
4348
  // src/billing/billing.schema.ts
3955
- var MoneySchema = (0, import_yup40.object)({
3956
- amountMinor: (0, import_yup40.number)().integer().min(0).required().label("Amount (minor units)"),
4349
+ var MoneySchema = (0, import_yup41.object)({
4350
+ amountMinor: (0, import_yup41.number)().integer().min(0).required().label("Amount (minor units)"),
3957
4351
  /**
3958
4352
  * ISO-4217, as returned by Paddle. Deliberately NOT constrained to
3959
4353
  * `SupportedSalaryCurrencies`: that list is the job-salary vocabulary, and
3960
4354
  * Paddle bills in currencies it does not contain. Constraining it here would
3961
4355
  * reject real payments.
3962
4356
  */
3963
- currencyCode: (0, import_yup40.string)().trim().uppercase().required().label("Currency")
4357
+ currencyCode: (0, import_yup41.string)().trim().uppercase().required().label("Currency")
3964
4358
  }).label("Money");
3965
- var PlanGrantSchema = (0, import_yup40.object)({
4359
+ var PlanGrantSchema = (0, import_yup41.object)({
3966
4360
  /**
3967
4361
  * The gated capability, e.g. `job.post`. A free string on purpose: see the
3968
4362
  * note on `FeatureKey` in `billing.constant.ts`. Adding a feature to the
3969
4363
  * paywall must not require releasing this package.
3970
4364
  */
3971
- feature: (0, import_yup40.string)().trim().required().min(1).max(64).label("Feature"),
3972
- type: (0, import_yup40.string)().oneOf(SupportedGrantTypes).required().default("boolean" /* Boolean */).label("Grant Type"),
4365
+ feature: (0, import_yup41.string)().trim().required().min(1).max(64).label("Feature"),
4366
+ type: (0, import_yup41.string)().oneOf(SupportedGrantTypes).required().default("boolean" /* Boolean */).label("Grant Type"),
3973
4367
  /** Uses per period. Required for `quota`, meaningless otherwise. */
3974
- limit: (0, import_yup40.number)().integer().min(1).max(GRANT_MAX_LIMIT).optional().label("Limit").when("type", {
4368
+ limit: (0, import_yup41.number)().integer().min(1).max(GRANT_MAX_LIMIT).optional().label("Limit").when("type", {
3975
4369
  is: "quota" /* Quota */,
3976
4370
  then: (s) => s.required("A quota grant needs a limit")
3977
4371
  }),
3978
- period: (0, import_yup40.string)().oneOf(SupportedQuotaPeriods).optional().default("month" /* Month */).label("Period").when("type", {
4372
+ period: (0, import_yup41.string)().oneOf(SupportedQuotaPeriods).optional().default("month" /* Month */).label("Period").when("type", {
3979
4373
  is: "quota" /* Quota */,
3980
4374
  then: (s) => s.required("A quota grant needs a period")
3981
4375
  }),
3982
4376
  /** Non-expiring uses granted per purchase. Required for `credit`. */
3983
- amount: (0, import_yup40.number)().integer().min(1).max(GRANT_MAX_LIMIT).optional().label("Amount").when("type", {
4377
+ amount: (0, import_yup41.number)().integer().min(1).max(GRANT_MAX_LIMIT).optional().label("Amount").when("type", {
3984
4378
  is: "credit" /* Credit */,
3985
4379
  then: (s) => s.required("A credit grant needs an amount")
3986
4380
  })
3987
4381
  }).label("Plan Grant");
3988
- var PaddlePriceIdsSchema = (0, import_yup40.object)({
3989
- sandbox: (0, import_yup40.array)().of((0, import_yup40.string)().required()).optional().default([]).label("Sandbox Price IDs"),
3990
- live: (0, import_yup40.array)().of((0, import_yup40.string)().required()).optional().default([]).label("Live Price IDs")
4382
+ var PaddlePriceIdsSchema = (0, import_yup41.object)({
4383
+ sandbox: (0, import_yup41.array)().of((0, import_yup41.string)().required()).optional().default([]).label("Sandbox Price IDs"),
4384
+ live: (0, import_yup41.array)().of((0, import_yup41.string)().required()).optional().default([]).label("Live Price IDs")
3991
4385
  }).label("Paddle Price IDs");
3992
- var PlanSchema = (0, import_yup40.object)({
4386
+ var PlanSchema = (0, import_yup41.object)({
3993
4387
  /** Stable slug, e.g. `employer-pro`. The identifier everything else references. */
3994
- key: (0, import_yup40.string)().trim().lowercase().required().min(2).max(64).label("Key"),
3995
- name: (0, import_yup40.string)().required().min(1).max(120).label("Name"),
3996
- description: (0, import_yup40.string)().optional().max(500).label("Description"),
3997
- kind: (0, import_yup40.string)().oneOf(SupportedPlanKinds).required().default("subscription" /* Subscription */).label("Kind"),
4388
+ key: (0, import_yup41.string)().trim().lowercase().required().min(2).max(64).label("Key"),
4389
+ name: (0, import_yup41.string)().required().min(1).max(120).label("Name"),
4390
+ description: (0, import_yup41.string)().optional().max(500).label("Description"),
4391
+ kind: (0, import_yup41.string)().oneOf(SupportedPlanKinds).required().default("subscription" /* Subscription */).label("Kind"),
3998
4392
  /**
3999
4393
  * The line this plan belongs to; a user holds one live subscription per line.
4000
4394
  * Optional on purpose: absent is the default line, so existing plans need no
4001
4395
  * migration and together still read as "one plan at a time".
4002
4396
  */
4003
- audience: (0, import_yup40.string)().oneOf(SupportedPlanAudiences).optional().label("Audience"),
4004
- status: (0, import_yup40.string)().oneOf(SupportedPlanStatuses).required().default("draft" /* Draft */).label("Status"),
4397
+ audience: (0, import_yup41.string)().oneOf(SupportedPlanAudiences).optional().label("Audience"),
4398
+ status: (0, import_yup41.string)().oneOf(SupportedPlanStatuses).required().default("draft" /* Draft */).label("Status"),
4005
4399
  paddlePriceIds: PaddlePriceIdsSchema.default(
4006
4400
  () => PaddlePriceIdsSchema.getDefault()
4007
4401
  ),
4008
- grants: (0, import_yup40.array)().of(PlanGrantSchema.required()).required().min(1, "A plan must grant at least one feature").label("Grants"),
4402
+ grants: (0, import_yup41.array)().of(PlanGrantSchema.required()).required().min(1, "A plan must grant at least one feature").label("Grants"),
4009
4403
  /** Display price for the pricing page. Billing is always Paddle's own figure. */
4010
4404
  price: MoneySchema.optional().default(void 0).label("Price"),
4011
4405
  /**
@@ -4018,133 +4412,189 @@ var PlanSchema = (0, import_yup40.object)({
4018
4412
  * a subscription as "monthly" at the use site rather than defaulting it here,
4019
4413
  * so an unset value stays visible as unset.
4020
4414
  */
4021
- billingPeriod: (0, import_yup40.string)().oneOf(SupportedBillingPeriods).optional().label("Billing Period"),
4415
+ billingPeriod: (0, import_yup41.string)().oneOf(SupportedBillingPeriods).optional().label("Billing Period"),
4022
4416
  /** Ordering on the pricing page, ascending. */
4023
- sortOrder: (0, import_yup40.number)().integer().optional().default(0).label("Sort Order"),
4024
- createdAt: (0, import_yup40.number)().optional().label("Created At"),
4025
- updatedAt: (0, import_yup40.number)().optional().label("Updated At")
4417
+ sortOrder: (0, import_yup41.number)().integer().optional().default(0).label("Sort Order"),
4418
+ createdAt: (0, import_yup41.number)().optional().label("Created At"),
4419
+ updatedAt: (0, import_yup41.number)().optional().label("Updated At")
4026
4420
  }).label("Plan");
4027
- var BillingSubscriptionSchema = (0, import_yup40.object)({
4028
- userId: (0, import_yup40.string)().required().label("User ID"),
4029
- paddleSubscriptionId: (0, import_yup40.string)().required().label("Paddle Subscription ID"),
4030
- paddleCustomerId: (0, import_yup40.string)().required().label("Paddle Customer ID"),
4031
- planKey: (0, import_yup40.string)().required().label("Plan Key"),
4032
- priceIds: (0, import_yup40.array)().of((0, import_yup40.string)().required()).required().label("Price IDs"),
4033
- status: (0, import_yup40.string)().oneOf(SupportedSubscriptionStatuses).required().label("Status"),
4421
+ var BillingSubscriptionSchema = (0, import_yup41.object)({
4422
+ userId: (0, import_yup41.string)().required().label("User ID"),
4423
+ paddleSubscriptionId: (0, import_yup41.string)().required().label("Paddle Subscription ID"),
4424
+ paddleCustomerId: (0, import_yup41.string)().required().label("Paddle Customer ID"),
4425
+ planKey: (0, import_yup41.string)().required().label("Plan Key"),
4426
+ priceIds: (0, import_yup41.array)().of((0, import_yup41.string)().required()).required().label("Price IDs"),
4427
+ status: (0, import_yup41.string)().oneOf(SupportedSubscriptionStatuses).required().label("Status"),
4034
4428
  /** Start of the period the quota is anchored to. */
4035
- currentPeriodStart: (0, import_yup40.number)().optional().label("Current Period Start"),
4036
- currentPeriodEnd: (0, import_yup40.number)().optional().label("Current Period End"),
4429
+ currentPeriodStart: (0, import_yup41.number)().optional().label("Current Period Start"),
4430
+ currentPeriodEnd: (0, import_yup41.number)().optional().label("Current Period End"),
4037
4431
  /** Set when a cancellation is scheduled; access continues until the period ends. */
4038
- canceledAt: (0, import_yup40.number)().optional().label("Canceled At"),
4432
+ canceledAt: (0, import_yup41.number)().optional().label("Canceled At"),
4039
4433
  /**
4040
4434
  * A downgrade booked for the end of the current period: the plan key it moves
4041
4435
  * to at renewal. Upgrades never set this; they apply immediately. Mirrored
4042
4436
  * from the Paddle subscription's own `customData`, so Paddle stays the source
4043
4437
  * of truth.
4044
4438
  */
4045
- pendingPlanKey: (0, import_yup40.string)().optional().label("Pending Plan Key"),
4439
+ pendingPlanKey: (0, import_yup41.string)().optional().label("Pending Plan Key"),
4046
4440
  /** `occurred_at` of the newest Paddle event applied. Guards out-of-order writes. */
4047
- lastEventAt: (0, import_yup40.number)().required().default(0).label("Last Event At"),
4048
- createdAt: (0, import_yup40.number)().optional().label("Created At"),
4049
- updatedAt: (0, import_yup40.number)().optional().label("Updated At")
4441
+ lastEventAt: (0, import_yup41.number)().required().default(0).label("Last Event At"),
4442
+ createdAt: (0, import_yup41.number)().optional().label("Created At"),
4443
+ updatedAt: (0, import_yup41.number)().optional().label("Updated At")
4050
4444
  }).label("Billing Subscription");
4051
- var BillingTransactionSchema = (0, import_yup40.object)({
4052
- userId: (0, import_yup40.string)().required().label("User ID"),
4053
- paddleTransactionId: (0, import_yup40.string)().required().label("Paddle Transaction ID"),
4054
- paddleCustomerId: (0, import_yup40.string)().optional().label("Paddle Customer ID"),
4055
- paddleSubscriptionId: (0, import_yup40.string)().optional().label("Paddle Subscription ID"),
4056
- planKey: (0, import_yup40.string)().optional().label("Plan Key"),
4057
- priceIds: (0, import_yup40.array)().of((0, import_yup40.string)().required()).required().label("Price IDs"),
4058
- status: (0, import_yup40.string)().oneOf(SupportedTransactionStatuses).required().label("Status"),
4445
+ var BillingTransactionSchema = (0, import_yup41.object)({
4446
+ userId: (0, import_yup41.string)().required().label("User ID"),
4447
+ paddleTransactionId: (0, import_yup41.string)().required().label("Paddle Transaction ID"),
4448
+ paddleCustomerId: (0, import_yup41.string)().optional().label("Paddle Customer ID"),
4449
+ paddleSubscriptionId: (0, import_yup41.string)().optional().label("Paddle Subscription ID"),
4450
+ planKey: (0, import_yup41.string)().optional().label("Plan Key"),
4451
+ priceIds: (0, import_yup41.array)().of((0, import_yup41.string)().required()).required().label("Price IDs"),
4452
+ status: (0, import_yup41.string)().oneOf(SupportedTransactionStatuses).required().label("Status"),
4059
4453
  total: MoneySchema.optional().default(void 0).label("Total"),
4060
- billedAt: (0, import_yup40.number)().optional().label("Billed At"),
4061
- lastEventAt: (0, import_yup40.number)().required().default(0).label("Last Event At"),
4062
- createdAt: (0, import_yup40.number)().optional().label("Created At"),
4063
- updatedAt: (0, import_yup40.number)().optional().label("Updated At")
4454
+ billedAt: (0, import_yup41.number)().optional().label("Billed At"),
4455
+ lastEventAt: (0, import_yup41.number)().required().default(0).label("Last Event At"),
4456
+ createdAt: (0, import_yup41.number)().optional().label("Created At"),
4457
+ updatedAt: (0, import_yup41.number)().optional().label("Updated At")
4064
4458
  }).label("Billing Transaction");
4065
- var FeatureEntitlementSchema = (0, import_yup40.object)({
4066
- feature: (0, import_yup40.string)().required().label("Feature"),
4067
- type: (0, import_yup40.string)().oneOf(SupportedGrantTypes).required().label("Grant Type"),
4459
+ var FeatureEntitlementSchema = (0, import_yup41.object)({
4460
+ feature: (0, import_yup41.string)().required().label("Feature"),
4461
+ type: (0, import_yup41.string)().oneOf(SupportedGrantTypes).required().label("Grant Type"),
4068
4462
  /** Whether the feature may be used AT ALL right now. */
4069
- allowed: (0, import_yup40.boolean)().required().default(false).label("Allowed"),
4463
+ allowed: (0, import_yup41.boolean)().required().default(false).label("Allowed"),
4070
4464
  /** Quota ceiling for the period. Absent for boolean grants. */
4071
- limit: (0, import_yup40.number)().integer().optional().label("Limit"),
4072
- used: (0, import_yup40.number)().integer().optional().label("Used"),
4465
+ limit: (0, import_yup41.number)().integer().optional().label("Limit"),
4466
+ used: (0, import_yup41.number)().integer().optional().label("Used"),
4073
4467
  /** Quota remaining plus any credit balance. Absent for boolean grants. */
4074
- remaining: (0, import_yup40.number)().integer().optional().label("Remaining"),
4468
+ remaining: (0, import_yup41.number)().integer().optional().label("Remaining"),
4075
4469
  /** Non-expiring balance from one-off purchases. */
4076
- credits: (0, import_yup40.number)().integer().optional().label("Credits"),
4470
+ credits: (0, import_yup41.number)().integer().optional().label("Credits"),
4077
4471
  /** When the quota next refreshes. */
4078
- resetsAt: (0, import_yup40.number)().optional().label("Resets At")
4472
+ resetsAt: (0, import_yup41.number)().optional().label("Resets At")
4079
4473
  }).label("Feature Entitlement");
4080
- var EntitlementDenialSchema = (0, import_yup40.object)({
4081
- feature: (0, import_yup40.string)().required().label("Feature"),
4082
- reason: (0, import_yup40.string)().oneOf(SupportedEntitlementDenialReasons).required().label("Reason"),
4083
- limit: (0, import_yup40.number)().integer().optional().label("Limit"),
4084
- used: (0, import_yup40.number)().integer().optional().label("Used"),
4085
- resetsAt: (0, import_yup40.number)().optional().label("Resets At"),
4086
- upgradeUrl: (0, import_yup40.string)().optional().label("Upgrade URL")
4474
+ var EntitlementDenialSchema = (0, import_yup41.object)({
4475
+ feature: (0, import_yup41.string)().required().label("Feature"),
4476
+ reason: (0, import_yup41.string)().oneOf(SupportedEntitlementDenialReasons).required().label("Reason"),
4477
+ limit: (0, import_yup41.number)().integer().optional().label("Limit"),
4478
+ used: (0, import_yup41.number)().integer().optional().label("Used"),
4479
+ resetsAt: (0, import_yup41.number)().optional().label("Resets At"),
4480
+ upgradeUrl: (0, import_yup41.string)().optional().label("Upgrade URL")
4087
4481
  }).label("Entitlement Denial");
4088
- var EntitlementConsumeSchema = (0, import_yup40.object)({
4089
- userId: (0, import_yup40.string)().required().label("User ID"),
4090
- feature: (0, import_yup40.string)().trim().required().min(1).max(64).label("Feature"),
4091
- units: (0, import_yup40.number)().integer().min(1).max(CONSUME_MAX_UNITS).required().default(1).label("Units"),
4482
+ var EntitlementConsumeSchema = (0, import_yup41.object)({
4483
+ userId: (0, import_yup41.string)().required().label("User ID"),
4484
+ feature: (0, import_yup41.string)().trim().required().min(1).max(64).label("Feature"),
4485
+ units: (0, import_yup41.number)().integer().min(1).max(CONSUME_MAX_UNITS).required().default(1).label("Units"),
4092
4486
  /**
4093
4487
  * Caller-supplied de-duplication key. Makes a spend exactly-once across the
4094
4488
  * retries that at-least-once delivery and ordinary network failures produce.
4095
4489
  */
4096
- idempotencyKey: (0, import_yup40.string)().trim().required().min(8).max(128).label("Idempotency Key")
4490
+ idempotencyKey: (0, import_yup41.string)().trim().required().min(8).max(128).label("Idempotency Key")
4097
4491
  }).label("Entitlement Consume");
4098
4492
 
4493
+ // src/taxonomy/taxonomy-filter.schema.ts
4494
+ var import_yup42 = require("yup");
4495
+ var ConceptFilterShape = (0, import_yup42.object)({
4496
+ /** Type ids. Open: which types exist is the vocabulary's data. */
4497
+ type: tokens("Type"),
4498
+ /** Category node ids the concept is placed under (`memberships.categoryId`). */
4499
+ categoryId: tokens("Category"),
4500
+ /** True: only live concepts with no backbone home (the uncategorized backlog). */
4501
+ unplaced: (0, import_yup42.boolean)().optional().label("Unplaced")
4502
+ }).label("Concept Filter");
4503
+ var ConceptFilterSchema = rejectUnknownKeys(
4504
+ ConceptFilterShape,
4505
+ () => Object.keys(ConceptFilterShape.fields)
4506
+ );
4507
+ var TaxonomyNodeFilterShape = (0, import_yup42.object)({
4508
+ kind: enumFacet(SupportedTaxonomyNodeKinds, "Kind"),
4509
+ /** Parent node ids: a node's children. */
4510
+ parentId: tokens("Parent")
4511
+ }).label("Taxonomy Node Filter");
4512
+ var TaxonomyNodeFilterSchema = rejectUnknownKeys(
4513
+ TaxonomyNodeFilterShape,
4514
+ () => Object.keys(TaxonomyNodeFilterShape.fields)
4515
+ );
4516
+ var UnmatchedFilterShape = (0, import_yup42.object)({
4517
+ resolution: enumFacet(SupportedUnmatchedResolutions, "Resolution"),
4518
+ reason: enumFacet(SupportedUnmatchedReasons, "Reason")
4519
+ }).label("Unmatched Filter");
4520
+ var UnmatchedFilterSchema = rejectUnknownKeys(
4521
+ UnmatchedFilterShape,
4522
+ () => Object.keys(UnmatchedFilterShape.fields)
4523
+ );
4524
+ var ConceptProposalFilterShape = (0, import_yup42.object)({
4525
+ status: enumFacet(SupportedProposalStatuses, "Status"),
4526
+ /** A kind, or `uncategorized`: concept and placement drafts with no home yet. */
4527
+ kind: enumFacet(SupportedProposalFilters, "Kind")
4528
+ }).label("Concept Proposal Filter");
4529
+ var ConceptProposalFilterSchema = rejectUnknownKeys(
4530
+ ConceptProposalFilterShape,
4531
+ () => Object.keys(ConceptProposalFilterShape.fields)
4532
+ );
4533
+ var ReleaseFilterShape = (0, import_yup42.object)({
4534
+ kind: enumFacet(SupportedReleaseKinds, "Kind"),
4535
+ status: enumFacet(SupportedReleaseStatuses, "Status")
4536
+ }).label("Release Filter");
4537
+ var ReleaseFilterSchema = rejectUnknownKeys(
4538
+ ReleaseFilterShape,
4539
+ () => Object.keys(ReleaseFilterShape.fields)
4540
+ );
4541
+ var AuditFilterShape = (0, import_yup42.object)({
4542
+ status: enumFacet(SupportedAuditStatuses, "Status")
4543
+ }).label("Audit Filter");
4544
+ var AuditFilterSchema = rejectUnknownKeys(
4545
+ AuditFilterShape,
4546
+ () => Object.keys(AuditFilterShape.fields)
4547
+ );
4548
+
4099
4549
  // src/user/user.schema.ts
4100
- var import_yup53 = require("yup");
4550
+ var import_yup55 = require("yup");
4101
4551
 
4102
4552
  // src/user/work-experience.schema.ts
4103
- var import_yup41 = require("yup");
4104
- var WorkExperienceSchema = (0, import_yup41.object)().shape({
4553
+ var import_yup43 = require("yup");
4554
+ var WorkExperienceSchema = (0, import_yup43.object)().shape({
4105
4555
  company: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company"),
4106
- designation: (0, import_yup41.string)().trim().required().label("Designation"),
4556
+ designation: (0, import_yup43.string)().trim().required().label("Designation"),
4107
4557
  duration: DurationSchema({
4108
4558
  format: "YYYY-MM",
4109
4559
  startLabel: "Start Date",
4110
4560
  endLabel: "End Date"
4111
4561
  }).required().label("Duration"),
4112
- description: (0, import_yup41.string)().trim().max(3e3).optional().label("Description"),
4562
+ description: (0, import_yup43.string)().trim().max(3e3).optional().label("Description"),
4113
4563
  location: LocationSchema.required().label("Location"),
4114
- isRemote: (0, import_yup41.boolean)().oneOf([true, false]).default(false).label("Is Remote")
4564
+ isRemote: (0, import_yup43.boolean)().oneOf([true, false]).default(false).label("Is Remote")
4115
4565
  }).noUnknown().strict().label("Work Experience");
4116
4566
 
4117
4567
  // src/user/education.schema.ts
4118
- var import_yup42 = require("yup");
4119
- var EducationSchema = (0, import_yup42.object)({
4568
+ var import_yup44 = require("yup");
4569
+ var EducationSchema = (0, import_yup44.object)({
4120
4570
  institute: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute"),
4121
- course: (0, import_yup42.string)().trim().required().label("Course"),
4122
- fieldOfStudy: (0, import_yup42.string)().trim().required().label("Field of Study"),
4571
+ course: (0, import_yup44.string)().trim().required().label("Course"),
4572
+ fieldOfStudy: (0, import_yup44.string)().trim().required().label("Field of Study"),
4123
4573
  duration: DurationSchema({
4124
4574
  format: "YYYY-MM",
4125
4575
  startLabel: "Start Date",
4126
4576
  endLabel: "End Date"
4127
4577
  }).required().label("Duration"),
4128
- description: (0, import_yup42.string)().trim().max(3e3).optional().label("Description"),
4129
- isDistanceLearning: (0, import_yup42.boolean)().default(false).label("Is Distance Learning"),
4578
+ description: (0, import_yup44.string)().trim().max(3e3).optional().label("Description"),
4579
+ isDistanceLearning: (0, import_yup44.boolean)().default(false).label("Is Distance Learning"),
4130
4580
  location: LocationSchema.required().label("Location"),
4131
- studyType: (0, import_yup42.string)().oneOf(SupportedStudyTypes).trim().max(50).required().label("Study Type")
4581
+ studyType: (0, import_yup44.string)().oneOf(SupportedStudyTypes).trim().max(50).required().label("Study Type")
4132
4582
  }).noUnknown().strict().label("Education");
4133
4583
 
4134
4584
  // src/user/user-skill.schema.ts
4135
- var import_yup43 = require("yup");
4136
- var UserSkillSchema = (0, import_yup43.object)({
4137
- name: (0, import_yup43.string)().required().label("Name"),
4138
- proficiencyLevel: (0, import_yup43.string)().oneOf(SupportedProficiencyLevels).required().label("Proficiency Level"),
4585
+ var import_yup45 = require("yup");
4586
+ var UserSkillSchema = (0, import_yup45.object)({
4587
+ name: (0, import_yup45.string)().required().label("Name"),
4588
+ proficiencyLevel: (0, import_yup45.string)().oneOf(SupportedProficiencyLevels).required().label("Proficiency Level"),
4139
4589
  lastUsed: dateString().format("YYYY-MM").nullable().optional().label("Last Used")
4140
4590
  }).noUnknown().strict().label("Skill");
4141
4591
 
4142
4592
  // src/user/project.schema.ts
4143
- var import_yup44 = require("yup");
4144
- var UserProjectSchema = (0, import_yup44.object)({
4145
- name: (0, import_yup44.string)().trim().max(50).required().label("Name"),
4146
- url: (0, import_yup44.string)().optional().label("URL"),
4147
- description: (0, import_yup44.string)().trim().min(100).max(3e3).required().label("Description"),
4593
+ var import_yup46 = require("yup");
4594
+ var UserProjectSchema = (0, import_yup46.object)({
4595
+ name: (0, import_yup46.string)().trim().max(50).required().label("Name"),
4596
+ url: (0, import_yup46.string)().optional().label("URL"),
4597
+ description: (0, import_yup46.string)().trim().min(100).max(3e3).required().label("Description"),
4148
4598
  duration: DurationSchema({
4149
4599
  format: "YYYY-MM",
4150
4600
  startLabel: "Start Date",
@@ -4153,68 +4603,68 @@ var UserProjectSchema = (0, import_yup44.object)({
4153
4603
  }).noUnknown().strict().label("Project");
4154
4604
 
4155
4605
  // src/user/user-certification.schema.ts
4156
- var import_yup45 = require("yup");
4157
- var UserCertificationSchema = (0, import_yup45.object)({
4158
- name: (0, import_yup45.string)().trim().max(100).required().label("Name"),
4606
+ var import_yup47 = require("yup");
4607
+ var UserCertificationSchema = (0, import_yup47.object)({
4608
+ name: (0, import_yup47.string)().trim().max(100).required().label("Name"),
4159
4609
  // TODO: Add validation for authority
4160
- authority: (0, import_yup45.string)().trim().max(100).required().label("Authority"),
4161
- licenseNumber: (0, import_yup45.string)().trim().max(50).optional().label("License Number"),
4610
+ authority: (0, import_yup47.string)().trim().max(100).required().label("Authority"),
4611
+ licenseNumber: (0, import_yup47.string)().trim().max(50).optional().label("License Number"),
4162
4612
  duration: DurationSchema({
4163
4613
  format: "YYYY-MM",
4164
4614
  startLabel: "Start Date",
4165
4615
  endLabel: "End Date"
4166
4616
  }).optional().nullable().label("Duration"),
4167
- url: (0, import_yup45.string)().optional().label("URL")
4617
+ url: (0, import_yup47.string)().optional().label("URL")
4168
4618
  }).noUnknown().strict().label("Certification");
4169
4619
 
4170
4620
  // src/user/user-interest.schema.ts
4171
- var import_yup46 = require("yup");
4172
- var UserInterestSchema = (0, import_yup46.object)({
4621
+ var import_yup48 = require("yup");
4622
+ var UserInterestSchema = (0, import_yup48.object)({
4173
4623
  /** The taxonomy entry's id. */
4174
- id: (0, import_yup46.string)().trim().required().label("Interest Id"),
4624
+ id: (0, import_yup48.string)().trim().required().label("Interest Id"),
4175
4625
  /** Display name, e.g. "Cloud Computing". */
4176
- name: (0, import_yup46.string)().trim().required().label("Interest"),
4626
+ name: (0, import_yup48.string)().trim().required().label("Interest"),
4177
4627
  /** Material-symbols icon name, e.g. "cloud". */
4178
- logo: (0, import_yup46.string)().trim().required().label("Interest Logo")
4628
+ logo: (0, import_yup48.string)().trim().required().label("Interest Logo")
4179
4629
  }).required().label("Interest");
4180
4630
 
4181
4631
  // src/user/user-language.schema.ts
4182
- var import_yup47 = require("yup");
4183
- var UserLanguageSchema = (0, import_yup47.object)({
4184
- name: (0, import_yup47.string)().trim().required().label("Name"),
4185
- proficiencyLevel: (0, import_yup47.string)().oneOf(SupportedProficiencyLevels).trim().max(50).required().label("Proficiency Level")
4632
+ var import_yup49 = require("yup");
4633
+ var UserLanguageSchema = (0, import_yup49.object)({
4634
+ name: (0, import_yup49.string)().trim().required().label("Name"),
4635
+ proficiencyLevel: (0, import_yup49.string)().oneOf(SupportedProficiencyLevels).trim().max(50).required().label("Proficiency Level")
4186
4636
  }).noUnknown().strict().label("Language");
4187
4637
 
4188
4638
  // src/user/user-additional-info.schema.ts
4189
- var import_yup48 = require("yup");
4190
- var UserAdditionalInfoSchema = (0, import_yup48.object)({
4191
- title: (0, import_yup48.string)().trim().max(60).required().label("Title"),
4192
- description: (0, import_yup48.string)().trim().max(1e3).required().label("Description")
4639
+ var import_yup50 = require("yup");
4640
+ var UserAdditionalInfoSchema = (0, import_yup50.object)({
4641
+ title: (0, import_yup50.string)().trim().max(60).required().label("Title"),
4642
+ description: (0, import_yup50.string)().trim().max(1e3).required().label("Description")
4193
4643
  }).noUnknown().strict().label("User Additional Info");
4194
4644
 
4195
4645
  // src/user/general-detail.schema.ts
4196
- var import_yup49 = require("yup");
4197
- var UserGeneralDetailSchema = (0, import_yup49.object)({
4198
- id: (0, import_yup49.string)().optional().label("ID"),
4199
- name: (0, import_yup49.object)().shape({
4200
- first: (0, import_yup49.string)().trim().max(50).required().label("First Name"),
4201
- last: (0, import_yup49.string)().trim().max(50).optional().label("Last Name")
4646
+ var import_yup51 = require("yup");
4647
+ var UserGeneralDetailSchema = (0, import_yup51.object)({
4648
+ id: (0, import_yup51.string)().optional().label("ID"),
4649
+ name: (0, import_yup51.object)().shape({
4650
+ first: (0, import_yup51.string)().trim().max(50).required().label("First Name"),
4651
+ last: (0, import_yup51.string)().trim().max(50).optional().label("Last Name")
4202
4652
  }).required().label("Name"),
4203
- headline: (0, import_yup49.string)().trim().max(200).optional().label("Headline"),
4204
- image: (0, import_yup49.string)().optional().label("Image"),
4653
+ headline: (0, import_yup51.string)().trim().max(200).optional().label("Headline"),
4654
+ image: (0, import_yup51.string)().optional().label("Image"),
4205
4655
  // The DISPLAYED avatar (`image`) is a flattened export with any status frame
4206
4656
  // ("#OpenToWork", …) already burned into the pixels. `imageOriginal` keeps the
4207
4657
  // un-framed source the user uploaded, so the image builder can reopen it and
4208
4658
  // apply a DIFFERENT frame instead of stacking a second one on top of the first.
4209
4659
  // Optional and absent on every pre-existing user: treat a missing value as
4210
4660
  // "only the flattened image is available".
4211
- imageOriginal: (0, import_yup49.string)().optional().label("Original Image"),
4212
- aboutMe: (0, import_yup49.string)().trim().max(3e3).optional().label("About Me"),
4213
- email: (0, import_yup49.string)().required().label("Email"),
4214
- mobile: (0, import_yup49.string)().nullable().optional().label("Mobile"),
4215
- emailVerified: (0, import_yup49.string)().nullable().optional().label("Email Verified"),
4216
- mobileVerified: (0, import_yup49.string)().nullable().optional().label("Mobile Verified"),
4217
- experienceLevel: (0, import_yup49.string)().oneOf(SupportedExperienceLevels).required().label("Experience level"),
4661
+ imageOriginal: (0, import_yup51.string)().optional().label("Original Image"),
4662
+ aboutMe: (0, import_yup51.string)().trim().max(3e3).optional().label("About Me"),
4663
+ email: (0, import_yup51.string)().required().label("Email"),
4664
+ mobile: (0, import_yup51.string)().nullable().optional().label("Mobile"),
4665
+ emailVerified: (0, import_yup51.string)().nullable().optional().label("Email Verified"),
4666
+ mobileVerified: (0, import_yup51.string)().nullable().optional().label("Mobile Verified"),
4667
+ experienceLevel: (0, import_yup51.string)().oneOf(SupportedExperienceLevels).required().label("Experience level"),
4218
4668
  /**
4219
4669
  * The user's HIGHEST qualification, e.g. `bachelor`.
4220
4670
  *
@@ -4233,7 +4683,7 @@ var UserGeneralDetailSchema = (0, import_yup49.object)({
4233
4683
  * UNCONSTRAINED on education rather than filtering the user out — the same
4234
4684
  * opt-out reasoning `notificationPrefs` uses.
4235
4685
  */
4236
- educationLevel: (0, import_yup49.string)().oneOf(SupportedEducationLevels).optional().label("Education level"),
4686
+ educationLevel: (0, import_yup51.string)().oneOf(SupportedEducationLevels).optional().label("Education level"),
4237
4687
  location: LocationSchema.required().label("Location"),
4238
4688
  /**
4239
4689
  * Where the account was created, captured once and never rewritten.
@@ -4249,38 +4699,38 @@ var UserGeneralDetailSchema = (0, import_yup49.object)({
4249
4699
  * - `location` derived from the user's self-entered profile location
4250
4700
  * - `default` assumed (no signal available); presumption, not evidence
4251
4701
  */
4252
- signupContext: (0, import_yup49.object)().shape({
4702
+ signupContext: (0, import_yup51.object)().shape({
4253
4703
  // ISO 3166-1 alpha-2, uppercase — the shape `cf-ipcountry` returns, so
4254
4704
  // measured and inferred values are directly comparable.
4255
- country: (0, import_yup49.string)().trim().uppercase().length(2).required().label("Signup Country"),
4256
- locale: (0, import_yup49.string)().trim().required().label("Signup Locale"),
4257
- source: (0, import_yup49.string)().oneOf(SupportedSignupContextSources).required().label("Signup Context Source"),
4258
- at: (0, import_yup49.number)().required().label("Signup Context At")
4705
+ country: (0, import_yup51.string)().trim().uppercase().length(2).required().label("Signup Country"),
4706
+ locale: (0, import_yup51.string)().trim().required().label("Signup Locale"),
4707
+ source: (0, import_yup51.string)().oneOf(SupportedSignupContextSources).required().label("Signup Context Source"),
4708
+ at: (0, import_yup51.number)().required().label("Signup Context At")
4259
4709
  }).optional().default(void 0).label("Signup Context"),
4260
- profileVisibility: (0, import_yup49.string)().oneOf(SupportedUserProfileVisibilities).default("public" /* Public */).label("Profile Visibility")
4710
+ profileVisibility: (0, import_yup51.string)().oneOf(SupportedUserProfileVisibilities).default("public" /* Public */).label("Profile Visibility")
4261
4711
  }).noUnknown().strict().label("General Detail");
4262
4712
 
4263
4713
  // src/user/user-job-preferences.schema.ts
4264
- var import_yup50 = require("yup");
4265
- var UserJobPreferencesSchema = (0, import_yup50.object)({
4714
+ var import_yup52 = require("yup");
4715
+ var UserJobPreferencesSchema = (0, import_yup52.object)({
4266
4716
  /**
4267
4717
  * Whether the job seeker is openly signalling availability. Surfaces the
4268
4718
  * "Open to work" badge on the public profile and boosts visibility in
4269
4719
  * recruiter search. Defaults to `false` - users must opt in.
4270
4720
  */
4271
- openToWork: (0, import_yup50.boolean)().default(false).label("Open to Work"),
4721
+ openToWork: (0, import_yup52.boolean)().default(false).label("Open to Work"),
4272
4722
  /**
4273
4723
  * How urgently the user is looking for their next job. Drives match scoring
4274
4724
  * and can downgrade the visibility of expired or low-relevance postings for
4275
4725
  * users in `passively_browsing` mode.
4276
4726
  */
4277
- jobSearchUrgency: (0, import_yup50.string)().oneOf(SupportedJobSearchUrgencies).required().label("Job Search Urgency"),
4727
+ jobSearchUrgency: (0, import_yup52.string)().oneOf(SupportedJobSearchUrgencies).required().label("Job Search Urgency"),
4278
4728
  /**
4279
4729
  * Locations the user wants to work in. Stores the full `LocationSchema`
4280
4730
  * shape (country, city, state, geo, etc.) as returned by the locations
4281
4731
  * autocomplete API.
4282
4732
  */
4283
- jobLocations: (0, import_yup50.array)().of(LocationSchema.required().label("Job Location")).min(1, "Pick at least one preferred location.").required().label("Job Locations"),
4733
+ jobLocations: (0, import_yup52.array)().of(LocationSchema.required().label("Job Location")).min(1, "Pick at least one preferred location.").required().label("Job Locations"),
4284
4734
  /**
4285
4735
  * Seniority levels the user wants jobs to be matched against. Multi-select
4286
4736
  * (up to 2) for borderline candidates.
@@ -4291,7 +4741,7 @@ var UserJobPreferencesSchema = (0, import_yup50.object)({
4291
4741
  * Both reuse the same `ExperienceLevel` taxonomy from `common.constant.ts`
4292
4742
  * so search/match logic doesn't have to translate between two vocabularies.
4293
4743
  */
4294
- targetExperienceLevels: (0, import_yup50.array)().of((0, import_yup50.string)().oneOf(SupportedExperienceLevels).required()).min(1, "Pick at least one experience level.").max(2, "You can select at most 2 experience levels.").required().label("Target Experience Levels"),
4744
+ targetExperienceLevels: (0, import_yup52.array)().of((0, import_yup52.string)().oneOf(SupportedExperienceLevels).required()).min(1, "Pick at least one experience level.").max(2, "You can select at most 2 experience levels.").required().label("Target Experience Levels"),
4295
4745
  /**
4296
4746
  * Specializations the user is searching for - free-form titles.
4297
4747
  *
@@ -4300,19 +4750,19 @@ var UserJobPreferencesSchema = (0, import_yup50.object)({
4300
4750
  * surfaces a curated "Popular Roles" picker for discovery, but the user
4301
4751
  * can ultimately add any title; matching/normalization happens downstream.
4302
4752
  */
4303
- jobRoles: (0, import_yup50.array)().of((0, import_yup50.string)().trim().max(120).required()).min(1, "Pick at least one role.").required().label("Job Roles"),
4753
+ jobRoles: (0, import_yup52.array)().of((0, import_yup52.string)().trim().max(120).required()).min(1, "Pick at least one role.").required().label("Job Roles"),
4304
4754
  /**
4305
4755
  * Minimum acceptable annual base salary, in `minSalaryCurrency`.
4306
4756
  * Stored as an integer in the currency's major unit (e.g. dollars, not cents).
4307
4757
  * Defaults to 0 ("any salary") rather than being optional - every job-seeker
4308
4758
  * has a floor, even if it's zero.
4309
4759
  */
4310
- minSalary: (0, import_yup50.number)().integer().min(MIN_SALARY_LOWER_BOUND).max(MIN_SALARY_UPPER_BOUND).default(0).required().label("Minimum Salary"),
4311
- minSalaryCurrency: (0, import_yup50.string)().oneOf(SupportedSalaryCurrencies).default("USD").required().label("Minimum Salary Currency"),
4760
+ minSalary: (0, import_yup52.number)().integer().min(MIN_SALARY_LOWER_BOUND).max(MIN_SALARY_UPPER_BOUND).default(0).required().label("Minimum Salary"),
4761
+ minSalaryCurrency: (0, import_yup52.string)().oneOf(SupportedSalaryCurrencies).default("USD").required().label("Minimum Salary Currency"),
4312
4762
  /**
4313
4763
  * Marketing-attribution capture from the final onboarding step.
4314
4764
  */
4315
- referralSource: (0, import_yup50.string)().oneOf(SupportedReferralSources).required().label("Referral Source"),
4765
+ referralSource: (0, import_yup52.string)().oneOf(SupportedReferralSources).required().label("Referral Source"),
4316
4766
  /**
4317
4767
  * Resumes the user has uploaded. Embedded directly on the user document
4318
4768
  * (capped at 5) - they're cheap to denormalize, every wizard step that
@@ -4326,25 +4776,25 @@ var UserJobPreferencesSchema = (0, import_yup50.object)({
4326
4776
  * AI resume-builder flow - onboarding uploads land here, AI-built resumes
4327
4777
  * live in their own collection.
4328
4778
  */
4329
- resumes: (0, import_yup50.array)().of(
4330
- (0, import_yup50.object)({
4779
+ resumes: (0, import_yup52.array)().of(
4780
+ (0, import_yup52.object)({
4331
4781
  // Stable id assigned on upload - used to address a specific entry
4332
4782
  // for delete / set-primary operations without exposing the GCS URL
4333
4783
  // as a route key.
4334
- id: (0, import_yup50.string)().required().label("ID"),
4335
- url: (0, import_yup50.string)().required().label("Resume URL"),
4336
- filename: (0, import_yup50.string)().trim().max(255).optional().label("Filename"),
4337
- sizeBytes: (0, import_yup50.number)().integer().min(0).optional().label("Size (bytes)"),
4338
- mimeType: (0, import_yup50.string)().trim().max(120).optional().label("MIME Type"),
4339
- uploadedAt: (0, import_yup50.date)().required().label("Uploaded At"),
4340
- isPrimary: (0, import_yup50.boolean)().default(false).label("Is Primary")
4784
+ id: (0, import_yup52.string)().required().label("ID"),
4785
+ url: (0, import_yup52.string)().required().label("Resume URL"),
4786
+ filename: (0, import_yup52.string)().trim().max(255).optional().label("Filename"),
4787
+ sizeBytes: (0, import_yup52.number)().integer().min(0).optional().label("Size (bytes)"),
4788
+ mimeType: (0, import_yup52.string)().trim().max(120).optional().label("MIME Type"),
4789
+ uploadedAt: (0, import_yup52.date)().required().label("Uploaded At"),
4790
+ isPrimary: (0, import_yup52.boolean)().default(false).label("Is Primary")
4341
4791
  }).noUnknown().strict().label("Resume")
4342
4792
  ).max(5, "You can keep at most 5 resumes on file.").default([]).label("Resumes"),
4343
4793
  /**
4344
4794
  * Set when the user finishes the wizard's last step. Acts as the gate the
4345
4795
  * onboarding hook checks to redirect users who haven't completed setup.
4346
4796
  */
4347
- onboardingCompletedAt: (0, import_yup50.date)().nullable().optional().label("Onboarding Completed At"),
4797
+ onboardingCompletedAt: (0, import_yup52.date)().nullable().optional().label("Onboarding Completed At"),
4348
4798
  /**
4349
4799
  * Parser-suggested values for wizard fields, written by the resume-upload
4350
4800
  * flow. Every parser-derived field lands here - including profile-shaped
@@ -4364,92 +4814,92 @@ var UserJobPreferencesSchema = (0, import_yup50.object)({
4364
4814
  * APIs. If `user.<field>` is empty there, the correct behavior is empty,
4365
4815
  * because the user has not confirmed it yet.
4366
4816
  */
4367
- pendingPrefill: (0, import_yup50.object)({
4368
- headline: (0, import_yup50.string)().trim().optional().label("Pending Headline"),
4369
- aboutMe: (0, import_yup50.string)().trim().optional().label("Pending About Me"),
4370
- mobile: (0, import_yup50.string)().trim().optional().label("Pending Mobile"),
4817
+ pendingPrefill: (0, import_yup52.object)({
4818
+ headline: (0, import_yup52.string)().trim().optional().label("Pending Headline"),
4819
+ aboutMe: (0, import_yup52.string)().trim().optional().label("Pending About Me"),
4820
+ mobile: (0, import_yup52.string)().trim().optional().label("Pending Mobile"),
4371
4821
  location: LocationSchema.optional().default(void 0).label("Pending Location"),
4372
- experienceLevel: (0, import_yup50.string)().oneOf(SupportedExperienceLevels).optional().label("Pending Experience Level"),
4373
- socialAccounts: (0, import_yup50.array)().of(SocialAccountSchema.required()).optional().label("Pending Social Accounts"),
4374
- workExperiences: (0, import_yup50.array)().of(WorkExperienceSchema.required()).optional().label("Pending Work Experiences"),
4375
- educations: (0, import_yup50.array)().of(EducationSchema.required()).optional().label("Pending Educations")
4822
+ experienceLevel: (0, import_yup52.string)().oneOf(SupportedExperienceLevels).optional().label("Pending Experience Level"),
4823
+ socialAccounts: (0, import_yup52.array)().of(SocialAccountSchema.required()).optional().label("Pending Social Accounts"),
4824
+ workExperiences: (0, import_yup52.array)().of(WorkExperienceSchema.required()).optional().label("Pending Work Experiences"),
4825
+ educations: (0, import_yup52.array)().of(EducationSchema.required()).optional().label("Pending Educations")
4376
4826
  }).nullable().optional().default(void 0).label("Pending Prefill")
4377
4827
  }).noUnknown().strict().label("User Job Preferences Schema");
4378
4828
 
4379
4829
  // src/user/user-recruiter-profile.schema.ts
4380
- var import_yup51 = require("yup");
4381
- var RecruiterPageLinkSchema = (0, import_yup51.object)({
4830
+ var import_yup53 = require("yup");
4831
+ var RecruiterPageLinkSchema = (0, import_yup53.object)({
4382
4832
  page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company Page"),
4383
- jobTitle: (0, import_yup51.string)().trim().max(100).optional().label("Job Title")
4833
+ jobTitle: (0, import_yup53.string)().trim().max(100).optional().label("Job Title")
4384
4834
  }).noUnknown().strict().label("Recruiter Page Link");
4385
- var UserRecruiterProfileSchema = (0, import_yup51.object)({
4386
- recruiterProfile: (0, import_yup51.object)({
4387
- hiringFor: (0, import_yup51.array)().of(RecruiterPageLinkSchema).default([]).label("Hiring For")
4835
+ var UserRecruiterProfileSchema = (0, import_yup53.object)({
4836
+ recruiterProfile: (0, import_yup53.object)({
4837
+ hiringFor: (0, import_yup53.array)().of(RecruiterPageLinkSchema).default([]).label("Hiring For")
4388
4838
  }).optional().default(void 0).label("Recruiter Profile")
4389
4839
  }).noUnknown().strict().label("User Recruiter Profile");
4390
4840
 
4391
4841
  // src/user/user-coordinator-profile.schema.ts
4392
- var import_yup52 = require("yup");
4393
- var CoordinatorPageLinkSchema = (0, import_yup52.object)({
4842
+ var import_yup54 = require("yup");
4843
+ var CoordinatorPageLinkSchema = (0, import_yup54.object)({
4394
4844
  page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute Page"),
4395
- jobTitle: (0, import_yup52.string)().trim().max(100).optional().label("Job Title")
4845
+ jobTitle: (0, import_yup54.string)().trim().max(100).optional().label("Job Title")
4396
4846
  }).noUnknown().strict().label("Coordinator Page Link");
4397
- var UserCoordinatorProfileSchema = (0, import_yup52.object)({
4398
- coordinatorProfile: (0, import_yup52.object)({
4399
- coordinatesAt: (0, import_yup52.array)().of(CoordinatorPageLinkSchema).default([]).label("Coordinates At")
4847
+ var UserCoordinatorProfileSchema = (0, import_yup54.object)({
4848
+ coordinatorProfile: (0, import_yup54.object)({
4849
+ coordinatesAt: (0, import_yup54.array)().of(CoordinatorPageLinkSchema).default([]).label("Coordinates At")
4400
4850
  }).optional().default(void 0).label("Coordinator Profile")
4401
4851
  }).noUnknown().strict().label("User Coordinator Profile");
4402
4852
 
4403
4853
  // src/user/user.schema.ts
4404
- var UserSchema = (0, import_yup53.object)({
4854
+ var UserSchema = (0, import_yup55.object)({
4405
4855
  /**
4406
4856
  * Related auth account id from auth Server (e.g. Better auth https://auth.thejob.dev)
4407
4857
  */
4408
- authAccountId: (0, import_yup53.string)().required().label("Auth Account ID"),
4858
+ authAccountId: (0, import_yup55.string)().required().label("Auth Account ID"),
4409
4859
  /**
4410
4860
  * Social media information about the user (e.g. LinkedIn, GitHub, etc.)
4411
4861
  */
4412
- socialAccounts: (0, import_yup53.array)().of(SocialAccountSchema).default([]).label("Social Accounts"),
4862
+ socialAccounts: (0, import_yup55.array)().of(SocialAccountSchema).default([]).label("Social Accounts"),
4413
4863
  /**
4414
4864
  * Work experience information about the user
4415
4865
  */
4416
- workExperiences: (0, import_yup53.array)().of(WorkExperienceSchema).required().default([]).label("Work Experiences"),
4866
+ workExperiences: (0, import_yup55.array)().of(WorkExperienceSchema).required().default([]).label("Work Experiences"),
4417
4867
  /**
4418
4868
  * Education information about the user
4419
4869
  */
4420
- educations: (0, import_yup53.array)().of(EducationSchema).required().default([]).label("Educations"),
4870
+ educations: (0, import_yup55.array)().of(EducationSchema).required().default([]).label("Educations"),
4421
4871
  /**
4422
4872
  * Skills information about the user
4423
4873
  */
4424
- skills: (0, import_yup53.array)().of(UserSkillSchema).required().default([]).label("Skills"),
4874
+ skills: (0, import_yup55.array)().of(UserSkillSchema).required().default([]).label("Skills"),
4425
4875
  /**
4426
4876
  * Projects information about the user
4427
4877
  */
4428
- projects: (0, import_yup53.array)().of(UserProjectSchema).default([]).label("Projects"),
4878
+ projects: (0, import_yup55.array)().of(UserProjectSchema).default([]).label("Projects"),
4429
4879
  /**
4430
4880
  * Certifications information about the user
4431
4881
  */
4432
- certifications: (0, import_yup53.array)().of(UserCertificationSchema).default([]).label("Certifications"),
4882
+ certifications: (0, import_yup55.array)().of(UserCertificationSchema).default([]).label("Certifications"),
4433
4883
  /**
4434
4884
  * Interests information about the user.
4435
4885
  */
4436
- interests: (0, import_yup53.array)().of(UserInterestSchema).optional().default([]).label("Interests"),
4886
+ interests: (0, import_yup55.array)().of(UserInterestSchema).optional().default([]).label("Interests"),
4437
4887
  /**
4438
4888
  * Languages information about the user
4439
4889
  */
4440
- languages: (0, import_yup53.array)().of(UserLanguageSchema).required().default([]).label("Languages"),
4890
+ languages: (0, import_yup55.array)().of(UserLanguageSchema).required().default([]).label("Languages"),
4441
4891
  /**
4442
4892
  * Additional information about the user
4443
4893
  */
4444
- additionalInfo: (0, import_yup53.array)().of(UserAdditionalInfoSchema).default([]).label("Additional Information"),
4894
+ additionalInfo: (0, import_yup55.array)().of(UserAdditionalInfoSchema).default([]).label("Additional Information"),
4445
4895
  /**
4446
4896
  * Status of the user account
4447
4897
  */
4448
- status: (0, import_yup53.string)().oneOf(SupportedUserStatuses).required().label("Status"),
4898
+ status: (0, import_yup55.string)().oneOf(SupportedUserStatuses).required().label("Status"),
4449
4899
  /**
4450
4900
  * Roles assigned to the user
4451
4901
  */
4452
- roles: (0, import_yup53.array)().of((0, import_yup53.string)().oneOf(SupportedUserRoles)).required().default(DefaultUserRoles).label("Roles"),
4902
+ roles: (0, import_yup55.array)().of((0, import_yup55.string)().oneOf(SupportedUserRoles)).required().default(DefaultUserRoles).label("Roles"),
4453
4903
  /**
4454
4904
  * Explicit consent to receive marketing email (newsletters, job alerts by
4455
4905
  * broadcast, product updates). Marketing sends are HARD-GATED on
@@ -4461,18 +4911,18 @@ var UserSchema = (0, import_yup53.object)({
4461
4911
  * unsubscribe sets `subscribed=false` so consent and the email-service
4462
4912
  * suppression list stay consistent. Defaults to NOT subscribed (opt-in).
4463
4913
  */
4464
- marketingConsent: (0, import_yup53.object)({
4465
- subscribed: (0, import_yup53.boolean)().default(false).label("Subscribed to marketing email"),
4914
+ marketingConsent: (0, import_yup55.object)({
4915
+ subscribed: (0, import_yup55.boolean)().default(false).label("Subscribed to marketing email"),
4466
4916
  /** Epoch ms of the last consent change (opt-in or opt-out). */
4467
- updatedAt: (0, import_yup53.number)().optional().label("Consent updated at"),
4917
+ updatedAt: (0, import_yup55.number)().optional().label("Consent updated at"),
4468
4918
  /** Where the consent change originated, e.g. `onboarding`, `unsubscribe`, `settings`. */
4469
- source: (0, import_yup53.string)().optional().label("Consent source"),
4919
+ source: (0, import_yup55.string)().optional().label("Consent source"),
4470
4920
  /**
4471
4921
  * How often the user receives job-alert emails. `off` disables job alerts
4472
4922
  * only; other marketing stays governed by `subscribed`. Unset means the
4473
4923
  * user has not chosen a cadence yet.
4474
4924
  */
4475
- jobAlertFrequency: (0, import_yup53.string)().oneOf(SupportedJobAlertFrequencies).optional().label("Job alert frequency")
4925
+ jobAlertFrequency: (0, import_yup55.string)().oneOf(SupportedJobAlertFrequencies).optional().label("Job alert frequency")
4476
4926
  }).default({ subscribed: false }).label("Marketing Consent"),
4477
4927
  /**
4478
4928
  * Per-channel toggles for NOTIFICATION email — mail about activity on the
@@ -4487,11 +4937,11 @@ var UserSchema = (0, import_yup53.object)({
4487
4937
  *
4488
4938
  * Transactional mail (magic-link, verification) ignores this object entirely.
4489
4939
  */
4490
- notificationPrefs: (0, import_yup53.object)({
4491
- groupActivity: (0, import_yup53.boolean)().default(true).label("Group activity email"),
4492
- jobActivity: (0, import_yup53.boolean)().default(true).label("Job activity email"),
4493
- applicationUpdates: (0, import_yup53.boolean)().default(true).label("Application update email"),
4494
- productUpdates: (0, import_yup53.boolean)().default(false).label("Product update email")
4940
+ notificationPrefs: (0, import_yup55.object)({
4941
+ groupActivity: (0, import_yup55.boolean)().default(true).label("Group activity email"),
4942
+ jobActivity: (0, import_yup55.boolean)().default(true).label("Job activity email"),
4943
+ applicationUpdates: (0, import_yup55.boolean)().default(true).label("Application update email"),
4944
+ productUpdates: (0, import_yup55.boolean)().default(false).label("Product update email")
4495
4945
  }).default({
4496
4946
  groupActivity: true,
4497
4947
  jobActivity: true,
@@ -4518,21 +4968,21 @@ var UserSchema = (0, import_yup53.object)({
4518
4968
  * subscription (see `PushSubscriptionSchema`). This flag is the user's
4519
4969
  * intent, the subscription is the browser grant, and both are required.
4520
4970
  */
4521
- pushConsent: (0, import_yup53.object)({
4522
- subscribed: (0, import_yup53.boolean)().default(false).label("Subscribed to push notifications"),
4971
+ pushConsent: (0, import_yup55.object)({
4972
+ subscribed: (0, import_yup55.boolean)().default(false).label("Subscribed to push notifications"),
4523
4973
  /** Epoch ms of the last consent change (opt-in or opt-out). */
4524
- updatedAt: (0, import_yup53.number)().optional().label("Push consent updated at"),
4974
+ updatedAt: (0, import_yup55.number)().optional().label("Push consent updated at"),
4525
4975
  /** Where the change originated, e.g. `onboarding`, `settings`, `prompt`. */
4526
- source: (0, import_yup53.string)().optional().label("Push consent source")
4976
+ source: (0, import_yup55.string)().optional().label("Push consent source")
4527
4977
  }).default({ subscribed: false }).label("Push Consent"),
4528
4978
  /**
4529
4979
  * Vector embedding of the user's profile for semantic/hybrid search.
4530
4980
  * Generated from a structured summary of skills, experience, education, etc.
4531
4981
  * Only generated for public profiles with sufficient completeness (≥60%).
4532
4982
  */
4533
- embedding: (0, import_yup53.object)({
4534
- vector: (0, import_yup53.array)((0, import_yup53.number)().required()).optional().label("Embedding vector"),
4535
- model: (0, import_yup53.string)().optional().label("Embedding model")
4983
+ embedding: (0, import_yup55.object)({
4984
+ vector: (0, import_yup55.array)((0, import_yup55.number)().required()).optional().label("Embedding vector"),
4985
+ model: (0, import_yup55.string)().optional().label("Embedding model")
4536
4986
  }).nullable().optional().label("Embedding"),
4537
4987
  /**
4538
4988
  * Epoch ms the account was created, assigned by the storing service.
@@ -4547,12 +4997,12 @@ var UserSchema = (0, import_yup53.object)({
4547
4997
  * `updatedAt` is deliberately NOT added alongside it: nothing derives from it
4548
4998
  * yet, and an optional field is only safe to add when something needs it.
4549
4999
  */
4550
- createdAt: (0, import_yup53.number)().optional().label("Created At")
5000
+ createdAt: (0, import_yup55.number)().optional().label("Created At")
4551
5001
  }).concat(UserGeneralDetailSchema).concat(UserJobPreferencesSchema).concat(UserRecruiterProfileSchema).concat(UserCoordinatorProfileSchema).noUnknown().strict().label("User Schema");
4552
5002
 
4553
5003
  // src/user/push-subscription.schema.ts
4554
- var import_yup54 = require("yup");
4555
- var PushSubscriptionSchema = (0, import_yup54.object)({
5004
+ var import_yup56 = require("yup");
5005
+ var PushSubscriptionSchema = (0, import_yup56.object)({
4556
5006
  /**
4557
5007
  * The user this subscription belongs to, by the `shortId` every service
4558
5008
  * keys a user on, matching `UserSchema.shortId`.
@@ -4566,7 +5016,7 @@ var PushSubscriptionSchema = (0, import_yup54.object)({
4566
5016
  * `shortId` of its OWN (see `PushSubscriptionRecord`); one field cannot be
4567
5017
  * both the row's id and its owner's.
4568
5018
  */
4569
- userShortId: (0, import_yup54.string)().required().label("User Short ID"),
5019
+ userShortId: (0, import_yup56.string)().required().label("User Short ID"),
4570
5020
  /**
4571
5021
  * The push service URL the browser issued. Vendor-specific (FCM, Mozilla,
4572
5022
  * Apple) and effectively unbounded in length, so it carries no length cap.
@@ -4575,16 +5025,16 @@ var PushSubscriptionSchema = (0, import_yup54.object)({
4575
5025
  * browser sends back unchanged, and what a 404/410 response identifies as
4576
5026
  * dead. Upserts and deletes both key on it.
4577
5027
  */
4578
- endpoint: (0, import_yup54.string)().required().label("Push Endpoint"),
5028
+ endpoint: (0, import_yup56.string)().required().label("Push Endpoint"),
4579
5029
  /**
4580
5030
  * Encryption material from the browser. Web Push payloads are encrypted to
4581
5031
  * these keys, so a row missing either one cannot be delivered to at all.
4582
5032
  */
4583
- keys: (0, import_yup54.object)({
5033
+ keys: (0, import_yup56.object)({
4584
5034
  /** Client public key, base64url. */
4585
- p256dh: (0, import_yup54.string)().required().label("P256DH Key"),
5035
+ p256dh: (0, import_yup56.string)().required().label("P256DH Key"),
4586
5036
  /** Client auth secret, base64url. */
4587
- auth: (0, import_yup54.string)().required().label("Auth Secret")
5037
+ auth: (0, import_yup56.string)().required().label("Auth Secret")
4588
5038
  }).required().label("Push Keys"),
4589
5039
  /**
4590
5040
  * Epoch ms the push service says the subscription expires, when it says
@@ -4592,22 +5042,22 @@ var PushSubscriptionSchema = (0, import_yup54.object)({
4592
5042
  * informational and never the basis for pruning. A 404/410 on send is the
4593
5043
  * only reliable death signal.
4594
5044
  */
4595
- expirationTime: (0, import_yup54.number)().nullable().optional().label("Expiration Time"),
5045
+ expirationTime: (0, import_yup56.number)().nullable().optional().label("Expiration Time"),
4596
5046
  /**
4597
5047
  * The subscribing browser's user agent, kept so a user can recognise their
4598
5048
  * own devices in a "where you receive notifications" list. Display only:
4599
5049
  * never parsed, and never used to decide delivery.
4600
5050
  */
4601
- userAgent: (0, import_yup54.string)().optional().label("User Agent"),
5051
+ userAgent: (0, import_yup56.string)().optional().label("User Agent"),
4602
5052
  /** Epoch ms the subscription was first registered. */
4603
- createdAt: (0, import_yup54.number)().optional().label("Created At"),
5053
+ createdAt: (0, import_yup56.number)().optional().label("Created At"),
4604
5054
  /**
4605
5055
  * Epoch ms this subscription was last confirmed live, refreshed when the
4606
5056
  * browser re-registers it. A subscription that stops being refreshed is a
4607
5057
  * device that stopped visiting, which is useful for pruning rows that never
4608
5058
  * fail loudly enough to be caught by a 410.
4609
5059
  */
4610
- lastSeenAt: (0, import_yup54.number)().optional().label("Last Seen At"),
5060
+ lastSeenAt: (0, import_yup56.number)().optional().label("Last Seen At"),
4611
5061
  /**
4612
5062
  * Epoch ms the owner explicitly signed out on this device, or absent.
4613
5063
  *
@@ -4617,12 +5067,12 @@ var PushSubscriptionSchema = (0, import_yup54.object)({
4617
5067
  * so that a MISSING row keeps one meaning to the browser ("stop, this device
4618
5068
  * was removed"), which it acts on by dropping its own subscription.
4619
5069
  */
4620
- signedOutAt: (0, import_yup54.number)().nullable().optional().label("Signed Out At")
5070
+ signedOutAt: (0, import_yup56.number)().nullable().optional().label("Signed Out At")
4621
5071
  }).noUnknown().strict().label("Push Subscription Schema");
4622
5072
 
4623
5073
  // src/user/user-completeness.schema.ts
4624
- var import_yup55 = require("yup");
4625
- var UserCompletenessSchema = (0, import_yup55.object)({
5074
+ var import_yup57 = require("yup");
5075
+ var UserCompletenessSchema = (0, import_yup57.object)({
4626
5076
  additionalInfo: CompletenessScoreSchema(0).label("Additional Info"),
4627
5077
  // Optional
4628
5078
  certifications: CompletenessScoreSchema(0).label("Certifications"),
@@ -4647,10 +5097,14 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4647
5097
  0 && (module.exports = {
4648
5098
  AnswerChoiceType,
4649
5099
  ApplicationReceivePreference,
5100
+ AuditFilterSchema,
5101
+ AuditSchema,
4650
5102
  BillingPeriod,
4651
5103
  BillingSubscriptionSchema,
4652
5104
  BillingTransactionSchema,
4653
5105
  CAMPAIGN_MAX_RECIPIENTS_CEILING,
5106
+ CONCEPT_ID_PATTERN,
5107
+ CONCEPT_TYPE_PATTERN,
4654
5108
  CONSUME_MAX_UNITS,
4655
5109
  CampaignDataSourceSchema,
4656
5110
  CampaignEndKind,
@@ -4666,6 +5120,11 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4666
5120
  Common,
4667
5121
  CompensationType,
4668
5122
  CompletenessScoreSchema,
5123
+ ConceptFilterSchema,
5124
+ ConceptMembershipSchema,
5125
+ ConceptProposalFilterSchema,
5126
+ ConceptProposalSchema,
5127
+ ConceptSchema,
4669
5128
  ContactTypes,
4670
5129
  CoordinatorPageLinkSchema,
4671
5130
  CountryFilterSchema,
@@ -4731,6 +5190,7 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4731
5190
  MailingListFilterSchema,
4732
5191
  MailingListSchema,
4733
5192
  MoneySchema,
5193
+ NormalizeContextSchema,
4734
5194
  NotificationType,
4735
5195
  OccurrenceStatus,
4736
5196
  PREFILL_MIRRORED_KEYS,
@@ -4750,6 +5210,8 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4750
5210
  PostSchema,
4751
5211
  PostStatus,
4752
5212
  ProficiencyLevel,
5213
+ ProposalCandidateSchema,
5214
+ ProposalMessageSchema,
4753
5215
  PushSubscriptionSchema,
4754
5216
  QuestionSchema,
4755
5217
  QuestionType,
@@ -4757,9 +5219,15 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4757
5219
  ReadAndAcknowledgeQuestionSchema,
4758
5220
  RecruiterPageLinkSchema,
4759
5221
  ReferralSource,
5222
+ ReleaseFilterSchema,
5223
+ ReleaseSchema,
4760
5224
  ReportReason,
4761
5225
  ReportSchema,
5226
+ ResolverSettingsSchema,
5227
+ ResolverVerificationSchema,
4762
5228
  ResourceType,
5229
+ SCHEDULE_MAX_HOURS,
5230
+ SCHEDULE_MIN_HOURS,
4763
5231
  SITEMAP_FORMAT,
4764
5232
  SYSTEM_DATE_FORMAT,
4765
5233
  SavedSearchSchema,
@@ -4774,14 +5242,17 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4774
5242
  StudentCompletenessSchema,
4775
5243
  StudyType,
4776
5244
  SubscriptionStatus,
5245
+ SuggestedHomeSchema,
4777
5246
  SupportedAnswerChoiceTypes,
4778
5247
  SupportedApplicationReceivePreferences,
5248
+ SupportedAuditStatuses,
4779
5249
  SupportedBillingPeriods,
4780
5250
  SupportedCampaignEndKinds,
4781
5251
  SupportedCampaignIntervalUnits,
4782
5252
  SupportedCampaignStatuses,
4783
5253
  SupportedCampaignTriggerKinds,
4784
5254
  SupportedCompensationTypes,
5255
+ SupportedConceptSources,
4785
5256
  SupportedContactTypes,
4786
5257
  SupportedEducationLevels,
4787
5258
  SupportedEmployeeCounts,
@@ -4806,6 +5277,7 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4806
5277
  SupportedJobSearchUrgencies,
4807
5278
  SupportedJobStatuses,
4808
5279
  SupportedJobSubCategories,
5280
+ SupportedMatchTypes,
4809
5281
  SupportedNotificationTypes,
4810
5282
  SupportedOccurrenceStatuses,
4811
5283
  SupportedPaddleEnvironments,
@@ -4815,11 +5287,19 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4815
5287
  SupportedPlanKinds,
4816
5288
  SupportedPlanStatuses,
4817
5289
  SupportedPostStatuses,
5290
+ SupportedPrefilterRules,
4818
5291
  SupportedProficiencyLevels,
5292
+ SupportedProposalFilters,
5293
+ SupportedProposalKinds,
5294
+ SupportedProposalMessageRoles,
5295
+ SupportedProposalStatuses,
4819
5296
  SupportedQuestionTypes,
4820
5297
  SupportedQuotaPeriods,
4821
5298
  SupportedReferralSources,
5299
+ SupportedReleaseKinds,
5300
+ SupportedReleaseStatuses,
4822
5301
  SupportedReportReasons,
5302
+ SupportedResolverVerdicts,
4823
5303
  SupportedResourceTypes,
4824
5304
  SupportedSalaryCurrencies,
4825
5305
  SupportedSavedSearchStatuses,
@@ -4827,19 +5307,31 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4827
5307
  SupportedSocialAccounts,
4828
5308
  SupportedStudyTypes,
4829
5309
  SupportedSubscriptionStatuses,
5310
+ SupportedTaxonomyJobKinds,
5311
+ SupportedTaxonomyJobStates,
5312
+ SupportedTaxonomyNodeKinds,
5313
+ SupportedTaxonomySources,
4830
5314
  SupportedTemplateVariableBindingKinds,
4831
5315
  SupportedTransactionStatuses,
5316
+ SupportedUnmatchedReasons,
5317
+ SupportedUnmatchedResolutions,
4832
5318
  SupportedUserProfileVisibilities,
4833
5319
  SupportedUserRoles,
4834
5320
  SupportedUserStatuses,
4835
5321
  SupportedWorkModes,
4836
5322
  TAXONOMY_LABELS,
5323
+ TAXONOMY_NODE_ID_PATTERN,
5324
+ TaxonomyNodeFilterSchema,
5325
+ TaxonomyNodeSchema,
5326
+ TaxonomyScheduleSchema,
4837
5327
  TemplateVariableBindingKind,
4838
5328
  TemplateVariableBindingSchema,
4839
5329
  TerminalCampaignStatuses,
4840
5330
  TerminalGeoSyncStatuses,
4841
5331
  TermsAcceptedSchema,
4842
5332
  TransactionStatus,
5333
+ UnmatchedFilterSchema,
5334
+ UnmatchedTermSchema,
4843
5335
  UserAdditionalInfoSchema,
4844
5336
  UserCertificationSchema,
4845
5337
  UserCompletenessSchema,
@@ -4858,6 +5350,9 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4858
5350
  UserSchema,
4859
5351
  UserSkillSchema,
4860
5352
  UserStatus,
5353
+ VOCABULARY_ID_PATTERN,
5354
+ VocabularySchema,
5355
+ VocabularyTypeSchema,
4861
5356
  WorkExperienceSchema,
4862
5357
  WorkMode,
4863
5358
  canTransitionCampaign,