@saasicat/nest 0.9.0 → 0.10.1

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 (86) hide show
  1. package/dist/_entries.cjs +17678 -0
  2. package/dist/admin/index.cjs +4 -1533
  3. package/dist/admin/index.d.cts +10 -173
  4. package/dist/admin/index.d.ts +10 -173
  5. package/dist/admin/index.js +3 -2
  6. package/dist/{admin-resources.module-BybEjZs-.d.cts → admin-resources.module-BZN_yBFj.d.cts} +1 -1
  7. package/dist/{admin-resources.module-CUCLlUAi.d.ts → admin-resources.module-Cms8MY6h.d.ts} +1 -1
  8. package/dist/admin-stats.module-15ac5KY3.d.ts +201 -0
  9. package/dist/admin-stats.module-v4SVvWzj.d.cts +201 -0
  10. package/dist/billing/index.cjs +4 -5130
  11. package/dist/billing/index.d.cts +8 -437
  12. package/dist/billing/index.d.ts +8 -437
  13. package/dist/billing/index.js +4 -4
  14. package/dist/catalog/index.cjs +4 -5624
  15. package/dist/catalog/index.d.cts +5 -328
  16. package/dist/catalog/index.d.ts +5 -328
  17. package/dist/catalog/index.js +4 -4
  18. package/dist/checkout-offer/index.cjs +4 -807
  19. package/dist/checkout-offer/index.d.cts +5 -84
  20. package/dist/checkout-offer/index.d.ts +5 -84
  21. package/dist/checkout-offer/index.js +3 -2
  22. package/dist/checkout-offer.module-Y0hDOVrq.d.ts +85 -0
  23. package/dist/checkout-offer.module-ZYF5IsDY.d.cts +85 -0
  24. package/dist/{chunk-PBQRPDO2.js → chunk-33TP26MR.js} +2 -2
  25. package/dist/{chunk-CK54YKVK.js → chunk-75JABGZK.js} +16 -16
  26. package/dist/{chunk-HRU3CP57.js → chunk-BOADBIGB.js} +1 -1
  27. package/dist/chunk-DBZGV3HC.js +0 -0
  28. package/dist/{chunk-ZLUGQE5D.js → chunk-E7AJ42AB.js} +8 -8
  29. package/dist/{chunk-HXAWPPFW.js → chunk-F3VV6EXG.js} +9 -9
  30. package/dist/{chunk-3M6VLT5N.js → chunk-FVT7KTUI.js} +2 -2
  31. package/dist/{chunk-GW2I3JZD.js → chunk-GBDUH6DO.js} +1 -1
  32. package/dist/{chunk-K3OPNVFR.js → chunk-HBFU5AN3.js} +5 -9
  33. package/dist/{chunk-OFBDEO45.js → chunk-IRWZC3GC.js} +1 -1
  34. package/dist/chunk-L4KTQ6CL.js +20 -0
  35. package/dist/{chunk-WGVTXSYW.js → chunk-LZHLGUQI.js} +1 -1
  36. package/dist/{chunk-ZZMAHX22.js → chunk-PUXLPUVH.js} +15 -12
  37. package/dist/{chunk-7K5PT2LX.js → chunk-TXDH4FUA.js} +1 -1
  38. package/dist/chunk-UF53DWWR.js +0 -0
  39. package/dist/{chunk-AJ3EPELS.js → chunk-V34AA7C7.js} +1 -1
  40. package/dist/chunk-WJ6BMDL3.js +313 -0
  41. package/dist/{chunk-M6CZQYPY.js → chunk-Z3FWN3HJ.js} +2 -2
  42. package/dist/discovery/index.cjs +4 -588
  43. package/dist/discovery/index.js +3 -3
  44. package/dist/{enforce-quota.interceptor-B3CL5MSw.d.ts → enforce-quota.interceptor-DMEvL-bE.d.ts} +43 -2
  45. package/dist/{enforce-quota.interceptor-SqrQVF91.d.cts → enforce-quota.interceptor-Dse3jSpU.d.cts} +43 -2
  46. package/dist/entitlement/index.cjs +4 -781
  47. package/dist/entitlement/index.js +2 -2
  48. package/dist/index.cjs +4 -15671
  49. package/dist/index.d.cts +21 -56
  50. package/dist/index.d.ts +21 -56
  51. package/dist/index.js +39 -334
  52. package/dist/{module-DeH_Jkcq.d.cts → module-CSN8j8Tp.d.cts} +1 -1
  53. package/dist/{module-B5m080F0.d.ts → module-DgYJur6f.d.ts} +1 -1
  54. package/dist/plan-versions.service-BB36Q1bg.d.ts +329 -0
  55. package/dist/plan-versions.service-CUR2Whyr.d.cts +329 -0
  56. package/dist/platform/index.cjs +4 -12925
  57. package/dist/platform/index.d.cts +17 -9
  58. package/dist/platform/index.d.ts +17 -9
  59. package/dist/platform/index.js +98 -14
  60. package/dist/promo/index.cjs +4 -1520
  61. package/dist/promo/index.d.cts +6 -21
  62. package/dist/promo/index.d.ts +6 -21
  63. package/dist/promo/index.js +2 -2
  64. package/dist/rate-limit.guard-dntqAlfZ.d.cts +19 -0
  65. package/dist/rate-limit.guard-dntqAlfZ.d.ts +19 -0
  66. package/dist/registration/index.cjs +4 -1655
  67. package/dist/registration/index.js +1 -1
  68. package/dist/{service-DlhMnYjW.d.ts → service-DX8KbGXl.d.cts} +1 -1
  69. package/dist/{service-DlhMnYjW.d.cts → service-DX8KbGXl.d.ts} +1 -1
  70. package/dist/setup.service-BPwJ7My_.d.cts +45 -0
  71. package/dist/setup.service-D2mrdDDB.d.ts +45 -0
  72. package/dist/subscription-bundle-preview.service-BkJXHAeP.d.cts +438 -0
  73. package/dist/subscription-bundle-preview.service-DBbrE_cw.d.ts +438 -0
  74. package/dist/subscription-contract/index.cjs +4 -471
  75. package/dist/subscription-contract/index.d.cts +5 -13
  76. package/dist/subscription-contract/index.d.ts +5 -13
  77. package/dist/subscription-contract.module-CG9fPKAr.d.cts +14 -0
  78. package/dist/subscription-contract.module-CVebZzHR.d.ts +14 -0
  79. package/dist/testing/index.cjs +4 -13888
  80. package/dist/testing/index.d.cts +5 -5
  81. package/dist/testing/index.d.ts +5 -5
  82. package/dist/testing/index.js +10 -10
  83. package/package.json +4 -4
  84. package/dist/admin-manifest.service-BMeSLRW4.d.ts +0 -33
  85. package/dist/admin-manifest.service-StAQe6QO.d.cts +0 -33
  86. package/dist/chunk-N3WANKSA.js +0 -20
