@happyvertical/smrt-subscriptions 0.57.9 → 0.57.11

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.
Files changed (42) hide show
  1. package/AGENTS.md +21 -0
  2. package/README.md +112 -3
  3. package/dist/chunks/SubscriptionPlanCollection-CqlYYtPg.js +229 -0
  4. package/dist/chunks/SubscriptionPlanCollection-CqlYYtPg.js.map +1 -0
  5. package/dist/chunks/SubscriptionPlanVersionCollection-CV0QPmp0.js +193 -0
  6. package/dist/chunks/SubscriptionPlanVersionCollection-CV0QPmp0.js.map +1 -0
  7. package/dist/chunks/plan-terms-BoeXvDhs.js +219 -0
  8. package/dist/chunks/plan-terms-BoeXvDhs.js.map +1 -0
  9. package/dist/chunks/plan-versioning-Bp0NqTJf.js +142 -0
  10. package/dist/chunks/plan-versioning-Bp0NqTJf.js.map +1 -0
  11. package/dist/chunks/rolldown-runtime-D7D4PA-g.js +13 -0
  12. package/dist/collections/SubscriptionPlanVersionCollection.d.ts +33 -0
  13. package/dist/collections/SubscriptionPlanVersionCollection.d.ts.map +1 -0
  14. package/dist/collections/index.d.ts +1 -0
  15. package/dist/collections/index.d.ts.map +1 -1
  16. package/dist/index.d.ts +7 -4
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +181 -349
  19. package/dist/index.js.map +1 -1
  20. package/dist/manifest.json +1114 -328
  21. package/dist/migrations/planVersions.d.ts +16 -0
  22. package/dist/migrations/planVersions.d.ts.map +1 -0
  23. package/dist/models/SubscriptionPlan.d.ts +39 -3
  24. package/dist/models/SubscriptionPlan.d.ts.map +1 -1
  25. package/dist/models/SubscriptionPlanVersion.d.ts +51 -0
  26. package/dist/models/SubscriptionPlanVersion.d.ts.map +1 -0
  27. package/dist/models/TenantSubscription.d.ts +49 -1
  28. package/dist/models/TenantSubscription.d.ts.map +1 -1
  29. package/dist/models/index.d.ts +1 -0
  30. package/dist/models/index.d.ts.map +1 -1
  31. package/dist/plan-terms.d.ts +26 -0
  32. package/dist/plan-terms.d.ts.map +1 -0
  33. package/dist/plan-versioning.d.ts +45 -0
  34. package/dist/plan-versioning.d.ts.map +1 -0
  35. package/dist/services/index.d.ts +1 -1
  36. package/dist/services/index.d.ts.map +1 -1
  37. package/dist/services/subscription-resolver.d.ts +26 -0
  38. package/dist/services/subscription-resolver.d.ts.map +1 -1
  39. package/dist/smrt-knowledge.json +547 -7
  40. package/dist/types.d.ts +72 -0
  41. package/dist/types.d.ts.map +1 -1
  42. package/package.json +6 -6
