@saasicat/nest 1.0.0-rc.21 → 1.0.0-rc.22

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 (64) hide show
  1. package/dist/.build-stamp +1 -1
  2. package/dist/_entries.cjs +4887 -3609
  3. package/dist/admin/index.js +7 -5
  4. package/dist/{aggregation-ChpZDh0g.d.ts → aggregation-6fPkeV8i.d.ts} +39 -4
  5. package/dist/{aggregation-OpnhwzF5.d.cts → aggregation-DjQUc7yd.d.cts} +39 -4
  6. package/dist/billing/index.d.cts +68 -9
  7. package/dist/billing/index.d.ts +68 -9
  8. package/dist/billing/index.js +16 -5
  9. package/dist/checkout-offer/index.d.cts +2 -2
  10. package/dist/checkout-offer/index.d.ts +2 -2
  11. package/dist/checkout-offer/index.js +4 -4
  12. package/dist/{checkout-offer.service-CCVxG9b2.d.cts → checkout-offer.service-DmVGrT4v.d.cts} +1 -1
  13. package/dist/{checkout-offer.service-BeHgYikI.d.ts → checkout-offer.service-Yi30L4ry.d.ts} +1 -1
  14. package/dist/{chunk-WHJSYKNC.js → chunk-3U4N5UYD.js} +1 -1
  15. package/dist/{chunk-M47BNEY2.js → chunk-3YYLOYUT.js} +1373 -266
  16. package/dist/{chunk-G6EZWECL.js → chunk-B4YP7REK.js} +94 -26
  17. package/dist/{chunk-QPVDCKYS.js → chunk-ESEWSAOV.js} +4 -3
  18. package/dist/{chunk-NDLC5GYK.js → chunk-EU4N5LET.js} +4 -3
  19. package/dist/{chunk-LLYVYRGJ.js → chunk-F2PF4IXB.js} +1 -275
  20. package/dist/{chunk-AOS2JPDD.js → chunk-FJIOHAO5.js} +77 -41
  21. package/dist/{chunk-TOEFN7DN.js → chunk-FPMBQDW7.js} +2 -2
  22. package/dist/chunk-OSOP4KWL.js +288 -0
  23. package/dist/{chunk-3RLWML2S.js → chunk-QWKBOLBH.js} +35 -0
  24. package/dist/{chunk-JBCC6C3M.js → chunk-R3I5X262.js} +5 -4
  25. package/dist/{chunk-4SDSYV4A.js → chunk-T6WXDGIU.js} +1 -1
  26. package/dist/{chunk-R5YCJBHY.js → chunk-U5UPEFWC.js} +2 -2
  27. package/dist/{chunk-XSSWYPP5.js → chunk-UMZCOCT5.js} +1 -1
  28. package/dist/{chunk-7NJKVC5X.js → chunk-WQNOCOI2.js} +53 -6
  29. package/dist/{chunk-55QEDAMX.js → chunk-WTAS2CLM.js} +4 -9
  30. package/dist/{enforce-quota.interceptor-BFyVdWe8.d.cts → enforce-quota.interceptor-B9UhCBXx.d.cts} +2 -2
  31. package/dist/{enforce-quota.interceptor-GaBXboGx.d.ts → enforce-quota.interceptor-CR2waXNA.d.ts} +2 -2
  32. package/dist/entitlement/index.d.cts +1 -1
  33. package/dist/entitlement/index.d.ts +1 -1
  34. package/dist/entitlement/index.js +4 -2
  35. package/dist/index.d.cts +11 -11
  36. package/dist/index.d.ts +11 -11
  37. package/dist/index.js +36 -20
  38. package/dist/{issuer-identity.check-CBO0vcsq.d.cts → issuer-identity.check-BntcNdld.d.cts} +1 -1
  39. package/dist/{issuer-identity.check-Cz9CEMkZ.d.ts → issuer-identity.check-DFmS8whs.d.ts} +1 -1
  40. package/dist/{module-options-qAOwinHR.d.cts → module-options-C4S_StYF.d.cts} +2 -2
  41. package/dist/{module-options-DmQ3G4sZ.d.ts → module-options-DxJI-1iH.d.ts} +2 -2
  42. package/dist/payments/index.js +2 -2
  43. package/dist/platform/index.d.cts +25 -16
  44. package/dist/platform/index.d.ts +25 -16
  45. package/dist/platform/index.js +16 -14
  46. package/dist/promo/index.d.cts +11 -4
  47. package/dist/promo/index.d.ts +11 -4
  48. package/dist/promo/index.js +5 -3
  49. package/dist/{promo.module-CKkECmU8.d.cts → promo.module-Ddx-swUV.d.cts} +1 -1
  50. package/dist/{promo.module-DuIJdK3U.d.ts → promo.module-PsIvDcUp.d.ts} +1 -1
  51. package/dist/{promo.service-BYBu6dy3.d.cts → promo.service-BextPvx5.d.cts} +23 -1
  52. package/dist/{promo.service-CFjfF0Xm.d.ts → promo.service-Dqqh0JXn.d.ts} +23 -1
  53. package/dist/registration/index.d.cts +2 -2
  54. package/dist/registration/index.d.ts +2 -2
  55. package/dist/registration/index.js +5 -5
  56. package/dist/subscription-contract/index.js +2 -2
  57. package/dist/{tenant-billing.controller-DKbAqTbM.d.cts → tenant-billing.controller-BC6-S5cT.d.cts} +91 -10
  58. package/dist/{tenant-billing.controller-BLqbsONe.d.ts → tenant-billing.controller-BuQDQ76i.d.ts} +91 -10
  59. package/dist/{tenant-billing.module-ClbjzocC.d.cts → tenant-billing.module-C6MFfCKq.d.cts} +24 -1
  60. package/dist/{tenant-billing.module-DohgJJ2m.d.ts → tenant-billing.module-CUCQL0-k.d.ts} +24 -1
  61. package/dist/testing/index.d.cts +6 -6
  62. package/dist/testing/index.d.ts +6 -6
  63. package/dist/testing/index.js +33 -31
  64. package/package.json +3 -3
@@ -1,7 +1,6 @@
1
1
  import "../chunk-UF53DWWR.js";
