@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.
- package/dist/_entries.cjs +17678 -0
- package/dist/admin/index.cjs +4 -1533
- package/dist/admin/index.d.cts +10 -173
- package/dist/admin/index.d.ts +10 -173
- package/dist/admin/index.js +3 -2
- package/dist/{admin-resources.module-BybEjZs-.d.cts → admin-resources.module-BZN_yBFj.d.cts} +1 -1
- package/dist/{admin-resources.module-CUCLlUAi.d.ts → admin-resources.module-Cms8MY6h.d.ts} +1 -1
- package/dist/admin-stats.module-15ac5KY3.d.ts +201 -0
- package/dist/admin-stats.module-v4SVvWzj.d.cts +201 -0
- package/dist/billing/index.cjs +4 -5130
- package/dist/billing/index.d.cts +8 -437
- package/dist/billing/index.d.ts +8 -437
- package/dist/billing/index.js +4 -4
- package/dist/catalog/index.cjs +4 -5624
- package/dist/catalog/index.d.cts +5 -328
- package/dist/catalog/index.d.ts +5 -328
- package/dist/catalog/index.js +4 -4
- package/dist/checkout-offer/index.cjs +4 -807
- package/dist/checkout-offer/index.d.cts +5 -84
- package/dist/checkout-offer/index.d.ts +5 -84
- package/dist/checkout-offer/index.js +3 -2
- package/dist/checkout-offer.module-Y0hDOVrq.d.ts +85 -0
- package/dist/checkout-offer.module-ZYF5IsDY.d.cts +85 -0
- package/dist/{chunk-PBQRPDO2.js → chunk-33TP26MR.js} +2 -2
- package/dist/{chunk-CK54YKVK.js → chunk-75JABGZK.js} +16 -16
- package/dist/{chunk-HRU3CP57.js → chunk-BOADBIGB.js} +1 -1
- package/dist/chunk-DBZGV3HC.js +0 -0
- package/dist/{chunk-ZLUGQE5D.js → chunk-E7AJ42AB.js} +8 -8
- package/dist/{chunk-HXAWPPFW.js → chunk-F3VV6EXG.js} +9 -9
- package/dist/{chunk-3M6VLT5N.js → chunk-FVT7KTUI.js} +2 -2
- package/dist/{chunk-GW2I3JZD.js → chunk-GBDUH6DO.js} +1 -1
- package/dist/{chunk-K3OPNVFR.js → chunk-HBFU5AN3.js} +5 -9
- package/dist/{chunk-OFBDEO45.js → chunk-IRWZC3GC.js} +1 -1
- package/dist/chunk-L4KTQ6CL.js +20 -0
- package/dist/{chunk-WGVTXSYW.js → chunk-LZHLGUQI.js} +1 -1
- package/dist/{chunk-ZZMAHX22.js → chunk-PUXLPUVH.js} +15 -12
- package/dist/{chunk-7K5PT2LX.js → chunk-TXDH4FUA.js} +1 -1
- package/dist/chunk-UF53DWWR.js +0 -0
- package/dist/{chunk-AJ3EPELS.js → chunk-V34AA7C7.js} +1 -1
- package/dist/chunk-WJ6BMDL3.js +313 -0
- package/dist/{chunk-M6CZQYPY.js → chunk-Z3FWN3HJ.js} +2 -2
- package/dist/discovery/index.cjs +4 -588
- package/dist/discovery/index.js +3 -3
- package/dist/{enforce-quota.interceptor-B3CL5MSw.d.ts → enforce-quota.interceptor-DMEvL-bE.d.ts} +43 -2
- package/dist/{enforce-quota.interceptor-SqrQVF91.d.cts → enforce-quota.interceptor-Dse3jSpU.d.cts} +43 -2
- package/dist/entitlement/index.cjs +4 -781
- package/dist/entitlement/index.js +2 -2
- package/dist/index.cjs +4 -15671
- package/dist/index.d.cts +21 -56
- package/dist/index.d.ts +21 -56
- package/dist/index.js +39 -334
- package/dist/{module-DeH_Jkcq.d.cts → module-CSN8j8Tp.d.cts} +1 -1
- package/dist/{module-B5m080F0.d.ts → module-DgYJur6f.d.ts} +1 -1
- package/dist/plan-versions.service-BB36Q1bg.d.ts +329 -0
- package/dist/plan-versions.service-CUR2Whyr.d.cts +329 -0
- package/dist/platform/index.cjs +4 -12925
- package/dist/platform/index.d.cts +17 -9
- package/dist/platform/index.d.ts +17 -9
- package/dist/platform/index.js +98 -14
- package/dist/promo/index.cjs +4 -1520
- package/dist/promo/index.d.cts +6 -21
- package/dist/promo/index.d.ts +6 -21
- package/dist/promo/index.js +2 -2
- package/dist/rate-limit.guard-dntqAlfZ.d.cts +19 -0
- package/dist/rate-limit.guard-dntqAlfZ.d.ts +19 -0
- package/dist/registration/index.cjs +4 -1655
- package/dist/registration/index.js +1 -1
- package/dist/{service-DlhMnYjW.d.ts → service-DX8KbGXl.d.cts} +1 -1
- package/dist/{service-DlhMnYjW.d.cts → service-DX8KbGXl.d.ts} +1 -1
- package/dist/setup.service-BPwJ7My_.d.cts +45 -0
- package/dist/setup.service-D2mrdDDB.d.ts +45 -0
- package/dist/subscription-bundle-preview.service-BkJXHAeP.d.cts +438 -0
- package/dist/subscription-bundle-preview.service-DBbrE_cw.d.ts +438 -0
- package/dist/subscription-contract/index.cjs +4 -471
- package/dist/subscription-contract/index.d.cts +5 -13
- package/dist/subscription-contract/index.d.ts +5 -13
- package/dist/subscription-contract.module-CG9fPKAr.d.cts +14 -0
- package/dist/subscription-contract.module-CVebZzHR.d.ts +14 -0
- package/dist/testing/index.cjs +4 -13888
- package/dist/testing/index.d.cts +5 -5
- package/dist/testing/index.d.ts +5 -5
- package/dist/testing/index.js +10 -10
- package/package.json +4 -4
- package/dist/admin-manifest.service-BMeSLRW4.d.ts +0 -33
- package/dist/admin-manifest.service-StAQe6QO.d.cts +0 -33
- package/dist/chunk-N3WANKSA.js +0 -20
package/dist/billing/index.d.cts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { BillingCycle, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalog, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository,
|
|
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
|
|
7
|
+
import { c as EntitlementService } from '../aggregation-CfI0bOsQ.cjs';
|
|
8
8
|
import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
|
|
9
|
-
import {
|
|
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
|
|
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 };
|