@thejob/schema 2.1.3 → 2.1.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
@@ -100,6 +100,9 @@ __export(index_exports, {
100
100
  ResourceType: () => ResourceType,
101
101
  SITEMAP_FORMAT: () => SITEMAP_FORMAT,
102
102
  SYSTEM_DATE_FORMAT: () => SYSTEM_DATE_FORMAT,
103
+ SavedSearchSchema: () => SavedSearchSchema,
104
+ SavedSearchStatus: () => SavedSearchStatus,
105
+ SignupContextSource: () => SignupContextSource,
103
106
  SkillSchema: () => SkillSchema,
104
107
  SocialAccount: () => SocialAccount,
105
108
  SocialAccountSchema: () => SocialAccountSchema,
@@ -132,6 +135,8 @@ __export(index_exports, {
132
135
  SupportedReportReasons: () => SupportedReportReasons,
133
136
  SupportedResourceTypes: () => SupportedResourceTypes,
134
137
  SupportedSalaryCurrencies: () => SupportedSalaryCurrencies,
138
+ SupportedSavedSearchStatuses: () => SupportedSavedSearchStatuses,
139
+ SupportedSignupContextSources: () => SupportedSignupContextSources,
135
140
  SupportedSocialAccounts: () => SupportedSocialAccounts,
136
141
  SupportedStudyTypes: () => SupportedStudyTypes,
137
142
  SupportedUserProfileVisibilities: () => SupportedUserProfileVisibilities,
@@ -2107,6 +2112,13 @@ var UserProfileVisibility = /* @__PURE__ */ ((UserProfileVisibility2) => {
2107
2112
  var SupportedUserProfileVisibilities = Object.values(
2108
2113
  UserProfileVisibility
2109
2114
  );
2115
+ var SignupContextSource = /* @__PURE__ */ ((SignupContextSource2) => {
2116
+ SignupContextSource2["CfHeader"] = "cf-header";
2117
+ SignupContextSource2["Location"] = "location";
2118
+ SignupContextSource2["Default"] = "default";
2119
+ return SignupContextSource2;
2120
+ })(SignupContextSource || {});
2121
+ var SupportedSignupContextSources = Object.values(SignupContextSource);
2110
2122
  var UserDetailType = /* @__PURE__ */ ((UserDetailType2) => {
2111
2123
  UserDetailType2["Overview"] = "overview";
2112
2124
  UserDetailType2["AdditionalInfo"] = "additionalInfo";
@@ -2299,9 +2311,70 @@ var DefaultPaginationOptions = {
2299
2311
  limit: 10
2300
2312
  };
2301
2313
 
2302
- // src/report/report.schema.ts
2314
+ // src/saved-search/saved-search.schema.ts
2303
2315
  var import_yup22 = require("yup");
2304
2316
 
2317
+ // src/saved-search/saved-search.constant.ts
2318
+ var SavedSearchStatus = /* @__PURE__ */ ((SavedSearchStatus2) => {
2319
+ SavedSearchStatus2["Active"] = "active";
2320
+ SavedSearchStatus2["Paused"] = "paused";
2321
+ return SavedSearchStatus2;
2322
+ })(SavedSearchStatus || {});
2323
+ var SupportedSavedSearchStatuses = Object.values(SavedSearchStatus);
2324
+
2325
+ // src/saved-search/saved-search.schema.ts
2326
+ var SavedSearchSchema = (0, import_yup22.object)({
2327
+ /** Public identifier. Server-assigned. */
2328
+ shortId: (0, import_yup22.string)().trim().label("Short Id"),
2329
+ /**
2330
+ * Owner's Better Auth account id. Server-assigned from the verified token,
2331
+ * never accepted from a request body.
2332
+ */
2333
+ ownerUserId: (0, import_yup22.string)().trim().label("Owner"),
2334
+ /** What the user calls this search, e.g. "Remote React roles". */
2335
+ label: (0, import_yup22.string)().trim().max(120).required().label("Label"),
2336
+ /**
2337
+ * The free-text query. Optional because a search can be filters-only ("all
2338
+ * remote jobs in Sweden"), which is a legitimate alert to want.
2339
+ */
2340
+ search: (0, import_yup22.string)().trim().max(500).optional().label("Search Text"),
2341
+ /**
2342
+ * Field filters, in the same `{ field: values }` shape the search endpoint
2343
+ * parses from `filter[field]=a,b`. Held as a free-form object rather than a
2344
+ * closed schema because the job facets it addresses live in jobs-service and
2345
+ * change independently; validating them here would put this package in the
2346
+ * business of tracking that vocabulary.
2347
+ */
2348
+ filter: (0, import_yup22.object)().optional().default({}).label("Filters"),
2349
+ /**
2350
+ * How often to mail matches. `off` keeps the search saved but silent, which is
2351
+ * the difference between "I don't want mail" and "delete my search".
2352
+ *
2353
+ * Reuses the cadence enum from `marketingConsent.jobAlertFrequency` rather
2354
+ * than defining a second one: two vocabularies for the same concept is how
2355
+ * they drift.
2356
+ */
2357
+ frequency: (0, import_yup22.string)().oneOf(SupportedJobAlertFrequencies).default("off" /* Off */).label("Alert Frequency"),
2358
+ status: (0, import_yup22.string)().oneOf(SupportedSavedSearchStatuses).default("active" /* Active */).label("Status"),
2359
+ /**
2360
+ * Epoch ms of the last alert sent for this search. The matching sweep reads it
2361
+ * to decide whether the cadence is due, and writes it only AFTER a successful
2362
+ * publish, so a failed run retries next tick rather than silently skipping a
2363
+ * period.
2364
+ */
2365
+ lastNotifiedAt: (0, import_yup22.number)().optional().label("Last Notified At"),
2366
+ /**
2367
+ * Epoch ms high-water mark: only jobs created after this are "new" for the
2368
+ * next alert. Kept separate from `lastNotifiedAt` because a run that finds no
2369
+ * matches should still advance what counts as new, without implying mail was
2370
+ * sent.
2371
+ */
2372
+ lastMatchedAt: (0, import_yup22.number)().optional().label("Last Matched At")
2373
+ }).noUnknown().strict();
2374
+
2375
+ // src/report/report.schema.ts
2376
+ var import_yup23 = require("yup");
2377
+
2305
2378
  // src/report/report.constant.ts
2306
2379
  var ResourceType = /* @__PURE__ */ ((ResourceType3) => {
2307
2380
  ResourceType3["Job"] = "job";
@@ -2324,15 +2397,15 @@ var ReportReason = /* @__PURE__ */ ((ReportReason3) => {
2324
2397
  var SupportedReportReasons = Object.values(ReportReason);
2325
2398
 
2326
2399
  // src/report/report.schema.ts
2327
- var ReportSchema = (0, import_yup22.object)({
2328
- type: (0, import_yup22.mixed)().oneOf(SupportedResourceTypes).required().label("Type"),
2329
- resourceId: (0, import_yup22.string)().required().label("Resource ID"),
2330
- reason: (0, import_yup22.mixed)().oneOf(SupportedReportReasons).required("Please choose a reason").label("Reason"),
2331
- comment: (0, import_yup22.string)().max(1e3).optional().label("Comment")
2400
+ var ReportSchema = (0, import_yup23.object)({
2401
+ type: (0, import_yup23.mixed)().oneOf(SupportedResourceTypes).required().label("Type"),
2402
+ resourceId: (0, import_yup23.string)().required().label("Resource ID"),
2403
+ reason: (0, import_yup23.mixed)().oneOf(SupportedReportReasons).required("Please choose a reason").label("Reason"),
2404
+ comment: (0, import_yup23.string)().max(1e3).optional().label("Comment")
2332
2405
  }).label("Report Schema");
2333
2406
 
2334
2407
  // src/feedback/feedback.schema.ts
2335
- var import_yup23 = require("yup");
2408
+ var import_yup24 = require("yup");
2336
2409
 
2337
2410
  // src/feedback/feedback.constant.ts
2338
2411
  var FeedbackType = /* @__PURE__ */ ((FeedbackType3) => {
@@ -2355,63 +2428,63 @@ var SupportedFeedbackStatuses = Object.values(FeedbackStatus);
2355
2428
  var FEEDBACK_MESSAGE_MAX = 4e3;
2356
2429
 
2357
2430
  // src/feedback/feedback.schema.ts
2358
- var FeedbackSchema = (0, import_yup23.object)({
2359
- type: (0, import_yup23.mixed)().oneOf(SupportedFeedbackTypes).required().label("Type"),
2360
- message: (0, import_yup23.string)().trim().required("Please enter a message").max(FEEDBACK_MESSAGE_MAX).label("Message"),
2361
- email: (0, import_yup23.string)().email().optional().label("Email"),
2362
- pageUrl: (0, import_yup23.string)().optional().label("Page URL"),
2363
- status: (0, import_yup23.mixed)().oneOf(SupportedFeedbackStatuses).optional().label("Status")
2431
+ var FeedbackSchema = (0, import_yup24.object)({
2432
+ type: (0, import_yup24.mixed)().oneOf(SupportedFeedbackTypes).required().label("Type"),
2433
+ message: (0, import_yup24.string)().trim().required("Please enter a message").max(FEEDBACK_MESSAGE_MAX).label("Message"),
2434
+ email: (0, import_yup24.string)().email().optional().label("Email"),
2435
+ pageUrl: (0, import_yup24.string)().optional().label("Page URL"),
2436
+ status: (0, import_yup24.mixed)().oneOf(SupportedFeedbackStatuses).optional().label("Status")
2364
2437
  }).label("Feedback Schema");
2365
2438
 
2366
2439
  // src/user/user.schema.ts
2367
- var import_yup36 = require("yup");
2440
+ var import_yup37 = require("yup");
2368
2441
 
2369
2442
  // src/user/work-experience.schema.ts
2370
- var import_yup24 = require("yup");
2371
- var WorkExperienceSchema = (0, import_yup24.object)().shape({
2443
+ var import_yup25 = require("yup");
2444
+ var WorkExperienceSchema = (0, import_yup25.object)().shape({
2372
2445
  company: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company"),
2373
- designation: (0, import_yup24.string)().trim().required().label("Designation"),
2446
+ designation: (0, import_yup25.string)().trim().required().label("Designation"),
2374
2447
  duration: DurationSchema({
2375
2448
  format: "YYYY-MM",
2376
2449
  startLabel: "Start Date",
2377
2450
  endLabel: "End Date"
2378
2451
  }).required().label("Duration"),
2379
- description: (0, import_yup24.string)().trim().max(3e3).optional().label("Description"),
2452
+ description: (0, import_yup25.string)().trim().max(3e3).optional().label("Description"),
2380
2453
  location: LocationSchema.required().label("Location"),
2381
- isRemote: (0, import_yup24.boolean)().oneOf([true, false]).default(false).label("Is Remote")
2454
+ isRemote: (0, import_yup25.boolean)().oneOf([true, false]).default(false).label("Is Remote")
2382
2455
  }).noUnknown().strict().label("Work Experience");
2383
2456
 
2384
2457
  // src/user/education.schema.ts
2385
- var import_yup25 = require("yup");
2386
- var EducationSchema = (0, import_yup25.object)({
2458
+ var import_yup26 = require("yup");
2459
+ var EducationSchema = (0, import_yup26.object)({
2387
2460
  institute: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute"),
2388
- course: (0, import_yup25.string)().trim().required().label("Course"),
2389
- fieldOfStudy: (0, import_yup25.string)().trim().required().label("Field of Study"),
2461
+ course: (0, import_yup26.string)().trim().required().label("Course"),
2462
+ fieldOfStudy: (0, import_yup26.string)().trim().required().label("Field of Study"),
2390
2463
  duration: DurationSchema({
2391
2464
  format: "YYYY-MM",
2392
2465
  startLabel: "Start Date",
2393
2466
  endLabel: "End Date"
2394
2467
  }).required().label("Duration"),
2395
- description: (0, import_yup25.string)().trim().max(3e3).optional().label("Description"),
2396
- isDistanceLearning: (0, import_yup25.boolean)().default(false).label("Is Distance Learning"),
2468
+ description: (0, import_yup26.string)().trim().max(3e3).optional().label("Description"),
2469
+ isDistanceLearning: (0, import_yup26.boolean)().default(false).label("Is Distance Learning"),
2397
2470
  location: LocationSchema.required().label("Location"),
2398
- studyType: (0, import_yup25.string)().oneOf(SupportedStudyTypes).trim().max(50).required().label("Study Type")
2471
+ studyType: (0, import_yup26.string)().oneOf(SupportedStudyTypes).trim().max(50).required().label("Study Type")
2399
2472
  }).noUnknown().strict().label("Education");
2400
2473
 
2401
2474
  // src/user/user-skill.schema.ts
2402
- var import_yup26 = require("yup");
2403
- var UserSkillSchema = (0, import_yup26.object)({
2404
- name: (0, import_yup26.string)().required().label("Name"),
2405
- proficiencyLevel: (0, import_yup26.string)().oneOf(SupportedProficiencyLevels).required().label("Proficiency Level"),
2475
+ var import_yup27 = require("yup");
2476
+ var UserSkillSchema = (0, import_yup27.object)({
2477
+ name: (0, import_yup27.string)().required().label("Name"),
2478
+ proficiencyLevel: (0, import_yup27.string)().oneOf(SupportedProficiencyLevels).required().label("Proficiency Level"),
2406
2479
  lastUsed: dateString().format("YYYY-MM").nullable().optional().label("Last Used")
2407
2480
  }).noUnknown().strict().label("Skill");
2408
2481
 
2409
2482
  // src/user/project.schema.ts
2410
- var import_yup27 = require("yup");
2411
- var UserProjectSchema = (0, import_yup27.object)({
2412
- name: (0, import_yup27.string)().trim().max(50).required().label("Name"),
2413
- url: (0, import_yup27.string)().optional().label("URL"),
2414
- description: (0, import_yup27.string)().trim().min(100).max(3e3).required().label("Description"),
2483
+ var import_yup28 = require("yup");
2484
+ var UserProjectSchema = (0, import_yup28.object)({
2485
+ name: (0, import_yup28.string)().trim().max(50).required().label("Name"),
2486
+ url: (0, import_yup28.string)().optional().label("URL"),
2487
+ description: (0, import_yup28.string)().trim().min(100).max(3e3).required().label("Description"),
2415
2488
  duration: DurationSchema({
2416
2489
  format: "YYYY-MM",
2417
2490
  startLabel: "Start Date",
@@ -2420,83 +2493,101 @@ var UserProjectSchema = (0, import_yup27.object)({
2420
2493
  }).noUnknown().strict().label("Project");
2421
2494
 
2422
2495
  // src/user/user-certification.schema.ts
2423
- var import_yup28 = require("yup");
2424
- var UserCertificationSchema = (0, import_yup28.object)({
2425
- name: (0, import_yup28.string)().trim().max(100).required().label("Name"),
2496
+ var import_yup29 = require("yup");
2497
+ var UserCertificationSchema = (0, import_yup29.object)({
2498
+ name: (0, import_yup29.string)().trim().max(100).required().label("Name"),
2426
2499
  // TODO: Add validation for authority
2427
- authority: (0, import_yup28.string)().trim().max(100).required().label("Authority"),
2428
- licenseNumber: (0, import_yup28.string)().trim().max(50).optional().label("License Number"),
2500
+ authority: (0, import_yup29.string)().trim().max(100).required().label("Authority"),
2501
+ licenseNumber: (0, import_yup29.string)().trim().max(50).optional().label("License Number"),
2429
2502
  duration: DurationSchema({
2430
2503
  format: "YYYY-MM",
2431
2504
  startLabel: "Start Date",
2432
2505
  endLabel: "End Date"
2433
2506
  }).optional().nullable().label("Duration"),
2434
- url: (0, import_yup28.string)().optional().label("URL")
2507
+ url: (0, import_yup29.string)().optional().label("URL")
2435
2508
  }).noUnknown().strict().label("Certification");
2436
2509
 
2437
2510
  // src/user/user-interest.schema.ts
2438
- var import_yup29 = require("yup");
2439
- var UserInterestSchema = (0, import_yup29.string)().trim().required().label("Interest");
2511
+ var import_yup30 = require("yup");
2512
+ var UserInterestSchema = (0, import_yup30.string)().trim().required().label("Interest");
2440
2513
 
2441
2514
  // src/user/user-language.schema.ts
2442
- var import_yup30 = require("yup");
2443
- var UserLanguageSchema = (0, import_yup30.object)({
2444
- name: (0, import_yup30.string)().trim().required().label("Name"),
2445
- proficiencyLevel: (0, import_yup30.string)().oneOf(SupportedProficiencyLevels).trim().max(50).required().label("Proficiency Level")
2515
+ var import_yup31 = require("yup");
2516
+ var UserLanguageSchema = (0, import_yup31.object)({
2517
+ name: (0, import_yup31.string)().trim().required().label("Name"),
2518
+ proficiencyLevel: (0, import_yup31.string)().oneOf(SupportedProficiencyLevels).trim().max(50).required().label("Proficiency Level")
2446
2519
  }).noUnknown().strict().label("Language");
2447
2520
 
2448
2521
  // src/user/user-additional-info.schema.ts
2449
- var import_yup31 = require("yup");
2450
- var UserAdditionalInfoSchema = (0, import_yup31.object)({
2451
- title: (0, import_yup31.string)().trim().max(60).required().label("Title"),
2452
- description: (0, import_yup31.string)().trim().max(1e3).required().label("Description")
2522
+ var import_yup32 = require("yup");
2523
+ var UserAdditionalInfoSchema = (0, import_yup32.object)({
2524
+ title: (0, import_yup32.string)().trim().max(60).required().label("Title"),
2525
+ description: (0, import_yup32.string)().trim().max(1e3).required().label("Description")
2453
2526
  }).noUnknown().strict().label("User Additional Info");
2454
2527
 
2455
2528
  // src/user/general-detail.schema.ts
2456
- var import_yup32 = require("yup");
2457
- var UserGeneralDetailSchema = (0, import_yup32.object)({
2458
- id: (0, import_yup32.string)().optional().label("ID"),
2459
- name: (0, import_yup32.object)().shape({
2460
- first: (0, import_yup32.string)().trim().max(50).required().label("First Name"),
2461
- last: (0, import_yup32.string)().trim().max(50).optional().label("Last Name")
2529
+ var import_yup33 = require("yup");
2530
+ var UserGeneralDetailSchema = (0, import_yup33.object)({
2531
+ id: (0, import_yup33.string)().optional().label("ID"),
2532
+ name: (0, import_yup33.object)().shape({
2533
+ first: (0, import_yup33.string)().trim().max(50).required().label("First Name"),
2534
+ last: (0, import_yup33.string)().trim().max(50).optional().label("Last Name")
2462
2535
  }).required().label("Name"),
2463
- headline: (0, import_yup32.string)().trim().max(200).optional().label("Headline"),
2464
- image: (0, import_yup32.string)().optional().label("Image"),
2465
- aboutMe: (0, import_yup32.string)().trim().max(3e3).optional().label("About Me"),
2466
- email: (0, import_yup32.string)().required().label("Email"),
2467
- mobile: (0, import_yup32.string)().nullable().optional().label("Mobile"),
2468
- emailVerified: (0, import_yup32.string)().nullable().optional().label("Email Verified"),
2469
- mobileVerified: (0, import_yup32.string)().nullable().optional().label("Mobile Verified"),
2470
- experienceLevel: (0, import_yup32.string)().oneOf(SupportedExperienceLevels).required().label("Experience level"),
2536
+ headline: (0, import_yup33.string)().trim().max(200).optional().label("Headline"),
2537
+ image: (0, import_yup33.string)().optional().label("Image"),
2538
+ aboutMe: (0, import_yup33.string)().trim().max(3e3).optional().label("About Me"),
2539
+ email: (0, import_yup33.string)().required().label("Email"),
2540
+ mobile: (0, import_yup33.string)().nullable().optional().label("Mobile"),
2541
+ emailVerified: (0, import_yup33.string)().nullable().optional().label("Email Verified"),
2542
+ mobileVerified: (0, import_yup33.string)().nullable().optional().label("Mobile Verified"),
2543
+ experienceLevel: (0, import_yup33.string)().oneOf(SupportedExperienceLevels).required().label("Experience level"),
2471
2544
  location: LocationSchema.required().label("Location"),
2472
- region: (0, import_yup32.object)().shape({
2473
- country: (0, import_yup32.string)().trim().required().label("Region Country"),
2474
- lang: (0, import_yup32.string)().trim().required().label("Region Language")
2475
- }).optional().default(void 0).label("Region"),
2476
- profileVisibility: (0, import_yup32.string)().oneOf(SupportedUserProfileVisibilities).default("public" /* Public */).label("Profile Visibility")
2545
+ /**
2546
+ * Where the account was created, captured once and never rewritten.
2547
+ *
2548
+ * Server-owned: listed in user-service's SERVER_CONTROLLED_FIELDS and absent
2549
+ * from every user-writable schema, so a client cannot set or amend it. That
2550
+ * immutability is the point — this answers "which market/jurisdiction governed
2551
+ * this user at sign-up?", which a field the user can PATCH could never do.
2552
+ *
2553
+ * `source` records HOW the value was obtained, because most of it is inferred
2554
+ * rather than measured, and an audit has to be able to tell those apart:
2555
+ * - `cf-header` measured from Cloudflare's `cf-ipcountry` at sign-up
2556
+ * - `location` derived from the user's self-entered profile location
2557
+ * - `default` assumed (no signal available); presumption, not evidence
2558
+ */
2559
+ signupContext: (0, import_yup33.object)().shape({
2560
+ // ISO 3166-1 alpha-2, uppercase — the shape `cf-ipcountry` returns, so
2561
+ // measured and inferred values are directly comparable.
2562
+ country: (0, import_yup33.string)().trim().uppercase().length(2).required().label("Signup Country"),
2563
+ locale: (0, import_yup33.string)().trim().required().label("Signup Locale"),
2564
+ source: (0, import_yup33.string)().oneOf(SupportedSignupContextSources).required().label("Signup Context Source"),
2565
+ at: (0, import_yup33.number)().required().label("Signup Context At")
2566
+ }).optional().default(void 0).label("Signup Context"),
2567
+ profileVisibility: (0, import_yup33.string)().oneOf(SupportedUserProfileVisibilities).default("public" /* Public */).label("Profile Visibility")
2477
2568
  }).noUnknown().strict().label("General Detail");
2478
2569
 
2479
2570
  // src/user/user-job-preferences.schema.ts
2480
- var import_yup33 = require("yup");
2481
- var UserJobPreferencesSchema = (0, import_yup33.object)({
2571
+ var import_yup34 = require("yup");
2572
+ var UserJobPreferencesSchema = (0, import_yup34.object)({
2482
2573
  /**
2483
2574
  * Whether the job seeker is openly signalling availability. Surfaces the
2484
2575
  * "Open to work" badge on the public profile and boosts visibility in
2485
2576
  * recruiter search. Defaults to `false` - users must opt in.
2486
2577
  */
2487
- openToWork: (0, import_yup33.boolean)().default(false).label("Open to Work"),
2578
+ openToWork: (0, import_yup34.boolean)().default(false).label("Open to Work"),
2488
2579
  /**
2489
2580
  * How urgently the user is looking for their next job. Drives match scoring
2490
2581
  * and can downgrade the visibility of expired or low-relevance postings for
2491
2582
  * users in `passively_browsing` mode.
2492
2583
  */
2493
- jobSearchUrgency: (0, import_yup33.string)().oneOf(SupportedJobSearchUrgencies).required().label("Job Search Urgency"),
2584
+ jobSearchUrgency: (0, import_yup34.string)().oneOf(SupportedJobSearchUrgencies).required().label("Job Search Urgency"),
2494
2585
  /**
2495
2586
  * Locations the user wants to work in. Stores the full `LocationSchema`
2496
2587
  * shape (country, city, state, geo, etc.) as returned by the locations
2497
2588
  * autocomplete API.
2498
2589
  */
2499
- jobLocations: (0, import_yup33.array)().of(LocationSchema.required().label("Job Location")).min(1, "Pick at least one preferred location.").required().label("Job Locations"),
2590
+ jobLocations: (0, import_yup34.array)().of(LocationSchema.required().label("Job Location")).min(1, "Pick at least one preferred location.").required().label("Job Locations"),
2500
2591
  /**
2501
2592
  * Seniority levels the user wants jobs to be matched against. Multi-select
2502
2593
  * (up to 2) for borderline candidates.
@@ -2507,7 +2598,7 @@ var UserJobPreferencesSchema = (0, import_yup33.object)({
2507
2598
  * Both reuse the same `ExperienceLevel` taxonomy from `common.constant.ts`
2508
2599
  * so search/match logic doesn't have to translate between two vocabularies.
2509
2600
  */
2510
- targetExperienceLevels: (0, import_yup33.array)().of((0, import_yup33.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"),
2601
+ targetExperienceLevels: (0, import_yup34.array)().of((0, import_yup34.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"),
2511
2602
  /**
2512
2603
  * Specializations the user is searching for - free-form titles.
2513
2604
  *
@@ -2516,19 +2607,19 @@ var UserJobPreferencesSchema = (0, import_yup33.object)({
2516
2607
  * surfaces a curated "Popular Roles" picker for discovery, but the user
2517
2608
  * can ultimately add any title; matching/normalization happens downstream.
2518
2609
  */
2519
- jobRoles: (0, import_yup33.array)().of((0, import_yup33.string)().trim().max(120).required()).min(1, "Pick at least one role.").required().label("Job Roles"),
2610
+ jobRoles: (0, import_yup34.array)().of((0, import_yup34.string)().trim().max(120).required()).min(1, "Pick at least one role.").required().label("Job Roles"),
2520
2611
  /**
2521
2612
  * Minimum acceptable annual base salary, in `minSalaryCurrency`.
2522
2613
  * Stored as an integer in the currency's major unit (e.g. dollars, not cents).
2523
2614
  * Defaults to 0 ("any salary") rather than being optional - every job-seeker
2524
2615
  * has a floor, even if it's zero.
2525
2616
  */
2526
- minSalary: (0, import_yup33.number)().integer().min(MIN_SALARY_LOWER_BOUND).max(MIN_SALARY_UPPER_BOUND).default(0).required().label("Minimum Salary"),
2527
- minSalaryCurrency: (0, import_yup33.string)().oneOf(SupportedSalaryCurrencies).default("USD").required().label("Minimum Salary Currency"),
2617
+ minSalary: (0, import_yup34.number)().integer().min(MIN_SALARY_LOWER_BOUND).max(MIN_SALARY_UPPER_BOUND).default(0).required().label("Minimum Salary"),
2618
+ minSalaryCurrency: (0, import_yup34.string)().oneOf(SupportedSalaryCurrencies).default("USD").required().label("Minimum Salary Currency"),
2528
2619
  /**
2529
2620
  * Marketing-attribution capture from the final onboarding step.
2530
2621
  */
2531
- referralSource: (0, import_yup33.string)().oneOf(SupportedReferralSources).required().label("Referral Source"),
2622
+ referralSource: (0, import_yup34.string)().oneOf(SupportedReferralSources).required().label("Referral Source"),
2532
2623
  /**
2533
2624
  * Resumes the user has uploaded. Embedded directly on the user document
2534
2625
  * (capped at 5) - they're cheap to denormalize, every wizard step that
@@ -2542,25 +2633,25 @@ var UserJobPreferencesSchema = (0, import_yup33.object)({
2542
2633
  * AI resume-builder flow - onboarding uploads land here, AI-built resumes
2543
2634
  * live in their own collection.
2544
2635
  */
2545
- resumes: (0, import_yup33.array)().of(
2546
- (0, import_yup33.object)({
2636
+ resumes: (0, import_yup34.array)().of(
2637
+ (0, import_yup34.object)({
2547
2638
  // Stable id assigned on upload - used to address a specific entry
2548
2639
  // for delete / set-primary operations without exposing the GCS URL
2549
2640
  // as a route key.
2550
- id: (0, import_yup33.string)().required().label("ID"),
2551
- url: (0, import_yup33.string)().required().label("Resume URL"),
2552
- filename: (0, import_yup33.string)().trim().max(255).optional().label("Filename"),
2553
- sizeBytes: (0, import_yup33.number)().integer().min(0).optional().label("Size (bytes)"),
2554
- mimeType: (0, import_yup33.string)().trim().max(120).optional().label("MIME Type"),
2555
- uploadedAt: (0, import_yup33.date)().required().label("Uploaded At"),
2556
- isPrimary: (0, import_yup33.boolean)().default(false).label("Is Primary")
2641
+ id: (0, import_yup34.string)().required().label("ID"),
2642
+ url: (0, import_yup34.string)().required().label("Resume URL"),
2643
+ filename: (0, import_yup34.string)().trim().max(255).optional().label("Filename"),
2644
+ sizeBytes: (0, import_yup34.number)().integer().min(0).optional().label("Size (bytes)"),
2645
+ mimeType: (0, import_yup34.string)().trim().max(120).optional().label("MIME Type"),
2646
+ uploadedAt: (0, import_yup34.date)().required().label("Uploaded At"),
2647
+ isPrimary: (0, import_yup34.boolean)().default(false).label("Is Primary")
2557
2648
  }).noUnknown().strict().label("Resume")
2558
2649
  ).max(5, "You can keep at most 5 resumes on file.").default([]).label("Resumes"),
2559
2650
  /**
2560
2651
  * Set when the user finishes the wizard's last step. Acts as the gate the
2561
2652
  * onboarding hook checks to redirect users who haven't completed setup.
2562
2653
  */
2563
- onboardingCompletedAt: (0, import_yup33.date)().nullable().optional().label("Onboarding Completed At"),
2654
+ onboardingCompletedAt: (0, import_yup34.date)().nullable().optional().label("Onboarding Completed At"),
2564
2655
  /**
2565
2656
  * Parser-suggested values for wizard fields, written by the resume-upload
2566
2657
  * flow. Every parser-derived field lands here - including profile-shaped
@@ -2580,92 +2671,92 @@ var UserJobPreferencesSchema = (0, import_yup33.object)({
2580
2671
  * APIs. If `user.<field>` is empty there, the correct behavior is empty,
2581
2672
  * because the user has not confirmed it yet.
2582
2673
  */
2583
- pendingPrefill: (0, import_yup33.object)({
2584
- headline: (0, import_yup33.string)().trim().optional().label("Pending Headline"),
2585
- aboutMe: (0, import_yup33.string)().trim().optional().label("Pending About Me"),
2586
- mobile: (0, import_yup33.string)().trim().optional().label("Pending Mobile"),
2674
+ pendingPrefill: (0, import_yup34.object)({
2675
+ headline: (0, import_yup34.string)().trim().optional().label("Pending Headline"),
2676
+ aboutMe: (0, import_yup34.string)().trim().optional().label("Pending About Me"),
2677
+ mobile: (0, import_yup34.string)().trim().optional().label("Pending Mobile"),
2587
2678
  location: LocationSchema.optional().default(void 0).label("Pending Location"),
2588
- experienceLevel: (0, import_yup33.string)().oneOf(SupportedExperienceLevels).optional().label("Pending Experience Level"),
2589
- socialAccounts: (0, import_yup33.array)().of(SocialAccountSchema.required()).optional().label("Pending Social Accounts"),
2590
- workExperiences: (0, import_yup33.array)().of(WorkExperienceSchema.required()).optional().label("Pending Work Experiences"),
2591
- educations: (0, import_yup33.array)().of(EducationSchema.required()).optional().label("Pending Educations")
2679
+ experienceLevel: (0, import_yup34.string)().oneOf(SupportedExperienceLevels).optional().label("Pending Experience Level"),
2680
+ socialAccounts: (0, import_yup34.array)().of(SocialAccountSchema.required()).optional().label("Pending Social Accounts"),
2681
+ workExperiences: (0, import_yup34.array)().of(WorkExperienceSchema.required()).optional().label("Pending Work Experiences"),
2682
+ educations: (0, import_yup34.array)().of(EducationSchema.required()).optional().label("Pending Educations")
2592
2683
  }).nullable().optional().default(void 0).label("Pending Prefill")
2593
2684
  }).noUnknown().strict().label("User Job Preferences Schema");
2594
2685
 
2595
2686
  // src/user/user-recruiter-profile.schema.ts
2596
- var import_yup34 = require("yup");
2597
- var RecruiterPageLinkSchema = (0, import_yup34.object)({
2687
+ var import_yup35 = require("yup");
2688
+ var RecruiterPageLinkSchema = (0, import_yup35.object)({
2598
2689
  page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Company Page"),
2599
- jobTitle: (0, import_yup34.string)().trim().max(100).optional().label("Job Title")
2690
+ jobTitle: (0, import_yup35.string)().trim().max(100).optional().label("Job Title")
2600
2691
  }).noUnknown().strict().label("Recruiter Page Link");
2601
- var UserRecruiterProfileSchema = (0, import_yup34.object)({
2602
- recruiterProfile: (0, import_yup34.object)({
2603
- hiringFor: (0, import_yup34.array)().of(RecruiterPageLinkSchema).default([]).label("Hiring For")
2692
+ var UserRecruiterProfileSchema = (0, import_yup35.object)({
2693
+ recruiterProfile: (0, import_yup35.object)({
2694
+ hiringFor: (0, import_yup35.array)().of(RecruiterPageLinkSchema).default([]).label("Hiring For")
2604
2695
  }).optional().default(void 0).label("Recruiter Profile")
2605
2696
  }).noUnknown().strict().label("User Recruiter Profile");
2606
2697
 
2607
2698
  // src/user/user-coordinator-profile.schema.ts
2608
- var import_yup35 = require("yup");
2609
- var CoordinatorPageLinkSchema = (0, import_yup35.object)({
2699
+ var import_yup36 = require("yup");
2700
+ var CoordinatorPageLinkSchema = (0, import_yup36.object)({
2610
2701
  page: PageSchema.pick(["name", "slug", "type", "logo"]).deepPartial().concat(PageSchema.pick(["name", "type"])).required().label("Institute Page"),
2611
- jobTitle: (0, import_yup35.string)().trim().max(100).optional().label("Job Title")
2702
+ jobTitle: (0, import_yup36.string)().trim().max(100).optional().label("Job Title")
2612
2703
  }).noUnknown().strict().label("Coordinator Page Link");
2613
- var UserCoordinatorProfileSchema = (0, import_yup35.object)({
2614
- coordinatorProfile: (0, import_yup35.object)({
2615
- coordinatesAt: (0, import_yup35.array)().of(CoordinatorPageLinkSchema).default([]).label("Coordinates At")
2704
+ var UserCoordinatorProfileSchema = (0, import_yup36.object)({
2705
+ coordinatorProfile: (0, import_yup36.object)({
2706
+ coordinatesAt: (0, import_yup36.array)().of(CoordinatorPageLinkSchema).default([]).label("Coordinates At")
2616
2707
  }).optional().default(void 0).label("Coordinator Profile")
2617
2708
  }).noUnknown().strict().label("User Coordinator Profile");
2618
2709
 
2619
2710
  // src/user/user.schema.ts
2620
- var UserSchema = (0, import_yup36.object)({
2711
+ var UserSchema = (0, import_yup37.object)({
2621
2712
  /**
2622
2713
  * Related auth account id from auth Server (e.g. Better auth https://auth.thejob.dev)
2623
2714
  */
2624
- authAccountId: (0, import_yup36.string)().required().label("Auth Account ID"),
2715
+ authAccountId: (0, import_yup37.string)().required().label("Auth Account ID"),
2625
2716
  /**
2626
2717
  * Social media information about the user (e.g. LinkedIn, GitHub, etc.)
2627
2718
  */
2628
- socialAccounts: (0, import_yup36.array)().of(SocialAccountSchema).default([]).label("Social Accounts"),
2719
+ socialAccounts: (0, import_yup37.array)().of(SocialAccountSchema).default([]).label("Social Accounts"),
2629
2720
  /**
2630
2721
  * Work experience information about the user
2631
2722
  */
2632
- workExperiences: (0, import_yup36.array)().of(WorkExperienceSchema).required().default([]).label("Work Experiences"),
2723
+ workExperiences: (0, import_yup37.array)().of(WorkExperienceSchema).required().default([]).label("Work Experiences"),
2633
2724
  /**
2634
2725
  * Education information about the user
2635
2726
  */
2636
- educations: (0, import_yup36.array)().of(EducationSchema).required().default([]).label("Educations"),
2727
+ educations: (0, import_yup37.array)().of(EducationSchema).required().default([]).label("Educations"),
2637
2728
  /**
2638
2729
  * Skills information about the user
2639
2730
  */
2640
- skills: (0, import_yup36.array)().of(UserSkillSchema).required().default([]).label("Skills"),
2731
+ skills: (0, import_yup37.array)().of(UserSkillSchema).required().default([]).label("Skills"),
2641
2732
  /**
2642
2733
  * Projects information about the user
2643
2734
  */
2644
- projects: (0, import_yup36.array)().of(UserProjectSchema).default([]).label("Projects"),
2735
+ projects: (0, import_yup37.array)().of(UserProjectSchema).default([]).label("Projects"),
2645
2736
  /**
2646
2737
  * Certifications information about the user
2647
2738
  */
2648
- certifications: (0, import_yup36.array)().of(UserCertificationSchema).default([]).label("Certifications"),
2739
+ certifications: (0, import_yup37.array)().of(UserCertificationSchema).default([]).label("Certifications"),
2649
2740
  /**
2650
2741
  * Interests information about the user.
2651
2742
  */
2652
- interests: (0, import_yup36.array)().of(UserInterestSchema).optional().default([]).label("Interests"),
2743
+ interests: (0, import_yup37.array)().of(UserInterestSchema).optional().default([]).label("Interests"),
2653
2744
  /**
2654
2745
  * Languages information about the user
2655
2746
  */
2656
- languages: (0, import_yup36.array)().of(UserLanguageSchema).required().default([]).label("Languages"),
2747
+ languages: (0, import_yup37.array)().of(UserLanguageSchema).required().default([]).label("Languages"),
2657
2748
  /**
2658
2749
  * Additional information about the user
2659
2750
  */
2660
- additionalInfo: (0, import_yup36.array)().of(UserAdditionalInfoSchema).default([]).label("Additional Information"),
2751
+ additionalInfo: (0, import_yup37.array)().of(UserAdditionalInfoSchema).default([]).label("Additional Information"),
2661
2752
  /**
2662
2753
  * Status of the user account
2663
2754
  */
2664
- status: (0, import_yup36.string)().oneOf(SupportedUserStatuses).required().label("Status"),
2755
+ status: (0, import_yup37.string)().oneOf(SupportedUserStatuses).required().label("Status"),
2665
2756
  /**
2666
2757
  * Roles assigned to the user
2667
2758
  */
2668
- roles: (0, import_yup36.array)().of((0, import_yup36.string)().oneOf(SupportedUserRoles)).required().default(DefaultUserRoles).label("Roles"),
2759
+ roles: (0, import_yup37.array)().of((0, import_yup37.string)().oneOf(SupportedUserRoles)).required().default(DefaultUserRoles).label("Roles"),
2669
2760
  /**
2670
2761
  * Explicit consent to receive marketing email (newsletters, job alerts by
2671
2762
  * broadcast, product updates). Marketing sends are HARD-GATED on
@@ -2677,18 +2768,18 @@ var UserSchema = (0, import_yup36.object)({
2677
2768
  * unsubscribe sets `subscribed=false` so consent and the email-service
2678
2769
  * suppression list stay consistent. Defaults to NOT subscribed (opt-in).
2679
2770
  */
2680
- marketingConsent: (0, import_yup36.object)({
2681
- subscribed: (0, import_yup36.boolean)().default(false).label("Subscribed to marketing email"),
2771
+ marketingConsent: (0, import_yup37.object)({
2772
+ subscribed: (0, import_yup37.boolean)().default(false).label("Subscribed to marketing email"),
2682
2773
  /** Epoch ms of the last consent change (opt-in or opt-out). */
2683
- updatedAt: (0, import_yup36.number)().optional().label("Consent updated at"),
2774
+ updatedAt: (0, import_yup37.number)().optional().label("Consent updated at"),
2684
2775
  /** Where the consent change originated, e.g. `onboarding`, `unsubscribe`, `settings`. */
2685
- source: (0, import_yup36.string)().optional().label("Consent source"),
2776
+ source: (0, import_yup37.string)().optional().label("Consent source"),
2686
2777
  /**
2687
2778
  * How often the user receives job-alert emails. `off` disables job alerts
2688
2779
  * only; other marketing stays governed by `subscribed`. Unset means the
2689
2780
  * user has not chosen a cadence yet.
2690
2781
  */
2691
- jobAlertFrequency: (0, import_yup36.string)().oneOf(SupportedJobAlertFrequencies).optional().label("Job alert frequency")
2782
+ jobAlertFrequency: (0, import_yup37.string)().oneOf(SupportedJobAlertFrequencies).optional().label("Job alert frequency")
2692
2783
  }).default({ subscribed: false }).label("Marketing Consent"),
2693
2784
  /**
2694
2785
  * Per-channel toggles for NOTIFICATION email — mail about activity on the
@@ -2703,11 +2794,11 @@ var UserSchema = (0, import_yup36.object)({
2703
2794
  *
2704
2795
  * Transactional mail (magic-link, verification) ignores this object entirely.
2705
2796
  */
2706
- notificationPrefs: (0, import_yup36.object)({
2707
- groupActivity: (0, import_yup36.boolean)().default(true).label("Group activity email"),
2708
- jobActivity: (0, import_yup36.boolean)().default(true).label("Job activity email"),
2709
- applicationUpdates: (0, import_yup36.boolean)().default(true).label("Application update email"),
2710
- productUpdates: (0, import_yup36.boolean)().default(false).label("Product update email")
2797
+ notificationPrefs: (0, import_yup37.object)({
2798
+ groupActivity: (0, import_yup37.boolean)().default(true).label("Group activity email"),
2799
+ jobActivity: (0, import_yup37.boolean)().default(true).label("Job activity email"),
2800
+ applicationUpdates: (0, import_yup37.boolean)().default(true).label("Application update email"),
2801
+ productUpdates: (0, import_yup37.boolean)().default(false).label("Product update email")
2711
2802
  }).default({
2712
2803
  groupActivity: true,
2713
2804
  jobActivity: true,
@@ -2719,15 +2810,15 @@ var UserSchema = (0, import_yup36.object)({
2719
2810
  * Generated from a structured summary of skills, experience, education, etc.
2720
2811
  * Only generated for public profiles with sufficient completeness (≥60%).
2721
2812
  */
2722
- embedding: (0, import_yup36.object)({
2723
- vector: (0, import_yup36.array)((0, import_yup36.number)().required()).optional().label("Embedding vector"),
2724
- model: (0, import_yup36.string)().optional().label("Embedding model")
2813
+ embedding: (0, import_yup37.object)({
2814
+ vector: (0, import_yup37.array)((0, import_yup37.number)().required()).optional().label("Embedding vector"),
2815
+ model: (0, import_yup37.string)().optional().label("Embedding model")
2725
2816
  }).nullable().optional().label("Embedding")
2726
2817
  }).concat(UserGeneralDetailSchema).concat(UserJobPreferencesSchema).concat(UserRecruiterProfileSchema).concat(UserCoordinatorProfileSchema).noUnknown().strict().label("User Schema");
2727
2818
 
2728
2819
  // src/user/user-completeness.schema.ts
2729
- var import_yup37 = require("yup");
2730
- var UserCompletenessSchema = (0, import_yup37.object)({
2820
+ var import_yup38 = require("yup");
2821
+ var UserCompletenessSchema = (0, import_yup38.object)({
2731
2822
  additionalInfo: CompletenessScoreSchema(0).label("Additional Info"),
2732
2823
  // Optional
2733
2824
  certifications: CompletenessScoreSchema(0).label("Certifications"),
@@ -2820,6 +2911,9 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
2820
2911
  ResourceType,
2821
2912
  SITEMAP_FORMAT,
2822
2913
  SYSTEM_DATE_FORMAT,
2914
+ SavedSearchSchema,
2915
+ SavedSearchStatus,
2916
+ SignupContextSource,
2823
2917
  SkillSchema,
2824
2918
  SocialAccount,
2825
2919
  SocialAccountSchema,
@@ -2852,6 +2946,8 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
2852
2946
  SupportedReportReasons,
2853
2947
  SupportedResourceTypes,
2854
2948
  SupportedSalaryCurrencies,
2949
+ SupportedSavedSearchStatuses,
2950
+ SupportedSignupContextSources,
2855
2951
  SupportedSocialAccounts,
2856
2952
  SupportedStudyTypes,
2857
2953
  SupportedUserProfileVisibilities,