2
2
  import {
3
3
  ADMIN_MANIFEST_CONFIG,
4
- ADMIN_RESOURCES_PORT_TOKEN,
5
4
  ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN,
6
5
  AUDIT_STATS_PORT_TOKEN,
7
6
  AdminBypassRlsInterceptor,
@@ -9,8 +8,6 @@ import {
9
8
  AdminManifestService,
10
9
  AdminModule,
11
10
  AdminPublicBootController,
12
- AdminResourcesModule,
13
- AdminResourcesService,
14
11
  AdminStatsController,
15
12
  AdminStatsModule,
16
13
  AdminStatsService,
@@ -19,9 +16,14 @@ import {
19
16
  PROMO_CODE_STATS_PORT_TOKEN,
20
17
  SUBSCRIPTION_STATS_PORT_TOKEN,
21
18
  SuperAdminGuard,
22
- SuspendTenantDto,
23
19
  buildAdminStatsController
24
- } from "../chunk-LLYVYRGJ.js";
20
+ } from "../chunk-F2PF4IXB.js";
21
+ import {
22
+ ADMIN_RESOURCES_PORT_TOKEN,
23
+ AdminResourcesModule,
24
+ AdminResourcesService,
25
+ SuspendTenantDto
26
+ } from "../chunk-OSOP4KWL.js";
25
27
  import {
26
28
  MfaGuard,
27
29
  MfaService,
@@ -88,6 +88,16 @@ interface EffectiveLimitsSnapshot {
88
88
  features: FeatureKey[];
89
89
  }
90
90
 
91
+ /** What a contract frozen at a moment records as its entitlements. */
92
+ interface ContractLimits {
93
+ limits: EffectiveLimits;
94
+ /**
95
+ * The add-ons left out of `limits` because their cancellation is declared.
96
+ * The contract names them in its snapshot, so that their bookings grant
97
+ * them until their effective date and a reader knows the snapshot does not.
98
+ */
99
+ leftOutBundleVersionIds: string[];
100
+ }
91
101
  interface EnforceLimitInput<T> {
92
102
  /** Tenant whose subscription is checked. */
93
103
  tenantId: string;
@@ -135,6 +145,17 @@ declare class EntitlementService {
135
145
  * older than the one everybody else should be answered from.
136
146
  */
137
147
  computeLimits(tenantId: string, now?: Date, catalog?: PlanCatalog): Promise<EffectiveLimits>;
148
+ /**
149
+ * What a contract frozen at `now` records as its entitlements: what
150
+ * `computeLimits` grants, less the add-ons whose cancellation is declared.
151
+ *
152
+ * Those are granted until their effective date by the booking rather than
153
+ * by the contract (`mergeSubscriptionBundlesIntoLimits`), so their end
154
+ * needs nobody to write the contract again. Frozen into the snapshot, they
155
+ * would be granted for as long as the contract runs. Never cached, like
156
+ * `computeLimits` with a catalogue.
157
+ */
158
+ computeContractLimits(tenantId: string, now: Date, catalog: PlanCatalog): Promise<ContractLimits>;
138
159
  /**
139
160
  * Clears a tenant's cache entry. MUST be called as soon as a mutation
140
161
  * changes the subscription, a bundle booking, or a PlanVersion binding —
@@ -149,13 +170,14 @@ declare class EntitlementService {
149
170
  * have a `SubscriptionRecord` (e.g. within a transaction).
150
171
  */
151
172
  deriveLimits(sub: SubscriptionRecord, now: Date, tx?: TransactionContext): Promise<EffectiveLimits>;
173
+ private requireSubscription;
152
174
  /**
153
175
  * `deriveLimits` against a catalogue already read. The catalogue decides
154
176
  * which features are `plannedOnly`, and it is read outside any transaction
155
177
  * a caller holds, so that checking a limit does not wait for a second
156
178
  * connection while the subscription row is locked.
157
179
  */
158
- private limitsFor;
180
+ private answerFor;
159
181
  /**
160
182
  * The last thing every path does, so that no path can skip it.
161
183
  *
@@ -208,6 +230,11 @@ declare class EntitlementService {
208
230
  * Spec:
209
231
  */
210
232
  declare function filterActiveSubscriptionBundles(bundles: readonly SubscriptionBundleSnapshot[], now: Date): SubscriptionBundleSnapshot[];
233
+ /**
234
+ * Whether a booking's end is already set. Such a booking is still active until
235
+ * that date, but it is not part of what a contract agrees to from here on.
236
+ */
237
+ declare function isCancellationDeclared(booking: Pick<SubscriptionBundleSnapshot, 'canceledEffectiveAt'>): boolean;
211
238
  /**
212
239
  * Aggregates the quotas of all active SubscriptionBundle bookings:
213
240
  * Σ per QuotaKey, `-1` (unlimited) dominates. Bundle features +
@@ -232,9 +259,17 @@ declare function aggregateContractLineItemEntitlements(lineItems: readonly Pick<
232
259
  declare function contractLimits(contract: Pick<SubscriptionContractRecord, 'entitlementSnapshot' | 'lineItems'>): EffectiveLimits;
233
260
  /**
234
261
  * `BundleVersion`s the contract already accounts for — from the freeze
235
- * (`originalBundleVersionIds`) and from its bundle line items.
262
+ * (`originalBundleVersionIds`) and from its bundle line items — less the ones
263
+ * its entitlement snapshot says it left out.
264
+ *
265
+ * A contract written while an add-on's cancellation is declared keeps the
266
+ * add-on's line, because it is billed until its effective date, but leaves its
267
+ * features and quotas out of the snapshot and names it there. Such an add-on is
268
+ * not covered: its booking grants it until that date, and nothing does after.
269
+ * A snapshot that names nothing — written earlier, or by an application —
270
+ * covers every add-on its contract lists, so nothing is counted twice.
236
271
  */
237
- declare function contractBundleVersionIds(contract: Pick<SubscriptionContractRecord, 'originalBundleVersionIds' | 'lineItems'>): Set<string>;
272
+ declare function contractBundleVersionIds(contract: Pick<SubscriptionContractRecord, 'originalBundleVersionIds' | 'lineItems' | 'entitlementSnapshot'>): Set<string>;
238
273
  /**
239
274
  * Adds bundle bookings on top of limits that came from a contract.
240
275
  *
@@ -290,4 +325,4 @@ declare function hasAnyFeature(limits: EffectiveLimits, features: readonly Featu
290
325
  */
291
326
  declare function toEffectiveLimitsSnapshot(limits: EffectiveLimits): EffectiveLimitsSnapshot;
292
327
 
293
- export { type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type EffectiveLimitsSnapshot as a, type EnforceLimitInput as b, EntitlementService as c, type SubscriptionLimitsInput as d, aggregateContractLineItemEntitlements as e, aggregateLimits as f, aggregateSubscriptionBundleQuotas as g, applyCustomLimits as h, collectSubscriptionBundleFeatures as i, contractBundleVersionIds as j, contractLimits as k, filterActiveSubscriptionBundles as l, filterPlannedOnlyFeatures as m, hasAnyFeature as n, hasFeature as o, mergeSubscriptionBundlesIntoLimits as p, toEffectiveLimitsSnapshot as t };
328
+ export { type ContractLimits as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type CustomLimitsShape as a, type EffectiveLimitsSnapshot as b, type EnforceLimitInput as c, EntitlementService as d, type SubscriptionLimitsInput as e, aggregateContractLineItemEntitlements as f, aggregateLimits as g, aggregateSubscriptionBundleQuotas as h, applyCustomLimits as i, collectSubscriptionBundleFeatures as j, contractBundleVersionIds as k, contractLimits as l, filterActiveSubscriptionBundles as m, filterPlannedOnlyFeatures as n, hasAnyFeature as o, hasFeature as p, isCancellationDeclared as q, mergeSubscriptionBundlesIntoLimits as r, toEffectiveLimitsSnapshot as t };
@@ -88,6 +88,16 @@ interface EffectiveLimitsSnapshot {
88
88
  features: FeatureKey[];
89
89
  }
90
90
 
91
+ /** What a contract frozen at a moment records as its entitlements. */
92
+ interface ContractLimits {
93
+ limits: EffectiveLimits;
94
+ /**
95
+ * The add-ons left out of `limits` because their cancellation is declared.
96
+ * The contract names them in its snapshot, so that their bookings grant
97
+ * them until their effective date and a reader knows the snapshot does not.
98
+ */
99
+ leftOutBundleVersionIds: string[];
100
+ }
91
101
  interface EnforceLimitInput<T> {
92
102
  /** Tenant whose subscription is checked. */
93
103
  tenantId: string;
@@ -135,6 +145,17 @@ declare class EntitlementService {
135
145
  * older than the one everybody else should be answered from.
136
146
  */
137
147
  computeLimits(tenantId: string, now?: Date, catalog?: PlanCatalog): Promise<EffectiveLimits>;
148
+ /**
149
+ * What a contract frozen at `now` records as its entitlements: what
150
+ * `computeLimits` grants, less the add-ons whose cancellation is declared.
151
+ *
152
+ * Those are granted until their effective date by the booking rather than
153
+ * by the contract (`mergeSubscriptionBundlesIntoLimits`), so their end
154
+ * needs nobody to write the contract again. Frozen into the snapshot, they
155
+ * would be granted for as long as the contract runs. Never cached, like
156
+ * `computeLimits` with a catalogue.
157
+ */
158
+ computeContractLimits(tenantId: string, now: Date, catalog: PlanCatalog): Promise<ContractLimits>;
138
159
  /**
139
160
  * Clears a tenant's cache entry. MUST be called as soon as a mutation
140
161
  * changes the subscription, a bundle booking, or a PlanVersion binding —
@@ -149,13 +170,14 @@ declare class EntitlementService {
149
170
  * have a `SubscriptionRecord` (e.g. within a transaction).
150
171
  */
151
172
  deriveLimits(sub: SubscriptionRecord, now: Date, tx?: TransactionContext): Promise<EffectiveLimits>;
173
+ private requireSubscription;
152
174
  /**
153
175
  * `deriveLimits` against a catalogue already read. The catalogue decides
154
176
  * which features are `plannedOnly`, and it is read outside any transaction
155
177
  * a caller holds, so that checking a limit does not wait for a second
156
178
  * connection while the subscription row is locked.
157
179
  */
158
- private limitsFor;
180
+ private answerFor;
159
181
  /**
160
182
  * The last thing every path does, so that no path can skip it.
161
183
  *
@@ -208,6 +230,11 @@ declare class EntitlementService {
208
230
  * Spec:
209
231
  */
210
232
  declare function filterActiveSubscriptionBundles(bundles: readonly SubscriptionBundleSnapshot[], now: Date): SubscriptionBundleSnapshot[];
233
+ /**
234
+ * Whether a booking's end is already set. Such a booking is still active until
235
+ * that date, but it is not part of what a contract agrees to from here on.
236
+ */
237
+ declare function isCancellationDeclared(booking: Pick<SubscriptionBundleSnapshot, 'canceledEffectiveAt'>): boolean;
211
238
  /**
212
239
  * Aggregates the quotas of all active SubscriptionBundle bookings:
213
240
  * Σ per QuotaKey, `-1` (unlimited) dominates. Bundle features +
@@ -232,9 +259,17 @@ declare function aggregateContractLineItemEntitlements(lineItems: readonly Pick<
232
259
  declare function contractLimits(contract: Pick<SubscriptionContractRecord, 'entitlementSnapshot' | 'lineItems'>): EffectiveLimits;
233
260
  /**
234
261
  * `BundleVersion`s the contract already accounts for — from the freeze
235
- * (`originalBundleVersionIds`) and from its bundle line items.
262
+ * (`originalBundleVersionIds`) and from its bundle line items — less the ones
263
+ * its entitlement snapshot says it left out.
264
+ *
265
+ * A contract written while an add-on's cancellation is declared keeps the
266
+ * add-on's line, because it is billed until its effective date, but leaves its
267
+ * features and quotas out of the snapshot and names it there. Such an add-on is
268
+ * not covered: its booking grants it until that date, and nothing does after.
269
+ * A snapshot that names nothing — written earlier, or by an application —
270
+ * covers every add-on its contract lists, so nothing is counted twice.
236
271
  */
237
- declare function contractBundleVersionIds(contract: Pick<SubscriptionContractRecord, 'originalBundleVersionIds' | 'lineItems'>): Set<string>;
272
+ declare function contractBundleVersionIds(contract: Pick<SubscriptionContractRecord, 'originalBundleVersionIds' | 'lineItems' | 'entitlementSnapshot'>): Set<string>;
238
273
  /**
239
274
  * Adds bundle bookings on top of limits that came from a contract.
240
275
  *
@@ -290,4 +325,4 @@ declare function hasAnyFeature(limits: EffectiveLimits, features: readonly Featu
290
325
  */
291
326
  declare function toEffectiveLimitsSnapshot(limits: EffectiveLimits): EffectiveLimitsSnapshot;
292
327
 
293
- export { type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type EffectiveLimitsSnapshot as a, type EnforceLimitInput as b, EntitlementService as c, type SubscriptionLimitsInput as d, aggregateContractLineItemEntitlements as e, aggregateLimits as f, aggregateSubscriptionBundleQuotas as g, applyCustomLimits as h, collectSubscriptionBundleFeatures as i, contractBundleVersionIds as j, contractLimits as k, filterActiveSubscriptionBundles as l, filterPlannedOnlyFeatures as m, hasAnyFeature as n, hasFeature as o, mergeSubscriptionBundlesIntoLimits as p, toEffectiveLimitsSnapshot as t };
328
+ export { type ContractLimits as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type CustomLimitsShape as a, type EffectiveLimitsSnapshot as b, type EnforceLimitInput as c, EntitlementService as d, type SubscriptionLimitsInput as e, aggregateContractLineItemEntitlements as f, aggregateLimits as g, aggregateSubscriptionBundleQuotas as h, applyCustomLimits as i, collectSubscriptionBundleFeatures as j, contractBundleVersionIds as k, contractLimits as l, filterActiveSubscriptionBundles as m, filterPlannedOnlyFeatures as n, hasAnyFeature as o, hasFeature as p, isCancellationDeclared as q, mergeSubscriptionBundlesIntoLimits as r, toEffectiveLimitsSnapshot as t };
@@ -1,20 +1,20 @@
1
- import { BillingCycle, BundleVersionRow, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalogSettings, PlanCatalogReadSink, PlanCatalog, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, TenantSubscriptionWritePort, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog } from '@saasicat/core';
1
+ import { BillingCycle, BundleVersionRow, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalogSettings, PlanCatalogReadSink, PlanCatalog, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, TenantSubscriptionWritePort, SubscriptionUsagePort, SubscriberLedgerRepository, SubscriptionContractRepository, SubscriberRepository, AdminSubscriberAccount, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog } from '@saasicat/core';
2
2
  export { BundleVersionFields, CancellationNoticePeriods, ChangeDirection, DiffResult, PlanVersionFields, SelfServiceBlockedPlans, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/core';
3
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as CancellableSubscription, c as CancellationDecision, d as CancellationInput, e as ChangePlanDto, f as CompleteOnboardingSubscriptionDto, g as ComposedTenantAuthGuard, h as CycleDirection, L as LimitsCheckRow, N as NO_NOTICE_PERIOD, P as PendingPlanMaterializationService, i as PlanChangeContext, j as PlanChangePreviewDto, k as PlanChangePreviewIssue, l as PlanChangePreviewService, m as PlanChangeType, n as PlanDirection, o as PlanSnapshotDto, p as PreviewPlanChangeDto, q as ProrationDto, r as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, s as SubscriptionBundleCancelPreviewDto, t as SubscriptionBundleConfig, u as SubscriptionBundlePreviewContext, v as SubscriptionBundlePreviewIssue, w as SubscriptionBundlePreviewService, x as SubscriptionBundlesService, T as TenantAdminGuard, y as TenantBillingController, U as UsageResponse, z as addMonths, D as clampToParent, E as computeProration, F as decideCancellation, G as decideCancellationFor, H as noticeDaysFor, I as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-DKbAqTbM.cjs';
4
- import { F as FEATURE_GUARD_MARKER, d as ContractFreezePort, e as ContractFreezeSourcePort } from '../tenant-billing.module-ClbjzocC.cjs';
5
- export { A as AjvErrorLike, C as CONTRACT_FREEZE_PORT_TOKEN, b as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, c as ContractFreezeBundleSnapshot, E as EnvironmentVariables, f as LoadPlanCatalogFromStringOptions, L as LoadPlanCatalogOptions, M as MarkedFeatureGuard, P as PLAN_CATALOG_UNREADABLE_ERROR, g as PlanCatalogValidationError, h as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SelfServiceBlockedBundles, a as SubscriptionBundleControllerOptions, k as SubscriptionBundleModule, S as SubscriptionBundleModuleOptions, l as TenantBillingModule, T as TenantBillingModuleOptions, m as catalogSource, n as isPlatformFeatureGuard, o as loadPlanCatalogFromFile, p as loadPlanCatalogFromString } from '../tenant-billing.module-ClbjzocC.cjs';
3
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as CancellableSubscription, c as CancellationDecision, d as CancellationInput, e as ChangePlanDto, f as CompleteOnboardingSubscriptionDto, g as ComposedTenantAuthGuard, h as CycleDirection, L as LimitsCheckRow, N as NO_NOTICE_PERIOD, P as PendingPlanMaterializationService, i as PlanChangeContext, j as PlanChangePreviewDto, k as PlanChangePreviewIssue, l as PlanChangePreviewService, m as PlanChangeType, n as PlanDirection, o as PlanSnapshotDto, p as PreviewPlanChangeDto, q as ProrationBasis, r as ProrationDto, s as ProrationInput, R as RedundantFeatureHint, S as SubscriberChargeService, t as SubscriptionBundleAddPreviewDto, u as SubscriptionBundleCancelPreviewDto, v as SubscriptionBundleConfig, w as SubscriptionBundlePreviewContext, x as SubscriptionBundlePreviewIssue, y as SubscriptionBundlePreviewService, z as SubscriptionBundlesService, T as TenantAdminGuard, D as TenantBillingController, U as UsageResponse, E as addMonths, F as clampToParent, G as computeNewPeriodCharge, H as computeProration, I as decideCancellation, J as decideCancellationFor, K as noticeDaysFor, M as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-BC6-S5cT.cjs';
4
+ import { F as FEATURE_GUARD_MARKER, d as ContractFreezePort, e as ContractFreezeSourcePort } from '../tenant-billing.module-C6MFfCKq.cjs';
5
+ export { A as AjvErrorLike, C as CONTRACT_FREEZE_PORT_TOKEN, b as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, c as ContractFreezeBundleSnapshot, E as EnvironmentVariables, f as LoadPlanCatalogFromStringOptions, L as LoadPlanCatalogOptions, M as MarkedFeatureGuard, P as PLAN_CATALOG_UNREADABLE_ERROR, g as PlanCatalogValidationError, h as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SelfServiceBlockedBundles, a as SubscriptionBundleControllerOptions, k as SubscriptionBundleModule, S as SubscriptionBundleModuleOptions, l as TenantBillingModule, T as TenantBillingModuleOptions, m as catalogSource, n as isPlatformFeatureGuard, o as loadPlanCatalogFromFile, p as loadPlanCatalogFromString } from '../tenant-billing.module-C6MFfCKq.cjs';
6
6
  import * as _nestjs_common from '@nestjs/common';
7
7
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
8
8
  export { Type as NestType } from '@nestjs/common';
9
9
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
10
- import { c as EntitlementService } from '../aggregation-OpnhwzF5.cjs';
10
+ import { d as EntitlementService } from '../aggregation-DjQUc7yd.cjs';
11
11
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
12
12
  import { P as PlanCatalogSource } from '../plan-catalog-source-DWe-BGY1.cjs';
13
13
  export { a as PlanCatalogOrigin, g as givenPlanCatalogSource } from '../plan-catalog-source-DWe-BGY1.cjs';
14
14
  import { d as AuthGuardList } from '../tenant-billing.tokens-G-1xOlMr.cjs';
15
15
  export { c as AUDIT_CONTEXT_RESOLVER_TOKEN, A as AuditContextResolver, B as BILLING_PERMISSION_GUARDS_TOKEN, C as CANCELLATION_NOTICE_DAYS_TOKEN, D as DuePendingPlanChange, e as PENDING_PLAN_QUERY_PORT_TOKEN, P as PendingPlanQueryPort, S as SUBSCRIPTION_USAGE_PORT_TOKEN, f as SUBSCRIPTION_WRITE_PORT_TOKEN, g as TENANT_AUTH_GUARDS_TOKEN, h as TENANT_ID_RESOLVER_TOKEN, i as TRIAL_PROJECTION_PORT_TOKEN, T as TenantIdResolver, j as TrialProjectionInput, a as TrialProjectionPort, k as USAGE_SNAPSHOT_PORT_TOKEN, l as USER_EMAIL_RESOLVER_TOKEN, m as USER_ID_RESOLVER_TOKEN, U as UserEmailResolver, b as UserIdResolver } from '../tenant-billing.tokens-G-1xOlMr.cjs';
16
16
  import { S as SubscriptionContractService } from '../subscription-contract.service-CfNApLuP.cjs';
17
- import '../promo.service-BYBu6dy3.cjs';
17
+ import { a as PromoCodesService } from '../promo.service-BextPvx5.cjs';
18
18
  import '../admin-audit.service-4P3Djdxk.cjs';
19
19
  import '../contract-line-item-money-B0Z3Ogur.cjs';
20
20
  import '../plan-resolution-CwUy_OqC.cjs';
@@ -277,7 +277,7 @@ declare function computeNextBundlePeriod(booking: BundlePeriodRollInput, plan: B
277
277
  * publish gate checks; what it cannot check is the combination, since that
278
278
  * depends on the plan the tenant is on and the rhythm they are billed in.
279
279
  */
280
- declare function resolveBundlePriceNet(bundleVersion: BundleVersionRow, planKey: string, billingCycle: string): number | null;
280
+ declare function resolveBundlePriceNet(bundleVersion: BundleVersionRow, planKey: string, billingCycle: BillingCycle): number | null;
281
281
  /**
282
282
  * The cycles a plan version is actually sold in.
283
283
  *
@@ -841,12 +841,71 @@ declare class SubscriptionContractFreezeService implements ContractFreezePort {
841
841
  private readonly entitlements;
842
842
  private readonly contracts;
843
843
  private readonly source;
844
- constructor(catalogs: PlanCatalogSource, entitlements: EntitlementService, contracts: SubscriptionContractService, source: ContractFreezeSourcePort, writes?: TenantSubscriptionWritePort | null);
844
+ private readonly subscriptions;
845
+ private readonly promoCodes;
846
+ constructor(catalogs: PlanCatalogSource, entitlements: EntitlementService, contracts: SubscriptionContractService, source: ContractFreezeSourcePort, writes?: TenantSubscriptionWritePort | null, subscriptions?: SubscriptionUsagePort | null, promoCodes?: PromoCodesService | null);
845
847
  assertPartyFor(tenantId: string): Promise<void>;
846
848
  endOnCancellation(tenantId: string, effectiveAt: Date): Promise<void>;
847
849
  freezeOnPlanChange(tenantId: string, newPlan: string, billingCycle: BillingCycle, effectiveFrom: Date, endsAt?: Date | null): Promise<void>;
850
+ /**
851
+ * The code redeemed for the tenant's subscription, as a discount line, where
852
+ * no contract of the tenant records it yet.
853
+ *
854
+ * The first contract written after a redemption records it — at onboarding,
855
+ * or at the activation after a trial, where onboarding wrote none — and the
856
+ * ones after it do not repeat it: the discount runs from where it was first
857
+ * agreed, for the duration on its snapshot, counted from the first period
858
+ * that is paid. A contract concluded from an offer that carried the code
859
+ * already records it. Nothing is recorded without the promo module, for a
860
+ * reversed redemption, or where a contract written since the redemption
861
+ * does not record it: that was the first one, written before contracts
862
+ * recorded codes or by the application itself, and a later contract does
863
+ * not start the discount again.
864
+ */
865
+ private redeemedCodeNotYetRecorded;
866
+ }
867
+
868
+ interface SubscriberAccountModuleOptions {
869
+ /** The same chain the tenant routes of the administration run behind. */
870
+ guards: Array<Type<CanActivate>>;
871
+ /**
872
+ * Must bring `AdminResourcesService` and `SubscriberAccountService` into
873
+ * scope — the modules that already provide them, passed as the very objects
874
+ * the application imports, so that no adapter is built a second time. The
875
+ * `RlsBypassPort` has to be visible too; `SaaSiCatModule` provides it
876
+ * globally.
877
+ */
878
+ imports: Array<Type<unknown> | DynamicModule | Promise<DynamicModule> | ForwardReference>;
879
+ }
880
+ /**
881
+ * The operator's view of a subscriber's account, served beside the tenant it
882
+ * belongs to. Mounted where the platform keeps both the administration's
883
+ * tenants and a charge journal.
884
+ */
885
+ declare class SubscriberAccountModule {
886
+ static forRoot(options: SubscriberAccountModuleOptions): DynamicModule;
848
887
  }
849
888
 
889
+ /**
890
+ * Reads a subscriber's account for the operator: the charges its journal
891
+ * holds, each with the title of the contract line it came from.
892
+ *
893
+ * It reads only. Nothing here derives or writes a charge — that is
894
+ * `SubscriberChargeService`'s — so looking at an account never changes it.
895
+ */
896
+ declare class SubscriberAccountService {
897
+ private readonly ledger;
898
+ private readonly contracts;
899
+ private readonly subscribers;
900
+ private readonly subscriptions;
901
+ constructor(ledger: SubscriberLedgerRepository, contracts: SubscriptionContractRepository, subscribers: SubscriberRepository, subscriptions: SubscriptionUsagePort);
902
+ /** The account of the tenant's subscriber; empty while it has no subscription. */
903
+ accountOf(tenantId: string): Promise<AdminSubscriberAccount>;
904
+ }
905
+
906
+ /** Adapter token: where the subscriber's charges are written (`tenantBilling.chargeJournal`). */
907
+ declare const SUBSCRIBER_LEDGER_REPOSITORY_TOKEN: unique symbol;
908
+
850
909
  declare function computeCarriedTrialEndsAt(currentTrialDays: number, newTrialDays: number, currentTrialEndsAt: Date, now: Date): Date;
851
910
 
852
911
  declare class AddSubscriptionBundleDto {
@@ -936,4 +995,4 @@ declare const SUBSCRIPTION_BUNDLE_CONFIG_TOKEN: unique symbol;
936
995
  */
937
996
  declare function buildTenantSubscriptionBundlesController(extraGuards?: Array<Type<CanActivate>>): Type;
938
997
 
939
- export { AddSubscriptionBundleDto, AuthGuardList, BILLING_FEATURE_UI_REGISTRY_TOKEN, BillingPermissionGuard, type BundleFirstPeriodInput, type BundlePeriodRollInput, type BundlePeriodWindow, type BundlePlanContext, BundlePriceLookupDto, CancelSubscriptionBundleDto, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder, ContractFreezePort, ContractFreezeSourcePort, DEFAULT_BUNDLE_MINIMUM_TERM_MONTHS, FEATURE_GUARD_CONFIG_TOKEN, FEATURE_GUARD_MARKER, FeatureGuard, type FeatureGuardConfig, LimitExceededFilter, type MarketingFields, type NextPeriodWindow, PLAN_CATALOG_IMPORT_SINK_TOKEN, PLAN_CATALOG_READ_SINK_TOKEN, PLAN_CATALOG_SETTINGS_TOKEN, PLAN_CATALOG_SOURCE_TOKEN, PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN, PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN, type PeriodRollInput, type PlanAnchorSource, type PlanCatalogBuildSettings, PlanCatalogImportDto, type PlanCatalogImporterControllerConfig, PlanCatalogImporterModule, type PlanCatalogImporterModuleOptions, PlanCatalogImporterService, PlanCatalogModule, type PlanCatalogModuleOptions, PlanCatalogSource, type PlanResponseEntry, PreviewSubscriptionBundleDto, type PublicBundleEntry, PublicCatalogController, PublicCatalogModule, type PublicCatalogModuleOptions, PublishValidationError, type PublishablePlanVersion, REQUIRE_FEATURE_KEY, type RenewalDecision, type RenewalSubInput, RequireFeature, SUBSCRIPTION_BUNDLE_CONFIG_TOKEN, SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN, SubscriptionContractFreezeService, UPSELL_OFFER_CURRENCY_TOKEN, UPSELL_OFFER_RESOLVER_TOKEN, advanceOneCycle, assertBaseVersionFresh, assertChangeNote, assertDraftPublishable, assertOptimisticLockHeld, billingAnchorDay, buildPlanCatalogFromSnapshot, buildPlanCatalogImporterController, buildTenantSubscriptionBundlesController, bundleCycleFitsPlan, bundleFirstPeriodEnd, bundleFirstPeriodStart, bundleNextPeriodEnd, clearPendingPlanVersionFields, computeCarriedTrialEndsAt, computeNextBundlePeriod, computeNextPeriod, cyclesSoldFor, decideRenewal, findPlan, getActiveFeatureKeys, getMarketedPlans, getPlanOrThrow, getPlanPriceGross, getPlanPriceNet, getPlanQuota, initialPeriodWindow, isFeatureInPlan, isFeaturePlannedOnly, isPlanNotSoldInCycle, listPriceNet, periodEndAfter, periodEndWithMinLead, planNotSoldInCycle, resolveBundlePriceNet, resolvePlanAnchorDay, retreatOneCycle };
998
+ export { AddSubscriptionBundleDto, AuthGuardList, BILLING_FEATURE_UI_REGISTRY_TOKEN, BillingPermissionGuard, type BundleFirstPeriodInput, type BundlePeriodRollInput, type BundlePeriodWindow, type BundlePlanContext, BundlePriceLookupDto, CancelSubscriptionBundleDto, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder, ContractFreezePort, ContractFreezeSourcePort, DEFAULT_BUNDLE_MINIMUM_TERM_MONTHS, FEATURE_GUARD_CONFIG_TOKEN, FEATURE_GUARD_MARKER, FeatureGuard, type FeatureGuardConfig, LimitExceededFilter, type MarketingFields, type NextPeriodWindow, PLAN_CATALOG_IMPORT_SINK_TOKEN, PLAN_CATALOG_READ_SINK_TOKEN, PLAN_CATALOG_SETTINGS_TOKEN, PLAN_CATALOG_SOURCE_TOKEN, PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN, PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN, type PeriodRollInput, type PlanAnchorSource, type PlanCatalogBuildSettings, PlanCatalogImportDto, type PlanCatalogImporterControllerConfig, PlanCatalogImporterModule, type PlanCatalogImporterModuleOptions, PlanCatalogImporterService, PlanCatalogModule, type PlanCatalogModuleOptions, PlanCatalogSource, type PlanResponseEntry, PreviewSubscriptionBundleDto, type PublicBundleEntry, PublicCatalogController, PublicCatalogModule, type PublicCatalogModuleOptions, PublishValidationError, type PublishablePlanVersion, REQUIRE_FEATURE_KEY, type RenewalDecision, type RenewalSubInput, RequireFeature, SUBSCRIBER_LEDGER_REPOSITORY_TOKEN, SUBSCRIPTION_BUNDLE_CONFIG_TOKEN, SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN, SubscriberAccountModule, type SubscriberAccountModuleOptions, SubscriberAccountService, SubscriptionContractFreezeService, UPSELL_OFFER_CURRENCY_TOKEN, UPSELL_OFFER_RESOLVER_TOKEN, advanceOneCycle, assertBaseVersionFresh, assertChangeNote, assertDraftPublishable, assertOptimisticLockHeld, billingAnchorDay, buildPlanCatalogFromSnapshot, buildPlanCatalogImporterController, buildTenantSubscriptionBundlesController, bundleCycleFitsPlan, bundleFirstPeriodEnd, bundleFirstPeriodStart, bundleNextPeriodEnd, clearPendingPlanVersionFields, computeCarriedTrialEndsAt, computeNextBundlePeriod, computeNextPeriod, cyclesSoldFor, decideRenewal, findPlan, getActiveFeatureKeys, getMarketedPlans, getPlanOrThrow, getPlanPriceGross, getPlanPriceNet, getPlanQuota, initialPeriodWindow, isFeatureInPlan, isFeaturePlannedOnly, isPlanNotSoldInCycle, listPriceNet, periodEndAfter, periodEndWithMinLead, planNotSoldInCycle, resolveBundlePriceNet, resolvePlanAnchorDay, retreatOneCycle };
@@ -1,20 +1,20 @@
1
- import { BillingCycle, BundleVersionRow, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalogSettings, PlanCatalogReadSink, PlanCatalog, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, TenantSubscriptionWritePort, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog } from '@saasicat/core';
1
+ import { BillingCycle, BundleVersionRow, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalogSettings, PlanCatalogReadSink, PlanCatalog, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, TenantSubscriptionWritePort, SubscriptionUsagePort, SubscriberLedgerRepository, SubscriptionContractRepository, SubscriberRepository, AdminSubscriberAccount, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog } from '@saasicat/core';
2
2
  export { BundleVersionFields, CancellationNoticePeriods, ChangeDirection, DiffResult, PlanVersionFields, SelfServiceBlockedPlans, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/core';
3
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as CancellableSubscription, c as CancellationDecision, d as CancellationInput, e as ChangePlanDto, f as CompleteOnboardingSubscriptionDto, g as ComposedTenantAuthGuard, h as CycleDirection, L as LimitsCheckRow, N as NO_NOTICE_PERIOD, P as PendingPlanMaterializationService, i as PlanChangeContext, j as PlanChangePreviewDto, k as PlanChangePreviewIssue, l as PlanChangePreviewService, m as PlanChangeType, n as PlanDirection, o as PlanSnapshotDto, p as PreviewPlanChangeDto, q as ProrationDto, r as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, s as SubscriptionBundleCancelPreviewDto, t as SubscriptionBundleConfig, u as SubscriptionBundlePreviewContext, v as SubscriptionBundlePreviewIssue, w as SubscriptionBundlePreviewService, x as SubscriptionBundlesService, T as TenantAdminGuard, y as TenantBillingController, U as UsageResponse, z as addMonths, D as clampToParent, E as computeProration, F as decideCancellation, G as decideCancellationFor, H as noticeDaysFor, I as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-BLqbsONe.js';
4
- import { F as FEATURE_GUARD_MARKER, d as ContractFreezePort, e as ContractFreezeSourcePort } from '../tenant-billing.module-DohgJJ2m.js';
5
- export { A as AjvErrorLike, C as CONTRACT_FREEZE_PORT_TOKEN, b as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, c as ContractFreezeBundleSnapshot, E as EnvironmentVariables, f as LoadPlanCatalogFromStringOptions, L as LoadPlanCatalogOptions, M as MarkedFeatureGuard, P as PLAN_CATALOG_UNREADABLE_ERROR, g as PlanCatalogValidationError, h as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SelfServiceBlockedBundles, a as SubscriptionBundleControllerOptions, k as SubscriptionBundleModule, S as SubscriptionBundleModuleOptions, l as TenantBillingModule, T as TenantBillingModuleOptions, m as catalogSource, n as isPlatformFeatureGuard, o as loadPlanCatalogFromFile, p as loadPlanCatalogFromString } from '../tenant-billing.module-DohgJJ2m.js';
3
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as CancellableSubscription, c as CancellationDecision, d as CancellationInput, e as ChangePlanDto, f as CompleteOnboardingSubscriptionDto, g as ComposedTenantAuthGuard, h as CycleDirection, L as LimitsCheckRow, N as NO_NOTICE_PERIOD, P as PendingPlanMaterializationService, i as PlanChangeContext, j as PlanChangePreviewDto, k as PlanChangePreviewIssue, l as PlanChangePreviewService, m as PlanChangeType, n as PlanDirection, o as PlanSnapshotDto, p as PreviewPlanChangeDto, q as ProrationBasis, r as ProrationDto, s as ProrationInput, R as RedundantFeatureHint, S as SubscriberChargeService, t as SubscriptionBundleAddPreviewDto, u as SubscriptionBundleCancelPreviewDto, v as SubscriptionBundleConfig, w as SubscriptionBundlePreviewContext, x as SubscriptionBundlePreviewIssue, y as SubscriptionBundlePreviewService, z as SubscriptionBundlesService, T as TenantAdminGuard, D as TenantBillingController, U as UsageResponse, E as addMonths, F as clampToParent, G as computeNewPeriodCharge, H as computeProration, I as decideCancellation, J as decideCancellationFor, K as noticeDaysFor, M as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-BuQDQ76i.js';
4
+ import { F as FEATURE_GUARD_MARKER, d as ContractFreezePort, e as ContractFreezeSourcePort } from '../tenant-billing.module-CUCQL0-k.js';
5
+ export { A as AjvErrorLike, C as CONTRACT_FREEZE_PORT_TOKEN, b as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, c as ContractFreezeBundleSnapshot, E as EnvironmentVariables, f as LoadPlanCatalogFromStringOptions, L as LoadPlanCatalogOptions, M as MarkedFeatureGuard, P as PLAN_CATALOG_UNREADABLE_ERROR, g as PlanCatalogValidationError, h as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SelfServiceBlockedBundles, a as SubscriptionBundleControllerOptions, k as SubscriptionBundleModule, S as SubscriptionBundleModuleOptions, l as TenantBillingModule, T as TenantBillingModuleOptions, m as catalogSource, n as isPlatformFeatureGuard, o as loadPlanCatalogFromFile, p as loadPlanCatalogFromString } from '../tenant-billing.module-CUCQL0-k.js';
6
6
  import * as _nestjs_common from '@nestjs/common';
7
7
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
8
8
  export { Type as NestType } from '@nestjs/common';
9
9
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
10
- import { c as EntitlementService } from '../aggregation-ChpZDh0g.js';
10
+ import { d as EntitlementService } from '../aggregation-6fPkeV8i.js';
11
11
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
12
12
  import { P as PlanCatalogSource } from '../plan-catalog-source-DWe-BGY1.js';
13
13
  export { a as PlanCatalogOrigin, g as givenPlanCatalogSource } from '../plan-catalog-source-DWe-BGY1.js';
14
14
  import { d as AuthGuardList } from '../tenant-billing.tokens-G-1xOlMr.js';
15
15
  export { c as AUDIT_CONTEXT_RESOLVER_TOKEN, A as AuditContextResolver, B as BILLING_PERMISSION_GUARDS_TOKEN, C as CANCELLATION_NOTICE_DAYS_TOKEN, D as DuePendingPlanChange, e as PENDING_PLAN_QUERY_PORT_TOKEN, P as PendingPlanQueryPort, S as SUBSCRIPTION_USAGE_PORT_TOKEN, f as SUBSCRIPTION_WRITE_PORT_TOKEN, g as TENANT_AUTH_GUARDS_TOKEN, h as TENANT_ID_RESOLVER_TOKEN, i as TRIAL_PROJECTION_PORT_TOKEN, T as TenantIdResolver, j as TrialProjectionInput, a as TrialProjectionPort, k as USAGE_SNAPSHOT_PORT_TOKEN, l as USER_EMAIL_RESOLVER_TOKEN, m as USER_ID_RESOLVER_TOKEN, U as UserEmailResolver, b as UserIdResolver } from '../tenant-billing.tokens-G-1xOlMr.js';
16
16
  import { S as SubscriptionContractService } from '../subscription-contract.service-CPZrTM9C.js';
17
- import '../promo.service-CFjfF0Xm.js';
17
+ import { a as PromoCodesService } from '../promo.service-Dqqh0JXn.js';
18
18
  import '../admin-audit.service-4P3Djdxk.js';
19
19
  import '../contract-line-item-money-B0Z3Ogur.js';
20
20
  import '../plan-resolution-CwUy_OqC.js';
@@ -277,7 +277,7 @@ declare function computeNextBundlePeriod(booking: BundlePeriodRollInput, plan: B
277
277
  * publish gate checks; what it cannot check is the combination, since that
278
278
  * depends on the plan the tenant is on and the rhythm they are billed in.
279
279
  */
280
- declare function resolveBundlePriceNet(bundleVersion: BundleVersionRow, planKey: string, billingCycle: string): number | null;
280
+ declare function resolveBundlePriceNet(bundleVersion: BundleVersionRow, planKey: string, billingCycle: BillingCycle): number | null;
281
281
  /**
282
282
  * The cycles a plan version is actually sold in.
283
283
  *
@@ -841,12 +841,71 @@ declare class SubscriptionContractFreezeService implements ContractFreezePort {
841
841
  private readonly entitlements;
842
842
  private readonly contracts;
843
843
  private readonly source;
844
- constructor(catalogs: PlanCatalogSource, entitlements: EntitlementService, contracts: SubscriptionContractService, source: ContractFreezeSourcePort, writes?: TenantSubscriptionWritePort | null);
844
+ private readonly subscriptions;
845
+ private readonly promoCodes;
846
+ constructor(catalogs: PlanCatalogSource, entitlements: EntitlementService, contracts: SubscriptionContractService, source: ContractFreezeSourcePort, writes?: TenantSubscriptionWritePort | null, subscriptions?: SubscriptionUsagePort | null, promoCodes?: PromoCodesService | null);
845
847
  assertPartyFor(tenantId: string): Promise<void>;
846
848
  endOnCancellation(tenantId: string, effectiveAt: Date): Promise<void>;
847
849
  freezeOnPlanChange(tenantId: string, newPlan: string, billingCycle: BillingCycle, effectiveFrom: Date, endsAt?: Date | null): Promise<void>;
850
+ /**
851
+ * The code redeemed for the tenant's subscription, as a discount line, where
852
+ * no contract of the tenant records it yet.
853
+ *
854
+ * The first contract written after a redemption records it — at onboarding,
855
+ * or at the activation after a trial, where onboarding wrote none — and the
856
+ * ones after it do not repeat it: the discount runs from where it was first
857
+ * agreed, for the duration on its snapshot, counted from the first period
858
+ * that is paid. A contract concluded from an offer that carried the code
859
+ * already records it. Nothing is recorded without the promo module, for a
860
+ * reversed redemption, or where a contract written since the redemption
861
+ * does not record it: that was the first one, written before contracts
862
+ * recorded codes or by the application itself, and a later contract does
863
+ * not start the discount again.
864
+ */
865
+ private redeemedCodeNotYetRecorded;
866
+ }
867
+
868
+ interface SubscriberAccountModuleOptions {
869
+ /** The same chain the tenant routes of the administration run behind. */
870
+ guards: Array<Type<CanActivate>>;
871
+ /**
872
+ * Must bring `AdminResourcesService` and `SubscriberAccountService` into
873
+ * scope — the modules that already provide them, passed as the very objects
874
+ * the application imports, so that no adapter is built a second time. The
875
+ * `RlsBypassPort` has to be visible too; `SaaSiCatModule` provides it
876
+ * globally.
877
+ */
878
+ imports: Array<Type<unknown> | DynamicModule | Promise<DynamicModule> | ForwardReference>;
879
+ }
880
+ /**
881
+ * The operator's view of a subscriber's account, served beside the tenant it
882
+ * belongs to. Mounted where the platform keeps both the administration's
883
+ * tenants and a charge journal.
884
+ */
885
+ declare class SubscriberAccountModule {
886
+ static forRoot(options: SubscriberAccountModuleOptions): DynamicModule;
848
887
  }
849
888
 
889
+ /**
890
+ * Reads a subscriber's account for the operator: the charges its journal
891
+ * holds, each with the title of the contract line it came from.
892
+ *
893
+ * It reads only. Nothing here derives or writes a charge — that is
894
+ * `SubscriberChargeService`'s — so looking at an account never changes it.
895
+ */
896
+ declare class SubscriberAccountService {
897
+ private readonly ledger;
898
+ private readonly contracts;
899
+ private readonly subscribers;
900
+ private readonly subscriptions;
901
+ constructor(ledger: SubscriberLedgerRepository, contracts: SubscriptionContractRepository, subscribers: SubscriberRepository, subscriptions: SubscriptionUsagePort);
902
+ /** The account of the tenant's subscriber; empty while it has no subscription. */
903
+ accountOf(tenantId: string): Promise<AdminSubscriberAccount>;
904
+ }
905
+
906
+ /** Adapter token: where the subscriber's charges are written (`tenantBilling.chargeJournal`). */
907
+ declare const SUBSCRIBER_LEDGER_REPOSITORY_TOKEN: unique symbol;
908
+
850
909
  declare function computeCarriedTrialEndsAt(currentTrialDays: number, newTrialDays: number, currentTrialEndsAt: Date, now: Date): Date;
851
910
 
852
911
  declare class AddSubscriptionBundleDto {
@@ -936,4 +995,4 @@ declare const SUBSCRIPTION_BUNDLE_CONFIG_TOKEN: unique symbol;
936
995
  */
937
996
  declare function buildTenantSubscriptionBundlesController(extraGuards?: Array<Type<CanActivate>>): Type;
938
997
 
939
- export { AddSubscriptionBundleDto, AuthGuardList, BILLING_FEATURE_UI_REGISTRY_TOKEN, BillingPermissionGuard, type BundleFirstPeriodInput, type BundlePeriodRollInput, type BundlePeriodWindow, type BundlePlanContext, BundlePriceLookupDto, CancelSubscriptionBundleDto, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder, ContractFreezePort, ContractFreezeSourcePort, DEFAULT_BUNDLE_MINIMUM_TERM_MONTHS, FEATURE_GUARD_CONFIG_TOKEN, FEATURE_GUARD_MARKER, FeatureGuard, type FeatureGuardConfig, LimitExceededFilter, type MarketingFields, type NextPeriodWindow, PLAN_CATALOG_IMPORT_SINK_TOKEN, PLAN_CATALOG_READ_SINK_TOKEN, PLAN_CATALOG_SETTINGS_TOKEN, PLAN_CATALOG_SOURCE_TOKEN, PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN, PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN, type PeriodRollInput, type PlanAnchorSource, type PlanCatalogBuildSettings, PlanCatalogImportDto, type PlanCatalogImporterControllerConfig, PlanCatalogImporterModule, type PlanCatalogImporterModuleOptions, PlanCatalogImporterService, PlanCatalogModule, type PlanCatalogModuleOptions, PlanCatalogSource, type PlanResponseEntry, PreviewSubscriptionBundleDto, type PublicBundleEntry, PublicCatalogController, PublicCatalogModule, type PublicCatalogModuleOptions, PublishValidationError, type PublishablePlanVersion, REQUIRE_FEATURE_KEY, type RenewalDecision, type RenewalSubInput, RequireFeature, SUBSCRIPTION_BUNDLE_CONFIG_TOKEN, SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN, SubscriptionContractFreezeService, UPSELL_OFFER_CURRENCY_TOKEN, UPSELL_OFFER_RESOLVER_TOKEN, advanceOneCycle, assertBaseVersionFresh, assertChangeNote, assertDraftPublishable, assertOptimisticLockHeld, billingAnchorDay, buildPlanCatalogFromSnapshot, buildPlanCatalogImporterController, buildTenantSubscriptionBundlesController, bundleCycleFitsPlan, bundleFirstPeriodEnd, bundleFirstPeriodStart, bundleNextPeriodEnd, clearPendingPlanVersionFields, computeCarriedTrialEndsAt, computeNextBundlePeriod, computeNextPeriod, cyclesSoldFor, decideRenewal, findPlan, getActiveFeatureKeys, getMarketedPlans, getPlanOrThrow, getPlanPriceGross, getPlanPriceNet, getPlanQuota, initialPeriodWindow, isFeatureInPlan, isFeaturePlannedOnly, isPlanNotSoldInCycle, listPriceNet, periodEndAfter, periodEndWithMinLead, planNotSoldInCycle, resolveBundlePriceNet, resolvePlanAnchorDay, retreatOneCycle };
998
+ export { AddSubscriptionBundleDto, AuthGuardList, BILLING_FEATURE_UI_REGISTRY_TOKEN, BillingPermissionGuard, type BundleFirstPeriodInput, type BundlePeriodRollInput, type BundlePeriodWindow, type BundlePlanContext, BundlePriceLookupDto, CancelSubscriptionBundleDto, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder, ContractFreezePort, ContractFreezeSourcePort, DEFAULT_BUNDLE_MINIMUM_TERM_MONTHS, FEATURE_GUARD_CONFIG_TOKEN, FEATURE_GUARD_MARKER, FeatureGuard, type FeatureGuardConfig, LimitExceededFilter, type MarketingFields, type NextPeriodWindow, PLAN_CATALOG_IMPORT_SINK_TOKEN, PLAN_CATALOG_READ_SINK_TOKEN, PLAN_CATALOG_SETTINGS_TOKEN, PLAN_CATALOG_SOURCE_TOKEN, PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN, PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN, type PeriodRollInput, type PlanAnchorSource, type PlanCatalogBuildSettings, PlanCatalogImportDto, type PlanCatalogImporterControllerConfig, PlanCatalogImporterModule, type PlanCatalogImporterModuleOptions, PlanCatalogImporterService, PlanCatalogModule, type PlanCatalogModuleOptions, PlanCatalogSource, type PlanResponseEntry, PreviewSubscriptionBundleDto, type PublicBundleEntry, PublicCatalogController, PublicCatalogModule, type PublicCatalogModuleOptions, PublishValidationError, type PublishablePlanVersion, REQUIRE_FEATURE_KEY, type RenewalDecision, type RenewalSubInput, RequireFeature, SUBSCRIBER_LEDGER_REPOSITORY_TOKEN, SUBSCRIPTION_BUNDLE_CONFIG_TOKEN, SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN, SubscriberAccountModule, type SubscriberAccountModuleOptions, SubscriberAccountService, SubscriptionContractFreezeService, UPSELL_OFFER_CURRENCY_TOKEN, UPSELL_OFFER_RESOLVER_TOKEN, advanceOneCycle, assertBaseVersionFresh, assertChangeNote, assertDraftPublishable, assertOptimisticLockHeld, billingAnchorDay, buildPlanCatalogFromSnapshot, buildPlanCatalogImporterController, buildTenantSubscriptionBundlesController, bundleCycleFitsPlan, bundleFirstPeriodEnd, bundleFirstPeriodStart, bundleNextPeriodEnd, clearPendingPlanVersionFields, computeCarriedTrialEndsAt, computeNextBundlePeriod, computeNextPeriod, cyclesSoldFor, decideRenewal, findPlan, getActiveFeatureKeys, getMarketedPlans, getPlanOrThrow, getPlanPriceGross, getPlanPriceNet, getPlanQuota, initialPeriodWindow, isFeatureInPlan, isFeaturePlannedOnly, isPlanNotSoldInCycle, listPriceNet, periodEndAfter, periodEndWithMinLead, planNotSoldInCycle, resolveBundlePriceNet, resolvePlanAnchorDay, retreatOneCycle };
@@ -20,7 +20,7 @@ import {
20
20
  computeCarriedTrialEndsAt,
21
21
  computeNextPeriod,
22
22
  decideRenewal
23
- } from "../chunk-R5YCJBHY.js";
23
+ } from "../chunk-U5UPEFWC.js";
24
24
  import {
25
25
  AddSubscriptionBundleDto,
26
26
  BILLING_FEATURE_UI_REGISTRY_TOKEN,
@@ -48,6 +48,10 @@ import {
48
48
  RequireFeature,
49
49
  SELF_SERVICE_BLOCKED_BUNDLES_TOKEN,
50
50
  SELF_SERVICE_BLOCKED_PLANS_TOKEN,
51
+ SUBSCRIBER_LEDGER_REPOSITORY_TOKEN,
52
+ SubscriberAccountModule,
53
+ SubscriberAccountService,
54
+ SubscriberChargeService,
51
55
  SubscriptionBundleModule,
52
56
  SubscriptionBundlePreviewService,
53
57
  SubscriptionBundlesService,
@@ -65,6 +69,7 @@ import {
65
69
  bundleNextPeriodEnd,
66
70
  catalogSource,
67
71
  clampToParent,
72
+ computeNewPeriodCharge,
68
73
  computeNextBundlePeriod,
69
74
  computeProration,
70
75
  decideCancellation,
@@ -79,15 +84,16 @@ import {
79
84
  resolveBundleCancelEffectiveAt,
80
85
  resolvePlanAnchorDay,
81
86
  retreatOneCycle
82
- } from "../chunk-M47BNEY2.js";
87
+ } from "../chunk-3YYLOYUT.js";
88
+ import "../chunk-OSOP4KWL.js";
83
89
  import {
84
90
  classifyBundleVersionDiff,
85
91
  classifyPlanDiff
86
92
  } from "../chunk-GZTL64QK.js";
87
93
  import "../chunk-34XVPR6P.js";
88
94
  import "../chunk-OOTEXP47.js";
89
- import "../chunk-3RLWML2S.js";
90
- import "../chunk-NDLC5GYK.js";
95
+ import "../chunk-QWKBOLBH.js";
96
+ import "../chunk-EU4N5LET.js";
91
97
  import {
92
98
  cyclesSoldFor,
93
99
  resolveBundlePriceNet
@@ -95,7 +101,7 @@ import {
95
101
  import {
96
102
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
97
103
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN
98
- } from "../chunk-G6EZWECL.js";
104
+ } from "../chunk-B4YP7REK.js";
99
105
  import "../chunk-OUDSQ3PU.js";
100
106
  import {
101
107
  findPlan,
@@ -194,10 +200,14 @@ export {
194
200
  RequireFeature,
195
201
  SELF_SERVICE_BLOCKED_BUNDLES_TOKEN,
196
202
  SELF_SERVICE_BLOCKED_PLANS_TOKEN,
203
+ SUBSCRIBER_LEDGER_REPOSITORY_TOKEN,
197
204
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
198
205
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN,
199
206
  SUBSCRIPTION_USAGE_PORT_TOKEN,
200
207
  SUBSCRIPTION_WRITE_PORT_TOKEN,
208
+ SubscriberAccountModule,
209
+ SubscriberAccountService,
210
+ SubscriberChargeService,
201
211
  SubscriptionBundleModule,
202
212
  SubscriptionBundlePreviewService,
203
213
  SubscriptionBundlesService,
@@ -233,6 +243,7 @@ export {
233
243
  classifyPlanDiff,
234
244
  clearPendingPlanVersionFields,
235
245
  computeCarriedTrialEndsAt,
246
+ computeNewPeriodCharge,
236
247
  computeNextBundlePeriod,
237
248
  computeNextPeriod,
238
249
  computeProration,
@@ -1,10 +1,10 @@
1
- export { C as CheckoutOfferPricing, a as CheckoutOfferPricingInput, b as CheckoutOfferService, c as ConcludeCheckoutOfferOptions, d as ConcludeCheckoutOfferWithin, e as ConcludedCheckoutOffer, P as PricedCheckoutOffer } from '../checkout-offer.service-CCVxG9b2.cjs';
1
+ export { C as CheckoutOfferPricing, a as CheckoutOfferPricingInput, b as CheckoutOfferService, c as ConcludeCheckoutOfferOptions, d as ConcludeCheckoutOfferWithin, e as ConcludedCheckoutOffer, P as PricedCheckoutOffer } from '../checkout-offer.service-DmVGrT4v.cjs';
2
2
  import { Type, CanActivate } from '@nestjs/common';
3
3
  export { a as CheckoutOfferConclusionOptions, b as CheckoutOfferControllerConfig, c as CheckoutOfferModule, C as CheckoutOfferModuleOptions } from '../checkout-offer.module-DFhGy6JO.cjs';
4
4
  import { CheckoutOfferSelection, CheckoutOfferSelectionUpdate } from '@saasicat/core';
5
5
  import '../subscription-contract.service-CfNApLuP.cjs';
6
6
  import '../subscriber.service-5W6Gi-1B.cjs';
7
- import '../promo.service-BYBu6dy3.cjs';
7
+ import '../promo.service-BextPvx5.cjs';
8
8
  import '../plan-catalog-source-DWe-BGY1.cjs';
9
9
  import '../di-CcNeq9v-.cjs';
10
10
 
@@ -1,10 +1,10 @@
1
- export { C as CheckoutOfferPricing, a as CheckoutOfferPricingInput, b as CheckoutOfferService, c as ConcludeCheckoutOfferOptions, d as ConcludeCheckoutOfferWithin, e as ConcludedCheckoutOffer, P as PricedCheckoutOffer } from '../checkout-offer.service-BeHgYikI.js';
1
+ export { C as CheckoutOfferPricing, a as CheckoutOfferPricingInput, b as CheckoutOfferService, c as ConcludeCheckoutOfferOptions, d as ConcludeCheckoutOfferWithin, e as ConcludedCheckoutOffer, P as PricedCheckoutOffer } from '../checkout-offer.service-Yi30L4ry.js';
2
2
  import { Type, CanActivate } from '@nestjs/common';
3
3
  export { a as CheckoutOfferConclusionOptions, b as CheckoutOfferControllerConfig, c as CheckoutOfferModule, C as CheckoutOfferModuleOptions } from '../checkout-offer.module-x7SP_dX4.js';
4
4
  import { CheckoutOfferSelection, CheckoutOfferSelectionUpdate } from '@saasicat/core';
5
5
  import '../subscription-contract.service-CPZrTM9C.js';
6
6
  import '../subscriber.service-5W6Gi-1B.js';
7
- import '../promo.service-CFjfF0Xm.js';
7
+ import '../promo.service-Dqqh0JXn.js';
8
8
  import '../plan-catalog-source-DWe-BGY1.js';
9
9
  import '../di-CcNeq9v-.js';
10
10
 
@@ -4,15 +4,15 @@ import {
4
4
  CreateCheckoutOfferDto,
5
5
  UpdateCheckoutOfferDto,
6
6
  buildCheckoutOfferController
7
- } from "../chunk-TOEFN7DN.js";
7
+ } from "../chunk-FPMBQDW7.js";
8
8
  import {
9
9
  CHECKOUT_OFFER_REPOSITORY_TOKEN,
10
10
  CHECKOUT_OFFER_TRANSACTION_RUNNER_TOKEN,
11
11
  CheckoutOfferPricing,
12
12
  CheckoutOfferService
13
- } from "../chunk-55QEDAMX.js";
14
- import "../chunk-3RLWML2S.js";
15
- import "../chunk-NDLC5GYK.js";
13
+ } from "../chunk-WTAS2CLM.js";
14
+ import "../chunk-QWKBOLBH.js";
15
+ import "../chunk-EU4N5LET.js";
16
16
  import "../chunk-KPEMTBOP.js";
17
17
  import "../chunk-TBBZWZQT.js";
18
18
  import "../chunk-VBRYPU7V.js";
@@ -1,7 +1,7 @@
1
1
  import { PlanCatalogSettings, PlanRepository, BundleRepository, PromotionRepository, CheckoutOfferPriceBreakdown, CheckoutOfferLineItem, CheckoutOfferPromotionSnapshot, CheckoutOfferPromoCodeSnapshot, CheckoutOfferRow, CheckoutOfferRepository, CatalogEntryRepository, TransactionRunner, CheckoutOfferFilter, CheckoutOfferSelection, CheckoutOfferSelectionUpdate, NewSubscriberDetails, TransactionContext, SubscriptionContractRecord } from '@saasicat/core';
2
2
  import { S as SubscriptionContractService, C as CreateContractFromOfferOptions } from './subscription-contract.service-CfNApLuP.cjs';
3
3
  import { S as SubscriberService } from './subscriber.service-5W6Gi-1B.cjs';
4
- import { a as PromoCodesService } from './promo.service-BYBu6dy3.cjs';
4
+ import { a as PromoCodesService } from './promo.service-BextPvx5.cjs';
5
5
 
6
6
  type Cycle = 'monthly' | 'yearly';
7
7
  /** What pricing needs to know about a selection. */
@@ -1,7 +1,7 @@
1
1
  import { PlanCatalogSettings, PlanRepository, BundleRepository, PromotionRepository, CheckoutOfferPriceBreakdown, CheckoutOfferLineItem, CheckoutOfferPromotionSnapshot, CheckoutOfferPromoCodeSnapshot, CheckoutOfferRow, CheckoutOfferRepository, CatalogEntryRepository, TransactionRunner, CheckoutOfferFilter, CheckoutOfferSelection, CheckoutOfferSelectionUpdate, NewSubscriberDetails, TransactionContext, SubscriptionContractRecord } from '@saasicat/core';
2
2
  import { S as SubscriptionContractService, C as CreateContractFromOfferOptions } from './subscription-contract.service-CPZrTM9C.js';
3
3
  import { S as SubscriberService } from './subscriber.service-5W6Gi-1B.js';
4
- import { a as PromoCodesService } from './promo.service-CFjfF0Xm.js';
4
+ import { a as PromoCodesService } from './promo.service-Dqqh0JXn.js';
5
5
 
6
6
  type Cycle = 'monthly' | 'yearly';
7
7
  /** What pricing needs to know about a selection. */