@thejob/schema 2.0.3 → 2.0.5

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
@@ -71,6 +71,8 @@ __export(index_exports, {
71
71
  PageStatus: () => PageStatus,
72
72
  PageType: () => PageType,
73
73
  PaginationSchema: () => PaginationSchema,
74
+ PostSchema: () => PostSchema,
75
+ PostStatus: () => PostStatus,
74
76
  ProficiencyLevel: () => ProficiencyLevel,
75
77
  QuestionSchema: () => QuestionSchema,
76
78
  QuestionType: () => QuestionType,
@@ -99,6 +101,7 @@ __export(index_exports, {
99
101
  SupportedJobStatuses: () => SupportedJobStatuses,
100
102
  SupportedPageStatuses: () => SupportedPageStatuses,
101
103
  SupportedPageTypes: () => SupportedPageTypes,
104
+ SupportedPostStatuses: () => SupportedPostStatuses,
102
105
  SupportedProficiencyLevels: () => SupportedProficiencyLevels,
103
106
  SupportedQuestionTypes: () => SupportedQuestionTypes,
104
107
  SupportedReferralSources: () => SupportedReferralSources,
@@ -783,6 +786,13 @@ var JobSchema = (0, import_yup18.object)({
783
786
  * re-check cadence so the same job is not re-crawled on every sweep.
784
787
  */
785
788
  lastExpiryCheckAt: (0, import_yup18.number)().optional().nullable().label("Last expiry check at"),
789
+ /**
790
+ * When this job transitioned to `status: closed` (epoch ms). Server-owned
791
+ * operational field: stamped by every jobs-service close path (expiry
792
+ * auto-close and the dated lapse sweep). Distinct from `updatedAt` so a later
793
+ * edit to a closed job does not move it.
794
+ */
795
+ closedAt: (0, import_yup18.number)().optional().nullable().label("Closed at"),
786
796
  experienceLevel: (0, import_yup18.string)().oneOf(SupportedExperienceLevels).nullable().optional().label("Experience level"),
787
797
  contactEmail: (0, import_yup18.string)().email().nullable().optional().label("Contact email"),
788
798
  workingHoursPerWeek: (0, import_yup18.number)().nullable().optional().min(1).max(24 * 7).label("Working hours per week"),
@@ -812,6 +822,20 @@ var JobSchema = (0, import_yup18.object)({
812
822
  keywords: (0, import_yup18.array)().of((0, import_yup18.string)()).optional().label("Keywords")
813
823
  }).nullable().optional().label("SEO Tags"),
814
824
  jdSummary: (0, import_yup18.string)().optional().label("JD Summary"),
825
+ /**
826
+ * Structured, model-extracted sections of the posting, re-organized into clean
827
+ * bullet points. This is our OWN unique presentation of the job (rendered as the
828
+ * primary, server-side page content) so the page adds value over the raw scraped
829
+ * description and is not penalized by Google as duplicate content. All sections
830
+ * optional: absent on jobs not yet (re-)enriched, and any section is `[]`/omitted
831
+ * when the posting genuinely has none.
832
+ */
833
+ jobHighlights: (0, import_yup18.object)({
834
+ responsibilities: (0, import_yup18.array)().of((0, import_yup18.string)()).optional().label("Responsibilities"),
835
+ requirements: (0, import_yup18.array)().of((0, import_yup18.string)()).optional().label("Requirements"),
836
+ benefits: (0, import_yup18.array)().of((0, import_yup18.string)()).optional().label("Benefits"),
837
+ qualifications: (0, import_yup18.array)().of((0, import_yup18.string)()).optional().label("Qualifications")
838
+ }).nullable().optional().label("Job Highlights"),
815
839
  canCreateAlert: (0, import_yup18.boolean)().optional().label("Can create alert"),
816
840
  canDirectApply: (0, import_yup18.boolean)().optional().label("Can direct apply"),
817
841
  hasApplied: (0, import_yup18.boolean)().optional().label("Has applied"),
@@ -837,15 +861,65 @@ var JobSchema = (0, import_yup18.object)({
837
861
  featuredMarkets: (0, import_yup18.array)().of((0, import_yup18.string)().required()).optional().default([]).label("Featured markets")
838
862
  }).concat(DbDefaultSchema).noUnknown().label("Job");
839
863
 
840
- // src/pagination/pagination.schema.ts
864
+ // src/post/post.schema.ts
841
865
  var import_yup19 = require("yup");
842
- var PaginationSchema = (0, import_yup19.object)().shape({
843
- page: (0, import_yup19.number)().required().min(1).label("Page").default(1),
844
- limit: (0, import_yup19.number)().required().min(1).max(100).label("Limit").default(10),
845
- sortBy: (0, import_yup19.string)().notOneOf([""]).optional().label("SortBy"),
846
- nextPage: (0, import_yup19.string)().optional().label("Next Page Token"),
847
- prevPage: (0, import_yup19.string)().optional().label("Previous Page Token"),
848
- sortDirection: (0, import_yup19.string)().oneOf(["asc", "desc"]).optional().label("Sort Direction")
866
+
867
+ // src/post/post.constant.ts
868
+ var PostStatus = /* @__PURE__ */ ((PostStatus2) => {
869
+ PostStatus2["Draft"] = "draft";
870
+ PostStatus2["Published"] = "published";
871
+ PostStatus2["Archived"] = "archived";
872
+ return PostStatus2;
873
+ })(PostStatus || {});
874
+ var SupportedPostStatuses = Object.values(PostStatus);
875
+
876
+ // src/post/post.schema.ts
877
+ var PostSchema = (0, import_yup19.object)({
878
+ /** Headline shown in listings and at the top of the post. */
879
+ title: (0, import_yup19.string)().required().min(5).max(200).label("Title"),
880
+ /** User-friendly, unique URL identifier. */
881
+ slug: (0, import_yup19.string)().required().max(250).label("Slug"),
882
+ /** Short summary used in listings and meta description fallback. */
883
+ excerpt: (0, import_yup19.string)().max(500).optional().label("Excerpt"),
884
+ /** Rendered HTML source of truth for the post body (sanitized on write/render).
885
+ * Supports rich formatting markdown can't express (image size/alignment, etc). */
886
+ bodyHTML: (0, import_yup19.string)().required().min(1).label("Body (HTML)"),
887
+ /** Optional Markdown mirror of the body (portable text / search fallback).
888
+ * Kept for back-compat and plain-text derivation; bodyHTML is authoritative. */
889
+ bodyMarkdown: (0, import_yup19.string)().optional().label("Body (Markdown)"),
890
+ /** Cover/hero image URL. Not `.url()`-validated: the value is either an
891
+ * uploaded file URL served by this platform (which may be a bare host like
892
+ * `http://localhost:3082/...` in dev, that yup's `.url()` wrongly rejects) or
893
+ * an admin-pasted link. Kept as a plain string; empty ⇒ null. */
894
+ coverImage: (0, import_yup19.string)().nullable().optional().label("Cover image"),
895
+ /** Author (user id). */
896
+ authorId: (0, import_yup19.string)().required().label("Author ID"),
897
+ /** Free-form tags for filtering and related-posts. */
898
+ tags: (0, import_yup19.array)().of((0, import_yup19.string)().trim().required()).default([]).label("Tags"),
899
+ /** Estimated reading time in minutes (server-derived from body length). */
900
+ readingTimeMinutes: (0, import_yup19.number)().min(0).optional().label("Reading time (minutes)"),
901
+ /** SEO overrides. */
902
+ seoTags: (0, import_yup19.object)({
903
+ description: (0, import_yup19.string)().optional().label("Description"),
904
+ keywords: (0, import_yup19.array)().of((0, import_yup19.string)().required()).optional().label("Keywords")
905
+ }).nullable().optional().label("SEO Tags"),
906
+ /** When the post was first published (epoch ms). Server-owned. */
907
+ publishedAt: (0, import_yup19.number)().nullable().optional().label("Published at"),
908
+ /** Whether the post is featured in the blog listing. */
909
+ isFeatured: (0, import_yup19.boolean)().default(false).optional().label("Is featured"),
910
+ /** Publication state. */
911
+ status: (0, import_yup19.string)().oneOf(SupportedPostStatuses).default("draft" /* Draft */).required().label("Status")
912
+ }).concat(DbDefaultSchema).noUnknown().label("Post");
913
+
914
+ // src/pagination/pagination.schema.ts
915
+ var import_yup20 = require("yup");
916
+ var PaginationSchema = (0, import_yup20.object)().shape({
917
+ page: (0, import_yup20.number)().required().min(1).label("Page").default(1),
918
+ limit: (0, import_yup20.number)().required().min(1).max(100).label("Limit").default(10),
919
+ sortBy: (0, import_yup20.string)().notOneOf([""]).optional().label("SortBy"),
920
+ nextPage: (0, import_yup20.string)().optional().label("Next Page Token"),
921
+ prevPage: (0, import_yup20.string)().optional().label("Previous Page Token"),
922
+ sortDirection: (0, import_yup20.string)().oneOf(["asc", "desc"]).optional().label("Sort Direction")
849
923
  });
850
924
 
851
925
  // src/pagination/pagination.constant.ts
@@ -861,7 +935,7 @@ var DefaultPaginationOptions = {
861
935
  };
862
936
 
863
937
  // src/report/report.schema.ts
864
- var import_yup20 = require("yup");
938
+ var import_yup21 = require("yup");
865
939
 
866
940
  // src/report/report.constant.ts
867
941
  var ResourceType = /* @__PURE__ */ ((ResourceType3) => {
@@ -885,15 +959,15 @@ var ReportReason = /* @__PURE__ */ ((ReportReason3) => {
885
959
  var SupportedReportReasons = Object.values(ReportReason);
886
960
 
887
961
  // src/report/report.schema.ts
888
- var ReportSchema = (0, import_yup20.object)({
889
- type: (0, import_yup20.mixed)().oneOf(SupportedResourceTypes).required().label("Type"),
890
- resourceId: (0, import_yup20.string)().required().label("Resource ID"),
891
- reason: (0, import_yup20.mixed)().oneOf(SupportedReportReasons).required("Please choose a reason").label("Reason"),
892
- comment: (0, import_yup20.string)().max(1e3).optional().label("Comment")
962
+ var ReportSchema = (0, import_yup21.object)({
963
+ type: (0, import_yup21.mixed)().oneOf(SupportedResourceTypes).required().label("Type"),
964
+ resourceId: (0, import_yup21.string)().required().label("Resource ID"),
965
+ reason: (0, import_yup21.mixed)().oneOf(SupportedReportReasons).required("Please choose a reason").label("Reason"),
966
+ comment: (0, import_yup21.string)().max(1e3).optional().label("Comment")
893
967
  }).label("Report Schema");
894
968
 
895
969
  // src/user/user.schema.ts
896
- var import_yup33 = require("yup");
970
+ var import_yup34 = require("yup");
897
971
 
898
972
  // src/user/user.constant.ts
899
973
  var UserRole = /* @__PURE__ */ ((UserRole2) => {
@@ -975,51 +1049,51 @@ var MIN_SALARY_LOWER_BOUND = 0;
975
1049
  var MIN_SALARY_UPPER_BOUND = 1e6;
976
1050
 
977
1051
  // src/user/work-experience.schema.ts
978
- var import_yup21 = require("yup");
979
- var WorkExperienceSchema = (0, import_yup21.object)().shape({
1052
+ var import_yup22 = require("yup");
1053
+ var WorkExperienceSchema = (0, import_yup22.object)().shape({
980
1054
  company: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company"),
981
- designation: (0, import_yup21.string)().trim().required().label("Designation"),
1055
+ designation: (0, import_yup22.string)().trim().required().label("Designation"),
982
1056
  duration: DurationSchema({
983
1057
  format: "YYYY-MM",
984
1058
  startLabel: "Start Date",
985
1059
  endLabel: "End Date"
986
1060
  }).required().label("Duration"),
987
- description: (0, import_yup21.string)().trim().max(3e3).optional().label("Description"),
1061
+ description: (0, import_yup22.string)().trim().max(3e3).optional().label("Description"),
988
1062
  location: LocationSchema.required().label("Location"),
989
- isRemote: (0, import_yup21.boolean)().oneOf([true, false]).default(false).label("Is Remote")
1063
+ isRemote: (0, import_yup22.boolean)().oneOf([true, false]).default(false).label("Is Remote")
990
1064
  }).noUnknown().strict().label("Work Experience");
991
1065
 
992
1066
  // src/user/education.schema.ts
993
- var import_yup22 = require("yup");
994
- var EducationSchema = (0, import_yup22.object)({
1067
+ var import_yup23 = require("yup");
1068
+ var EducationSchema = (0, import_yup23.object)({
995
1069
  institute: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute"),
996
- course: (0, import_yup22.string)().trim().required().label("Course"),
997
- fieldOfStudy: (0, import_yup22.string)().trim().required().label("Field of Study"),
1070
+ course: (0, import_yup23.string)().trim().required().label("Course"),
1071
+ fieldOfStudy: (0, import_yup23.string)().trim().required().label("Field of Study"),
998
1072
  duration: DurationSchema({
999
1073
  format: "YYYY-MM",
1000
1074
  startLabel: "Start Date",
1001
1075
  endLabel: "End Date"
1002
1076
  }).required().label("Duration"),
1003
- description: (0, import_yup22.string)().trim().max(3e3).optional().label("Description"),
1004
- isDistanceLearning: (0, import_yup22.boolean)().default(false).label("Is Distance Learning"),
1077
+ description: (0, import_yup23.string)().trim().max(3e3).optional().label("Description"),
1078
+ isDistanceLearning: (0, import_yup23.boolean)().default(false).label("Is Distance Learning"),
1005
1079
  location: LocationSchema.required().label("Location"),
1006
- studyType: (0, import_yup22.string)().oneOf(SupportedStudyTypes).trim().max(50).required().label("Study Type")
1080
+ studyType: (0, import_yup23.string)().oneOf(SupportedStudyTypes).trim().max(50).required().label("Study Type")
1007
1081
  }).noUnknown().strict().label("Education");
1008
1082
 
1009
1083
  // src/user/user-skill.schema.ts
1010
- var import_yup23 = require("yup");
1011
- var UserSkillSchema = (0, import_yup23.object)({
1012
- name: (0, import_yup23.string)().required().label("Name"),
1013
- proficiencyLevel: (0, import_yup23.string)().oneOf(SupportedProficiencyLevels).required().label("Proficiency Level"),
1084
+ var import_yup24 = require("yup");
1085
+ var UserSkillSchema = (0, import_yup24.object)({
1086
+ name: (0, import_yup24.string)().required().label("Name"),
1087
+ proficiencyLevel: (0, import_yup24.string)().oneOf(SupportedProficiencyLevels).required().label("Proficiency Level"),
1014
1088
  lastUsed: dateString().format("YYYY-MM").nullable().optional().label("Last Used")
1015
1089
  }).noUnknown().strict().label("Skill");
1016
1090
 
1017
1091
  // src/user/project.schema.ts
1018
- var import_yup24 = require("yup");
1019
- var UserProjectSchema = (0, import_yup24.object)({
1020
- name: (0, import_yup24.string)().trim().max(50).required().label("Name"),
1021
- url: (0, import_yup24.string)().optional().label("URL"),
1022
- description: (0, import_yup24.string)().trim().min(100).max(3e3).required().label("Description"),
1092
+ var import_yup25 = require("yup");
1093
+ var UserProjectSchema = (0, import_yup25.object)({
1094
+ name: (0, import_yup25.string)().trim().max(50).required().label("Name"),
1095
+ url: (0, import_yup25.string)().optional().label("URL"),
1096
+ description: (0, import_yup25.string)().trim().min(100).max(3e3).required().label("Description"),
1023
1097
  duration: DurationSchema({
1024
1098
  format: "YYYY-MM",
1025
1099
  startLabel: "Start Date",
@@ -1028,83 +1102,83 @@ var UserProjectSchema = (0, import_yup24.object)({
1028
1102
  }).noUnknown().strict().label("Project");
1029
1103
 
1030
1104
  // src/user/user-certification.schema.ts
1031
- var import_yup25 = require("yup");
1032
- var UserCertificationSchema = (0, import_yup25.object)({
1033
- name: (0, import_yup25.string)().trim().max(100).required().label("Name"),
1105
+ var import_yup26 = require("yup");
1106
+ var UserCertificationSchema = (0, import_yup26.object)({
1107
+ name: (0, import_yup26.string)().trim().max(100).required().label("Name"),
1034
1108
  // TODO: Add validation for authority
1035
- authority: (0, import_yup25.string)().trim().max(100).required().label("Authority"),
1036
- licenseNumber: (0, import_yup25.string)().trim().max(50).optional().label("License Number"),
1109
+ authority: (0, import_yup26.string)().trim().max(100).required().label("Authority"),
1110
+ licenseNumber: (0, import_yup26.string)().trim().max(50).optional().label("License Number"),
1037
1111
  duration: DurationSchema({
1038
1112
  format: "YYYY-MM",
1039
1113
  startLabel: "Start Date",
1040
1114
  endLabel: "End Date"
1041
1115
  }).optional().nullable().label("Duration"),
1042
- url: (0, import_yup25.string)().optional().label("URL")
1116
+ url: (0, import_yup26.string)().optional().label("URL")
1043
1117
  }).noUnknown().strict().label("Certification");
1044
1118
 
1045
1119
  // src/user/user-interest.schema.ts
1046
- var import_yup26 = require("yup");
1047
- var UserInterestSchema = (0, import_yup26.string)().trim().required().label("Interest");
1120
+ var import_yup27 = require("yup");
1121
+ var UserInterestSchema = (0, import_yup27.string)().trim().required().label("Interest");
1048
1122
 
1049
1123
  // src/user/user-language.schema.ts
1050
- var import_yup27 = require("yup");
1051
- var UserLanguageSchema = (0, import_yup27.object)({
1052
- name: (0, import_yup27.string)().trim().required().label("Name"),
1053
- proficiencyLevel: (0, import_yup27.string)().oneOf(SupportedProficiencyLevels).trim().max(50).required().label("Proficiency Level")
1124
+ var import_yup28 = require("yup");
1125
+ var UserLanguageSchema = (0, import_yup28.object)({
1126
+ name: (0, import_yup28.string)().trim().required().label("Name"),
1127
+ proficiencyLevel: (0, import_yup28.string)().oneOf(SupportedProficiencyLevels).trim().max(50).required().label("Proficiency Level")
1054
1128
  }).noUnknown().strict().label("Language");
1055
1129
 
1056
1130
  // src/user/user-additional-info.schema.ts
1057
- var import_yup28 = require("yup");
1058
- var UserAdditionalInfoSchema = (0, import_yup28.object)({
1059
- title: (0, import_yup28.string)().trim().max(60).required().label("Title"),
1060
- description: (0, import_yup28.string)().trim().max(1e3).required().label("Description")
1131
+ var import_yup29 = require("yup");
1132
+ var UserAdditionalInfoSchema = (0, import_yup29.object)({
1133
+ title: (0, import_yup29.string)().trim().max(60).required().label("Title"),
1134
+ description: (0, import_yup29.string)().trim().max(1e3).required().label("Description")
1061
1135
  }).noUnknown().strict().label("User Additional Info");
1062
1136
 
1063
1137
  // src/user/general-detail.schema.ts
1064
- var import_yup29 = require("yup");
1065
- var UserGeneralDetailSchema = (0, import_yup29.object)({
1066
- id: (0, import_yup29.string)().optional().label("ID"),
1067
- name: (0, import_yup29.object)().shape({
1068
- first: (0, import_yup29.string)().trim().max(50).required().label("First Name"),
1069
- last: (0, import_yup29.string)().trim().max(50).optional().label("Last Name")
1138
+ var import_yup30 = require("yup");
1139
+ var UserGeneralDetailSchema = (0, import_yup30.object)({
1140
+ id: (0, import_yup30.string)().optional().label("ID"),
1141
+ name: (0, import_yup30.object)().shape({
1142
+ first: (0, import_yup30.string)().trim().max(50).required().label("First Name"),
1143
+ last: (0, import_yup30.string)().trim().max(50).optional().label("Last Name")
1070
1144
  }).required().label("Name"),
1071
- headline: (0, import_yup29.string)().trim().max(200).optional().label("Headline"),
1072
- image: (0, import_yup29.string)().optional().label("Image"),
1073
- aboutMe: (0, import_yup29.string)().trim().max(3e3).optional().label("About Me"),
1074
- email: (0, import_yup29.string)().required().label("Email"),
1075
- mobile: (0, import_yup29.string)().nullable().optional().label("Mobile"),
1076
- emailVerified: (0, import_yup29.string)().nullable().optional().label("Email Verified"),
1077
- mobileVerified: (0, import_yup29.string)().nullable().optional().label("Mobile Verified"),
1078
- experienceLevel: (0, import_yup29.string)().oneOf(SupportedExperienceLevels).required().label("Experience level"),
1145
+ headline: (0, import_yup30.string)().trim().max(200).optional().label("Headline"),
1146
+ image: (0, import_yup30.string)().optional().label("Image"),
1147
+ aboutMe: (0, import_yup30.string)().trim().max(3e3).optional().label("About Me"),
1148
+ email: (0, import_yup30.string)().required().label("Email"),
1149
+ mobile: (0, import_yup30.string)().nullable().optional().label("Mobile"),
1150
+ emailVerified: (0, import_yup30.string)().nullable().optional().label("Email Verified"),
1151
+ mobileVerified: (0, import_yup30.string)().nullable().optional().label("Mobile Verified"),
1152
+ experienceLevel: (0, import_yup30.string)().oneOf(SupportedExperienceLevels).required().label("Experience level"),
1079
1153
  location: LocationSchema.required().label("Location"),
1080
- region: (0, import_yup29.object)().shape({
1081
- country: (0, import_yup29.string)().trim().required().label("Region Country"),
1082
- lang: (0, import_yup29.string)().trim().required().label("Region Language")
1154
+ region: (0, import_yup30.object)().shape({
1155
+ country: (0, import_yup30.string)().trim().required().label("Region Country"),
1156
+ lang: (0, import_yup30.string)().trim().required().label("Region Language")
1083
1157
  }).optional().default(void 0).label("Region"),
1084
- profileVisibility: (0, import_yup29.string)().oneOf(SupportedUserProfileVisibilities).default("public" /* Public */).label("Profile Visibility")
1158
+ profileVisibility: (0, import_yup30.string)().oneOf(SupportedUserProfileVisibilities).default("public" /* Public */).label("Profile Visibility")
1085
1159
  }).noUnknown().strict().label("General Detail");
1086
1160
 
1087
1161
  // src/user/user-job-preferences.schema.ts
1088
- var import_yup30 = require("yup");
1089
- var UserJobPreferencesSchema = (0, import_yup30.object)({
1162
+ var import_yup31 = require("yup");
1163
+ var UserJobPreferencesSchema = (0, import_yup31.object)({
1090
1164
  /**
1091
1165
  * Whether the job seeker is openly signalling availability. Surfaces the
1092
1166
  * "Open to work" badge on the public profile and boosts visibility in
1093
1167
  * recruiter search. Defaults to `false` - users must opt in.
1094
1168
  */
1095
- openToWork: (0, import_yup30.boolean)().default(false).label("Open to Work"),
1169
+ openToWork: (0, import_yup31.boolean)().default(false).label("Open to Work"),
1096
1170
  /**
1097
1171
  * How urgently the user is looking for their next job. Drives match scoring
1098
1172
  * and can downgrade the visibility of expired or low-relevance postings for
1099
1173
  * users in `passively_browsing` mode.
1100
1174
  */
1101
- jobSearchUrgency: (0, import_yup30.string)().oneOf(SupportedJobSearchUrgencies).required().label("Job Search Urgency"),
1175
+ jobSearchUrgency: (0, import_yup31.string)().oneOf(SupportedJobSearchUrgencies).required().label("Job Search Urgency"),
1102
1176
  /**
1103
1177
  * Locations the user wants to work in. Stores the full `LocationSchema`
1104
1178
  * shape (country, city, state, geo, etc.) as returned by the locations
1105
1179
  * autocomplete API.
1106
1180
  */
1107
- jobLocations: (0, import_yup30.array)().of(LocationSchema.required().label("Job Location")).min(1, "Pick at least one preferred location.").required().label("Job Locations"),
1181
+ jobLocations: (0, import_yup31.array)().of(LocationSchema.required().label("Job Location")).min(1, "Pick at least one preferred location.").required().label("Job Locations"),
1108
1182
  /**
1109
1183
  * Seniority levels the user wants jobs to be matched against. Multi-select
1110
1184
  * (up to 2) for borderline candidates.
@@ -1115,7 +1189,7 @@ var UserJobPreferencesSchema = (0, import_yup30.object)({
1115
1189
  * Both reuse the same `ExperienceLevel` taxonomy from `common.constant.ts`
1116
1190
  * so search/match logic doesn't have to translate between two vocabularies.
1117
1191
  */
1118
- targetExperienceLevels: (0, import_yup30.array)().of((0, import_yup30.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"),
1192
+ targetExperienceLevels: (0, import_yup31.array)().of((0, import_yup31.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"),
1119
1193
  /**
1120
1194
  * Specializations the user is searching for - free-form titles.
1121
1195
  *
@@ -1124,19 +1198,19 @@ var UserJobPreferencesSchema = (0, import_yup30.object)({
1124
1198
  * surfaces a curated "Popular Roles" picker for discovery, but the user
1125
1199
  * can ultimately add any title; matching/normalization happens downstream.
1126
1200
  */
1127
- jobRoles: (0, import_yup30.array)().of((0, import_yup30.string)().trim().max(120).required()).min(1, "Pick at least one role.").required().label("Job Roles"),
1201
+ jobRoles: (0, import_yup31.array)().of((0, import_yup31.string)().trim().max(120).required()).min(1, "Pick at least one role.").required().label("Job Roles"),
1128
1202
  /**
1129
1203
  * Minimum acceptable annual base salary, in `minSalaryCurrency`.
1130
1204
  * Stored as an integer in the currency's major unit (e.g. dollars, not cents).
1131
1205
  * Defaults to 0 ("any salary") rather than being optional - every job-seeker
1132
1206
  * has a floor, even if it's zero.
1133
1207
  */
1134
- minSalary: (0, import_yup30.number)().integer().min(MIN_SALARY_LOWER_BOUND).max(MIN_SALARY_UPPER_BOUND).default(0).required().label("Minimum Salary"),
1135
- minSalaryCurrency: (0, import_yup30.string)().oneOf(SupportedSalaryCurrencies).default("USD").required().label("Minimum Salary Currency"),
1208
+ minSalary: (0, import_yup31.number)().integer().min(MIN_SALARY_LOWER_BOUND).max(MIN_SALARY_UPPER_BOUND).default(0).required().label("Minimum Salary"),
1209
+ minSalaryCurrency: (0, import_yup31.string)().oneOf(SupportedSalaryCurrencies).default("USD").required().label("Minimum Salary Currency"),
1136
1210
  /**
1137
1211
  * Marketing-attribution capture from the final onboarding step.
1138
1212
  */
1139
- referralSource: (0, import_yup30.string)().oneOf(SupportedReferralSources).required().label("Referral Source"),
1213
+ referralSource: (0, import_yup31.string)().oneOf(SupportedReferralSources).required().label("Referral Source"),
1140
1214
  /**
1141
1215
  * Resumes the user has uploaded. Embedded directly on the user document
1142
1216
  * (capped at 5) - they're cheap to denormalize, every wizard step that
@@ -1150,25 +1224,25 @@ var UserJobPreferencesSchema = (0, import_yup30.object)({
1150
1224
  * AI resume-builder flow - onboarding uploads land here, AI-built resumes
1151
1225
  * live in their own collection.
1152
1226
  */
1153
- resumes: (0, import_yup30.array)().of(
1154
- (0, import_yup30.object)({
1227
+ resumes: (0, import_yup31.array)().of(
1228
+ (0, import_yup31.object)({
1155
1229
  // Stable id assigned on upload - used to address a specific entry
1156
1230
  // for delete / set-primary operations without exposing the GCS URL
1157
1231
  // as a route key.
1158
- id: (0, import_yup30.string)().required().label("ID"),
1159
- url: (0, import_yup30.string)().required().label("Resume URL"),
1160
- filename: (0, import_yup30.string)().trim().max(255).optional().label("Filename"),
1161
- sizeBytes: (0, import_yup30.number)().integer().min(0).optional().label("Size (bytes)"),
1162
- mimeType: (0, import_yup30.string)().trim().max(120).optional().label("MIME Type"),
1163
- uploadedAt: (0, import_yup30.date)().required().label("Uploaded At"),
1164
- isPrimary: (0, import_yup30.boolean)().default(false).label("Is Primary")
1232
+ id: (0, import_yup31.string)().required().label("ID"),
1233
+ url: (0, import_yup31.string)().required().label("Resume URL"),
1234
+ filename: (0, import_yup31.string)().trim().max(255).optional().label("Filename"),
1235
+ sizeBytes: (0, import_yup31.number)().integer().min(0).optional().label("Size (bytes)"),
1236
+ mimeType: (0, import_yup31.string)().trim().max(120).optional().label("MIME Type"),
1237
+ uploadedAt: (0, import_yup31.date)().required().label("Uploaded At"),
1238
+ isPrimary: (0, import_yup31.boolean)().default(false).label("Is Primary")
1165
1239
  }).noUnknown().strict().label("Resume")
1166
1240
  ).max(5, "You can keep at most 5 resumes on file.").default([]).label("Resumes"),
1167
1241
  /**
1168
1242
  * Set when the user finishes the wizard's last step. Acts as the gate the
1169
1243
  * onboarding hook checks to redirect users who haven't completed setup.
1170
1244
  */
1171
- onboardingCompletedAt: (0, import_yup30.date)().nullable().optional().label("Onboarding Completed At"),
1245
+ onboardingCompletedAt: (0, import_yup31.date)().nullable().optional().label("Onboarding Completed At"),
1172
1246
  /**
1173
1247
  * Parser-suggested values for wizard fields, written by the resume-upload
1174
1248
  * flow. Every parser-derived field lands here - including profile-shaped
@@ -1188,106 +1262,106 @@ var UserJobPreferencesSchema = (0, import_yup30.object)({
1188
1262
  * APIs. If `user.<field>` is empty there, the correct behavior is empty,
1189
1263
  * because the user has not confirmed it yet.
1190
1264
  */
1191
- pendingPrefill: (0, import_yup30.object)({
1192
- headline: (0, import_yup30.string)().trim().optional().label("Pending Headline"),
1193
- aboutMe: (0, import_yup30.string)().trim().optional().label("Pending About Me"),
1194
- mobile: (0, import_yup30.string)().trim().optional().label("Pending Mobile"),
1265
+ pendingPrefill: (0, import_yup31.object)({
1266
+ headline: (0, import_yup31.string)().trim().optional().label("Pending Headline"),
1267
+ aboutMe: (0, import_yup31.string)().trim().optional().label("Pending About Me"),
1268
+ mobile: (0, import_yup31.string)().trim().optional().label("Pending Mobile"),
1195
1269
  location: LocationSchema.optional().default(void 0).label("Pending Location"),
1196
- experienceLevel: (0, import_yup30.string)().oneOf(SupportedExperienceLevels).optional().label("Pending Experience Level"),
1197
- socialAccounts: (0, import_yup30.array)().of(SocialAccountSchema.required()).optional().label("Pending Social Accounts"),
1198
- workExperiences: (0, import_yup30.array)().of(WorkExperienceSchema.required()).optional().label("Pending Work Experiences"),
1199
- educations: (0, import_yup30.array)().of(EducationSchema.required()).optional().label("Pending Educations")
1270
+ experienceLevel: (0, import_yup31.string)().oneOf(SupportedExperienceLevels).optional().label("Pending Experience Level"),
1271
+ socialAccounts: (0, import_yup31.array)().of(SocialAccountSchema.required()).optional().label("Pending Social Accounts"),
1272
+ workExperiences: (0, import_yup31.array)().of(WorkExperienceSchema.required()).optional().label("Pending Work Experiences"),
1273
+ educations: (0, import_yup31.array)().of(EducationSchema.required()).optional().label("Pending Educations")
1200
1274
  }).nullable().optional().default(void 0).label("Pending Prefill")
1201
1275
  }).noUnknown().strict().label("User Job Preferences Schema");
1202
1276
 
1203
1277
  // src/user/user-recruiter-profile.schema.ts
1204
- var import_yup31 = require("yup");
1205
- var RecruiterPageLinkSchema = (0, import_yup31.object)({
1278
+ var import_yup32 = require("yup");
1279
+ var RecruiterPageLinkSchema = (0, import_yup32.object)({
1206
1280
  page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company Page"),
1207
- jobTitle: (0, import_yup31.string)().trim().max(100).optional().label("Job Title")
1281
+ jobTitle: (0, import_yup32.string)().trim().max(100).optional().label("Job Title")
1208
1282
  }).noUnknown().strict().label("Recruiter Page Link");
1209
- var UserRecruiterProfileSchema = (0, import_yup31.object)({
1210
- recruiterProfile: (0, import_yup31.object)({
1211
- hiringFor: (0, import_yup31.array)().of(RecruiterPageLinkSchema).default([]).label("Hiring For")
1283
+ var UserRecruiterProfileSchema = (0, import_yup32.object)({
1284
+ recruiterProfile: (0, import_yup32.object)({
1285
+ hiringFor: (0, import_yup32.array)().of(RecruiterPageLinkSchema).default([]).label("Hiring For")
1212
1286
  }).optional().default(void 0).label("Recruiter Profile")
1213
1287
  }).noUnknown().strict().label("User Recruiter Profile");
1214
1288
 
1215
1289
  // src/user/user-coordinator-profile.schema.ts
1216
- var import_yup32 = require("yup");
1217
- var CoordinatorPageLinkSchema = (0, import_yup32.object)({
1290
+ var import_yup33 = require("yup");
1291
+ var CoordinatorPageLinkSchema = (0, import_yup33.object)({
1218
1292
  page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute Page"),
1219
- jobTitle: (0, import_yup32.string)().trim().max(100).optional().label("Job Title")
1293
+ jobTitle: (0, import_yup33.string)().trim().max(100).optional().label("Job Title")
1220
1294
  }).noUnknown().strict().label("Coordinator Page Link");
1221
- var UserCoordinatorProfileSchema = (0, import_yup32.object)({
1222
- coordinatorProfile: (0, import_yup32.object)({
1223
- coordinatesAt: (0, import_yup32.array)().of(CoordinatorPageLinkSchema).default([]).label("Coordinates At")
1295
+ var UserCoordinatorProfileSchema = (0, import_yup33.object)({
1296
+ coordinatorProfile: (0, import_yup33.object)({
1297
+ coordinatesAt: (0, import_yup33.array)().of(CoordinatorPageLinkSchema).default([]).label("Coordinates At")
1224
1298
  }).optional().default(void 0).label("Coordinator Profile")
1225
1299
  }).noUnknown().strict().label("User Coordinator Profile");
1226
1300
 
1227
1301
  // src/user/user.schema.ts
1228
- var UserSchema = (0, import_yup33.object)({
1302
+ var UserSchema = (0, import_yup34.object)({
1229
1303
  /**
1230
1304
  * Related auth account id from auth Server (e.g. Better auth https://auth.thejob.dev)
1231
1305
  */
1232
- authAccountId: (0, import_yup33.string)().required().label("Auth Account ID"),
1306
+ authAccountId: (0, import_yup34.string)().required().label("Auth Account ID"),
1233
1307
  /**
1234
1308
  * Social media information about the user (e.g. LinkedIn, GitHub, etc.)
1235
1309
  */
1236
- socialAccounts: (0, import_yup33.array)().of(SocialAccountSchema).default([]).label("Social Accounts"),
1310
+ socialAccounts: (0, import_yup34.array)().of(SocialAccountSchema).default([]).label("Social Accounts"),
1237
1311
  /**
1238
1312
  * Work experience information about the user
1239
1313
  */
1240
- workExperiences: (0, import_yup33.array)().of(WorkExperienceSchema).required().default([]).label("Work Experiences"),
1314
+ workExperiences: (0, import_yup34.array)().of(WorkExperienceSchema).required().default([]).label("Work Experiences"),
1241
1315
  /**
1242
1316
  * Education information about the user
1243
1317
  */
1244
- educations: (0, import_yup33.array)().of(EducationSchema).required().default([]).label("Educations"),
1318
+ educations: (0, import_yup34.array)().of(EducationSchema).required().default([]).label("Educations"),
1245
1319
  /**
1246
1320
  * Skills information about the user
1247
1321
  */
1248
- skills: (0, import_yup33.array)().of(UserSkillSchema).required().default([]).label("Skills"),
1322
+ skills: (0, import_yup34.array)().of(UserSkillSchema).required().default([]).label("Skills"),
1249
1323
  /**
1250
1324
  * Projects information about the user
1251
1325
  */
1252
- projects: (0, import_yup33.array)().of(UserProjectSchema).default([]).label("Projects"),
1326
+ projects: (0, import_yup34.array)().of(UserProjectSchema).default([]).label("Projects"),
1253
1327
  /**
1254
1328
  * Certifications information about the user
1255
1329
  */
1256
- certifications: (0, import_yup33.array)().of(UserCertificationSchema).default([]).label("Certifications"),
1330
+ certifications: (0, import_yup34.array)().of(UserCertificationSchema).default([]).label("Certifications"),
1257
1331
  /**
1258
1332
  * Interests information about the user.
1259
1333
  */
1260
- interests: (0, import_yup33.array)().of(UserInterestSchema).optional().default([]).label("Interests"),
1334
+ interests: (0, import_yup34.array)().of(UserInterestSchema).optional().default([]).label("Interests"),
1261
1335
  /**
1262
1336
  * Languages information about the user
1263
1337
  */
1264
- languages: (0, import_yup33.array)().of(UserLanguageSchema).required().default([]).label("Languages"),
1338
+ languages: (0, import_yup34.array)().of(UserLanguageSchema).required().default([]).label("Languages"),
1265
1339
  /**
1266
1340
  * Additional information about the user
1267
1341
  */
1268
- additionalInfo: (0, import_yup33.array)().of(UserAdditionalInfoSchema).default([]).label("Additional Information"),
1342
+ additionalInfo: (0, import_yup34.array)().of(UserAdditionalInfoSchema).default([]).label("Additional Information"),
1269
1343
  /**
1270
1344
  * Status of the user account
1271
1345
  */
1272
- status: (0, import_yup33.string)().oneOf(SupportedUserStatuses).required().label("Status"),
1346
+ status: (0, import_yup34.string)().oneOf(SupportedUserStatuses).required().label("Status"),
1273
1347
  /**
1274
1348
  * Roles assigned to the user
1275
1349
  */
1276
- roles: (0, import_yup33.array)().of((0, import_yup33.string)().oneOf(SupportedUserRoles)).required().default(DefaultUserRoles).label("Roles"),
1350
+ roles: (0, import_yup34.array)().of((0, import_yup34.string)().oneOf(SupportedUserRoles)).required().default(DefaultUserRoles).label("Roles"),
1277
1351
  /**
1278
1352
  * Vector embedding of the user's profile for semantic/hybrid search.
1279
1353
  * Generated from a structured summary of skills, experience, education, etc.
1280
1354
  * Only generated for public profiles with sufficient completeness (≥60%).
1281
1355
  */
1282
- embedding: (0, import_yup33.object)({
1283
- vector: (0, import_yup33.array)((0, import_yup33.number)().required()).optional().label("Embedding vector"),
1284
- model: (0, import_yup33.string)().optional().label("Embedding model")
1356
+ embedding: (0, import_yup34.object)({
1357
+ vector: (0, import_yup34.array)((0, import_yup34.number)().required()).optional().label("Embedding vector"),
1358
+ model: (0, import_yup34.string)().optional().label("Embedding model")
1285
1359
  }).nullable().optional().label("Embedding")
1286
1360
  }).concat(UserGeneralDetailSchema).concat(UserJobPreferencesSchema).concat(UserRecruiterProfileSchema).concat(UserCoordinatorProfileSchema).noUnknown().strict().label("User Schema");
1287
1361
 
1288
1362
  // src/user/user-completeness.schema.ts
1289
- var import_yup34 = require("yup");
1290
- var UserCompletenessSchema = (0, import_yup34.object)({
1363
+ var import_yup35 = require("yup");
1364
+ var UserCompletenessSchema = (0, import_yup35.object)({
1291
1365
  additionalInfo: CompletenessScoreSchema(0).label("Additional Info"),
1292
1366
  // Optional
1293
1367
  certifications: CompletenessScoreSchema(0).label("Certifications"),
@@ -1351,6 +1425,8 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
1351
1425
  PageStatus,
1352
1426
  PageType,
1353
1427
  PaginationSchema,
1428
+ PostSchema,
1429
+ PostStatus,
1354
1430
  ProficiencyLevel,
1355
1431
  QuestionSchema,
1356
1432
  QuestionType,
@@ -1379,6 +1455,7 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
1379
1455
  SupportedJobStatuses,
1380
1456
  SupportedPageStatuses,
1381
1457
  SupportedPageTypes,
1458
+ SupportedPostStatuses,
1382
1459
  SupportedProficiencyLevels,
1383
1460
  SupportedQuestionTypes,
1384
1461
  SupportedReferralSources,