@thejob/schema 2.0.4 → 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 +198 -128
- package/dist/index.d.cts +68 -1
- package/dist/index.d.ts +68 -1
- package/dist/index.js +191 -124
- package/package.json +1 -1
- package/src/index.ts +6 -0
- package/src/job/job.schema.ts +18 -0
- package/src/post/post.constant.ts +7 -0
- package/src/post/post.schema.ts +68 -0
package/dist/index.js
CHANGED
|
@@ -681,6 +681,20 @@ var JobSchema = object16({
|
|
|
681
681
|
keywords: array8().of(string13()).optional().label("Keywords")
|
|
682
682
|
}).nullable().optional().label("SEO Tags"),
|
|
683
683
|
jdSummary: string13().optional().label("JD Summary"),
|
|
684
|
+
/**
|
|
685
|
+
* Structured, model-extracted sections of the posting, re-organized into clean
|
|
686
|
+
* bullet points. This is our OWN unique presentation of the job (rendered as the
|
|
687
|
+
* primary, server-side page content) so the page adds value over the raw scraped
|
|
688
|
+
* description and is not penalized by Google as duplicate content. All sections
|
|
689
|
+
* optional: absent on jobs not yet (re-)enriched, and any section is `[]`/omitted
|
|
690
|
+
* when the posting genuinely has none.
|
|
691
|
+
*/
|
|
692
|
+
jobHighlights: object16({
|
|
693
|
+
responsibilities: array8().of(string13()).optional().label("Responsibilities"),
|
|
694
|
+
requirements: array8().of(string13()).optional().label("Requirements"),
|
|
695
|
+
benefits: array8().of(string13()).optional().label("Benefits"),
|
|
696
|
+
qualifications: array8().of(string13()).optional().label("Qualifications")
|
|
697
|
+
}).nullable().optional().label("Job Highlights"),
|
|
684
698
|
canCreateAlert: boolean9().optional().label("Can create alert"),
|
|
685
699
|
canDirectApply: boolean9().optional().label("Can direct apply"),
|
|
686
700
|
hasApplied: boolean9().optional().label("Has applied"),
|
|
@@ -706,15 +720,65 @@ var JobSchema = object16({
|
|
|
706
720
|
featuredMarkets: array8().of(string13().required()).optional().default([]).label("Featured markets")
|
|
707
721
|
}).concat(DbDefaultSchema).noUnknown().label("Job");
|
|
708
722
|
|
|
723
|
+
// src/post/post.schema.ts
|
|
724
|
+
import { array as array9, boolean as boolean10, number as number6, object as object17, string as string14 } from "yup";
|
|
725
|
+
|
|
726
|
+
// src/post/post.constant.ts
|
|
727
|
+
var PostStatus = /* @__PURE__ */ ((PostStatus2) => {
|
|
728
|
+
PostStatus2["Draft"] = "draft";
|
|
729
|
+
PostStatus2["Published"] = "published";
|
|
730
|
+
PostStatus2["Archived"] = "archived";
|
|
731
|
+
return PostStatus2;
|
|
732
|
+
})(PostStatus || {});
|
|
733
|
+
var SupportedPostStatuses = Object.values(PostStatus);
|
|
734
|
+
|
|
735
|
+
// src/post/post.schema.ts
|
|
736
|
+
var PostSchema = object17({
|
|
737
|
+
/** Headline shown in listings and at the top of the post. */
|
|
738
|
+
title: string14().required().min(5).max(200).label("Title"),
|
|
739
|
+
/** User-friendly, unique URL identifier. */
|
|
740
|
+
slug: string14().required().max(250).label("Slug"),
|
|
741
|
+
/** Short summary used in listings and meta description fallback. */
|
|
742
|
+
excerpt: string14().max(500).optional().label("Excerpt"),
|
|
743
|
+
/** Rendered HTML source of truth for the post body (sanitized on write/render).
|
|
744
|
+
* Supports rich formatting markdown can't express (image size/alignment, etc). */
|
|
745
|
+
bodyHTML: string14().required().min(1).label("Body (HTML)"),
|
|
746
|
+
/** Optional Markdown mirror of the body (portable text / search fallback).
|
|
747
|
+
* Kept for back-compat and plain-text derivation; bodyHTML is authoritative. */
|
|
748
|
+
bodyMarkdown: string14().optional().label("Body (Markdown)"),
|
|
749
|
+
/** Cover/hero image URL. Not `.url()`-validated: the value is either an
|
|
750
|
+
* uploaded file URL served by this platform (which may be a bare host like
|
|
751
|
+
* `http://localhost:3082/...` in dev, that yup's `.url()` wrongly rejects) or
|
|
752
|
+
* an admin-pasted link. Kept as a plain string; empty ⇒ null. */
|
|
753
|
+
coverImage: string14().nullable().optional().label("Cover image"),
|
|
754
|
+
/** Author (user id). */
|
|
755
|
+
authorId: string14().required().label("Author ID"),
|
|
756
|
+
/** Free-form tags for filtering and related-posts. */
|
|
757
|
+
tags: array9().of(string14().trim().required()).default([]).label("Tags"),
|
|
758
|
+
/** Estimated reading time in minutes (server-derived from body length). */
|
|
759
|
+
readingTimeMinutes: number6().min(0).optional().label("Reading time (minutes)"),
|
|
760
|
+
/** SEO overrides. */
|
|
761
|
+
seoTags: object17({
|
|
762
|
+
description: string14().optional().label("Description"),
|
|
763
|
+
keywords: array9().of(string14().required()).optional().label("Keywords")
|
|
764
|
+
}).nullable().optional().label("SEO Tags"),
|
|
765
|
+
/** When the post was first published (epoch ms). Server-owned. */
|
|
766
|
+
publishedAt: number6().nullable().optional().label("Published at"),
|
|
767
|
+
/** Whether the post is featured in the blog listing. */
|
|
768
|
+
isFeatured: boolean10().default(false).optional().label("Is featured"),
|
|
769
|
+
/** Publication state. */
|
|
770
|
+
status: string14().oneOf(SupportedPostStatuses).default("draft" /* Draft */).required().label("Status")
|
|
771
|
+
}).concat(DbDefaultSchema).noUnknown().label("Post");
|
|
772
|
+
|
|
709
773
|
// src/pagination/pagination.schema.ts
|
|
710
|
-
import { number as
|
|
711
|
-
var PaginationSchema =
|
|
712
|
-
page:
|
|
713
|
-
limit:
|
|
714
|
-
sortBy:
|
|
715
|
-
nextPage:
|
|
716
|
-
prevPage:
|
|
717
|
-
sortDirection:
|
|
774
|
+
import { number as number7, object as object18, string as string15 } from "yup";
|
|
775
|
+
var PaginationSchema = object18().shape({
|
|
776
|
+
page: number7().required().min(1).label("Page").default(1),
|
|
777
|
+
limit: number7().required().min(1).max(100).label("Limit").default(10),
|
|
778
|
+
sortBy: string15().notOneOf([""]).optional().label("SortBy"),
|
|
779
|
+
nextPage: string15().optional().label("Next Page Token"),
|
|
780
|
+
prevPage: string15().optional().label("Previous Page Token"),
|
|
781
|
+
sortDirection: string15().oneOf(["asc", "desc"]).optional().label("Sort Direction")
|
|
718
782
|
});
|
|
719
783
|
|
|
720
784
|
// src/pagination/pagination.constant.ts
|
|
@@ -730,7 +794,7 @@ var DefaultPaginationOptions = {
|
|
|
730
794
|
};
|
|
731
795
|
|
|
732
796
|
// src/report/report.schema.ts
|
|
733
|
-
import { mixed as mixed4, object as
|
|
797
|
+
import { mixed as mixed4, object as object19, string as string16 } from "yup";
|
|
734
798
|
|
|
735
799
|
// src/report/report.constant.ts
|
|
736
800
|
var ResourceType = /* @__PURE__ */ ((ResourceType3) => {
|
|
@@ -754,15 +818,15 @@ var ReportReason = /* @__PURE__ */ ((ReportReason3) => {
|
|
|
754
818
|
var SupportedReportReasons = Object.values(ReportReason);
|
|
755
819
|
|
|
756
820
|
// src/report/report.schema.ts
|
|
757
|
-
var ReportSchema =
|
|
821
|
+
var ReportSchema = object19({
|
|
758
822
|
type: mixed4().oneOf(SupportedResourceTypes).required().label("Type"),
|
|
759
|
-
resourceId:
|
|
823
|
+
resourceId: string16().required().label("Resource ID"),
|
|
760
824
|
reason: mixed4().oneOf(SupportedReportReasons).required("Please choose a reason").label("Reason"),
|
|
761
|
-
comment:
|
|
825
|
+
comment: string16().max(1e3).optional().label("Comment")
|
|
762
826
|
}).label("Report Schema");
|
|
763
827
|
|
|
764
828
|
// src/user/user.schema.ts
|
|
765
|
-
import { array as
|
|
829
|
+
import { array as array13, number as number9, object as object31, string as string29 } from "yup";
|
|
766
830
|
|
|
767
831
|
// src/user/user.constant.ts
|
|
768
832
|
var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
@@ -844,51 +908,51 @@ var MIN_SALARY_LOWER_BOUND = 0;
|
|
|
844
908
|
var MIN_SALARY_UPPER_BOUND = 1e6;
|
|
845
909
|
|
|
846
910
|
// src/user/work-experience.schema.ts
|
|
847
|
-
import { boolean as
|
|
848
|
-
var WorkExperienceSchema =
|
|
911
|
+
import { boolean as boolean11, object as object20, string as string17 } from "yup";
|
|
912
|
+
var WorkExperienceSchema = object20().shape({
|
|
849
913
|
company: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company"),
|
|
850
|
-
designation:
|
|
914
|
+
designation: string17().trim().required().label("Designation"),
|
|
851
915
|
duration: DurationSchema({
|
|
852
916
|
format: "YYYY-MM",
|
|
853
917
|
startLabel: "Start Date",
|
|
854
918
|
endLabel: "End Date"
|
|
855
919
|
}).required().label("Duration"),
|
|
856
|
-
description:
|
|
920
|
+
description: string17().trim().max(3e3).optional().label("Description"),
|
|
857
921
|
location: LocationSchema.required().label("Location"),
|
|
858
|
-
isRemote:
|
|
922
|
+
isRemote: boolean11().oneOf([true, false]).default(false).label("Is Remote")
|
|
859
923
|
}).noUnknown().strict().label("Work Experience");
|
|
860
924
|
|
|
861
925
|
// src/user/education.schema.ts
|
|
862
|
-
import { boolean as
|
|
863
|
-
var EducationSchema =
|
|
926
|
+
import { boolean as boolean12, object as object21, string as string18 } from "yup";
|
|
927
|
+
var EducationSchema = object21({
|
|
864
928
|
institute: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute"),
|
|
865
|
-
course:
|
|
866
|
-
fieldOfStudy:
|
|
929
|
+
course: string18().trim().required().label("Course"),
|
|
930
|
+
fieldOfStudy: string18().trim().required().label("Field of Study"),
|
|
867
931
|
duration: DurationSchema({
|
|
868
932
|
format: "YYYY-MM",
|
|
869
933
|
startLabel: "Start Date",
|
|
870
934
|
endLabel: "End Date"
|
|
871
935
|
}).required().label("Duration"),
|
|
872
|
-
description:
|
|
873
|
-
isDistanceLearning:
|
|
936
|
+
description: string18().trim().max(3e3).optional().label("Description"),
|
|
937
|
+
isDistanceLearning: boolean12().default(false).label("Is Distance Learning"),
|
|
874
938
|
location: LocationSchema.required().label("Location"),
|
|
875
|
-
studyType:
|
|
939
|
+
studyType: string18().oneOf(SupportedStudyTypes).trim().max(50).required().label("Study Type")
|
|
876
940
|
}).noUnknown().strict().label("Education");
|
|
877
941
|
|
|
878
942
|
// src/user/user-skill.schema.ts
|
|
879
|
-
import { object as
|
|
880
|
-
var UserSkillSchema =
|
|
881
|
-
name:
|
|
882
|
-
proficiencyLevel:
|
|
943
|
+
import { object as object22, string as string19 } from "yup";
|
|
944
|
+
var UserSkillSchema = object22({
|
|
945
|
+
name: string19().required().label("Name"),
|
|
946
|
+
proficiencyLevel: string19().oneOf(SupportedProficiencyLevels).required().label("Proficiency Level"),
|
|
883
947
|
lastUsed: dateString().format("YYYY-MM").nullable().optional().label("Last Used")
|
|
884
948
|
}).noUnknown().strict().label("Skill");
|
|
885
949
|
|
|
886
950
|
// src/user/project.schema.ts
|
|
887
|
-
import { object as
|
|
888
|
-
var UserProjectSchema =
|
|
889
|
-
name:
|
|
890
|
-
url:
|
|
891
|
-
description:
|
|
951
|
+
import { object as object23, string as string20 } from "yup";
|
|
952
|
+
var UserProjectSchema = object23({
|
|
953
|
+
name: string20().trim().max(50).required().label("Name"),
|
|
954
|
+
url: string20().optional().label("URL"),
|
|
955
|
+
description: string20().trim().min(100).max(3e3).required().label("Description"),
|
|
892
956
|
duration: DurationSchema({
|
|
893
957
|
format: "YYYY-MM",
|
|
894
958
|
startLabel: "Start Date",
|
|
@@ -897,83 +961,83 @@ var UserProjectSchema = object22({
|
|
|
897
961
|
}).noUnknown().strict().label("Project");
|
|
898
962
|
|
|
899
963
|
// src/user/user-certification.schema.ts
|
|
900
|
-
import { object as
|
|
901
|
-
var UserCertificationSchema =
|
|
902
|
-
name:
|
|
964
|
+
import { object as object24, string as string21 } from "yup";
|
|
965
|
+
var UserCertificationSchema = object24({
|
|
966
|
+
name: string21().trim().max(100).required().label("Name"),
|
|
903
967
|
// TODO: Add validation for authority
|
|
904
|
-
authority:
|
|
905
|
-
licenseNumber:
|
|
968
|
+
authority: string21().trim().max(100).required().label("Authority"),
|
|
969
|
+
licenseNumber: string21().trim().max(50).optional().label("License Number"),
|
|
906
970
|
duration: DurationSchema({
|
|
907
971
|
format: "YYYY-MM",
|
|
908
972
|
startLabel: "Start Date",
|
|
909
973
|
endLabel: "End Date"
|
|
910
974
|
}).optional().nullable().label("Duration"),
|
|
911
|
-
url:
|
|
975
|
+
url: string21().optional().label("URL")
|
|
912
976
|
}).noUnknown().strict().label("Certification");
|
|
913
977
|
|
|
914
978
|
// src/user/user-interest.schema.ts
|
|
915
|
-
import { string as
|
|
916
|
-
var UserInterestSchema =
|
|
979
|
+
import { string as string22 } from "yup";
|
|
980
|
+
var UserInterestSchema = string22().trim().required().label("Interest");
|
|
917
981
|
|
|
918
982
|
// src/user/user-language.schema.ts
|
|
919
|
-
import { object as
|
|
920
|
-
var UserLanguageSchema =
|
|
921
|
-
name:
|
|
922
|
-
proficiencyLevel:
|
|
983
|
+
import { object as object25, string as string23 } from "yup";
|
|
984
|
+
var UserLanguageSchema = object25({
|
|
985
|
+
name: string23().trim().required().label("Name"),
|
|
986
|
+
proficiencyLevel: string23().oneOf(SupportedProficiencyLevels).trim().max(50).required().label("Proficiency Level")
|
|
923
987
|
}).noUnknown().strict().label("Language");
|
|
924
988
|
|
|
925
989
|
// src/user/user-additional-info.schema.ts
|
|
926
|
-
import { object as
|
|
927
|
-
var UserAdditionalInfoSchema =
|
|
928
|
-
title:
|
|
929
|
-
description:
|
|
990
|
+
import { object as object26, string as string24 } from "yup";
|
|
991
|
+
var UserAdditionalInfoSchema = object26({
|
|
992
|
+
title: string24().trim().max(60).required().label("Title"),
|
|
993
|
+
description: string24().trim().max(1e3).required().label("Description")
|
|
930
994
|
}).noUnknown().strict().label("User Additional Info");
|
|
931
995
|
|
|
932
996
|
// src/user/general-detail.schema.ts
|
|
933
|
-
import { object as
|
|
934
|
-
var UserGeneralDetailSchema =
|
|
935
|
-
id:
|
|
936
|
-
name:
|
|
937
|
-
first:
|
|
938
|
-
last:
|
|
997
|
+
import { object as object27, string as string25 } from "yup";
|
|
998
|
+
var UserGeneralDetailSchema = object27({
|
|
999
|
+
id: string25().optional().label("ID"),
|
|
1000
|
+
name: object27().shape({
|
|
1001
|
+
first: string25().trim().max(50).required().label("First Name"),
|
|
1002
|
+
last: string25().trim().max(50).optional().label("Last Name")
|
|
939
1003
|
}).required().label("Name"),
|
|
940
|
-
headline:
|
|
941
|
-
image:
|
|
942
|
-
aboutMe:
|
|
943
|
-
email:
|
|
944
|
-
mobile:
|
|
945
|
-
emailVerified:
|
|
946
|
-
mobileVerified:
|
|
947
|
-
experienceLevel:
|
|
1004
|
+
headline: string25().trim().max(200).optional().label("Headline"),
|
|
1005
|
+
image: string25().optional().label("Image"),
|
|
1006
|
+
aboutMe: string25().trim().max(3e3).optional().label("About Me"),
|
|
1007
|
+
email: string25().required().label("Email"),
|
|
1008
|
+
mobile: string25().nullable().optional().label("Mobile"),
|
|
1009
|
+
emailVerified: string25().nullable().optional().label("Email Verified"),
|
|
1010
|
+
mobileVerified: string25().nullable().optional().label("Mobile Verified"),
|
|
1011
|
+
experienceLevel: string25().oneOf(SupportedExperienceLevels).required().label("Experience level"),
|
|
948
1012
|
location: LocationSchema.required().label("Location"),
|
|
949
|
-
region:
|
|
950
|
-
country:
|
|
951
|
-
lang:
|
|
1013
|
+
region: object27().shape({
|
|
1014
|
+
country: string25().trim().required().label("Region Country"),
|
|
1015
|
+
lang: string25().trim().required().label("Region Language")
|
|
952
1016
|
}).optional().default(void 0).label("Region"),
|
|
953
|
-
profileVisibility:
|
|
1017
|
+
profileVisibility: string25().oneOf(SupportedUserProfileVisibilities).default("public" /* Public */).label("Profile Visibility")
|
|
954
1018
|
}).noUnknown().strict().label("General Detail");
|
|
955
1019
|
|
|
956
1020
|
// src/user/user-job-preferences.schema.ts
|
|
957
|
-
import { array as
|
|
958
|
-
var UserJobPreferencesSchema =
|
|
1021
|
+
import { array as array10, boolean as boolean13, date as date2, number as number8, object as object28, string as string26 } from "yup";
|
|
1022
|
+
var UserJobPreferencesSchema = object28({
|
|
959
1023
|
/**
|
|
960
1024
|
* Whether the job seeker is openly signalling availability. Surfaces the
|
|
961
1025
|
* "Open to work" badge on the public profile and boosts visibility in
|
|
962
1026
|
* recruiter search. Defaults to `false` - users must opt in.
|
|
963
1027
|
*/
|
|
964
|
-
openToWork:
|
|
1028
|
+
openToWork: boolean13().default(false).label("Open to Work"),
|
|
965
1029
|
/**
|
|
966
1030
|
* How urgently the user is looking for their next job. Drives match scoring
|
|
967
1031
|
* and can downgrade the visibility of expired or low-relevance postings for
|
|
968
1032
|
* users in `passively_browsing` mode.
|
|
969
1033
|
*/
|
|
970
|
-
jobSearchUrgency:
|
|
1034
|
+
jobSearchUrgency: string26().oneOf(SupportedJobSearchUrgencies).required().label("Job Search Urgency"),
|
|
971
1035
|
/**
|
|
972
1036
|
* Locations the user wants to work in. Stores the full `LocationSchema`
|
|
973
1037
|
* shape (country, city, state, geo, etc.) as returned by the locations
|
|
974
1038
|
* autocomplete API.
|
|
975
1039
|
*/
|
|
976
|
-
jobLocations:
|
|
1040
|
+
jobLocations: array10().of(LocationSchema.required().label("Job Location")).min(1, "Pick at least one preferred location.").required().label("Job Locations"),
|
|
977
1041
|
/**
|
|
978
1042
|
* Seniority levels the user wants jobs to be matched against. Multi-select
|
|
979
1043
|
* (up to 2) for borderline candidates.
|
|
@@ -984,7 +1048,7 @@ var UserJobPreferencesSchema = object27({
|
|
|
984
1048
|
* Both reuse the same `ExperienceLevel` taxonomy from `common.constant.ts`
|
|
985
1049
|
* so search/match logic doesn't have to translate between two vocabularies.
|
|
986
1050
|
*/
|
|
987
|
-
targetExperienceLevels:
|
|
1051
|
+
targetExperienceLevels: array10().of(string26().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"),
|
|
988
1052
|
/**
|
|
989
1053
|
* Specializations the user is searching for - free-form titles.
|
|
990
1054
|
*
|
|
@@ -993,19 +1057,19 @@ var UserJobPreferencesSchema = object27({
|
|
|
993
1057
|
* surfaces a curated "Popular Roles" picker for discovery, but the user
|
|
994
1058
|
* can ultimately add any title; matching/normalization happens downstream.
|
|
995
1059
|
*/
|
|
996
|
-
jobRoles:
|
|
1060
|
+
jobRoles: array10().of(string26().trim().max(120).required()).min(1, "Pick at least one role.").required().label("Job Roles"),
|
|
997
1061
|
/**
|
|
998
1062
|
* Minimum acceptable annual base salary, in `minSalaryCurrency`.
|
|
999
1063
|
* Stored as an integer in the currency's major unit (e.g. dollars, not cents).
|
|
1000
1064
|
* Defaults to 0 ("any salary") rather than being optional - every job-seeker
|
|
1001
1065
|
* has a floor, even if it's zero.
|
|
1002
1066
|
*/
|
|
1003
|
-
minSalary:
|
|
1004
|
-
minSalaryCurrency:
|
|
1067
|
+
minSalary: number8().integer().min(MIN_SALARY_LOWER_BOUND).max(MIN_SALARY_UPPER_BOUND).default(0).required().label("Minimum Salary"),
|
|
1068
|
+
minSalaryCurrency: string26().oneOf(SupportedSalaryCurrencies).default("USD").required().label("Minimum Salary Currency"),
|
|
1005
1069
|
/**
|
|
1006
1070
|
* Marketing-attribution capture from the final onboarding step.
|
|
1007
1071
|
*/
|
|
1008
|
-
referralSource:
|
|
1072
|
+
referralSource: string26().oneOf(SupportedReferralSources).required().label("Referral Source"),
|
|
1009
1073
|
/**
|
|
1010
1074
|
* Resumes the user has uploaded. Embedded directly on the user document
|
|
1011
1075
|
* (capped at 5) - they're cheap to denormalize, every wizard step that
|
|
@@ -1019,18 +1083,18 @@ var UserJobPreferencesSchema = object27({
|
|
|
1019
1083
|
* AI resume-builder flow - onboarding uploads land here, AI-built resumes
|
|
1020
1084
|
* live in their own collection.
|
|
1021
1085
|
*/
|
|
1022
|
-
resumes:
|
|
1023
|
-
|
|
1086
|
+
resumes: array10().of(
|
|
1087
|
+
object28({
|
|
1024
1088
|
// Stable id assigned on upload - used to address a specific entry
|
|
1025
1089
|
// for delete / set-primary operations without exposing the GCS URL
|
|
1026
1090
|
// as a route key.
|
|
1027
|
-
id:
|
|
1028
|
-
url:
|
|
1029
|
-
filename:
|
|
1030
|
-
sizeBytes:
|
|
1031
|
-
mimeType:
|
|
1091
|
+
id: string26().required().label("ID"),
|
|
1092
|
+
url: string26().required().label("Resume URL"),
|
|
1093
|
+
filename: string26().trim().max(255).optional().label("Filename"),
|
|
1094
|
+
sizeBytes: number8().integer().min(0).optional().label("Size (bytes)"),
|
|
1095
|
+
mimeType: string26().trim().max(120).optional().label("MIME Type"),
|
|
1032
1096
|
uploadedAt: date2().required().label("Uploaded At"),
|
|
1033
|
-
isPrimary:
|
|
1097
|
+
isPrimary: boolean13().default(false).label("Is Primary")
|
|
1034
1098
|
}).noUnknown().strict().label("Resume")
|
|
1035
1099
|
).max(5, "You can keep at most 5 resumes on file.").default([]).label("Resumes"),
|
|
1036
1100
|
/**
|
|
@@ -1057,106 +1121,106 @@ var UserJobPreferencesSchema = object27({
|
|
|
1057
1121
|
* APIs. If `user.<field>` is empty there, the correct behavior is empty,
|
|
1058
1122
|
* because the user has not confirmed it yet.
|
|
1059
1123
|
*/
|
|
1060
|
-
pendingPrefill:
|
|
1061
|
-
headline:
|
|
1062
|
-
aboutMe:
|
|
1063
|
-
mobile:
|
|
1124
|
+
pendingPrefill: object28({
|
|
1125
|
+
headline: string26().trim().optional().label("Pending Headline"),
|
|
1126
|
+
aboutMe: string26().trim().optional().label("Pending About Me"),
|
|
1127
|
+
mobile: string26().trim().optional().label("Pending Mobile"),
|
|
1064
1128
|
location: LocationSchema.optional().default(void 0).label("Pending Location"),
|
|
1065
|
-
experienceLevel:
|
|
1066
|
-
socialAccounts:
|
|
1067
|
-
workExperiences:
|
|
1068
|
-
educations:
|
|
1129
|
+
experienceLevel: string26().oneOf(SupportedExperienceLevels).optional().label("Pending Experience Level"),
|
|
1130
|
+
socialAccounts: array10().of(SocialAccountSchema.required()).optional().label("Pending Social Accounts"),
|
|
1131
|
+
workExperiences: array10().of(WorkExperienceSchema.required()).optional().label("Pending Work Experiences"),
|
|
1132
|
+
educations: array10().of(EducationSchema.required()).optional().label("Pending Educations")
|
|
1069
1133
|
}).nullable().optional().default(void 0).label("Pending Prefill")
|
|
1070
1134
|
}).noUnknown().strict().label("User Job Preferences Schema");
|
|
1071
1135
|
|
|
1072
1136
|
// src/user/user-recruiter-profile.schema.ts
|
|
1073
|
-
import { array as
|
|
1074
|
-
var RecruiterPageLinkSchema =
|
|
1137
|
+
import { array as array11, object as object29, string as string27 } from "yup";
|
|
1138
|
+
var RecruiterPageLinkSchema = object29({
|
|
1075
1139
|
page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company Page"),
|
|
1076
|
-
jobTitle:
|
|
1140
|
+
jobTitle: string27().trim().max(100).optional().label("Job Title")
|
|
1077
1141
|
}).noUnknown().strict().label("Recruiter Page Link");
|
|
1078
|
-
var UserRecruiterProfileSchema =
|
|
1079
|
-
recruiterProfile:
|
|
1080
|
-
hiringFor:
|
|
1142
|
+
var UserRecruiterProfileSchema = object29({
|
|
1143
|
+
recruiterProfile: object29({
|
|
1144
|
+
hiringFor: array11().of(RecruiterPageLinkSchema).default([]).label("Hiring For")
|
|
1081
1145
|
}).optional().default(void 0).label("Recruiter Profile")
|
|
1082
1146
|
}).noUnknown().strict().label("User Recruiter Profile");
|
|
1083
1147
|
|
|
1084
1148
|
// src/user/user-coordinator-profile.schema.ts
|
|
1085
|
-
import { array as
|
|
1086
|
-
var CoordinatorPageLinkSchema =
|
|
1149
|
+
import { array as array12, object as object30, string as string28 } from "yup";
|
|
1150
|
+
var CoordinatorPageLinkSchema = object30({
|
|
1087
1151
|
page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute Page"),
|
|
1088
|
-
jobTitle:
|
|
1152
|
+
jobTitle: string28().trim().max(100).optional().label("Job Title")
|
|
1089
1153
|
}).noUnknown().strict().label("Coordinator Page Link");
|
|
1090
|
-
var UserCoordinatorProfileSchema =
|
|
1091
|
-
coordinatorProfile:
|
|
1092
|
-
coordinatesAt:
|
|
1154
|
+
var UserCoordinatorProfileSchema = object30({
|
|
1155
|
+
coordinatorProfile: object30({
|
|
1156
|
+
coordinatesAt: array12().of(CoordinatorPageLinkSchema).default([]).label("Coordinates At")
|
|
1093
1157
|
}).optional().default(void 0).label("Coordinator Profile")
|
|
1094
1158
|
}).noUnknown().strict().label("User Coordinator Profile");
|
|
1095
1159
|
|
|
1096
1160
|
// src/user/user.schema.ts
|
|
1097
|
-
var UserSchema =
|
|
1161
|
+
var UserSchema = object31({
|
|
1098
1162
|
/**
|
|
1099
1163
|
* Related auth account id from auth Server (e.g. Better auth https://auth.thejob.dev)
|
|
1100
1164
|
*/
|
|
1101
|
-
authAccountId:
|
|
1165
|
+
authAccountId: string29().required().label("Auth Account ID"),
|
|
1102
1166
|
/**
|
|
1103
1167
|
* Social media information about the user (e.g. LinkedIn, GitHub, etc.)
|
|
1104
1168
|
*/
|
|
1105
|
-
socialAccounts:
|
|
1169
|
+
socialAccounts: array13().of(SocialAccountSchema).default([]).label("Social Accounts"),
|
|
1106
1170
|
/**
|
|
1107
1171
|
* Work experience information about the user
|
|
1108
1172
|
*/
|
|
1109
|
-
workExperiences:
|
|
1173
|
+
workExperiences: array13().of(WorkExperienceSchema).required().default([]).label("Work Experiences"),
|
|
1110
1174
|
/**
|
|
1111
1175
|
* Education information about the user
|
|
1112
1176
|
*/
|
|
1113
|
-
educations:
|
|
1177
|
+
educations: array13().of(EducationSchema).required().default([]).label("Educations"),
|
|
1114
1178
|
/**
|
|
1115
1179
|
* Skills information about the user
|
|
1116
1180
|
*/
|
|
1117
|
-
skills:
|
|
1181
|
+
skills: array13().of(UserSkillSchema).required().default([]).label("Skills"),
|
|
1118
1182
|
/**
|
|
1119
1183
|
* Projects information about the user
|
|
1120
1184
|
*/
|
|
1121
|
-
projects:
|
|
1185
|
+
projects: array13().of(UserProjectSchema).default([]).label("Projects"),
|
|
1122
1186
|
/**
|
|
1123
1187
|
* Certifications information about the user
|
|
1124
1188
|
*/
|
|
1125
|
-
certifications:
|
|
1189
|
+
certifications: array13().of(UserCertificationSchema).default([]).label("Certifications"),
|
|
1126
1190
|
/**
|
|
1127
1191
|
* Interests information about the user.
|
|
1128
1192
|
*/
|
|
1129
|
-
interests:
|
|
1193
|
+
interests: array13().of(UserInterestSchema).optional().default([]).label("Interests"),
|
|
1130
1194
|
/**
|
|
1131
1195
|
* Languages information about the user
|
|
1132
1196
|
*/
|
|
1133
|
-
languages:
|
|
1197
|
+
languages: array13().of(UserLanguageSchema).required().default([]).label("Languages"),
|
|
1134
1198
|
/**
|
|
1135
1199
|
* Additional information about the user
|
|
1136
1200
|
*/
|
|
1137
|
-
additionalInfo:
|
|
1201
|
+
additionalInfo: array13().of(UserAdditionalInfoSchema).default([]).label("Additional Information"),
|
|
1138
1202
|
/**
|
|
1139
1203
|
* Status of the user account
|
|
1140
1204
|
*/
|
|
1141
|
-
status:
|
|
1205
|
+
status: string29().oneOf(SupportedUserStatuses).required().label("Status"),
|
|
1142
1206
|
/**
|
|
1143
1207
|
* Roles assigned to the user
|
|
1144
1208
|
*/
|
|
1145
|
-
roles:
|
|
1209
|
+
roles: array13().of(string29().oneOf(SupportedUserRoles)).required().default(DefaultUserRoles).label("Roles"),
|
|
1146
1210
|
/**
|
|
1147
1211
|
* Vector embedding of the user's profile for semantic/hybrid search.
|
|
1148
1212
|
* Generated from a structured summary of skills, experience, education, etc.
|
|
1149
1213
|
* Only generated for public profiles with sufficient completeness (≥60%).
|
|
1150
1214
|
*/
|
|
1151
|
-
embedding:
|
|
1152
|
-
vector:
|
|
1153
|
-
model:
|
|
1215
|
+
embedding: object31({
|
|
1216
|
+
vector: array13(number9().required()).optional().label("Embedding vector"),
|
|
1217
|
+
model: string29().optional().label("Embedding model")
|
|
1154
1218
|
}).nullable().optional().label("Embedding")
|
|
1155
1219
|
}).concat(UserGeneralDetailSchema).concat(UserJobPreferencesSchema).concat(UserRecruiterProfileSchema).concat(UserCoordinatorProfileSchema).noUnknown().strict().label("User Schema");
|
|
1156
1220
|
|
|
1157
1221
|
// src/user/user-completeness.schema.ts
|
|
1158
|
-
import { object as
|
|
1159
|
-
var UserCompletenessSchema =
|
|
1222
|
+
import { object as object32 } from "yup";
|
|
1223
|
+
var UserCompletenessSchema = object32({
|
|
1160
1224
|
additionalInfo: CompletenessScoreSchema(0).label("Additional Info"),
|
|
1161
1225
|
// Optional
|
|
1162
1226
|
certifications: CompletenessScoreSchema(0).label("Certifications"),
|
|
@@ -1219,6 +1283,8 @@ export {
|
|
|
1219
1283
|
PageStatus,
|
|
1220
1284
|
PageType,
|
|
1221
1285
|
PaginationSchema,
|
|
1286
|
+
PostSchema,
|
|
1287
|
+
PostStatus,
|
|
1222
1288
|
ProficiencyLevel,
|
|
1223
1289
|
QuestionSchema,
|
|
1224
1290
|
QuestionType,
|
|
@@ -1247,6 +1313,7 @@ export {
|
|
|
1247
1313
|
SupportedJobStatuses,
|
|
1248
1314
|
SupportedPageStatuses,
|
|
1249
1315
|
SupportedPageTypes,
|
|
1316
|
+
SupportedPostStatuses,
|
|
1250
1317
|
SupportedProficiencyLevels,
|
|
1251
1318
|
SupportedQuestionTypes,
|
|
1252
1319
|
SupportedReferralSources,
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -26,6 +26,12 @@ export * from "./group/group.constant.js";
|
|
|
26
26
|
export * from "./job/job.schema.js";
|
|
27
27
|
export * from "./job/job.constant.js";
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Post schemas and constants (blog).
|
|
31
|
+
*/
|
|
32
|
+
export * from "./post/post.schema.js";
|
|
33
|
+
export * from "./post/post.constant.js";
|
|
34
|
+
|
|
29
35
|
/**
|
|
30
36
|
* Question schemas and constants (job questionnaire).
|
|
31
37
|
*/
|
package/src/job/job.schema.ts
CHANGED
|
@@ -196,6 +196,24 @@ export const JobSchema = object({
|
|
|
196
196
|
|
|
197
197
|
jdSummary: string().optional().label("JD Summary"),
|
|
198
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Structured, model-extracted sections of the posting, re-organized into clean
|
|
201
|
+
* bullet points. This is our OWN unique presentation of the job (rendered as the
|
|
202
|
+
* primary, server-side page content) so the page adds value over the raw scraped
|
|
203
|
+
* description and is not penalized by Google as duplicate content. All sections
|
|
204
|
+
* optional: absent on jobs not yet (re-)enriched, and any section is `[]`/omitted
|
|
205
|
+
* when the posting genuinely has none.
|
|
206
|
+
*/
|
|
207
|
+
jobHighlights: object({
|
|
208
|
+
responsibilities: array().of(string()).optional().label("Responsibilities"),
|
|
209
|
+
requirements: array().of(string()).optional().label("Requirements"),
|
|
210
|
+
benefits: array().of(string()).optional().label("Benefits"),
|
|
211
|
+
qualifications: array().of(string()).optional().label("Qualifications"),
|
|
212
|
+
})
|
|
213
|
+
.nullable()
|
|
214
|
+
.optional()
|
|
215
|
+
.label("Job Highlights"),
|
|
216
|
+
|
|
199
217
|
canCreateAlert: boolean().optional().label("Can create alert"),
|
|
200
218
|
|
|
201
219
|
canDirectApply: boolean().optional().label("Can direct apply"),
|