@thejob/schema 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -109,6 +109,7 @@ __export(index_exports, {
109
109
  JobStatus: () => JobStatus,
110
110
  JobSubCategory: () => JobSubCategory,
111
111
  LanguageFilterSchema: () => LanguageFilterSchema,
112
+ LiveSubscriptionStatuses: () => LiveSubscriptionStatuses,
112
113
  LocationSchema: () => LocationSchema,
113
114
  MIN_SALARY_LOWER_BOUND: () => MIN_SALARY_LOWER_BOUND,
114
115
  MIN_SALARY_UPPER_BOUND: () => MIN_SALARY_UPPER_BOUND,
@@ -126,6 +127,7 @@ __export(index_exports, {
126
127
  PageStatus: () => PageStatus,
127
128
  PageType: () => PageType,
128
129
  PaginationSchema: () => PaginationSchema,
130
+ PlanAudience: () => PlanAudience,
129
131
  PlanGrantSchema: () => PlanGrantSchema,
130
132
  PlanKind: () => PlanKind,
131
133
  PlanSchema: () => PlanSchema,
@@ -194,6 +196,7 @@ __export(index_exports, {
194
196
  SupportedPaddleEnvironments: () => SupportedPaddleEnvironments,
195
197
  SupportedPageStatuses: () => SupportedPageStatuses,
196
198
  SupportedPageTypes: () => SupportedPageTypes,
199
+ SupportedPlanAudiences: () => SupportedPlanAudiences,
197
200
  SupportedPlanKinds: () => SupportedPlanKinds,
198
201
  SupportedPlanStatuses: () => SupportedPlanStatuses,
199
202
  SupportedPostStatuses: () => SupportedPostStatuses,
@@ -3854,6 +3857,14 @@ var PlanStatus = /* @__PURE__ */ ((PlanStatus2) => {
3854
3857
  return PlanStatus2;
3855
3858
  })(PlanStatus || {});
3856
3859
  var SupportedPlanStatuses = Object.values(PlanStatus);
3860
+ var PlanAudience = /* @__PURE__ */ ((PlanAudience2) => {
3861
+ PlanAudience2["Employer"] = "employer";
3862
+ PlanAudience2["JobSeeker"] = "job-seeker";
3863
+ PlanAudience2["Recruiter"] = "recruiter";
3864
+ PlanAudience2["Company"] = "company";
3865
+ return PlanAudience2;
3866
+ })(PlanAudience || {});
3867
+ var SupportedPlanAudiences = Object.values(PlanAudience);
3857
3868
  var GrantType = /* @__PURE__ */ ((GrantType2) => {
3858
3869
  GrantType2["Boolean"] = "boolean";
3859
3870
  GrantType2["Quota"] = "quota";
@@ -3888,6 +3899,10 @@ var EntitlingSubscriptionStatuses = [
3888
3899
  "trialing" /* Trialing */,
3889
3900
  "past_due" /* PastDue */
3890
3901
  ];
3902
+ var LiveSubscriptionStatuses = [
3903
+ ...EntitlingSubscriptionStatuses,
3904
+ "paused" /* Paused */
3905
+ ];
3891
3906
  var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
3892
3907
  TransactionStatus2["Draft"] = "draft";
3893
3908
  TransactionStatus2["Ready"] = "ready";
@@ -3972,6 +3987,12 @@ var PlanSchema = (0, import_yup40.object)({
3972
3987
  name: (0, import_yup40.string)().required().min(1).max(120).label("Name"),
3973
3988
  description: (0, import_yup40.string)().optional().max(500).label("Description"),
3974
3989
  kind: (0, import_yup40.string)().oneOf(SupportedPlanKinds).required().default("subscription" /* Subscription */).label("Kind"),
3990
+ /**
3991
+ * The line this plan belongs to; a user holds one live subscription per line.
3992
+ * Optional on purpose: absent is the default line, so existing plans need no
3993
+ * migration and together still read as "one plan at a time".
3994
+ */
3995
+ audience: (0, import_yup40.string)().oneOf(SupportedPlanAudiences).optional().label("Audience"),
3975
3996
  status: (0, import_yup40.string)().oneOf(SupportedPlanStatuses).required().default("draft" /* Draft */).label("Status"),
3976
3997
  paddlePriceIds: PaddlePriceIdsSchema.default(
3977
3998
  () => PaddlePriceIdsSchema.getDefault()
@@ -4571,7 +4592,17 @@ var PushSubscriptionSchema = (0, import_yup54.object)({
4571
4592
  * device that stopped visiting, which is useful for pruning rows that never
4572
4593
  * fail loudly enough to be caught by a 410.
4573
4594
  */
4574
- lastSeenAt: (0, import_yup54.number)().optional().label("Last Seen At")
4595
+ lastSeenAt: (0, import_yup54.number)().optional().label("Last Seen At"),
4596
+ /**
4597
+ * Epoch ms the owner explicitly signed out on this device, or absent.
4598
+ *
4599
+ * A PAUSE, not a removal: the sender skips flagged rows, so a shared device
4600
+ * stops receiving the previous user's notifications, while the same user
4601
+ * signing back in clears the flag with no prompt. A flag rather than a delete
4602
+ * so that a MISSING row keeps one meaning to the browser ("stop, this device
4603
+ * was removed"), which it acts on by dropping its own subscription.
4604
+ */
4605
+ signedOutAt: (0, import_yup54.number)().nullable().optional().label("Signed Out At")
4575
4606
  }).noUnknown().strict().label("Push Subscription Schema");
4576
4607
 
4577
4608
  // src/user/user-completeness.schema.ts
@@ -4678,6 +4709,7 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4678
4709
  JobStatus,
4679
4710
  JobSubCategory,
4680
4711
  LanguageFilterSchema,
4712
+ LiveSubscriptionStatuses,
4681
4713
  LocationSchema,
4682
4714
  MIN_SALARY_LOWER_BOUND,
4683
4715
  MIN_SALARY_UPPER_BOUND,
@@ -4695,6 +4727,7 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4695
4727
  PageStatus,
4696
4728
  PageType,
4697
4729
  PaginationSchema,
4730
+ PlanAudience,
4698
4731
  PlanGrantSchema,
4699
4732
  PlanKind,
4700
4733
  PlanSchema,
@@ -4763,6 +4796,7 @@ var StudentCompletenessSchema = UserCompletenessSchema.omit([
4763
4796
  SupportedPaddleEnvironments,
4764
4797
  SupportedPageStatuses,
4765
4798
  SupportedPageTypes,
4799
+ SupportedPlanAudiences,
4766
4800
  SupportedPlanKinds,
4767
4801
  SupportedPlanStatuses,
4768
4802
  SupportedPostStatuses,
package/dist/index.d.cts CHANGED
@@ -3286,6 +3286,21 @@ declare enum PlanStatus {
3286
3286
  Archived = "archived"
3287
3287
  }
3288
3288
  declare const SupportedPlanStatuses: PlanStatus[];
3289
+ /**
3290
+ * The product line a plan belongs to. A user holds at most ONE live
3291
+ * subscription per audience: switching within a line updates that subscription,
3292
+ * it never adds a second one. Different audiences may be held side by side.
3293
+ *
3294
+ * A plan with no audience belongs to the single default line, which is every
3295
+ * plan seeded before this existed.
3296
+ */
3297
+ declare enum PlanAudience {
3298
+ Employer = "employer",
3299
+ JobSeeker = "job-seeker",
3300
+ Recruiter = "recruiter",
3301
+ Company = "company"
3302
+ }
3303
+ declare const SupportedPlanAudiences: PlanAudience[];
3289
3304
  /**
3290
3305
  * How a grant gives access to a feature.
3291
3306
  *
@@ -3344,6 +3359,12 @@ declare enum SubscriptionStatus {
3344
3359
  declare const SupportedSubscriptionStatuses: SubscriptionStatus[];
3345
3360
  /** Subscription statuses that currently entitle the holder to their plan's grants. */
3346
3361
  declare const EntitlingSubscriptionStatuses: SubscriptionStatus[];
3362
+ /**
3363
+ * Subscription statuses that still occupy the user's slot in a plan audience.
3364
+ * Wider than `EntitlingSubscriptionStatuses`: a paused subscription grants
3365
+ * nothing, but buying again would still leave two subscriptions to one plan.
3366
+ */
3367
+ declare const LiveSubscriptionStatuses: SubscriptionStatus[];
3347
3368
  /** Paddle transaction status, verbatim. `completed` is where a one-off is fulfilled. */
3348
3369
  declare enum TransactionStatus {
3349
3370
  Draft = "draft",
@@ -3468,6 +3489,7 @@ declare const PlanSchema: yup.ObjectSchema<{
3468
3489
  name: string;
3469
3490
  description: string | undefined;
3470
3491
  kind: NonNullable<PlanKind | undefined>;
3492
+ audience: PlanAudience | undefined;
3471
3493
  status: NonNullable<PlanStatus | undefined>;
3472
3494
  paddlePriceIds: {
3473
3495
  sandbox: string[];
@@ -3493,6 +3515,7 @@ declare const PlanSchema: yup.ObjectSchema<{
3493
3515
  name: undefined;
3494
3516
  description: undefined;
3495
3517
  kind: PlanKind.Subscription;
3518
+ audience: undefined;
3496
3519
  status: PlanStatus.Draft;
3497
3520
  paddlePriceIds: {
3498
3521
  sandbox: never[];
@@ -4392,6 +4415,7 @@ declare const PushSubscriptionSchema: yup.ObjectSchema<{
4392
4415
  userAgent: string | undefined;
4393
4416
  createdAt: number | undefined;
4394
4417
  lastSeenAt: number | undefined;
4418
+ signedOutAt: number | null | undefined;
4395
4419
  }, yup.AnyObject, {
4396
4420
  userShortId: undefined;
4397
4421
  endpoint: undefined;
@@ -4403,6 +4427,7 @@ declare const PushSubscriptionSchema: yup.ObjectSchema<{
4403
4427
  userAgent: undefined;
4404
4428
  createdAt: undefined;
4405
4429
  lastSeenAt: undefined;
4430
+ signedOutAt: undefined;
4406
4431
  }, "">;
4407
4432
 
4408
4433
  declare const UserLanguageSchema: yup.ObjectSchema<{
@@ -5314,4 +5339,4 @@ declare const StudentCompletenessSchema: yup.ObjectSchema<{
5314
5339
  };
5315
5340
  }, "">;
5316
5341
 
5317
- export { AnswerChoiceType, ApplicationReceivePreference, BillingPeriod, BillingSubscriptionSchema, BillingTransactionSchema, CAMPAIGN_MAX_RECIPIENTS_CEILING, CONSUME_MAX_UNITS, CampaignDataSourceSchema, CampaignEndKind, CampaignIntervalUnit, CampaignSchema, CampaignStatus, CampaignStatusTransitions, CampaignTriggerKind, CampaignTriggerSchema, ChoiceQuestionSchema, type City, CityFilterSchema, CitySchema, Common, CompensationType, CompletenessScoreSchema, ContactTypes, CoordinatorPageLinkSchema, type Country, CountryFilterSchema, CountrySchema, type CountryTimezone, DISPLAY_DATE_FORMAT, DISPLAY_DATE_FORMAT_SHORT, DateStringSchema, DbDefaultSchema, DefaultPaginatedResponse, DefaultPaginationOptions, DefaultUserRoles, DurationSchema, EMPTY_STRING, EducationLevel, EducationSchema, EmployeeCount, EmploymentType, EntitlementConsumeSchema, EntitlementDenialReason, EntitlementDenialSchema, EntitlingSubscriptionStatuses, ExperienceLevel, FEEDBACK_MESSAGE_MAX, FeatureEntitlementSchema, FeatureKey, FeedbackFilterSchema, FeedbackSchema, FeedbackStatus, FeedbackType, GEO_COLLECTIONS, GEO_SEARCH_MAX, GRANT_MAX_LIMIT, GeneraDetailFields, GeoKind, type GeoSyncCounts, GeoSyncPhase, type GeoSyncRun, GeoSyncRunSchema, GeoSyncStatus, GeoSyncTrigger, type GeoTranslations, GrantType, GroupFilterSchema, GroupManagedBy, GroupMembershipSchema, GroupMembershipStatus, GroupSchema, GroupStatus, GroupTranslationSchema, GroupVisibility, InputQuestionSchema, JOB_TAXONOMY, JobAlertFrequency, JobCategory, JobFilterSchema, JobIndustry, JobSchema, JobSearchUrgency, JobStatus, JobSubCategory, LanguageFilterSchema, LocationSchema, MIN_SALARY_LOWER_BOUND, MIN_SALARY_UPPER_BOUND, MailingListFilterSchema, MailingListSchema, MoneySchema, NotificationType, OccurrenceStatus, PREFILL_MIRRORED_KEYS, PRIVATE_PROFILE_FIELDS, PaddleEnvironment, PaddlePriceIdsSchema, PageFilterSchema, PageSchema, PageStatus, PageType, type PaginatedResponse, PaginationSchema, PlanGrantSchema, PlanKind, PlanSchema, PlanStatus, PostSchema, PostStatus, type PrefillMirroredKey, type PrivateProfileField, ProficiencyLevel, type PushSubscriptionRecord, PushSubscriptionSchema, QuestionSchema, QuestionType, QuotaPeriod, ReadAndAcknowledgeQuestionSchema, RecruiterPageLinkSchema, ReferralSource, ReportReason, ReportSchema, ResourceType, SITEMAP_FORMAT, SYSTEM_DATE_FORMAT, SavedSearchSchema, SavedSearchStatus, SignupContextSource, SkillFilterSchema, SkillSchema, SocialAccount, SocialAccountSchema, type State, StateFilterSchema, StateSchema, StudentCompletenessSchema, StudyType, SubscriptionStatus, SupportedAnswerChoiceTypes, SupportedApplicationReceivePreferences, SupportedBillingPeriods, SupportedCampaignEndKinds, SupportedCampaignIntervalUnits, SupportedCampaignStatuses, SupportedCampaignTriggerKinds, SupportedCompensationTypes, SupportedContactTypes, SupportedEducationLevels, SupportedEmployeeCounts, SupportedEmploymentTypes, SupportedEntitlementDenialReasons, SupportedExperienceLevels, SupportedFeatureKeys, SupportedFeedbackStatuses, SupportedFeedbackTypes, SupportedGeoKinds, SupportedGeoSyncPhases, SupportedGeoSyncStatuses, SupportedGeoSyncTriggers, SupportedGrantTypes, SupportedGroupManagedBy, SupportedGroupMembershipStatuses, SupportedGroupStatuses, SupportedGroupVisibilities, SupportedJobAlertFrequencies, SupportedJobCategories, SupportedJobIndustries, SupportedJobSearchUrgencies, SupportedJobStatuses, SupportedJobSubCategories, SupportedNotificationTypes, SupportedOccurrenceStatuses, SupportedPaddleEnvironments, SupportedPageStatuses, SupportedPageTypes, SupportedPlanKinds, SupportedPlanStatuses, SupportedPostStatuses, SupportedProficiencyLevels, SupportedQuestionTypes, SupportedQuotaPeriods, SupportedReferralSources, SupportedReportReasons, SupportedResourceTypes, SupportedSalaryCurrencies, type SupportedSalaryCurrency, SupportedSavedSearchStatuses, SupportedSignupContextSources, SupportedSocialAccounts, SupportedStudyTypes, SupportedSubscriptionStatuses, SupportedTemplateVariableBindingKinds, SupportedTransactionStatuses, SupportedUserProfileVisibilities, SupportedUserRoles, SupportedUserStatuses, SupportedWorkModes, TAXONOMY_LABELS, type TChoiceQuestionSchema, type TDurationSchema, type TInputQuestionSchema, type TJobSchema, type TPostSchema, type TQuestionSchema, type TReadAndAcknowledgeQuestionSchema, type TUserIdAndCreatedAtSchema, TemplateVariableBindingKind, TemplateVariableBindingSchema, TerminalCampaignStatuses, TerminalGeoSyncStatuses, TermsAcceptedSchema, TransactionStatus, type User, UserAdditionalInfoSchema, UserCertificationSchema, UserCompletenessSchema, UserCoordinatorProfileSchema, UserDetailType, UserFilterSchema, UserGeneralDetailSchema, UserIdAndCreatedAtSchema, UserInterestSchema, UserJobPreferencesSchema, UserLanguageSchema, type UserProfileOverview, UserProfileVisibility, UserProjectSchema, UserRecruiterProfileSchema, UserRole, UserSchema, UserSkillSchema, UserStatus, WorkExperienceSchema, WorkMode, canTransitionCampaign, categoryOfIndustry, categoryOfSubCategory, codeTokens, conjunction, currencyBound, dateString, days, deriveIndustry, enumFacet, epoch, getSchemaByQuestion, industriesOfCategory, industryOfSubCategory, months, percent, qualified, rejectUnknownKeys, subCategoriesOfIndustry, tokens };
5342
+ export { AnswerChoiceType, ApplicationReceivePreference, BillingPeriod, BillingSubscriptionSchema, BillingTransactionSchema, CAMPAIGN_MAX_RECIPIENTS_CEILING, CONSUME_MAX_UNITS, CampaignDataSourceSchema, CampaignEndKind, CampaignIntervalUnit, CampaignSchema, CampaignStatus, CampaignStatusTransitions, CampaignTriggerKind, CampaignTriggerSchema, ChoiceQuestionSchema, type City, CityFilterSchema, CitySchema, Common, CompensationType, CompletenessScoreSchema, ContactTypes, CoordinatorPageLinkSchema, type Country, CountryFilterSchema, CountrySchema, type CountryTimezone, DISPLAY_DATE_FORMAT, DISPLAY_DATE_FORMAT_SHORT, DateStringSchema, DbDefaultSchema, DefaultPaginatedResponse, DefaultPaginationOptions, DefaultUserRoles, DurationSchema, EMPTY_STRING, EducationLevel, EducationSchema, EmployeeCount, EmploymentType, EntitlementConsumeSchema, EntitlementDenialReason, EntitlementDenialSchema, EntitlingSubscriptionStatuses, ExperienceLevel, FEEDBACK_MESSAGE_MAX, FeatureEntitlementSchema, FeatureKey, FeedbackFilterSchema, FeedbackSchema, FeedbackStatus, FeedbackType, GEO_COLLECTIONS, GEO_SEARCH_MAX, GRANT_MAX_LIMIT, GeneraDetailFields, GeoKind, type GeoSyncCounts, GeoSyncPhase, type GeoSyncRun, GeoSyncRunSchema, GeoSyncStatus, GeoSyncTrigger, type GeoTranslations, GrantType, GroupFilterSchema, GroupManagedBy, GroupMembershipSchema, GroupMembershipStatus, GroupSchema, GroupStatus, GroupTranslationSchema, GroupVisibility, InputQuestionSchema, JOB_TAXONOMY, JobAlertFrequency, JobCategory, JobFilterSchema, JobIndustry, JobSchema, JobSearchUrgency, JobStatus, JobSubCategory, LanguageFilterSchema, LiveSubscriptionStatuses, LocationSchema, MIN_SALARY_LOWER_BOUND, MIN_SALARY_UPPER_BOUND, MailingListFilterSchema, MailingListSchema, MoneySchema, NotificationType, OccurrenceStatus, PREFILL_MIRRORED_KEYS, PRIVATE_PROFILE_FIELDS, PaddleEnvironment, PaddlePriceIdsSchema, PageFilterSchema, PageSchema, PageStatus, PageType, type PaginatedResponse, PaginationSchema, PlanAudience, PlanGrantSchema, PlanKind, PlanSchema, PlanStatus, PostSchema, PostStatus, type PrefillMirroredKey, type PrivateProfileField, ProficiencyLevel, type PushSubscriptionRecord, PushSubscriptionSchema, QuestionSchema, QuestionType, QuotaPeriod, ReadAndAcknowledgeQuestionSchema, RecruiterPageLinkSchema, ReferralSource, ReportReason, ReportSchema, ResourceType, SITEMAP_FORMAT, SYSTEM_DATE_FORMAT, SavedSearchSchema, SavedSearchStatus, SignupContextSource, SkillFilterSchema, SkillSchema, SocialAccount, SocialAccountSchema, type State, StateFilterSchema, StateSchema, StudentCompletenessSchema, StudyType, SubscriptionStatus, SupportedAnswerChoiceTypes, SupportedApplicationReceivePreferences, SupportedBillingPeriods, SupportedCampaignEndKinds, SupportedCampaignIntervalUnits, SupportedCampaignStatuses, SupportedCampaignTriggerKinds, SupportedCompensationTypes, SupportedContactTypes, SupportedEducationLevels, SupportedEmployeeCounts, SupportedEmploymentTypes, SupportedEntitlementDenialReasons, SupportedExperienceLevels, SupportedFeatureKeys, SupportedFeedbackStatuses, SupportedFeedbackTypes, SupportedGeoKinds, SupportedGeoSyncPhases, SupportedGeoSyncStatuses, SupportedGeoSyncTriggers, SupportedGrantTypes, SupportedGroupManagedBy, SupportedGroupMembershipStatuses, SupportedGroupStatuses, SupportedGroupVisibilities, SupportedJobAlertFrequencies, SupportedJobCategories, SupportedJobIndustries, SupportedJobSearchUrgencies, SupportedJobStatuses, SupportedJobSubCategories, SupportedNotificationTypes, SupportedOccurrenceStatuses, SupportedPaddleEnvironments, SupportedPageStatuses, SupportedPageTypes, SupportedPlanAudiences, SupportedPlanKinds, SupportedPlanStatuses, SupportedPostStatuses, SupportedProficiencyLevels, SupportedQuestionTypes, SupportedQuotaPeriods, SupportedReferralSources, SupportedReportReasons, SupportedResourceTypes, SupportedSalaryCurrencies, type SupportedSalaryCurrency, SupportedSavedSearchStatuses, SupportedSignupContextSources, SupportedSocialAccounts, SupportedStudyTypes, SupportedSubscriptionStatuses, SupportedTemplateVariableBindingKinds, SupportedTransactionStatuses, SupportedUserProfileVisibilities, SupportedUserRoles, SupportedUserStatuses, SupportedWorkModes, TAXONOMY_LABELS, type TChoiceQuestionSchema, type TDurationSchema, type TInputQuestionSchema, type TJobSchema, type TPostSchema, type TQuestionSchema, type TReadAndAcknowledgeQuestionSchema, type TUserIdAndCreatedAtSchema, TemplateVariableBindingKind, TemplateVariableBindingSchema, TerminalCampaignStatuses, TerminalGeoSyncStatuses, TermsAcceptedSchema, TransactionStatus, type User, UserAdditionalInfoSchema, UserCertificationSchema, UserCompletenessSchema, UserCoordinatorProfileSchema, UserDetailType, UserFilterSchema, UserGeneralDetailSchema, UserIdAndCreatedAtSchema, UserInterestSchema, UserJobPreferencesSchema, UserLanguageSchema, type UserProfileOverview, UserProfileVisibility, UserProjectSchema, UserRecruiterProfileSchema, UserRole, UserSchema, UserSkillSchema, UserStatus, WorkExperienceSchema, WorkMode, canTransitionCampaign, categoryOfIndustry, categoryOfSubCategory, codeTokens, conjunction, currencyBound, dateString, days, deriveIndustry, enumFacet, epoch, getSchemaByQuestion, industriesOfCategory, industryOfSubCategory, months, percent, qualified, rejectUnknownKeys, subCategoriesOfIndustry, tokens };
package/dist/index.d.ts CHANGED
@@ -3286,6 +3286,21 @@ declare enum PlanStatus {
3286
3286
  Archived = "archived"
3287
3287
  }
3288
3288
  declare const SupportedPlanStatuses: PlanStatus[];
3289
+ /**
3290
+ * The product line a plan belongs to. A user holds at most ONE live
3291
+ * subscription per audience: switching within a line updates that subscription,
3292
+ * it never adds a second one. Different audiences may be held side by side.
3293
+ *
3294
+ * A plan with no audience belongs to the single default line, which is every
3295
+ * plan seeded before this existed.
3296
+ */
3297
+ declare enum PlanAudience {
3298
+ Employer = "employer",
3299
+ JobSeeker = "job-seeker",
3300
+ Recruiter = "recruiter",
3301
+ Company = "company"
3302
+ }
3303
+ declare const SupportedPlanAudiences: PlanAudience[];
3289
3304
  /**
3290
3305
  * How a grant gives access to a feature.
3291
3306
  *
@@ -3344,6 +3359,12 @@ declare enum SubscriptionStatus {
3344
3359
  declare const SupportedSubscriptionStatuses: SubscriptionStatus[];
3345
3360
  /** Subscription statuses that currently entitle the holder to their plan's grants. */
3346
3361
  declare const EntitlingSubscriptionStatuses: SubscriptionStatus[];
3362
+ /**
3363
+ * Subscription statuses that still occupy the user's slot in a plan audience.
3364
+ * Wider than `EntitlingSubscriptionStatuses`: a paused subscription grants
3365
+ * nothing, but buying again would still leave two subscriptions to one plan.
3366
+ */
3367
+ declare const LiveSubscriptionStatuses: SubscriptionStatus[];
3347
3368
  /** Paddle transaction status, verbatim. `completed` is where a one-off is fulfilled. */
3348
3369
  declare enum TransactionStatus {
3349
3370
  Draft = "draft",
@@ -3468,6 +3489,7 @@ declare const PlanSchema: yup.ObjectSchema<{
3468
3489
  name: string;
3469
3490
  description: string | undefined;
3470
3491
  kind: NonNullable<PlanKind | undefined>;
3492
+ audience: PlanAudience | undefined;
3471
3493
  status: NonNullable<PlanStatus | undefined>;
3472
3494
  paddlePriceIds: {
3473
3495
  sandbox: string[];
@@ -3493,6 +3515,7 @@ declare const PlanSchema: yup.ObjectSchema<{
3493
3515
  name: undefined;
3494
3516
  description: undefined;
3495
3517
  kind: PlanKind.Subscription;
3518
+ audience: undefined;
3496
3519
  status: PlanStatus.Draft;
3497
3520
  paddlePriceIds: {
3498
3521
  sandbox: never[];
@@ -4392,6 +4415,7 @@ declare const PushSubscriptionSchema: yup.ObjectSchema<{
4392
4415
  userAgent: string | undefined;
4393
4416
  createdAt: number | undefined;
4394
4417
  lastSeenAt: number | undefined;
4418
+ signedOutAt: number | null | undefined;
4395
4419
  }, yup.AnyObject, {
4396
4420
  userShortId: undefined;
4397
4421
  endpoint: undefined;
@@ -4403,6 +4427,7 @@ declare const PushSubscriptionSchema: yup.ObjectSchema<{
4403
4427
  userAgent: undefined;
4404
4428
  createdAt: undefined;
4405
4429
  lastSeenAt: undefined;
4430
+ signedOutAt: undefined;
4406
4431
  }, "">;
4407
4432
 
4408
4433
  declare const UserLanguageSchema: yup.ObjectSchema<{
@@ -5314,4 +5339,4 @@ declare const StudentCompletenessSchema: yup.ObjectSchema<{
5314
5339
  };
5315
5340
  }, "">;
5316
5341
 
5317
- export { AnswerChoiceType, ApplicationReceivePreference, BillingPeriod, BillingSubscriptionSchema, BillingTransactionSchema, CAMPAIGN_MAX_RECIPIENTS_CEILING, CONSUME_MAX_UNITS, CampaignDataSourceSchema, CampaignEndKind, CampaignIntervalUnit, CampaignSchema, CampaignStatus, CampaignStatusTransitions, CampaignTriggerKind, CampaignTriggerSchema, ChoiceQuestionSchema, type City, CityFilterSchema, CitySchema, Common, CompensationType, CompletenessScoreSchema, ContactTypes, CoordinatorPageLinkSchema, type Country, CountryFilterSchema, CountrySchema, type CountryTimezone, DISPLAY_DATE_FORMAT, DISPLAY_DATE_FORMAT_SHORT, DateStringSchema, DbDefaultSchema, DefaultPaginatedResponse, DefaultPaginationOptions, DefaultUserRoles, DurationSchema, EMPTY_STRING, EducationLevel, EducationSchema, EmployeeCount, EmploymentType, EntitlementConsumeSchema, EntitlementDenialReason, EntitlementDenialSchema, EntitlingSubscriptionStatuses, ExperienceLevel, FEEDBACK_MESSAGE_MAX, FeatureEntitlementSchema, FeatureKey, FeedbackFilterSchema, FeedbackSchema, FeedbackStatus, FeedbackType, GEO_COLLECTIONS, GEO_SEARCH_MAX, GRANT_MAX_LIMIT, GeneraDetailFields, GeoKind, type GeoSyncCounts, GeoSyncPhase, type GeoSyncRun, GeoSyncRunSchema, GeoSyncStatus, GeoSyncTrigger, type GeoTranslations, GrantType, GroupFilterSchema, GroupManagedBy, GroupMembershipSchema, GroupMembershipStatus, GroupSchema, GroupStatus, GroupTranslationSchema, GroupVisibility, InputQuestionSchema, JOB_TAXONOMY, JobAlertFrequency, JobCategory, JobFilterSchema, JobIndustry, JobSchema, JobSearchUrgency, JobStatus, JobSubCategory, LanguageFilterSchema, LocationSchema, MIN_SALARY_LOWER_BOUND, MIN_SALARY_UPPER_BOUND, MailingListFilterSchema, MailingListSchema, MoneySchema, NotificationType, OccurrenceStatus, PREFILL_MIRRORED_KEYS, PRIVATE_PROFILE_FIELDS, PaddleEnvironment, PaddlePriceIdsSchema, PageFilterSchema, PageSchema, PageStatus, PageType, type PaginatedResponse, PaginationSchema, PlanGrantSchema, PlanKind, PlanSchema, PlanStatus, PostSchema, PostStatus, type PrefillMirroredKey, type PrivateProfileField, ProficiencyLevel, type PushSubscriptionRecord, PushSubscriptionSchema, QuestionSchema, QuestionType, QuotaPeriod, ReadAndAcknowledgeQuestionSchema, RecruiterPageLinkSchema, ReferralSource, ReportReason, ReportSchema, ResourceType, SITEMAP_FORMAT, SYSTEM_DATE_FORMAT, SavedSearchSchema, SavedSearchStatus, SignupContextSource, SkillFilterSchema, SkillSchema, SocialAccount, SocialAccountSchema, type State, StateFilterSchema, StateSchema, StudentCompletenessSchema, StudyType, SubscriptionStatus, SupportedAnswerChoiceTypes, SupportedApplicationReceivePreferences, SupportedBillingPeriods, SupportedCampaignEndKinds, SupportedCampaignIntervalUnits, SupportedCampaignStatuses, SupportedCampaignTriggerKinds, SupportedCompensationTypes, SupportedContactTypes, SupportedEducationLevels, SupportedEmployeeCounts, SupportedEmploymentTypes, SupportedEntitlementDenialReasons, SupportedExperienceLevels, SupportedFeatureKeys, SupportedFeedbackStatuses, SupportedFeedbackTypes, SupportedGeoKinds, SupportedGeoSyncPhases, SupportedGeoSyncStatuses, SupportedGeoSyncTriggers, SupportedGrantTypes, SupportedGroupManagedBy, SupportedGroupMembershipStatuses, SupportedGroupStatuses, SupportedGroupVisibilities, SupportedJobAlertFrequencies, SupportedJobCategories, SupportedJobIndustries, SupportedJobSearchUrgencies, SupportedJobStatuses, SupportedJobSubCategories, SupportedNotificationTypes, SupportedOccurrenceStatuses, SupportedPaddleEnvironments, SupportedPageStatuses, SupportedPageTypes, SupportedPlanKinds, SupportedPlanStatuses, SupportedPostStatuses, SupportedProficiencyLevels, SupportedQuestionTypes, SupportedQuotaPeriods, SupportedReferralSources, SupportedReportReasons, SupportedResourceTypes, SupportedSalaryCurrencies, type SupportedSalaryCurrency, SupportedSavedSearchStatuses, SupportedSignupContextSources, SupportedSocialAccounts, SupportedStudyTypes, SupportedSubscriptionStatuses, SupportedTemplateVariableBindingKinds, SupportedTransactionStatuses, SupportedUserProfileVisibilities, SupportedUserRoles, SupportedUserStatuses, SupportedWorkModes, TAXONOMY_LABELS, type TChoiceQuestionSchema, type TDurationSchema, type TInputQuestionSchema, type TJobSchema, type TPostSchema, type TQuestionSchema, type TReadAndAcknowledgeQuestionSchema, type TUserIdAndCreatedAtSchema, TemplateVariableBindingKind, TemplateVariableBindingSchema, TerminalCampaignStatuses, TerminalGeoSyncStatuses, TermsAcceptedSchema, TransactionStatus, type User, UserAdditionalInfoSchema, UserCertificationSchema, UserCompletenessSchema, UserCoordinatorProfileSchema, UserDetailType, UserFilterSchema, UserGeneralDetailSchema, UserIdAndCreatedAtSchema, UserInterestSchema, UserJobPreferencesSchema, UserLanguageSchema, type UserProfileOverview, UserProfileVisibility, UserProjectSchema, UserRecruiterProfileSchema, UserRole, UserSchema, UserSkillSchema, UserStatus, WorkExperienceSchema, WorkMode, canTransitionCampaign, categoryOfIndustry, categoryOfSubCategory, codeTokens, conjunction, currencyBound, dateString, days, deriveIndustry, enumFacet, epoch, getSchemaByQuestion, industriesOfCategory, industryOfSubCategory, months, percent, qualified, rejectUnknownKeys, subCategoriesOfIndustry, tokens };
5342
+ export { AnswerChoiceType, ApplicationReceivePreference, BillingPeriod, BillingSubscriptionSchema, BillingTransactionSchema, CAMPAIGN_MAX_RECIPIENTS_CEILING, CONSUME_MAX_UNITS, CampaignDataSourceSchema, CampaignEndKind, CampaignIntervalUnit, CampaignSchema, CampaignStatus, CampaignStatusTransitions, CampaignTriggerKind, CampaignTriggerSchema, ChoiceQuestionSchema, type City, CityFilterSchema, CitySchema, Common, CompensationType, CompletenessScoreSchema, ContactTypes, CoordinatorPageLinkSchema, type Country, CountryFilterSchema, CountrySchema, type CountryTimezone, DISPLAY_DATE_FORMAT, DISPLAY_DATE_FORMAT_SHORT, DateStringSchema, DbDefaultSchema, DefaultPaginatedResponse, DefaultPaginationOptions, DefaultUserRoles, DurationSchema, EMPTY_STRING, EducationLevel, EducationSchema, EmployeeCount, EmploymentType, EntitlementConsumeSchema, EntitlementDenialReason, EntitlementDenialSchema, EntitlingSubscriptionStatuses, ExperienceLevel, FEEDBACK_MESSAGE_MAX, FeatureEntitlementSchema, FeatureKey, FeedbackFilterSchema, FeedbackSchema, FeedbackStatus, FeedbackType, GEO_COLLECTIONS, GEO_SEARCH_MAX, GRANT_MAX_LIMIT, GeneraDetailFields, GeoKind, type GeoSyncCounts, GeoSyncPhase, type GeoSyncRun, GeoSyncRunSchema, GeoSyncStatus, GeoSyncTrigger, type GeoTranslations, GrantType, GroupFilterSchema, GroupManagedBy, GroupMembershipSchema, GroupMembershipStatus, GroupSchema, GroupStatus, GroupTranslationSchema, GroupVisibility, InputQuestionSchema, JOB_TAXONOMY, JobAlertFrequency, JobCategory, JobFilterSchema, JobIndustry, JobSchema, JobSearchUrgency, JobStatus, JobSubCategory, LanguageFilterSchema, LiveSubscriptionStatuses, LocationSchema, MIN_SALARY_LOWER_BOUND, MIN_SALARY_UPPER_BOUND, MailingListFilterSchema, MailingListSchema, MoneySchema, NotificationType, OccurrenceStatus, PREFILL_MIRRORED_KEYS, PRIVATE_PROFILE_FIELDS, PaddleEnvironment, PaddlePriceIdsSchema, PageFilterSchema, PageSchema, PageStatus, PageType, type PaginatedResponse, PaginationSchema, PlanAudience, PlanGrantSchema, PlanKind, PlanSchema, PlanStatus, PostSchema, PostStatus, type PrefillMirroredKey, type PrivateProfileField, ProficiencyLevel, type PushSubscriptionRecord, PushSubscriptionSchema, QuestionSchema, QuestionType, QuotaPeriod, ReadAndAcknowledgeQuestionSchema, RecruiterPageLinkSchema, ReferralSource, ReportReason, ReportSchema, ResourceType, SITEMAP_FORMAT, SYSTEM_DATE_FORMAT, SavedSearchSchema, SavedSearchStatus, SignupContextSource, SkillFilterSchema, SkillSchema, SocialAccount, SocialAccountSchema, type State, StateFilterSchema, StateSchema, StudentCompletenessSchema, StudyType, SubscriptionStatus, SupportedAnswerChoiceTypes, SupportedApplicationReceivePreferences, SupportedBillingPeriods, SupportedCampaignEndKinds, SupportedCampaignIntervalUnits, SupportedCampaignStatuses, SupportedCampaignTriggerKinds, SupportedCompensationTypes, SupportedContactTypes, SupportedEducationLevels, SupportedEmployeeCounts, SupportedEmploymentTypes, SupportedEntitlementDenialReasons, SupportedExperienceLevels, SupportedFeatureKeys, SupportedFeedbackStatuses, SupportedFeedbackTypes, SupportedGeoKinds, SupportedGeoSyncPhases, SupportedGeoSyncStatuses, SupportedGeoSyncTriggers, SupportedGrantTypes, SupportedGroupManagedBy, SupportedGroupMembershipStatuses, SupportedGroupStatuses, SupportedGroupVisibilities, SupportedJobAlertFrequencies, SupportedJobCategories, SupportedJobIndustries, SupportedJobSearchUrgencies, SupportedJobStatuses, SupportedJobSubCategories, SupportedNotificationTypes, SupportedOccurrenceStatuses, SupportedPaddleEnvironments, SupportedPageStatuses, SupportedPageTypes, SupportedPlanAudiences, SupportedPlanKinds, SupportedPlanStatuses, SupportedPostStatuses, SupportedProficiencyLevels, SupportedQuestionTypes, SupportedQuotaPeriods, SupportedReferralSources, SupportedReportReasons, SupportedResourceTypes, SupportedSalaryCurrencies, type SupportedSalaryCurrency, SupportedSavedSearchStatuses, SupportedSignupContextSources, SupportedSocialAccounts, SupportedStudyTypes, SupportedSubscriptionStatuses, SupportedTemplateVariableBindingKinds, SupportedTransactionStatuses, SupportedUserProfileVisibilities, SupportedUserRoles, SupportedUserStatuses, SupportedWorkModes, TAXONOMY_LABELS, type TChoiceQuestionSchema, type TDurationSchema, type TInputQuestionSchema, type TJobSchema, type TPostSchema, type TQuestionSchema, type TReadAndAcknowledgeQuestionSchema, type TUserIdAndCreatedAtSchema, TemplateVariableBindingKind, TemplateVariableBindingSchema, TerminalCampaignStatuses, TerminalGeoSyncStatuses, TermsAcceptedSchema, TransactionStatus, type User, UserAdditionalInfoSchema, UserCertificationSchema, UserCompletenessSchema, UserCoordinatorProfileSchema, UserDetailType, UserFilterSchema, UserGeneralDetailSchema, UserIdAndCreatedAtSchema, UserInterestSchema, UserJobPreferencesSchema, UserLanguageSchema, type UserProfileOverview, UserProfileVisibility, UserProjectSchema, UserRecruiterProfileSchema, UserRole, UserSchema, UserSkillSchema, UserStatus, WorkExperienceSchema, WorkMode, canTransitionCampaign, categoryOfIndustry, categoryOfSubCategory, codeTokens, conjunction, currencyBound, dateString, days, deriveIndustry, enumFacet, epoch, getSchemaByQuestion, industriesOfCategory, industryOfSubCategory, months, percent, qualified, rejectUnknownKeys, subCategoriesOfIndustry, tokens };
package/dist/index.js CHANGED
@@ -3587,6 +3587,14 @@ var PlanStatus = /* @__PURE__ */ ((PlanStatus2) => {
3587
3587
  return PlanStatus2;
3588
3588
  })(PlanStatus || {});
3589
3589
  var SupportedPlanStatuses = Object.values(PlanStatus);
3590
+ var PlanAudience = /* @__PURE__ */ ((PlanAudience2) => {
3591
+ PlanAudience2["Employer"] = "employer";
3592
+ PlanAudience2["JobSeeker"] = "job-seeker";
3593
+ PlanAudience2["Recruiter"] = "recruiter";
3594
+ PlanAudience2["Company"] = "company";
3595
+ return PlanAudience2;
3596
+ })(PlanAudience || {});
3597
+ var SupportedPlanAudiences = Object.values(PlanAudience);
3590
3598
  var GrantType = /* @__PURE__ */ ((GrantType2) => {
3591
3599
  GrantType2["Boolean"] = "boolean";
3592
3600
  GrantType2["Quota"] = "quota";
@@ -3621,6 +3629,10 @@ var EntitlingSubscriptionStatuses = [
3621
3629
  "trialing" /* Trialing */,
3622
3630
  "past_due" /* PastDue */
3623
3631
  ];
3632
+ var LiveSubscriptionStatuses = [
3633
+ ...EntitlingSubscriptionStatuses,
3634
+ "paused" /* Paused */
3635
+ ];
3624
3636
  var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
3625
3637
  TransactionStatus2["Draft"] = "draft";
3626
3638
  TransactionStatus2["Ready"] = "ready";
@@ -3705,6 +3717,12 @@ var PlanSchema = object38({
3705
3717
  name: string27().required().min(1).max(120).label("Name"),
3706
3718
  description: string27().optional().max(500).label("Description"),
3707
3719
  kind: string27().oneOf(SupportedPlanKinds).required().default("subscription" /* Subscription */).label("Kind"),
3720
+ /**
3721
+ * The line this plan belongs to; a user holds one live subscription per line.
3722
+ * Optional on purpose: absent is the default line, so existing plans need no
3723
+ * migration and together still read as "one plan at a time".
3724
+ */
3725
+ audience: string27().oneOf(SupportedPlanAudiences).optional().label("Audience"),
3708
3726
  status: string27().oneOf(SupportedPlanStatuses).required().default("draft" /* Draft */).label("Status"),
3709
3727
  paddlePriceIds: PaddlePriceIdsSchema.default(
3710
3728
  () => PaddlePriceIdsSchema.getDefault()
@@ -4304,7 +4322,17 @@ var PushSubscriptionSchema = object52({
4304
4322
  * device that stopped visiting, which is useful for pruning rows that never
4305
4323
  * fail loudly enough to be caught by a 410.
4306
4324
  */
4307
- lastSeenAt: number21().optional().label("Last Seen At")
4325
+ lastSeenAt: number21().optional().label("Last Seen At"),
4326
+ /**
4327
+ * Epoch ms the owner explicitly signed out on this device, or absent.
4328
+ *
4329
+ * A PAUSE, not a removal: the sender skips flagged rows, so a shared device
4330
+ * stops receiving the previous user's notifications, while the same user
4331
+ * signing back in clears the flag with no prompt. A flag rather than a delete
4332
+ * so that a MISSING row keeps one meaning to the browser ("stop, this device
4333
+ * was removed"), which it acts on by dropping its own subscription.
4334
+ */
4335
+ signedOutAt: number21().nullable().optional().label("Signed Out At")
4308
4336
  }).noUnknown().strict().label("Push Subscription Schema");
4309
4337
 
4310
4338
  // src/user/user-completeness.schema.ts
@@ -4410,6 +4438,7 @@ export {
4410
4438
  JobStatus,
4411
4439
  JobSubCategory,
4412
4440
  LanguageFilterSchema,
4441
+ LiveSubscriptionStatuses,
4413
4442
  LocationSchema,
4414
4443
  MIN_SALARY_LOWER_BOUND,
4415
4444
  MIN_SALARY_UPPER_BOUND,
@@ -4427,6 +4456,7 @@ export {
4427
4456
  PageStatus,
4428
4457
  PageType,
4429
4458
  PaginationSchema,
4459
+ PlanAudience,
4430
4460
  PlanGrantSchema,
4431
4461
  PlanKind,
4432
4462
  PlanSchema,
@@ -4495,6 +4525,7 @@ export {
4495
4525
  SupportedPaddleEnvironments,
4496
4526
  SupportedPageStatuses,
4497
4527
  SupportedPageTypes,
4528
+ SupportedPlanAudiences,
4498
4529
  SupportedPlanKinds,
4499
4530
  SupportedPlanStatuses,
4500
4531
  SupportedPostStatuses,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thejob/schema",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -34,6 +34,23 @@ export enum PlanStatus {
34
34
 
35
35
  export const SupportedPlanStatuses = Object.values(PlanStatus);
36
36
 
37
+ /**
38
+ * The product line a plan belongs to. A user holds at most ONE live
39
+ * subscription per audience: switching within a line updates that subscription,
40
+ * it never adds a second one. Different audiences may be held side by side.
41
+ *
42
+ * A plan with no audience belongs to the single default line, which is every
43
+ * plan seeded before this existed.
44
+ */
45
+ export enum PlanAudience {
46
+ Employer = "employer",
47
+ JobSeeker = "job-seeker",
48
+ Recruiter = "recruiter",
49
+ Company = "company",
50
+ }
51
+
52
+ export const SupportedPlanAudiences = Object.values(PlanAudience);
53
+
37
54
  /**
38
55
  * How a grant gives access to a feature.
39
56
  *
@@ -107,6 +124,16 @@ export const EntitlingSubscriptionStatuses = [
107
124
  SubscriptionStatus.PastDue,
108
125
  ];
109
126
 
127
+ /**
128
+ * Subscription statuses that still occupy the user's slot in a plan audience.
129
+ * Wider than `EntitlingSubscriptionStatuses`: a paused subscription grants
130
+ * nothing, but buying again would still leave two subscriptions to one plan.
131
+ */
132
+ export const LiveSubscriptionStatuses = [
133
+ ...EntitlingSubscriptionStatuses,
134
+ SubscriptionStatus.Paused,
135
+ ];
136
+
110
137
  /** Paddle transaction status, verbatim. `completed` is where a one-off is fulfilled. */
111
138
  export enum TransactionStatus {
112
139
  Draft = "draft",
@@ -9,6 +9,7 @@ import {
9
9
  SupportedBillingPeriods,
10
10
  SupportedEntitlementDenialReasons,
11
11
  SupportedGrantTypes,
12
+ SupportedPlanAudiences,
12
13
  SupportedPlanKinds,
13
14
  SupportedPlanStatuses,
14
15
  SupportedQuotaPeriods,
@@ -137,6 +138,15 @@ export const PlanSchema = object({
137
138
  .required()
138
139
  .default(PlanKind.Subscription)
139
140
  .label("Kind"),
141
+ /**
142
+ * The line this plan belongs to; a user holds one live subscription per line.
143
+ * Optional on purpose: absent is the default line, so existing plans need no
144
+ * migration and together still read as "one plan at a time".
145
+ */
146
+ audience: string()
147
+ .oneOf(SupportedPlanAudiences)
148
+ .optional()
149
+ .label("Audience"),
140
150
  status: string()
141
151
  .oneOf(SupportedPlanStatuses)
142
152
  .required()
@@ -80,6 +80,17 @@ export const PushSubscriptionSchema = object({
80
80
  * fail loudly enough to be caught by a 410.
81
81
  */
82
82
  lastSeenAt: number().optional().label("Last Seen At"),
83
+
84
+ /**
85
+ * Epoch ms the owner explicitly signed out on this device, or absent.
86
+ *
87
+ * A PAUSE, not a removal: the sender skips flagged rows, so a shared device
88
+ * stops receiving the previous user's notifications, while the same user
89
+ * signing back in clears the flag with no prompt. A flag rather than a delete
90
+ * so that a MISSING row keeps one meaning to the browser ("stop, this device
91
+ * was removed"), which it acts on by dropping its own subscription.
92
+ */
93
+ signedOutAt: number().nullable().optional().label("Signed Out At"),
83
94
  })
84
95
  .noUnknown()
85
96
  .strict()