@@ -0,0 +1,16 @@
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
+ export interface SubscriptionPlanVersionsMigrationReport {
3
+ /** Plans that received their version 1. */
4
+ plansVersioned: number;
5
+ /** Subscriptions that received a pin. */
6
+ subscriptionsPinned: number;
7
+ /** Subscriptions that could not be pinned, with the validation error. */
8
+ failed: Array<{
9
+ subscriptionId: string;
10
+ error: string;
11
+ }>;
12
+ }
13
+ export declare function migrateSubscriptionPlanVersions(db: DatabaseInterface, options?: {
14
+ pageSize?: number;
15
+ }): Promise<SubscriptionPlanVersionsMigrationReport>;
16
+ //# sourceMappingURL=planVersions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planVersions.d.ts","sourceRoot":"","sources":["../../src/migrations/planVersions.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAK5D,MAAM,WAAW,uCAAuC;IACtD,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yEAAyE;IACzE,MAAM,EAAE,KAAK,CAAC;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,wBAAsB,+BAA+B,CACnD,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,uCAAuC,CAAC,CA2ClD"}
@@ -1,6 +1,7 @@
1
- import { SmrtObject } from '@happyvertical/smrt-core';
2
- import type { BillingInterval, JsonObject, PlanFeatureGrant, PlanThreshold, PricingMode, SubscriptionPlanOptions, SubscriptionPlanStatus } from '../types.js';
3
- export declare class SubscriptionPlan extends SmrtObject {
1
+ import { SmrtObject, type SmrtSaveOptions } from '@happyvertical/smrt-core';
2
+ import type { BillingInterval, JsonObject, PlanFeatureGrant, PlanTerms, PlanThreshold, PricingMode, SubscriptionPlanOptions, SubscriptionPlanStatus } from '../types.js';
3
+ import type { SubscriptionPlanVersion } from './SubscriptionPlanVersion.js';
4
+ export declare class SubscriptionPlan extends SmrtObject implements PlanTerms {
4
5
  tenantId: string | null;
5
6
  planKey: string;
6
7
  name: string;
@@ -31,6 +32,41 @@ export declare class SubscriptionPlan extends SmrtObject {
31
32
  metadata: string;
32
33
  constructor(options?: SubscriptionPlanOptions);
33
34
  isActive(): boolean;
35
+ /** The versioned terms currently on this row (the latest published). */
36
+ getTerms(): PlanTerms;
37
+ /**
38
+ * Persist this plan. When its terms (status, price, pricing configuration,
39
+ * feature grants or thresholds) differ from the latest published version —
40
+ * or no version exists yet — the save then publishes the next immutable
41
+ * {@link SubscriptionPlanVersion}, effective now (#4032). Use
42
+ * {@link publishTerms} to choose a different effective date. Subscribers
43
+ * keep the version pinned for their current period; the new terms apply
44
+ * from their next renewal.
45
+ *
46
+ * A plan saved before versioning existed first records its pre-edit terms
47
+ * as version 1, effective from its creation, so subscriptions sold under
48
+ * them are not re-priced.
49
+ *
50
+ * The row is written before the version. If publishing fails the save
51
+ * rejects with the row already updated; saving again publishes the
52
+ * missing version. Wrap the call in `plan.withTransaction()` when the
53
+ * adapter supports transactions and the two writes must be atomic.
54
+ */
55
+ save(options?: SmrtSaveOptions): Promise<this>;
56
+ /**
57
+ * Save this plan and publish its current terms as a version effective at
58
+ * `effectiveFrom` (default now). A future date schedules an amendment: the
59
+ * plan row shows the new terms immediately, but subscriptions starting or
60
+ * renewing before that date pin the earlier version. Versions are
61
+ * monotonic, so `effectiveFrom` may not precede the latest version's.
62
+ *
63
+ * @returns the latest version, which carries the saved terms.
64
+ */
65
+ publishTerms(options?: {
66
+ effectiveFrom?: Date;
67
+ }): Promise<SubscriptionPlanVersion>;
68
+ /** The version of this plan in force at `at` (default now). */
69
+ getVersionInForce(at?: Date): Promise<SubscriptionPlanVersion | null>;
34
70
  getFeatureGrants(): PlanFeatureGrant[];
35
71
  setFeatureGrants(grants: Array<string | PlanFeatureGrant>): void;
36
72
  getFeatureKeys(): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionPlan.d.ts","sourceRoot":"","sources":["../../src/models/SubscriptionPlan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAM5D,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAQrB,qBAQa,gBAAiB,SAAQ,UAAU;IAE9C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,OAAO,EAAE,MAAM,CAAM;IACrB,IAAI,EAAE,MAAM,CAAM;IAClB,WAAW,EAAE,MAAM,CAAM;IACzB,MAAM,EAAE,sBAAsB,CAAY;IAC1C,SAAS,EAAE,MAAM,CAAK;IACtB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAK;IACxB,QAAQ,EAAE,MAAM,CAAS;IACzB,eAAe,EAAE,eAAe,CAAW;IAC3C,WAAW,EAAE,WAAW,CAAW;IACnC,aAAa,EAAE,MAAM,CAAK;IAC1B,eAAe,EAAE,MAAM,CAAK;IAC5B,0EAA0E;IAC1E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACvC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,yCAAyC;IACzC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,uCAAuC;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,QAAQ,EAAE,MAAM,CAAQ;IACxB,UAAU,EAAE,MAAM,CAAQ;IAC1B,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,uBAA4B;IAyCjD,QAAQ,IAAI,OAAO;IAInB,gBAAgB,IAAI,gBAAgB,EAAE;IAMtC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,IAAI;IAIhE,cAAc,IAAI,MAAM,EAAE;IAM1B,aAAa,IAAI,aAAa,EAAE;IAMhC,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI;IAIhD,WAAW,IAAI,UAAU;IAIzB,WAAW,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;cAIvB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAqDpD;AAED,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SubscriptionPlan.d.ts","sourceRoot":"","sources":["../../src/models/SubscriptionPlan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,eAAe,EAErB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAOrB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAY5E,qBAQa,gBAAiB,SAAQ,UAAW,YAAW,SAAS;IAEnE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,OAAO,EAAE,MAAM,CAAM;IACrB,IAAI,EAAE,MAAM,CAAM;IAClB,WAAW,EAAE,MAAM,CAAM;IACzB,MAAM,EAAE,sBAAsB,CAAY;IAC1C,SAAS,EAAE,MAAM,CAAK;IACtB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAK;IACxB,QAAQ,EAAE,MAAM,CAAS;IACzB,eAAe,EAAE,eAAe,CAAW;IAC3C,WAAW,EAAE,WAAW,CAAW;IACnC,aAAa,EAAE,MAAM,CAAK;IAC1B,eAAe,EAAE,MAAM,CAAK;IAC5B,0EAA0E;IAC1E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACvC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,yCAAyC;IACzC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,uCAAuC;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,QAAQ,EAAE,MAAM,CAAQ;IACxB,UAAU,EAAE,MAAM,CAAQ;IAC1B,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,uBAA4B;IAyCjD,QAAQ,IAAI,OAAO;IAInB,wEAAwE;IACxE,QAAQ,IAAI,SAAS;IAIrB;;;;;;;;;;;;;;;;;OAiBG;IACY,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAc7D;;;;;;;;OAQG;IACG,YAAY,CAChB,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,IAAI,CAAA;KAAO,GACrC,OAAO,CAAC,uBAAuB,CAAC;IAUnC,+DAA+D;IACzD,iBAAiB,CACrB,EAAE,OAAa,GACd,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAW1C,gBAAgB,IAAI,gBAAgB,EAAE;IAMtC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,IAAI;IAIhE,cAAc,IAAI,MAAM,EAAE;IAM1B,aAAa,IAAI,aAAa,EAAE;IAMhC,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI;IAIhD,WAAW,IAAI,UAAU;IAIzB,WAAW,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;cAIvB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAsDpD;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import type { BillingInterval, PlanFeatureGrant, PlanTerms, PlanThreshold, PricingMode, SubscriptionPlanStatus, SubscriptionPlanVersionOptions } from '../types.js';
3
+ /**
4
+ * An immutable, effective-dated snapshot of a plan's terms (#4032).
5
+ *
6
+ * `SubscriptionPlan` is the stable tier identity; each change to its terms
7
+ * (status, price, pricing configuration, feature grants, thresholds) publishes
8
+ * the next version. A version is in force from `effectiveFrom` until the next
9
+ * version's `effectiveFrom`; before its first version's `effectiveFrom` a plan
10
+ * resolves to that first version. Subscriptions pin the version in force when
11
+ * their period starts, so a later amendment never changes a paid period.
12
+ *
13
+ * Versions are append-only: updates and deletes are refused.
14
+ */
15
+ export declare class SubscriptionPlanVersion extends SmrtObject implements PlanTerms {
16
+ /** Always the owning plan's tenant (null for a legacy global plan). */
17
+ tenantId: string | null;
18
+ /** The stable tier identity this version belongs to. */
19
+ planId: string;
20
+ /** The plan's natural key, copied for auditing and resolution output. */
21
+ planKey: string;
22
+ /** 1-based sequence within the plan; contiguous and monotonic. */
23
+ version: number;
24
+ /** Start of this version's effective interval. */
25
+ effectiveFrom: Date;
26
+ /** Plan name when this version was published (display only). */
27
+ name: string;
28
+ status: SubscriptionPlanStatus;
29
+ /** Integer minor units of {@link currency}. */
30
+ priceAmount: number;
31
+ currency: string;
32
+ billingInterval: BillingInterval;
33
+ pricingMode: PricingMode;
34
+ /** Integer minor units. */
35
+ minimumAmount: number;
36
+ /** Integer minor units. */
37
+ suggestedAmount: number;
38
+ features: string;
39
+ thresholds: string;
40
+ constructor(options?: SubscriptionPlanVersionOptions);
41
+ isActive(): boolean;
42
+ getTerms(): PlanTerms;
43
+ getFeatureGrants(): PlanFeatureGrant[];
44
+ getFeatureKeys(): string[];
45
+ getThresholds(): PlanThreshold[];
46
+ /** Append-only: a version is corrected by publishing the next one. */
47
+ protected refuseDelete(): void;
48
+ protected validateBeforeSave(): Promise<void>;
49
+ }
50
+ export default SubscriptionPlanVersion;
51
+ //# sourceMappingURL=SubscriptionPlanVersion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionPlanVersion.d.ts","sourceRoot":"","sources":["../../src/models/SubscriptionPlanVersion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAWxE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,8BAA8B,EAC/B,MAAM,aAAa,CAAC;AAKrB;;;;;;;;;;;GAWG;AACH,qBAUa,uBAAwB,SAAQ,UAAW,YAAW,SAAS;IAC1E,uEAAuE;IAEvE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,wDAAwD;IAExD,MAAM,EAAE,MAAM,CAAM;IAEpB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAM;IACrB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAK;IACpB,kDAAkD;IAClD,aAAa,EAAE,IAAI,CAAc;IACjC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAM;IAClB,MAAM,EAAE,sBAAsB,CAAY;IAC1C,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAK;IACxB,QAAQ,EAAE,MAAM,CAAS;IACzB,eAAe,EAAE,eAAe,CAAW;IAC3C,WAAW,EAAE,WAAW,CAAW;IACnC,2BAA2B;IAC3B,aAAa,EAAE,MAAM,CAAK;IAC1B,2BAA2B;IAC3B,eAAe,EAAE,MAAM,CAAK;IAC5B,QAAQ,EAAE,MAAM,CAAQ;IACxB,UAAU,EAAE,MAAM,CAAQ;gBAEd,OAAO,GAAE,8BAAmC;IAyBxD,QAAQ,IAAI,OAAO;IAInB,QAAQ,IAAI,SAAS;IAIrB,gBAAgB,IAAI,gBAAgB,EAAE;IAMtC,cAAc,IAAI,MAAM,EAAE;IAI1B,aAAa,IAAI,aAAa,EAAE;IAIhC,sEAAsE;IACtE,SAAS,CAAC,YAAY,IAAI,IAAI;cAMd,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAqEpD;AAED,eAAe,uBAAuB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { SmrtObject } from '@happyvertical/smrt-core';
2
- import type { JsonObject, Subscriber, SubscriberKind, SubscriptionStatus, TenantSubscriptionOptions } from '../types.js';
2
+ import { type PlanVersionReplacement } from '../plan-versioning.js';
3
+ import type { JsonObject, PlanVersionPinReason, Subscriber, SubscriberKind, SubscriptionStatus, TenantSubscriptionOptions } from '../types.js';
3
4
  export declare class TenantSubscription extends SmrtObject {
4
5
  tenantId?: string;
5
6
  /**
@@ -31,6 +32,28 @@ export declare class TenantSubscription extends SmrtObject {
31
32
  canceledAt: Date | null;
32
33
  /** Amount selected for this subscription, in integer minor units. */
33
34
  agreedAmount: number | null;
35
+ /**
36
+ * The immutable `SubscriptionPlanVersion` frozen for the current period
37
+ * (#4032). Maintained on save: pinned at period start, re-pinned when
38
+ * `currentPeriodStart` moves (renewal), and replaced mid-period only by an
39
+ * entitlement upgrade or an authorized {@link replacePlanVersion}. Null
40
+ * only for subscriptions to unmigrated legacy plans with no versions.
41
+ */
42
+ planVersionId: string | null;
43
+ /** When {@link planVersionId} was last set. */
44
+ planVersionPinnedAt: Date | null;
45
+ /** Why {@link planVersionId} was last set (audit). */
46
+ planVersionPinReason: PlanVersionPinReason | null;
47
+ /** Caller-supplied reason for an `upgrade`/`authorized` replacement. */
48
+ planVersionPinNote: string;
49
+ /**
50
+ * Set when the row was canceled while it entitled (`active`/`trialing`
51
+ * within its period), so the paid period runs to `currentPeriodEnd`.
52
+ * Derived on save from the stored row and never taken from the caller: a
53
+ * subscription canceled while `incomplete`, `past_due` or `unpaid` (for
54
+ * example a provider's `incomplete_expired`) entitles nothing.
55
+ */
56
+ retainsPaidPeriod: boolean;
34
57
  externalProvider: string | null;
35
58
  stripeCustomerId: string;
36
59
  stripeSubscriptionId: string;
@@ -47,6 +70,31 @@ export declare class TenantSubscription extends SmrtObject {
47
70
  * under the same tenant.
48
71
  */
49
72
  protected validateBeforeSave(): Promise<void>;
73
+ /**
74
+ * Replace the plan version frozen for the current period and save (#4032).
75
+ *
76
+ * - `policy: 'upgrade'` succeeds only when the target's entitlements cover
77
+ * the frozen version's (see `isEntitlementUpgrade`); otherwise the save
78
+ * is rejected and the paid period keeps its terms.
79
+ * - `policy: 'authorized'` accepts any target and requires a `reason`,
80
+ * recorded with `planVersionPinReason: 'authorized'` for audit — use it
81
+ * for an operator-approved downgrade, refund, or correction.
82
+ *
83
+ * The target is `planVersionId`, else the version of `planId` (as set on
84
+ * this instance) in force now. A plain `planId` change in the same period
85
+ * is treated as `policy: 'upgrade'`.
86
+ */
87
+ replacePlanVersion(options: PlanVersionReplacement & {
88
+ planId?: string;
89
+ }): Promise<this>;
90
+ /**
91
+ * Whether the subscription grants entitlements at `now`. Active and
92
+ * trialing subscriptions entitle until `currentPeriodEnd`. A subscription
93
+ * canceled while it entitled keeps its paid period ({@link
94
+ * retainsPaidPeriod}) until `currentPeriodEnd`, never without one (#4032).
95
+ * For an immediate cancellation (for example with a refund) set
96
+ * `currentPeriodEnd` to the cancellation time.
97
+ */
50
98
  isEntitled(now?: Date): boolean;
51
99
  /**
52
100
  * Project this row's polymorphic subscriber columns onto the
@@ -1 +1 @@
1
- {"version":3,"file":"TenantSubscription.d.ts","sourceRoot":"","sources":["../../src/models/TenantSubscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AASxE,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAOrB,qBAwBa,kBAAmB,SAAQ,UAAU;IAEhD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;OAQG;IACH,cAAc,EAAE,cAAc,CAAY;IAE1C;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAM;IAGlC,MAAM,EAAE,MAAM,CAAM;IAEpB,MAAM,EAAE,kBAAkB,CAAgB;IAC1C,SAAS,EAAE,IAAI,CAAc;IAC7B,kBAAkB,EAAE,IAAI,GAAG,IAAI,CAAQ;IACvC,gBAAgB,EAAE,IAAI,GAAG,IAAI,CAAQ;IACrC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAChC,iBAAiB,EAAE,OAAO,CAAS;IACnC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAC/B,qEAAqE;IACrE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACvC,gBAAgB,EAAE,MAAM,CAAM;IAC9B,oBAAoB,EAAE,MAAM,CAAM;IAClC,uBAAuB,EAAE,MAAM,CAAM;IACrC,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,yBAA8B;IAgDnD;;;;;;;;OAQG;cACa,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA2CnD,UAAU,CAAC,GAAG,OAAa,GAAG,OAAO;IAarC;;;;OAIG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IAiBlC,WAAW,IAAI,UAAU;IAIzB,WAAW,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;CAGxC;AAED,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"TenantSubscription.d.ts","sourceRoot":"","sources":["../../src/models/TenantSubscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AASxE,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAarB,qBAwBa,kBAAmB,SAAQ,UAAU;IAEhD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;OAQG;IACH,cAAc,EAAE,cAAc,CAAY;IAE1C;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAM;IAGlC,MAAM,EAAE,MAAM,CAAM;IAEpB,MAAM,EAAE,kBAAkB,CAAgB;IAC1C,SAAS,EAAE,IAAI,CAAc;IAC7B,kBAAkB,EAAE,IAAI,GAAG,IAAI,CAAQ;IACvC,gBAAgB,EAAE,IAAI,GAAG,IAAI,CAAQ;IACrC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAChC,iBAAiB,EAAE,OAAO,CAAS;IACnC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAC/B,qEAAqE;IACrE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC;;;;;;OAMG;IAEH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,+CAA+C;IAC/C,mBAAmB,EAAE,IAAI,GAAG,IAAI,CAAQ;IACxC,sDAAsD;IACtD,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IACzD,wEAAwE;IACxE,kBAAkB,EAAE,MAAM,CAAM;IAChC;;;;;;OAMG;IACH,iBAAiB,EAAE,OAAO,CAAS;IACnC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACvC,gBAAgB,EAAE,MAAM,CAAM;IAC9B,oBAAoB,EAAE,MAAM,CAAM;IAClC,uBAAuB,EAAE,MAAM,CAAM;IACrC,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,yBAA8B;IA0DnD;;;;;;;;OAQG;cACa,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiFnD;;;;;;;;;;;;;OAaG;IACG,kBAAkB,CACtB,OAAO,EAAE,sBAAsB,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACpD,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;;;;OAOG;IACH,UAAU,CAAC,GAAG,OAAa,GAAG,OAAO;IAgBrC;;;;OAIG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IAiBlC,WAAW,IAAI,UAAU;IAIzB,WAAW,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;CAGxC;AAED,eAAe,kBAAkB,CAAC"}
@@ -3,6 +3,7 @@ export { BillingAdjustment, BillingAdjustmentCollection, ClientCharge, ClientCha
3
3
  export type { PriceBookKind } from './reseller.js';
4
4
  export { CreditGrant, CreditGrantCollection, isCurrencyCode, isPriceBookKind, PriceBook, PriceBookAssignment, PriceBookCollection, RetailCharge, RetailChargeCollection, } from './reseller.js';
5
5
  export { SubscriptionPlan } from './SubscriptionPlan.js';
6
+ export { SubscriptionPlanVersion } from './SubscriptionPlanVersion.js';
6
7
  export { TenantSubscription } from './TenantSubscription.js';
7
8
  export { TenantUsageMetric } from './TenantUsageMetric.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,YAAY,EACZ,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,cAAc,EACd,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,YAAY,EACZ,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,cAAc,EACd,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Plan terms and the entitlement-upgrade policy for effective-dated plan
3
+ * versions (#4032).
4
+ */
5
+ import type { PlanTerms, PlanThreshold } from './types.js';
6
+ /** The versioned term fields, in a stable order. */
7
+ export declare const PLAN_TERM_FIELDS: readonly ["status", "priceAmount", "currency", "billingInterval", "pricingMode", "minimumAmount", "suggestedAmount", "features", "thresholds"];
8
+ /** Copy the versioned terms off a plan or version. */
9
+ export declare function extractPlanTerms(source: PlanTerms): PlanTerms;
10
+ /** True when two term sets would grant and charge the same thing. */
11
+ export declare function samePlanTerms(left: PlanTerms, right: PlanTerms): boolean;
12
+ /** Enabled feature keys of a term set. */
13
+ export declare function enabledFeatureKeys(terms: Pick<PlanTerms, 'features'>): string[];
14
+ /** Valid thresholds of a term set. */
15
+ export declare function validThresholds(terms: Pick<PlanTerms, 'thresholds'>): PlanThreshold[];
16
+ /**
17
+ * The in-period upgrade policy: `to` is an upgrade of `from` when it is
18
+ * `active` and takes nothing away. Every feature enabled in `from` stays
19
+ * enabled, and every threshold in `to` has a counterpart in `from` (same
20
+ * metric and window) whose limit is no higher and whose enforcement is no
21
+ * looser. Removing a threshold loosens it; adding one restricts. Price is not
22
+ * an entitlement and is ignored. Anything else is a downgrade, which only
23
+ * takes effect at renewal or through an explicit authorized replacement.
24
+ */
25
+ export declare function isEntitlementUpgrade(from: PlanTerms, to: PlanTerms): boolean;
26
+ //# sourceMappingURL=plan-terms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-terms.d.ts","sourceRoot":"","sources":["../src/plan-terms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAEV,SAAS,EACT,aAAa,EAEd,MAAM,YAAY,CAAC;AAQpB,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,gJAUsB,CAAC;AAEpD,sDAAsD;AACtD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAY7D;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAIxE;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,YAIpE;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,GACnC,aAAa,EAAE,CAIjB;AAQD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAkB5E"}
@@ -0,0 +1,45 @@
1
+ import type { SubscriptionPlan } from './models/SubscriptionPlan.js';
2
+ import { SubscriptionPlanVersion } from './models/SubscriptionPlanVersion.js';
3
+ import type { TenantSubscription } from './models/TenantSubscription.js';
4
+ /** An in-period replacement requested through `replacePlanVersion()`. */
5
+ export interface PlanVersionReplacement {
6
+ policy: 'upgrade' | 'authorized';
7
+ reason?: string;
8
+ planVersionId?: string;
9
+ }
10
+ /**
11
+ * Version 1 for a plan that predates versioning: its current (persisted)
12
+ * terms, effective from the plan's creation. Returns false when the plan
13
+ * already has versions.
14
+ */
15
+ export declare function snapshotLegacyPlanVersion(plan: SubscriptionPlan): Promise<boolean>;
16
+ /**
17
+ * After a plan save, publish its terms as the next version when they differ
18
+ * from the latest one (or when none exists). `prior` is the row the save
19
+ * overwrote: when the plan had no versions yet, its terms become version 1,
20
+ * effective from the plan's creation.
21
+ */
22
+ export declare function publishPlanVersion(plan: SubscriptionPlan, effectiveFrom: Date, prior?: SubscriptionPlan): Promise<SubscriptionPlanVersion>;
23
+ /**
24
+ * Bind a subscription to the plan version its current period paid for.
25
+ * Called from `TenantSubscription.validateBeforeSave()`.
26
+ *
27
+ * - A new subscription, or a legacy row without a pin, pins the version in
28
+ * force at its period start (`currentPeriodStart ?? startedAt`).
29
+ * - A renewal re-pins the version in force at the new boundary, for the
30
+ * (possibly changed) plan. A save is a renewal only when the new period
31
+ * starts at or after the stored `currentPeriodEnd` (or, without one, after
32
+ * the stored start); moving the start within a paid period is not.
33
+ * - At creation and renewal the boundary decides the version: a caller may
34
+ * name only that version, unless the save is an authorized replacement.
35
+ * - Within a paid period, a different plan or version is accepted only when
36
+ * it is an entitlement upgrade of the frozen terms, when the period no
37
+ * longer entitles, or through an explicit authorized replacement.
38
+ *
39
+ * A plan without versions (an unmigrated legacy plan) leaves the pin empty;
40
+ * resolution then falls back to the live plan.
41
+ */
42
+ export declare function pinSubscriptionPlanVersion(subscription: TenantSubscription, persisted: TenantSubscription | null, replacement: PlanVersionReplacement | undefined, now?: Date): Promise<void>;
43
+ /** Start of a subscription's current period. */
44
+ export declare function periodBoundary(subscription: Pick<TenantSubscription, 'currentPeriodStart' | 'startedAt'>): Date;
45
+ //# sourceMappingURL=plan-versioning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-versioning.d.ts","sourceRoot":"","sources":["../src/plan-versioning.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAQzE,yEAAyE;AACzE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,gBAAgB,EACtB,aAAa,EAAE,IAAI,EACnB,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,uBAAuB,CAAC,CAalC;AA4BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,kBAAkB,EAChC,SAAS,EAAE,kBAAkB,GAAG,IAAI,EACpC,WAAW,EAAE,sBAAsB,GAAG,SAAS,EAC/C,GAAG,OAAa,GACf,OAAO,CAAC,IAAI,CAAC,CAsIf;AA0CD,gDAAgD;AAChD,wBAAgB,cAAc,CAC5B,YAAY,EAAE,IAAI,CAAC,kBAAkB,EAAE,oBAAoB,GAAG,WAAW,CAAC,GACzE,IAAI,CAEN"}
@@ -3,7 +3,7 @@ export type { AutoTopUpGrant, AutoTopUpHook, AutoTopUpRequest, BillingRelationsh
3
3
  export { assertCommercialBillingStorageSupported, CommercialBillingStorageConfigurationError, CommercialUsageService, SpendingPolicyEvaluator, UnsupportedCommercialBillingStorageError, } from './commercial.js';
4
4
  export { type AssignPriceBooksInput, type DefinePriceBookPriceInput, type DelegatedSpendingPolicyInput, type GrantChildCreditInput, type PriceBookAssignmentView, type PriceBookLeg, type ResellerBillingAction, ResellerBillingService, type ResellerBillingServiceOptions, } from './reseller.js';
5
5
  export { ResellerBillingError, type ResellerBillingErrorCode, } from './reseller-errors.js';
6
- export { type SubscriptionPlanReader, SubscriptionResolver, type SubscriptionResolverReaders, type TenantSubscriptionReader, type UsageSummaryReader, } from './subscription-resolver.js';
6
+ export { type SubscriptionPlanReader, type SubscriptionPlanVersionReader, SubscriptionResolver, type SubscriptionResolverReaders, type TenantSubscriptionReader, type UsageSummaryReader, } from './subscription-resolver.js';
7
7
  export { evaluateThreshold, evaluateThresholds, } from './threshold-evaluator.js';
8
8
  export { TenantUsageMeter } from './usage-meter.js';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,iCAAiC,EACjC,8BAA8B,EAC9B,WAAW,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,uCAAuC,EACvC,0CAA0C,EAC1C,sBAAsB,EACtB,uBAAuB,EACvB,wCAAwC,GACzC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,KAAK,wBAAwB,GAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,sBAAsB,EAC3B,oBAAoB,EACpB,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,iCAAiC,EACjC,8BAA8B,EAC9B,WAAW,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,uCAAuC,EACvC,0CAA0C,EAC1C,sBAAsB,EACtB,uBAAuB,EACvB,wCAAwC,GACzC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,KAAK,wBAAwB,GAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,EAClC,oBAAoB,EACpB,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { SubscriptionPlan } from '../models/SubscriptionPlan.js';
2
+ import type { SubscriptionPlanVersion } from '../models/SubscriptionPlanVersion.js';
2
3
  import type { TenantSubscription } from '../models/TenantSubscription.js';
3
4
  import type { EntitlementResolution, EntitlementResolutionContext, PlanThreshold, SmrtClassOptions, Subscriber, SubscriptionResolverOptions, UsageSummary, UsageWindow } from '../types.js';
4
5
  export interface SubscriptionPlanReader {
@@ -6,6 +7,17 @@ export interface SubscriptionPlanReader {
6
7
  id: string;
7
8
  }): Promise<SubscriptionPlan | null>;
8
9
  }
10
+ /**
11
+ * Reader for effective-dated plan versions (#4032). `findInForce` resolves
12
+ * subscriptions that have no pinned version yet (rows written before
13
+ * versioning and not yet migrated).
14
+ */
15
+ export interface SubscriptionPlanVersionReader {
16
+ get(criteria: {
17
+ id: string;
18
+ }): Promise<SubscriptionPlanVersion | null>;
19
+ findInForce?(planId: string, at: Date): Promise<SubscriptionPlanVersion | null>;
20
+ }
9
21
  /**
10
22
  * Reader contract for finding the current subscription for a subscriber.
11
23
  *
@@ -49,6 +61,12 @@ export interface SubscriptionResolverReaders {
49
61
  plans: SubscriptionPlanReader;
50
62
  subscriptions: TenantSubscriptionReader;
51
63
  usage: UsageSummaryReader;
64
+ /**
65
+ * Plan versions. When present, entitlements come from the version frozen
66
+ * for the subscription's current period instead of the live plan row.
67
+ * Omitting it keeps the pre-#4032 live-plan behavior.
68
+ */
69
+ planVersions?: SubscriptionPlanVersionReader;
52
70
  }
53
71
  export declare class SubscriptionResolver {
54
72
  private readonly readers;
@@ -79,6 +97,14 @@ export declare class SubscriptionResolver {
79
97
  assertWithinThresholds(subscriberOrTenantId: Subscriber | string, options?: SubscriptionResolverOptions): Promise<void>;
80
98
  private resolveSubscription;
81
99
  private resolvePlan;
100
+ /**
101
+ * The version frozen for the subscription's current period: its pinned
102
+ * `planVersionId`, or — for rows not yet pinned — the version in force at
103
+ * its period start. Null when the subscription has no plan or a pinned
104
+ * version is missing (the resolver then fails closed); undefined when no
105
+ * version reader or context is available.
106
+ */
107
+ private resolvePlanVersion;
82
108
  /**
83
109
  * Bridge the legacy and polymorphic reader contracts.
84
110
  *
@@ -1 +1 @@
1
- {"version":3,"file":"subscription-resolver.d.ts","sourceRoot":"","sources":["../../src/services/subscription-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,2BAA2B,EAE3B,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AASrB,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACjE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACtC,wBAAwB,CAAC,CACvB,UAAU,EAAE,UAAU,EACtB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACvC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,OAAO,EAAE;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1B,cAAc,CAAC,CAAC,OAAO,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,sBAAsB,CAAC;IAC9B,aAAa,EAAE,wBAAwB,CAAC;IACxC,KAAK,EAAE,kBAAkB,CAAC;CAC3B;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,2BAA2B;IAEjE;;;OAGG;WACU,MAAM,CACjB,YAAY,GAAE,gBAAqB,GAClC,OAAO,CAAC,oBAAoB,CAAC;IAShC;;;;OAIG;IACG,sBAAsB,CAC1B,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,4BAA4B,CAAC;IAYxC;;;;OAIG;IACG,mBAAmB,CACvB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC;IA2CjC;;;OAGG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC;IAI3B,gBAAgB,CACpB,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,OAAO,CAAC;IAQb,sBAAsB,CAC1B,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,IAAI,CAAC;YAkBF,mBAAmB;YAanB,WAAW;IAiBzB;;;;;;;;;OASG;YACW,uBAAuB;YAsBvB,2BAA2B;CA4E1C;AA0GD,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"subscription-resolver.d.ts","sourceRoot":"","sources":["../../src/services/subscription-resolver.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,2BAA2B,EAE3B,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AASrB,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACjE;AAED;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,GAAG,CAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;IACvE,WAAW,CAAC,CACV,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,IAAI,GACP,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;CAC5C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACtC,wBAAwB,CAAC,CACvB,UAAU,EAAE,UAAU,EACtB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACvC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,OAAO,EAAE;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1B,cAAc,CAAC,CAAC,OAAO,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,sBAAsB,CAAC;IAC9B,aAAa,EAAE,wBAAwB,CAAC;IACxC,KAAK,EAAE,kBAAkB,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,6BAA6B,CAAC;CAC9C;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,2BAA2B;IAEjE;;;OAGG;WACU,MAAM,CACjB,YAAY,GAAE,gBAAqB,GAClC,OAAO,CAAC,oBAAoB,CAAC;IAoBhC;;;;OAIG;IACG,sBAAsB,CAC1B,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,4BAA4B,CAAC;IAgBxC;;;;OAIG;IACG,mBAAmB,CACvB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC;IAqDjC;;;OAGG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC;IAI3B,gBAAgB,CACpB,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,OAAO,CAAC;IAQb,sBAAsB,CAC1B,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,IAAI,CAAC;YAkBF,mBAAmB;YAanB,WAAW;IAiBzB;;;;;;OAMG;YACW,kBAAkB;IA0BhC;;;;;;;;;OASG;YACW,uBAAuB;YAsBvB,2BAA2B;CA4E1C;AAwID,YAAY,EAAE,aAAa,EAAE,CAAC"}