@@ -1,17 +1,18 @@
1
- import { BillingCycle, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalog, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, SubscriptionUsagePort, UsageSnapshotPort, TenantSubscriptionWritePort, SubscriptionBundleRepository, SubscriptionBundleView, SubscriptionBundleRecord, SubscriptionUsageRecord, OnboardingSelectionResponse, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog, PlanRepository, BundleVersionRow } from '@saasicat/types';
1
+ import { BillingCycle, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalog, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog } from '@saasicat/types';
2
2
  export { BundleVersionFields, ChangeDirection, DiffResult, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/types';
3
3
  import * as _nestjs_common from '@nestjs/common';
4
4
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
5
5
  export { Type as NestType } from '@nestjs/common';
6
6
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
7
- import { c as EntitlementService, a as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from '../aggregation-CfI0bOsQ.cjs';
7
+ import { c as EntitlementService } from '../aggregation-CfI0bOsQ.cjs';
8
8
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
9
- import { b as AuthGuardList, m as SelfServiceBlockedPlans, w as TrialProjectionPort, h as PendingPlanQueryPort, f as ContractFreezePort, g as ContractFreezeSourcePort, l as SelfServiceBlockedBundles, u as TenantIdResolver, B as UserIdResolver, z as UserEmailResolver, a as AuditContextResolver } from '../subscription-bundles.module-DCpV-Pb5.cjs';
10
- export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, P as PENDING_PLAN_QUERY_PORT_TOKEN, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SUBSCRIPTION_USAGE_PORT_TOKEN, k as SUBSCRIPTION_WRITE_PORT_TOKEN, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, v as TrialProjectionInput, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN } from '../subscription-bundles.module-DCpV-Pb5.cjs';
9
+ import { f as ContractFreezePort, g as ContractFreezeSourcePort } from '../subscription-bundles.module-DCpV-Pb5.cjs';
10
+ export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, P as PENDING_PLAN_QUERY_PORT_TOKEN, h as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SUBSCRIPTION_USAGE_PORT_TOKEN, k as SUBSCRIPTION_WRITE_PORT_TOKEN, l as SelfServiceBlockedBundles, m as SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from '../subscription-bundles.module-DCpV-Pb5.cjs';
11
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../subscription-bundle-preview.service-BkJXHAeP.cjs';
11
12
  import { S as SubscriptionContractService } from '../subscription-contract.service--cm47ZJJ.cjs';
12
- import { g as PromoCodesService } from '../service-DlhMnYjW.cjs';
13
- import { A as AdminAuditService } from '../admin-audit.service-9IqXMlZm.cjs';
14
13
  import '../plan-resolution-CFCoUkrE.cjs';
14
+ import '../service-DX8KbGXl.cjs';
15
+ import '../admin-audit.service-9IqXMlZm.cjs';
15
16
 
16
17
  /**
17
18
  * Finds the next period boundary that lies strictly **after** `after`.
@@ -550,133 +551,6 @@ declare const PUBLIC_CATALOG_PROJECT_KEY_TOKEN: unique symbol;
550
551
  declare const PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN: unique symbol;
551
552
  declare const PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN: unique symbol;
552
553
 
553
- declare class ComposedTenantAuthGuard implements CanActivate {
554
- private readonly guards;
555
- constructor(guards?: AuthGuardList | null);
556
- canActivate(context: ExecutionContext): Promise<boolean>;
557
- }
558
-
559
- declare class TenantAdminGuard implements CanActivate {
560
- canActivate(context: ExecutionContext): boolean;
561
- }
562
-
563
- interface ProrationDto {
564
- daysRemainingInPeriod: number;
565
- daysInPeriod: number;
566
- periodStart: Date;
567
- periodEnd: Date;
568
- currentPriceNet: number;
569
- targetPriceNet: number;
570
- /** Prorated surcharge/credit until end of period. Negative = credit. */
571
- prorataDeltaNet: number;
572
- }
573
- interface ProrationInput {
574
- periodStart: Date;
575
- periodEnd: Date;
576
- now: Date;
577
- /** Previous period price (bundle add: 0 — something is only added). */
578
- currentPriceNet: number;
579
- targetPriceNet: number;
580
- }
581
- declare function computeProration(input: ProrationInput): ProrationDto;
582
-
583
- type PlanChangeType = 'UPGRADE' | 'DOWNGRADE' | 'CYCLE_CHANGE' | 'NOOP';
584
- interface PlanSnapshotDto {
585
- id: string;
586
- name: string;
587
- monthlyNet: number | null;
588
- yearlyNet: number | null;
589
- quotas: Record<string, number>;
590
- features: string[];
591
- }
592
- interface LimitsCheckRow {
593
- used: number;
594
- currentMax: number;
595
- targetMax: number;
596
- exceeded: boolean;
597
- }
598
- interface PlanChangePreviewIssue {
599
- code: string;
600
- message: string;
601
- }
602
- interface PlanChangePreviewDto {
603
- changeType: PlanChangeType;
604
- current: {
605
- plan: PlanSnapshotDto;
606
- billingCycle: string;
607
- };
608
- target: {
609
- plan: PlanSnapshotDto;
610
- billingCycle: string;
611
- };
612
- /** For upgrade/NOOP: immediately (null). Otherwise period end. */
613
- effectiveAt: Date | null;
614
- isImmediate: boolean;
615
- /**
616
- * Projected new trial end after the change (app trial logic, e.g.
617
- * carry-over of the remaining time). `null` if no TrialProjectionPort is
618
- * configured, the subscription is not in a trial, or nothing changes.
619
- * The wizard uses this to show "regulär ab Ende der Testphase".
620
- */
621
- projectedTrialEndsAt: Date | null;
622
- proration: ProrationDto | null;
623
- /** Map quotaKey → LimitsCheckRow across all quota dimensions from the current limit, target plan and usage. */
624
- limitsCheck: Record<string, LimitsCheckRow>;
625
- featuresLost: string[];
626
- featuresGained: string[];
627
- /** Hard prevention reasons — e.g. usage > target limit. */
628
- blockers: PlanChangePreviewIssue[];
629
- /** Non-blocking hints — e.g. feature loss. */
630
- warnings: PlanChangePreviewIssue[];
631
- }
632
- interface PlanChangeContext {
633
- /** Current period start time from the subscription, if present. */
634
- currentPeriodStart: Date | null;
635
- /** Current period end from the subscription, if present. */
636
- currentPeriodEnd: Date | null;
637
- /** TRIAL end, if status === 'TRIAL'. */
638
- trialEndsAt: Date | null;
639
- /** Subscription status (TRIAL/ACTIVE/...). */
640
- status: string;
641
- /** Current cycle of the subscription (for cycle-change classification). */
642
- currentBillingCycle: string;
643
- /** Current plan of the subscription. */
644
- currentPlan: string;
645
- /** Subscription start, if present (for the periodEndAfter fallback). */
646
- startedAt: Date | null;
647
- }
648
- declare class PlanChangePreviewService {
649
- private readonly catalog;
650
- private readonly entitlements;
651
- private readonly subscriptions;
652
- private readonly usageSnapshot;
653
- private readonly blockedPlans;
654
- private readonly trialProjection;
655
- constructor(catalog: PlanCatalog, entitlements: EntitlementService, subscriptions: SubscriptionUsagePort, usageSnapshot: UsageSnapshotPort, blockedPlans?: SelfServiceBlockedPlans | null, trialProjection?: TrialProjectionPort | null);
656
- preview(tenantId: string, targetPlan: string, targetCycle: string, now?: Date): Promise<PlanChangePreviewDto>;
657
- /** Like `preview`, but only the blocker list — for a server-side
658
- * pre-check before the `changePlan` mutation (defense-in-depth). */
659
- assertChangeAllowed(tenantId: string, targetPlan: string, targetCycle: string, now?: Date): Promise<PlanChangePreviewIssue[]>;
660
- private classify;
661
- /** Catalog order = rank. Non-marketed plans go to the end. */
662
- private planRank;
663
- private resolveEffectiveAt;
664
- private computeProration;
665
- }
666
-
667
- declare class PendingPlanMaterializationService {
668
- private readonly query;
669
- private readonly subscriptionWrite;
670
- private readonly entitlements;
671
- private readonly contractFreeze;
672
- private readonly logger;
673
- constructor(query: PendingPlanQueryPort, subscriptionWrite: TenantSubscriptionWritePort, entitlements: EntitlementService, contractFreeze?: ContractFreezePort | null);
674
- materializeDuePlanChanges(now?: Date): Promise<{
675
- applied: number;
676
- }>;
677
- private tryFreeze;
678
- }
679
-
680
554
  declare class SubscriptionContractFreezeService implements ContractFreezePort {
681
555
  private readonly catalog;
682
556
  private readonly entitlements;
@@ -689,205 +563,6 @@ declare class SubscriptionContractFreezeService implements ContractFreezePort {
689
563
 
690
564
  declare function computeCarriedTrialEndsAt(currentTrialDays: number, newTrialDays: number, currentTrialEndsAt: Date, now: Date): Date;
691
565
 
692
- declare class PreviewPlanChangeDto {
693
- plan: string;
694
- billingCycle: string;
695
- }
696
- declare class ChangePlanDto extends PreviewPlanChangeDto {
697
- /** Immediate change (true) vs. change at period end (false/undefined). */
698
- effectiveImmediately?: boolean;
699
- }
700
- declare class CancelSubscriptionDto {
701
- /** true = cancel immediately (status CANCELED). false/undefined = at period end. */
702
- immediately?: boolean;
703
- }
704
-
705
- declare class CompleteOnboardingSubscriptionDto {
706
- plan: string;
707
- billingCycle: string;
708
- promoCode?: string;
709
- /**
710
- * Optional — UUIDs of the BundleVersions that should be booked
711
- * together with the plan (P11.7.3). Per bundle, the platform
712
- * default minimum term (12 months) is set. Bundles are added
713
- * best-effort **after** the plan change — an error on an individual
714
- * bundle (e.g. incompatible with the chosen plan) lands as a
715
- * warning in the response, without rolling back the plan change.
716
- */
717
- bundleVersionIds?: string[];
718
- }
719
-
720
- interface SubscriptionBundleConfig {
721
- /** Default minimum term in months on `add`. Default = 12. */
722
- defaultMinimumTermMonths?: number;
723
- }
724
- interface AddBundleToSubscriptionInput {
725
- subscriptionId: string;
726
- bundleVersionId: string;
727
- /** PlanKey of the current subscription for the plan-compatibility check. */
728
- currentPlanKey: string;
729
- /** Default = now (service time). */
730
- startedAt?: Date;
731
- /**
732
- * Override for the minimum term (months). Default = config or
733
- * 12. `0` explicitly means "no minimum term"
734
- * (`minimumTermEndsAt = null`).
735
- */
736
- minimumTermMonths?: number;
737
- }
738
- interface CancelBundleFromSubscriptionInput {
739
- subscriptionBundleId: string;
740
- /** Default = now. */
741
- canceledAt?: Date;
742
- /**
743
- * Period end of the subscription from which the cancellation could take effect.
744
- * Effective date = `max(currentPeriodEnd, minimumTermEndsAt)`.
745
- * If not set, `canceledAt` is interpreted as the period end
746
- * (= immediate effect, provided the minimum term has already expired).
747
- */
748
- currentPeriodEnd?: Date;
749
- }
750
- declare class SubscriptionBundlesService {
751
- private readonly repo;
752
- private readonly bundles;
753
- private readonly blockedBundles;
754
- private readonly defaultMinTermMonths;
755
- constructor(repo: SubscriptionBundleRepository, bundles: BundleRepository, config?: SubscriptionBundleConfig, blockedBundles?: SelfServiceBlockedBundles | null);
756
- /** All bundle bookings of a subscription (for the "My Bundles" page). */
757
- listForSubscription(subscriptionId: string): Promise<SubscriptionBundleView[]>;
758
- addBundleToSubscription(input: AddBundleToSubscriptionInput): Promise<SubscriptionBundleRecord>;
759
- cancelBundleFromSubscription(input: CancelBundleFromSubscriptionInput): Promise<SubscriptionBundleRecord>;
760
- /**
761
- * "Undo cancellation" — only as long as the cancellation is not yet effective
762
- * (the bundle runs until `canceledEffectiveAt`). After that, re-booking is the way.
763
- */
764
- reactivateBundle(subscriptionBundleId: string): Promise<SubscriptionBundleRecord>;
765
- }
766
- /**
767
- * Effective date of a bundle cancellation:
768
- * `max(currentPeriodEnd, minimumTermEndsAt)` — missing values fall back to
769
- * `canceledAt` (= immediate effect). Shared between the
770
- * cancellation mutation and the preview (#37).
771
- */
772
- declare function resolveBundleCancelEffectiveAt(input: {
773
- canceledAt: Date;
774
- currentPeriodEnd: Date | null;
775
- minimumTermEndsAt: Date | null;
776
- }): Date;
777
- /**
778
- * Adds `months` to `date` and keeps the UTC day. Edge case
779
- * 31.01 + 1 month → 28/29.02 (JS Date does this automatically by
780
- * setMonth normalizing the day).
781
- */
782
- declare function addMonths(date: Date, months: number): Date;
783
-
784
- interface RequestLike {
785
- user?: {
786
- tenantId?: string;
787
- sub?: string;
788
- id?: string;
789
- };
790
- }
791
- interface UsageResponse {
792
- plan: string;
793
- effectivePlan: string;
794
- billingCycle: string;
795
- status: string;
796
- isPilot: boolean;
797
- pilotEndsAt: Date | null;
798
- trialEndsAt: Date | null;
799
- startedAt: Date | null;
800
- currentPeriodStart: Date | null;
801
- currentPeriodEnd: Date | null;
802
- pendingPlan: string | null;
803
- pendingBillingCycle: string | null;
804
- pendingEffectiveAt: Date | null;
805
- planVersion: SubscriptionUsageRecord['planVersion'];
806
- pendingPlanVersion: SubscriptionUsageRecord['pendingPlanVersion'];
807
- pendingPlanVersionEffectiveAt: Date | null;
808
- pendingPlanVersionAccepted: boolean;
809
- pendingPlanVersionAcceptedAt: Date | null;
810
- limits: ReturnType<typeof toEffectiveLimitsSnapshot>;
811
- usage: Record<string, number>;
812
- /**
813
- * P11.4 (METAMODELL §17a): Frozen package snapshot from the
814
- * `CheckoutOffer` that was activated during onboarding. Read-only
815
- * for the tenant self-service UI. `null` for subscriptions without
816
- * a CheckoutOffer origin.
817
- */
818
- packageSnapshot: unknown | null;
819
- /** P11.4: Optional reference to the originating CheckoutOffer. */
820
- checkoutOfferId: string | null;
821
- }
822
- declare class TenantBillingController {
823
- private readonly entitlements;
824
- private readonly planPreview;
825
- private readonly subscriptionUsage;
826
- private readonly usageSnapshot;
827
- private readonly subscriptionWrite;
828
- private readonly tenantIdResolver;
829
- private readonly userIdResolver;
830
- private readonly blockedPlans;
831
- private readonly promoCodes;
832
- private readonly auditService;
833
- private readonly userEmailResolver;
834
- private readonly auditContextResolver;
835
- private readonly subscriptionBundles;
836
- private readonly contractFreeze;
837
- private readonly trialProjection;
838
- constructor(entitlements: EntitlementService, planPreview: PlanChangePreviewService, subscriptionUsage: SubscriptionUsagePort, usageSnapshot: UsageSnapshotPort, subscriptionWrite: TenantSubscriptionWritePort, tenantIdResolver?: TenantIdResolver | null, userIdResolver?: UserIdResolver | null, blockedPlans?: SelfServiceBlockedPlans | null, promoCodes?: PromoCodesService | null, auditService?: AdminAuditService | null, userEmailResolver?: UserEmailResolver | null, auditContextResolver?: AuditContextResolver | null, subscriptionBundles?: SubscriptionBundlesService | null, contractFreeze?: ContractFreezePort | null, trialProjection?: TrialProjectionPort | null);
839
- private readonly logger;
840
- getEntitlement(req: RequestLike): Promise<EffectiveLimitsSnapshot>;
841
- getUsage(req: RequestLike): Promise<UsageResponse>;
842
- previewPlanChange(req: RequestLike, dto: PreviewPlanChangeDto): Promise<PlanChangePreviewDto>;
843
- changePlan(req: RequestLike, dto: ChangePlanDto): Promise<{
844
- plan: string;
845
- billingCycle: string;
846
- immediate: boolean;
847
- pendingPlan?: undefined;
848
- pendingBillingCycle?: undefined;
849
- pendingEffectiveAt?: undefined;
850
- } | {
851
- plan: string;
852
- billingCycle: string;
853
- pendingPlan: string;
854
- pendingBillingCycle: string;
855
- pendingEffectiveAt: Date;
856
- immediate: boolean;
857
- }>;
858
- completeOnboardingSubscription(req: RequestLike, dto: CompleteOnboardingSubscriptionDto): Promise<OnboardingSelectionResponse>;
859
- acceptPendingPlanVersion(req: RequestLike): Promise<{
860
- accepted: boolean;
861
- acceptedAt: Date | null;
862
- effectiveAt: Date | null;
863
- idempotent: boolean;
864
- }>;
865
- cancelSubscription(req: RequestLike, dto: CancelSubscriptionDto): Promise<{
866
- canceledAt: Date | null;
867
- status: string;
868
- immediate: boolean;
869
- }>;
870
- private requireTenantId;
871
- private requireUserId;
872
- private buildActor;
873
- private resolveUserEmail;
874
- private toResponseRedemption;
875
- private collectPromoSkipReasons;
876
- /**
877
- * #18: contract freeze after the plan change — non-fatal, only outside of
878
- * the trial (during a trial the trial entitlements apply, not the booked plan;
879
- * the freeze happens on the transition to ACTIVE, i.e. on materialization).
880
- * Without a configured `contractFreeze` hook the call is a no-op.
881
- */
882
- private tryFreezeOnPlanChange;
883
- /**
884
- * Audit-log helper — writes best-effort, does not block the response path.
885
- * If `AdminAuditService` is not injected (e.g. a minimal deploy without
886
- * AdminModule), the call is silently discarded.
887
- */
888
- private auditLog;
889
- }
890
-
891
566
  /**
892
567
  * Builds the `ConfiguratorCatalog` (for onboarding step 3) from the
893
568
  * live `plan_versions` (SuperAdmin defines plans + prices) plus the
@@ -908,110 +583,6 @@ declare const SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN: unique symbol;
908
583
  /** Optional config token; default = 12 months minimum term. */
909
584
  declare const SUBSCRIPTION_BUNDLE_CONFIG_TOKEN: unique symbol;
910
585
 
911
- interface SubscriptionBundlePreviewIssue {
912
- code: string;
913
- message: string;
914
- }
915
- /** Subscription context — the controller reads it from the SubscriptionUsagePort. */
916
- interface SubscriptionBundlePreviewContext {
917
- subscriptionId: string;
918
- /** PlanKey of the current subscription (plan compatibility + redundancy source). */
919
- currentPlanKey: string;
920
- /** 'MONTHLY' | 'YEARLY' (port convention). */
921
- billingCycle: string;
922
- /** Subscription status (TRIAL/ACTIVE/...). No proration during TRIAL. */
923
- status: string;
924
- startedAt: Date | null;
925
- currentPeriodStart: Date | null;
926
- currentPeriodEnd: Date | null;
927
- }
928
- interface BundlePreviewSnapshot {
929
- bundleKey: string;
930
- label: string;
931
- bundleVersionId: string;
932
- features: string[];
933
- quotas: Record<string, number>;
934
- }
935
- /** AK-13: feature is already paid for elsewhere — double-payment hint. */
936
- interface RedundantFeatureHint {
937
- featureKey: string;
938
- coveredBy: 'PLAN' | 'BUNDLE';
939
- /** planKey or bundleKey of the covering source. */
940
- coveredByKey: string;
941
- }
942
- interface SubscriptionBundleAddPreviewDto {
943
- action: 'add';
944
- bundle: BundlePreviewSnapshot;
945
- billingCycle: string;
946
- /**
947
- * Prorated amount until period end. `null` during TRIAL (no paid
948
- * period yet) or without a list price for the cycle.
949
- */
950
- proration: ProrationDto | null;
951
- /** List price per follow-up period in the current cycle; null = no price maintained. */
952
- nextPeriodPriceNet: number | null;
953
- minimumTermMonths: number;
954
- /** Projected minimum-term end from `now`; null = no minimum term. */
955
- minimumTermEndsAt: Date | null;
956
- redundantFeatures: RedundantFeatureHint[];
957
- /**
958
- * requires-features (#35) that neither the plan nor active bundles nor the
959
- * bundle itself cover. Non-empty ⇒ blocker
960
- * BUNDLE_FEATURE_DEPENDENCY_UNSATISFIED.
961
- */
962
- missingRequires: string[];
963
- blockers: SubscriptionBundlePreviewIssue[];
964
- warnings: SubscriptionBundlePreviewIssue[];
965
- }
966
- interface SubscriptionBundleCancelPreviewDto {
967
- action: 'cancel';
968
- subscriptionBundleId: string;
969
- bundle: BundlePreviewSnapshot;
970
- billingCycle: string;
971
- /** Effective date = max(currentPeriodEnd, minimumTermEndsAt). */
972
- effectiveAt: Date;
973
- /** Savings per period from the effective date; null = no price maintained. */
974
- nextPeriodSavingsNet: number | null;
975
- blockers: SubscriptionBundlePreviewIssue[];
976
- warnings: SubscriptionBundlePreviewIssue[];
977
- }
978
- declare class SubscriptionBundlePreviewService {
979
- private readonly subscriptionBundles;
980
- private readonly bundles;
981
- private readonly plans;
982
- private readonly catalogEntries;
983
- private readonly blockedBundles;
984
- private readonly defaultMinTermMonths;
985
- constructor(subscriptionBundles: SubscriptionBundleRepository, bundles: BundleRepository, plans?: PlanRepository | null, catalogEntries?: CatalogEntryRepository | null, blockedBundles?: SelfServiceBlockedBundles | null, config?: SubscriptionBundleConfig);
986
- previewAdd(ctx: SubscriptionBundlePreviewContext, input: {
987
- bundleVersionId: string;
988
- minimumTermMonths?: number;
989
- }, now?: Date): Promise<SubscriptionBundleAddPreviewDto>;
990
- previewCancel(ctx: SubscriptionBundlePreviewContext, input: {
991
- subscriptionBundleId: string;
992
- }, now?: Date): Promise<SubscriptionBundleCancelPreviewDto>;
993
- /** Bookability checks — same codes as `addBundleToSubscription` (422 path). */
994
- private collectBookabilityBlockers;
995
- /** Versions of the active bundle bookings (for redundancy + requires coverage). */
996
- private loadActiveBundleVersions;
997
- /** Features of the currently live PlanVersion state; empty without PlanRepository. */
998
- private resolvePlanFeatures;
999
- private collectRedundantFeatures;
1000
- /**
1001
- * requires of the new bundle that neither the bundle itself nor plan ∪
1002
- * active bundles cover (#35). Empty without CatalogEntryRepository.
1003
- */
1004
- private collectMissingRequires;
1005
- /** `projectKey` lives on the bundle stem, not on the version. */
1006
- private resolveProjectKey;
1007
- }
1008
- /**
1009
- * List price (net) for the billing cycle including plan-specific
1010
- * pricing override (BundlePricingOverride with `planId`). null = no price
1011
- * maintained for the cycle.
1012
- */
1013
- declare function resolveBundlePriceNet(bundleVersion: BundleVersionRow, planKey: string, billingCycle: string): number | null;
1014
-
1015
586
  /**
1016
587
  * Factory analogous to `buildBundlesController` etc. — the consumer can pass
1017
588
  * additional guards (e.g. RoleGuard) in addition to the platform default
@@ -1019,4 +590,4 @@ declare function resolveBundlePriceNet(bundleVersion: BundleVersionRow, planKey:
1019
590
  */
1020
591
  declare function buildTenantSubscriptionBundlesController(extraGuards?: Array<Type<CanActivate>>): Type;
1021
592
 
1022
- export { type AddBundleToSubscriptionInput, type AjvErrorLike, AuditContextResolver, AuthGuardList, type BundlePreviewSnapshot, type CancelBundleFromSubscriptionInput, CancelSubscriptionDto, CatalogBundleUpsellResolver, ChangePlanDto, CompleteOnboardingSubscriptionDto, ComposedTenantAuthGuard, ConfiguratorCatalogBuilder, ContractFreezePort, ContractFreezeSourcePort, FEATURE_GUARD_CONFIG_TOKEN, FEATURE_UI_REGISTRY_TOKEN, FeatureGuard, type FeatureGuardConfig, LimitExceededFilter, type LimitsCheckRow, type LoadPlanCatalogOptions, type MarketingFields, type NextPeriodWindow, PLAN_CATALOG_IMPORT_SINK_TOKEN, PLAN_CATALOG_READ_SINK_TOKEN, PLAN_CATALOG_TOKEN, PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN, PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN, PUBLIC_CATALOG_PROJECT_KEY_TOKEN, PendingPlanMaterializationService, PendingPlanQueryPort, type PeriodRollInput, type PlanCatalogBuildSettings, PlanCatalogImportDto, type PlanCatalogImporterControllerConfig, PlanCatalogImporterModule, type PlanCatalogImporterModuleOptions, PlanCatalogImporterService, PlanCatalogModule, type PlanCatalogModuleOptions, PlanCatalogValidationError, type PlanChangeContext, type PlanChangePreviewDto, type PlanChangePreviewIssue, PlanChangePreviewService, type PlanChangeType, type PlanResponseEntry, type PlanSnapshotDto, PreviewPlanChangeDto, type ProrationDto, type ProrationInput, type PublicBundleEntry, PublicCatalogController, PublicCatalogModule, type PublicCatalogModuleOptions, PublishValidationError, type PublishablePlanVersion, REQUIRE_FEATURE_KEY, type RedundantFeatureHint, type RenewalDecision, type RenewalSubInput, RequireFeature, SUBSCRIPTION_BUNDLE_CONFIG_TOKEN, SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN, SelfServiceBlockedBundles, SelfServiceBlockedPlans, type SubscriptionBundleAddPreviewDto, type SubscriptionBundleCancelPreviewDto, type SubscriptionBundleConfig, type SubscriptionBundlePreviewContext, type SubscriptionBundlePreviewIssue, SubscriptionBundlePreviewService, SubscriptionBundlesService, SubscriptionContractFreezeService, TenantAdminGuard, TenantBillingController, TenantIdResolver, TrialProjectionPort, UPSELL_OFFER_CURRENCY_TOKEN, UPSELL_OFFER_RESOLVER_TOKEN, type UsageResponse, UserEmailResolver, UserIdResolver, addMonths, assertBaseVersionFresh, assertChangeNote, assertDraftPublishable, assertOptimisticLockHeld, buildPlanCatalogFromSnapshot, buildPlanCatalogImporterController, buildTenantSubscriptionBundlesController, clearPendingPlanVersionFields, computeCarriedTrialEndsAt, computeNextPeriod, computeProration, decideRenewal, findPlan, getActiveFeatureKeys, getMarketedPlans, getPlanOrThrow, getPlanPriceGross, getPlanPriceNet, getPlanQuota, initialPeriodWindow, isFeatureInPlan, isFeaturePlannedOnly, loadPlanCatalogFromFile, loadPlanCatalogFromString, periodEndAfter, periodEndWithMinLead, resolveBundleCancelEffectiveAt, resolveBundlePriceNet };
593
+ export { type AjvErrorLike, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder, ContractFreezePort, ContractFreezeSourcePort, FEATURE_GUARD_CONFIG_TOKEN, FEATURE_UI_REGISTRY_TOKEN, FeatureGuard, type FeatureGuardConfig, LimitExceededFilter, type LoadPlanCatalogOptions, type MarketingFields, type NextPeriodWindow, PLAN_CATALOG_IMPORT_SINK_TOKEN, PLAN_CATALOG_READ_SINK_TOKEN, PLAN_CATALOG_TOKEN, PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN, PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN, PUBLIC_CATALOG_PROJECT_KEY_TOKEN, type PeriodRollInput, type PlanCatalogBuildSettings, PlanCatalogImportDto, type PlanCatalogImporterControllerConfig, PlanCatalogImporterModule, type PlanCatalogImporterModuleOptions, PlanCatalogImporterService, PlanCatalogModule, type PlanCatalogModuleOptions, PlanCatalogValidationError, type PlanResponseEntry, 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, assertBaseVersionFresh, assertChangeNote, assertDraftPublishable, assertOptimisticLockHeld, buildPlanCatalogFromSnapshot, buildPlanCatalogImporterController, buildTenantSubscriptionBundlesController, clearPendingPlanVersionFields, computeCarriedTrialEndsAt, computeNextPeriod, decideRenewal, findPlan, getActiveFeatureKeys, getMarketedPlans, getPlanOrThrow, getPlanPriceGross, getPlanPriceNet, getPlanQuota, initialPeriodWindow, isFeatureInPlan, isFeaturePlannedOnly, loadPlanCatalogFromFile, loadPlanCatalogFromString, periodEndAfter, periodEndWithMinLead };