@saasicat/adapter-prisma 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -23
- package/dist/index.cjs +1014 -176
- package/dist/index.d.cts +297 -60
- package/dist/index.d.ts +297 -60
- package/dist/index.js +1013 -180
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PersistenceInjectionToken, PasswordHasher, SaasicatPersistenceAdapter, TransactionRunner, TransactionContext, MfaPort, AuditPort, AdminActor, AuditQueryPort, AuditQuery, AuditEntry, AuditStatsPort, RlsBypassPort, SubscriptionRepository, SubscriptionRecord, SubscriptionBundleRepository, SubscriptionBundleRecord, CreateSubscriptionBundleData, CancelSubscriptionBundleData, TenantSubscriptionWritePort, ImmediatePlanChangeInput, ScheduledPlanChangeInput, PlanVersionRepository, PlanVersionRecord, PromoCodeRepository, PromoCodeRecord, PromoCodeFilter, CreatePromoCodeData, UpdatePromoCodeData, PromoCodeRedemptionRepository, PromoCodeRedemptionRecord, PromoCodeRedemptionStatus, PromoCodeRedemptionListItem, PromoCodeValidationLogRepository, PromoSubscriptionLookup, BillingCycle, PromoRevenueDeductionAggregator, SuperAdminProvisioningPort, CreateSuperAdminCliInput, PlatformUserDto, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, UpsertPlanInput, UpsertResult, UpsertPlanVersionInput, UpsertFeatureCatalogEntryInput, PlanRepository, PlanListFilter, PlanRow, CreatePlanData, UpdatePlanData, PlanVersionRow, CreatePlanVersionDraftData, UpdatePlanVersionDraftData, VersionChange, BundleRepository, BundleListFilter, BundleRow, CreateBundleData, UpdateBundleData,
|
|
1
|
+
import { PersistenceInjectionToken, PasswordHasher, SaasicatPersistenceAdapter, TransactionRunner, TransactionContext, MfaPort, AuditPort, AdminActor, AuditQueryPort, AuditQuery, AuditEntry, AuditStatsPort, RlsBypassPort, SubscriptionRepository, SubscriptionRecord, SubscriptionBundleRepository, SubscriptionBundleRecord, CreateSubscriptionBundleData, CancelSubscriptionBundleData, TenantSubscriptionWritePort, ApplyOnboardingSelectionInput, RedeemPromoInTransactionCallback, ApplyOnboardingSelectionResult, ImmediatePlanChangeInput, ScheduledPlanChangeInput, PlanVersionRepository, PlanVersionRecord, PromoCodeRepository, PromoCodeRecord, PromoCodeFilter, CreatePromoCodeData, UpdatePromoCodeData, PromoCodeRedemptionRepository, PromoCodeRedemptionRecord, PromoCodeRedemptionStatus, PromoCodeRedemptionListItem, PromoCodeValidationLogRepository, PromoSubscriptionLookup, BillingCycle, PromoRevenueDeductionAggregator, SuperAdminProvisioningPort, CreateSuperAdminCliInput, PlatformUserDto, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, UpsertPlanInput, UpsertResult, UpsertPlanVersionInput, UpsertFeatureCatalogEntryInput, PlanRepository, PlanListFilter, PlanRow, CreatePlanData, UpdatePlanData, PlanVersionRow, CreatePlanVersionDraftData, UpdatePlanVersionDraftData, VersionChange, BundleRepository, BundleVersionRow, BundleListFilter, BundleRow, CreateBundleData, UpdateBundleData, CreateBundleVersionDraftData, UpdateBundleVersionDraftData, CatalogEntryRepository, CatalogEntryFilter, CapabilityCatalogEntryRow, FeatureCatalogEntryRow, QuotaCatalogEntryRow, UpsertCapabilityEntryData, UpsertFeatureEntryData, UpsertQuotaEntryData, SetCatalogEntryReviewData, CatalogEntryI18n, UpdateCatalogEntryBaseData, MarketingProjectionRepository, MarketingProjectionFilter, MarketingProjectionRow, CreateMarketingProjectionData, UpdateMarketingProjectionData, MarketingSettingsRepository, MarketingSettingsRow, UpdateMarketingSettingsData, PromotionRepository, PromotionFilter, PromotionRow, CreatePromotionData, UpdatePromotionData, SubscriptionContractRepository, SubscriptionContractFilter, SubscriptionContractRecord, CreateSubscriptionContractData, TerminateSubscriptionContractData } from '@saasicat/types';
|
|
2
2
|
|
|
3
3
|
declare const PRISMA_CLIENT_TOKEN: unique symbol;
|
|
4
4
|
/** Prisma `Decimal` values arrive as objects with `toString()`; tests may use plain values. */
|
|
@@ -37,6 +37,9 @@ interface PlanVersionRowLike {
|
|
|
37
37
|
nonRegressive: boolean;
|
|
38
38
|
createdByUserId: string | null;
|
|
39
39
|
publishedByUserId: string | null;
|
|
40
|
+
validFrom?: Date | null;
|
|
41
|
+
validUntil?: Date | null;
|
|
42
|
+
endsAt?: Date | null;
|
|
40
43
|
createdAt: Date;
|
|
41
44
|
updatedAt: Date;
|
|
42
45
|
}
|
|
@@ -578,6 +581,102 @@ interface PrismaModelDelegateLike<Row> {
|
|
|
578
581
|
count(args?: unknown): Promise<number>;
|
|
579
582
|
}
|
|
580
583
|
|
|
584
|
+
/**
|
|
585
|
+
* How `PlanVersion.planId` is persisted.
|
|
586
|
+
*
|
|
587
|
+
* - `legacy-plan-key`: SaaSiCat 0.6 behavior. `planId` stores the semantic
|
|
588
|
+
* `Plan.planKey` directly and no lookup is performed.
|
|
589
|
+
* - `normalized-plan-id`: `planId` stores the database `Plan.id` foreign key.
|
|
590
|
+
* Adapter ports still accept and return semantic plan keys.
|
|
591
|
+
*/
|
|
592
|
+
type PrismaPlanBindingMode = 'legacy-plan-key' | 'normalized-plan-id';
|
|
593
|
+
type PrismaPlanBindingOptions = {
|
|
594
|
+
mode?: 'legacy-plan-key';
|
|
595
|
+
projectKey?: string;
|
|
596
|
+
} | {
|
|
597
|
+
mode: 'normalized-plan-id';
|
|
598
|
+
projectKey: string;
|
|
599
|
+
};
|
|
600
|
+
/**
|
|
601
|
+
* Prisma delegate names used by the two independent plan-version slices.
|
|
602
|
+
* Both default to `planVersion`, preserving the 0.6 canonical schema.
|
|
603
|
+
*/
|
|
604
|
+
interface PrismaPlanDelegateOptions {
|
|
605
|
+
catalogPlanVersion?: string;
|
|
606
|
+
entitlementPlanVersion?: string;
|
|
607
|
+
}
|
|
608
|
+
interface PrismaPlanVersionFieldCapabilities {
|
|
609
|
+
/** The delegate carries `validFrom` and `validUntil` columns. */
|
|
610
|
+
validityWindows?: boolean;
|
|
611
|
+
/** The delegate carries the optional, precise `endsAt` timestamp. */
|
|
612
|
+
endsAt?: boolean;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Shared field defaults plus optional per-slice overrides. A consumer with
|
|
616
|
+
* one plan-version model can set the top-level flags; split schemas can
|
|
617
|
+
* configure catalog and entitlement independently.
|
|
618
|
+
*/
|
|
619
|
+
interface PrismaPlanVersionFieldOptions extends PrismaPlanVersionFieldCapabilities {
|
|
620
|
+
catalog?: PrismaPlanVersionFieldCapabilities;
|
|
621
|
+
entitlement?: PrismaPlanVersionFieldCapabilities;
|
|
622
|
+
}
|
|
623
|
+
interface PrismaTenantSubscriptionOptions {
|
|
624
|
+
/**
|
|
625
|
+
* Prisma model delegate used for every Subscription ORM operation.
|
|
626
|
+
* Locked reads still address the canonical physical `subscriptions`
|
|
627
|
+
* table, so a differently named model must use `@@map("subscriptions")`.
|
|
628
|
+
*/
|
|
629
|
+
delegate?: string;
|
|
630
|
+
/**
|
|
631
|
+
* Optional SubscriptionBundle delegate used for BundleVersion booking
|
|
632
|
+
* counts. `false` keeps the capability absent for schemas without the
|
|
633
|
+
* junction table.
|
|
634
|
+
*/
|
|
635
|
+
subscriptionBundleDelegate?: string | false;
|
|
636
|
+
synchronizePlanVersion?: boolean;
|
|
637
|
+
/** Expose the optional atomic onboarding + promo callback capability. */
|
|
638
|
+
atomicOnboardingSelection?: boolean;
|
|
639
|
+
activeVersionSelection?: 'latest-live' | 'validity-window';
|
|
640
|
+
withEndsAt?: boolean;
|
|
641
|
+
}
|
|
642
|
+
/** Schema differences understood by the plan-related Prisma adapters. */
|
|
643
|
+
interface PrismaSchemaOptions {
|
|
644
|
+
planBinding?: PrismaPlanBindingOptions;
|
|
645
|
+
delegates?: PrismaPlanDelegateOptions;
|
|
646
|
+
planVersionFields?: PrismaPlanVersionFieldOptions;
|
|
647
|
+
tenantSubscription?: PrismaTenantSubscriptionOptions;
|
|
648
|
+
}
|
|
649
|
+
interface ResolvedPrismaSchemaOptions {
|
|
650
|
+
planBinding: {
|
|
651
|
+
mode: PrismaPlanBindingMode;
|
|
652
|
+
projectKey?: string;
|
|
653
|
+
};
|
|
654
|
+
delegates: {
|
|
655
|
+
catalogPlanVersion: string;
|
|
656
|
+
entitlementPlanVersion: string;
|
|
657
|
+
};
|
|
658
|
+
planVersionFields: {
|
|
659
|
+
catalog: Required<PrismaPlanVersionFieldCapabilities>;
|
|
660
|
+
entitlement: Required<PrismaPlanVersionFieldCapabilities>;
|
|
661
|
+
};
|
|
662
|
+
tenantSubscription: Required<PrismaTenantSubscriptionOptions>;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Optional DI token for direct Nest registration of individual adapters.
|
|
666
|
+
* `prismaPersistence()` passes the options to constructors itself.
|
|
667
|
+
*/
|
|
668
|
+
declare const PRISMA_SCHEMA_OPTIONS_TOKEN: unique symbol;
|
|
669
|
+
interface PrismaPlanBindingResolver {
|
|
670
|
+
readonly mode: PrismaPlanBindingMode;
|
|
671
|
+
readonly projectKey?: string;
|
|
672
|
+
toStoragePlanId(client: unknown, planKey: string, projectKey?: string): Promise<string>;
|
|
673
|
+
toPlanKey(client: unknown, storedPlanId: string, projectKey?: string): Promise<string>;
|
|
674
|
+
}
|
|
675
|
+
declare function resolvePrismaSchemaOptions(options?: PrismaSchemaOptions): ResolvedPrismaSchemaOptions;
|
|
676
|
+
declare function createPrismaPlanBindingResolver(options?: PrismaPlanBindingOptions): PrismaPlanBindingResolver;
|
|
677
|
+
/** Resolves a configurable Prisma delegate and fails early on misspellings. */
|
|
678
|
+
declare function getPrismaDelegate<Row>(client: unknown, delegateName: string): PrismaModelDelegateLike<Row>;
|
|
679
|
+
|
|
581
680
|
interface PrismaPersistenceOptions {
|
|
582
681
|
/**
|
|
583
682
|
* The app's Prisma client: either its injection token (typically the
|
|
@@ -599,6 +698,12 @@ interface PrismaPersistenceOptions {
|
|
|
599
698
|
* middleware. Default false.
|
|
600
699
|
*/
|
|
601
700
|
rlsIntegration?: boolean;
|
|
701
|
+
/**
|
|
702
|
+
* Optional plan-schema adaptations. Omitted means the exact 0.6 layout:
|
|
703
|
+
* soft `planId === planKey`, one `planVersion` delegate, no validity or
|
|
704
|
+
* termination columns.
|
|
705
|
+
*/
|
|
706
|
+
schema?: PrismaSchemaOptions;
|
|
602
707
|
}
|
|
603
708
|
/**
|
|
604
709
|
* Builds the `SaasicatPersistenceAdapter` bundle for Prisma + PostgreSQL on
|
|
@@ -629,7 +734,7 @@ declare function prismaPersistence(options: PrismaPersistenceOptions): SaasicatP
|
|
|
629
734
|
*/
|
|
630
735
|
declare class PrismaTransactionRunner implements TransactionRunner {
|
|
631
736
|
private readonly prisma;
|
|
632
|
-
constructor(prisma:
|
|
737
|
+
constructor(prisma: Record<'$transaction', unknown>);
|
|
633
738
|
run<T>(fn: (tx: TransactionContext) => Promise<T>): Promise<T>;
|
|
634
739
|
}
|
|
635
740
|
|
|
@@ -650,7 +755,7 @@ declare class PrismaTransactionRunner implements TransactionRunner {
|
|
|
650
755
|
*/
|
|
651
756
|
declare class PrismaMfaAdapter implements MfaPort {
|
|
652
757
|
private readonly prisma;
|
|
653
|
-
constructor(prisma: PrismaLike);
|
|
758
|
+
constructor(prisma: Pick<PrismaLike, 'superAdminMfa'>);
|
|
654
759
|
getSecret(userId: string): Promise<string | null>;
|
|
655
760
|
setSecret(userId: string, secret: string | null): Promise<void>;
|
|
656
761
|
isEnabled(userId: string): Promise<boolean>;
|
|
@@ -667,7 +772,7 @@ declare function buildActorTag(actor: AdminActor): string;
|
|
|
667
772
|
*/
|
|
668
773
|
declare class PrismaAuditAdapter implements AuditPort {
|
|
669
774
|
private readonly prisma;
|
|
670
|
-
constructor(prisma: PrismaLike);
|
|
775
|
+
constructor(prisma: Pick<PrismaLike, 'auditLog'>);
|
|
671
776
|
write(input: {
|
|
672
777
|
actor: AdminActor;
|
|
673
778
|
entity: string;
|
|
@@ -683,14 +788,14 @@ declare class PrismaAuditAdapter implements AuditPort {
|
|
|
683
788
|
*/
|
|
684
789
|
declare class PrismaAuditQueryAdapter implements AuditQueryPort {
|
|
685
790
|
private readonly prisma;
|
|
686
|
-
constructor(prisma: PrismaLike);
|
|
791
|
+
constructor(prisma: Pick<PrismaLike, 'auditLog'>);
|
|
687
792
|
list(filter: AuditQuery): Promise<AuditEntry[]>;
|
|
688
793
|
}
|
|
689
794
|
|
|
690
795
|
/** `AuditStatsPort` against the canonical `audit_logs` table. */
|
|
691
796
|
declare class PrismaAuditStatsAdapter implements AuditStatsPort {
|
|
692
797
|
private readonly prisma;
|
|
693
|
-
constructor(prisma: PrismaLike);
|
|
798
|
+
constructor(prisma: Pick<PrismaLike, 'auditLog'>);
|
|
694
799
|
countSince(since: Date): Promise<number>;
|
|
695
800
|
}
|
|
696
801
|
|
|
@@ -727,25 +832,44 @@ declare class AsyncLocalRlsBypassAdapter implements RlsBypassPort {
|
|
|
727
832
|
isBypassActive(): boolean;
|
|
728
833
|
}
|
|
729
834
|
|
|
835
|
+
/** Root-client fields used directly; subscription and PlanVersion delegates are configurable. */
|
|
836
|
+
interface SubscriptionRepositoryClient {
|
|
837
|
+
/** Used by normalized semantic-key ↔ UUID binding. */
|
|
838
|
+
plan: unknown;
|
|
839
|
+
}
|
|
730
840
|
/**
|
|
731
841
|
* `SubscriptionRepository` against the canonical `subscriptions` +
|
|
732
842
|
* `plan_versions` tables.
|
|
733
843
|
*
|
|
734
|
-
*
|
|
735
|
-
* `
|
|
736
|
-
*
|
|
844
|
+
* BundleVersion booking counts are an optional capability. Configure
|
|
845
|
+
* `tenantSubscription.subscriptionBundleDelegate` for schemas carrying the
|
|
846
|
+
* `subscription_bundles` junction; without it the platform keeps affected
|
|
847
|
+
* versions frozen (fail-closed).
|
|
737
848
|
*/
|
|
738
849
|
declare class PrismaSubscriptionRepository implements SubscriptionRepository {
|
|
739
850
|
private readonly prisma;
|
|
740
|
-
|
|
851
|
+
readonly countByBundleVersionId?: (bundleVersionId: string) => Promise<number>;
|
|
852
|
+
private readonly binding;
|
|
853
|
+
private readonly planVersionDelegateName;
|
|
854
|
+
private readonly subscriptionDelegateName;
|
|
855
|
+
private readonly subscriptionBundleDelegateName;
|
|
856
|
+
constructor(prisma: SubscriptionRepositoryClient, options?: PrismaSchemaOptions);
|
|
857
|
+
private db;
|
|
741
858
|
findByTenantId(tenantId: string): Promise<SubscriptionRecord | null>;
|
|
742
859
|
findByTenantIdLocked(tenantId: string, tx: TransactionContext): Promise<SubscriptionRecord | null>;
|
|
743
860
|
countByPlanVersionId(planVersionId: string): Promise<number>;
|
|
744
|
-
countActiveByPlanKey(
|
|
861
|
+
countActiveByPlanKey(projectKey: string): Promise<Record<string, number>>;
|
|
862
|
+
private countActiveBundleBindings;
|
|
745
863
|
private loadByTenantId;
|
|
746
864
|
private toRecord;
|
|
865
|
+
private planVersions;
|
|
866
|
+
private subscriptions;
|
|
867
|
+
private planKeysForProject;
|
|
747
868
|
}
|
|
748
869
|
|
|
870
|
+
interface SubscriptionBundleClient {
|
|
871
|
+
subscriptionBundle: unknown;
|
|
872
|
+
}
|
|
749
873
|
/**
|
|
750
874
|
* `SubscriptionBundleRepository` against the canonical `subscription_bundles`
|
|
751
875
|
* junction (SPEC_V2 §11.1 M6 Pack 2e). Dumb persistence: domain constraints
|
|
@@ -756,7 +880,7 @@ declare class PrismaSubscriptionRepository implements SubscriptionRepository {
|
|
|
756
880
|
*/
|
|
757
881
|
declare class PrismaSubscriptionBundleRepository implements SubscriptionBundleRepository {
|
|
758
882
|
private readonly prisma;
|
|
759
|
-
constructor(prisma:
|
|
883
|
+
constructor(prisma: SubscriptionBundleClient);
|
|
760
884
|
private db;
|
|
761
885
|
listBySubscription(subscriptionId: string): Promise<SubscriptionBundleRecord[]>;
|
|
762
886
|
findById(subscriptionBundleId: string): Promise<SubscriptionBundleRecord | null>;
|
|
@@ -767,24 +891,42 @@ declare class PrismaSubscriptionBundleRepository implements SubscriptionBundleRe
|
|
|
767
891
|
countActiveByBundleVersionId(bundleVersionId: string, asOf?: Date): Promise<number>;
|
|
768
892
|
}
|
|
769
893
|
|
|
894
|
+
/** Structural minimum of the root client; model delegates are configurable. */
|
|
895
|
+
interface TransactionalPrismaClient {
|
|
896
|
+
$transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T>;
|
|
897
|
+
}
|
|
770
898
|
/**
|
|
771
|
-
* `TenantSubscriptionWritePort` against
|
|
899
|
+
* `TenantSubscriptionWritePort` against a configurable Prisma subscription
|
|
900
|
+
* delegate.
|
|
901
|
+
*
|
|
902
|
+
* The 0.6 default remains deliberately conservative:
|
|
903
|
+
* `tenantSubscription.synchronizePlanVersion` is false, so
|
|
904
|
+
* `changePlanImmediate` writes the semantic `plan` and cycle exactly as
|
|
905
|
+
* before. Opting into synchronization resolves the target plan through the
|
|
906
|
+
* configured plan binding, selects its live/active PlanVersion, and writes
|
|
907
|
+
* `plan` + `planVersionId` in one transaction.
|
|
908
|
+
*
|
|
772
909
|
* Pure persistence: trial carry-over (#17) and contract freeze (#18) are
|
|
773
910
|
* resolved in the platform `changePlan` path and handed down as plain values —
|
|
774
911
|
* this adapter only writes what it receives.
|
|
775
912
|
*
|
|
776
|
-
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
913
|
+
* `applyOnboardingSelection` is an explicit opt-in capability. When
|
|
914
|
+
* `tenantSubscription.atomicOnboardingSelection` is true it uses one
|
|
915
|
+
* interactive transaction for the subscription write and optional promo
|
|
916
|
+
* callback. In synchronized mode it also binds the concrete PlanVersion and
|
|
917
|
+
* clears stale pending-version state.
|
|
779
918
|
*/
|
|
780
919
|
declare class PrismaTenantSubscriptionWriteAdapter implements TenantSubscriptionWritePort {
|
|
781
920
|
private readonly prisma;
|
|
782
|
-
|
|
783
|
-
private
|
|
921
|
+
readonly applyOnboardingSelection?: (tenantId: string, input: ApplyOnboardingSelectionInput, redeemPromo: RedeemPromoInTransactionCallback | null) => Promise<ApplyOnboardingSelectionResult>;
|
|
922
|
+
private readonly schema;
|
|
923
|
+
private readonly planBinding;
|
|
924
|
+
constructor(prisma: TransactionalPrismaClient, options?: PrismaSchemaOptions);
|
|
784
925
|
changePlanImmediate(tenantId: string, input: ImmediatePlanChangeInput): Promise<{
|
|
785
926
|
plan: string;
|
|
786
927
|
billingCycle: string;
|
|
787
928
|
}>;
|
|
929
|
+
private changePlanImmediateInClient;
|
|
788
930
|
schedulePlanChange(tenantId: string, input: ScheduledPlanChangeInput): Promise<void>;
|
|
789
931
|
acceptPendingPlanVersion(tenantId: string, userId: string, now: Date): Promise<{
|
|
790
932
|
accepted: boolean;
|
|
@@ -792,24 +934,44 @@ declare class PrismaTenantSubscriptionWriteAdapter implements TenantSubscription
|
|
|
792
934
|
effectiveAt: Date | null;
|
|
793
935
|
alreadyAccepted: boolean;
|
|
794
936
|
}>;
|
|
937
|
+
private applyOnboardingSelectionAtomic;
|
|
795
938
|
cancelSubscription(tenantId: string, immediate: boolean, now: Date): Promise<{
|
|
796
939
|
canceledAt: Date | null;
|
|
797
940
|
status: string;
|
|
798
941
|
}>;
|
|
942
|
+
private subscription;
|
|
943
|
+
private planVersions;
|
|
944
|
+
private findTargetPlanVersionId;
|
|
945
|
+
private pendingVersionBelongsToAnotherPlan;
|
|
946
|
+
private assertConfiguration;
|
|
799
947
|
}
|
|
800
948
|
|
|
949
|
+
/**
|
|
950
|
+
* Root-client fields needed outside the configurable PlanVersion delegate.
|
|
951
|
+
* `plan` is used by normalized semantic-key ↔ UUID binding.
|
|
952
|
+
*/
|
|
953
|
+
interface PlanVersionRepositoryClient {
|
|
954
|
+
plan: unknown;
|
|
955
|
+
}
|
|
801
956
|
/**
|
|
802
957
|
* `PlanVersionRepository` against the canonical `plan_versions` table.
|
|
803
958
|
*
|
|
804
|
-
* `findActive`
|
|
805
|
-
*
|
|
806
|
-
*
|
|
807
|
-
* behavior).
|
|
959
|
+
* `findActive` remains absent with the canonical 0.6 defaults. Extended
|
|
960
|
+
* schemas enable it through `schema.planVersionFields.entitlement`; its query
|
|
961
|
+
* then uses the shared day-inclusive validity semantics.
|
|
808
962
|
*/
|
|
809
963
|
declare class PrismaPlanVersionRepository implements PlanVersionRepository {
|
|
810
964
|
private readonly prisma;
|
|
811
|
-
|
|
965
|
+
readonly findActive?: (planId: string, asOf?: Date, tx?: TransactionContext) => Promise<PlanVersionRecord | null>;
|
|
966
|
+
private readonly binding;
|
|
967
|
+
private readonly delegateName;
|
|
968
|
+
private readonly fields;
|
|
969
|
+
constructor(prisma: PlanVersionRepositoryClient, options?: PrismaSchemaOptions);
|
|
970
|
+
private db;
|
|
812
971
|
findLatestLive(planId: string, tx?: TransactionContext): Promise<PlanVersionRecord | null>;
|
|
972
|
+
private findActivePlanVersion;
|
|
973
|
+
private versions;
|
|
974
|
+
private toRecord;
|
|
813
975
|
}
|
|
814
976
|
|
|
815
977
|
/**
|
|
@@ -909,58 +1071,82 @@ declare class PrismaSuperAdminBootstrapAdapter implements SuperAdminProvisioning
|
|
|
909
1071
|
createSuperAdmin(input: CreateSuperAdminCliInput): Promise<PlatformUserDto>;
|
|
910
1072
|
}
|
|
911
1073
|
|
|
1074
|
+
/** Root-client fields used directly; the PlanVersion delegate is configurable. */
|
|
1075
|
+
interface PlanCatalogReadClient {
|
|
1076
|
+
plan: unknown;
|
|
1077
|
+
featureCatalogEntry: unknown;
|
|
1078
|
+
}
|
|
912
1079
|
/**
|
|
913
1080
|
* `PlanCatalogReadSink` against the canonical `plans`, `plan_versions` and
|
|
914
1081
|
* `feature_catalog_entries` tables — DB hydration of the plan catalog at
|
|
915
1082
|
* boot (`PlanCatalogModule.forRoot({ sink })`).
|
|
916
1083
|
*
|
|
917
|
-
*
|
|
918
|
-
*
|
|
1084
|
+
* The canonical 0.6 defaults report validity fields as null. Extended schemas
|
|
1085
|
+
* can opt into validity/termination fields and can point this sink at a
|
|
1086
|
+
* catalog-specific plan-version delegate.
|
|
919
1087
|
*/
|
|
920
1088
|
declare class PrismaPlanCatalogReadSink implements PlanCatalogReadSink {
|
|
921
1089
|
private readonly prisma;
|
|
922
|
-
|
|
1090
|
+
private readonly binding;
|
|
1091
|
+
private readonly delegateName;
|
|
1092
|
+
private readonly fields;
|
|
1093
|
+
constructor(prisma: PlanCatalogReadClient, options?: PrismaSchemaOptions);
|
|
1094
|
+
private db;
|
|
923
1095
|
loadSnapshot(projectKey: string): Promise<PlanCatalogReadSnapshot>;
|
|
1096
|
+
private planVersions;
|
|
924
1097
|
}
|
|
925
1098
|
|
|
1099
|
+
/** Root-client fields used directly; the PlanVersion delegate is configurable. */
|
|
1100
|
+
interface PlanCatalogImportClient {
|
|
1101
|
+
plan: unknown;
|
|
1102
|
+
featureCatalogEntry: unknown;
|
|
1103
|
+
}
|
|
926
1104
|
/**
|
|
927
1105
|
* `PlanCatalogImportSink` against the canonical catalog tables — the
|
|
928
1106
|
* one-shot `saas.yaml → DB` import at boot.
|
|
929
1107
|
*
|
|
930
1108
|
* Idempotency per the port contract: existing rows (identity match) are
|
|
931
|
-
* skipped without error; only the created/skipped flags are reported.
|
|
1109
|
+
* skipped without error; only the created/skipped flags are reported. In
|
|
1110
|
+
* normalized mode the semantic `planKey` input is resolved to `Plan.id`.
|
|
932
1111
|
*/
|
|
933
1112
|
declare class PrismaPlanCatalogImportSink implements PlanCatalogImportSink {
|
|
934
1113
|
private readonly prisma;
|
|
935
|
-
|
|
1114
|
+
private readonly binding;
|
|
1115
|
+
private readonly delegateName;
|
|
1116
|
+
constructor(prisma: PlanCatalogImportClient, options?: PrismaSchemaOptions);
|
|
1117
|
+
private db;
|
|
936
1118
|
upsertPlan(input: UpsertPlanInput): Promise<UpsertResult>;
|
|
937
1119
|
upsertPlanVersion(input: UpsertPlanVersionInput): Promise<UpsertResult>;
|
|
1120
|
+
private planVersions;
|
|
938
1121
|
upsertFeatureCatalogEntry(input: UpsertFeatureCatalogEntryInput): Promise<UpsertResult>;
|
|
939
1122
|
}
|
|
940
1123
|
|
|
1124
|
+
/** Root-client fields used directly; the version delegate is configurable. */
|
|
1125
|
+
interface PlanRepositoryClient {
|
|
1126
|
+
plan: unknown;
|
|
1127
|
+
$transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T>;
|
|
1128
|
+
}
|
|
941
1129
|
/**
|
|
942
1130
|
* `PlanRepository` against the canonical `plans` + `plan_versions` tables
|
|
943
1131
|
* (SPEC_V2 §11.1 M6). Plan stem CRUD (Pack 1) and PlanVersion lifecycle
|
|
944
|
-
* (Pack 2a) live in one adapter
|
|
945
|
-
*
|
|
946
|
-
*
|
|
1132
|
+
* (Pack 2a) live in one adapter. Ports always use the semantic **planKey**;
|
|
1133
|
+
* storage defaults to the 0.6 soft binding
|
|
1134
|
+
* `PlanVersion.planId === Plan.planKey`. The opt-in normalized binding resolves
|
|
1135
|
+
* that key to `Plan.id` for every database operation.
|
|
947
1136
|
*
|
|
948
|
-
*
|
|
949
|
-
*
|
|
950
|
-
*
|
|
951
|
-
* `
|
|
952
|
-
* - Every `PlanVersionRow.validFrom`/`validUntil` maps to `null`.
|
|
953
|
-
* - `publishPlanVersionDraft` persists only the publish/supersede state; the
|
|
954
|
-
* `validFrom`/`validUntil` in `publishMeta` cannot be stored, so
|
|
955
|
-
* auto-succession reduces to setting `supersededAt` on the previous live version.
|
|
956
|
-
* - `findActivePlanVersion` (validity-window read) and `terminate` (endsAt)
|
|
957
|
-
* throw, because their contract depends on columns this schema does not have.
|
|
958
|
-
* Consumers that need them provide a custom adapter on an extended schema.
|
|
1137
|
+
* The canonical 0.6 schema has neither validity-window nor `endsAt` columns.
|
|
1138
|
+
* Both capabilities therefore default off for rolling compatibility; apps
|
|
1139
|
+
* that applied the current additive schema opt in through
|
|
1140
|
+
* `schema.planVersionFields.catalog`.
|
|
959
1141
|
*/
|
|
960
1142
|
declare class PrismaPlanRepository implements PlanRepository {
|
|
961
1143
|
private readonly prisma;
|
|
962
|
-
|
|
1144
|
+
private readonly binding;
|
|
1145
|
+
private readonly delegateName;
|
|
1146
|
+
private readonly fields;
|
|
1147
|
+
constructor(prisma: PlanRepositoryClient, options?: PrismaSchemaOptions);
|
|
963
1148
|
private db;
|
|
1149
|
+
private versions;
|
|
964
1150
|
list(filter: PlanListFilter): Promise<PlanRow[]>;
|
|
965
1151
|
findById(planId: string): Promise<PlanRow | null>;
|
|
966
1152
|
findByKey(projectKey: string, planKey: string): Promise<PlanRow | null>;
|
|
@@ -972,7 +1158,7 @@ declare class PrismaPlanRepository implements PlanRepository {
|
|
|
972
1158
|
findVersionById(versionId: string): Promise<PlanVersionRow | null>;
|
|
973
1159
|
findCurrentDraft(planKey: string): Promise<PlanVersionRow | null>;
|
|
974
1160
|
findLatestLivePlanVersion(planKey: string, tx?: TransactionContext): Promise<PlanVersionRow | null>;
|
|
975
|
-
findActivePlanVersion(): Promise<PlanVersionRow | null>;
|
|
1161
|
+
findActivePlanVersion(planKey: string, asOf?: Date, tx?: TransactionContext): Promise<PlanVersionRow | null>;
|
|
976
1162
|
createPlanVersionDraft(data: CreatePlanVersionDraftData): Promise<PlanVersionRow>;
|
|
977
1163
|
updatePlanVersionDraft(versionId: string, data: UpdatePlanVersionDraftData): Promise<PlanVersionRow>;
|
|
978
1164
|
publishPlanVersionDraft(versionId: string, publishMeta: {
|
|
@@ -983,30 +1169,64 @@ declare class PrismaPlanRepository implements PlanRepository {
|
|
|
983
1169
|
validUntil: Date | null;
|
|
984
1170
|
}, tx?: TransactionContext): Promise<PlanVersionRow>;
|
|
985
1171
|
deletePlanVersionDraft(versionId: string): Promise<void>;
|
|
986
|
-
terminate(): Promise<PlanVersionRow>;
|
|
1172
|
+
terminate(versionId: string, endsAt: Date): Promise<PlanVersionRow>;
|
|
1173
|
+
private toPlanVersionRow;
|
|
987
1174
|
}
|
|
988
1175
|
|
|
1176
|
+
/**
|
|
1177
|
+
* Root-client shape accepted by this repository. Delegates and `$transaction`
|
|
1178
|
+
* stay opaque at the injection boundary because generated Prisma delegates
|
|
1179
|
+
* have schema-specific generic signatures; calls are narrowed locally to the
|
|
1180
|
+
* exact Bundle operations below.
|
|
1181
|
+
*/
|
|
1182
|
+
interface BundlePrismaClient {
|
|
1183
|
+
bundle: unknown;
|
|
1184
|
+
bundleVersion: unknown;
|
|
1185
|
+
$transaction: unknown;
|
|
1186
|
+
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Optional DI token for apps that register `PrismaBundleRepository` directly
|
|
1189
|
+
* as a Nest provider. Factory users may pass the same options as the second
|
|
1190
|
+
* constructor argument.
|
|
1191
|
+
*/
|
|
1192
|
+
declare const PRISMA_BUNDLE_REPOSITORY_OPTIONS: unique symbol;
|
|
1193
|
+
interface PrismaBundleRepositoryOptions {
|
|
1194
|
+
/**
|
|
1195
|
+
* Enables reads and writes of `BundleVersion.validFrom`/`validUntil`.
|
|
1196
|
+
*
|
|
1197
|
+
* Default `false` preserves compatibility with databases and Prisma
|
|
1198
|
+
* clients generated from the 0.6 schema, where the columns do not exist.
|
|
1199
|
+
*/
|
|
1200
|
+
validityWindows?: boolean;
|
|
1201
|
+
}
|
|
989
1202
|
/**
|
|
990
1203
|
* `BundleRepository` against the canonical `bundles` + `bundle_versions`
|
|
991
1204
|
* tables (SPEC_V2 §5 + §11.1 M3). Versioning mirrors `PlanVersion`: at most one
|
|
992
1205
|
* draft (`publishedAt IS NULL`) per bundle, monotonically incrementing
|
|
993
1206
|
* `version`, `supersededAt` marking the previous live version on publish.
|
|
994
1207
|
*
|
|
995
|
-
*
|
|
996
|
-
*
|
|
997
|
-
* therefore
|
|
998
|
-
*
|
|
999
|
-
* accepted (to satisfy the port signature) but not persisted — consistent with
|
|
1000
|
-
* `PrismaPlanVersionRepository`, which documents the same schema gap.
|
|
1208
|
+
* Validity-window support is opt-in via `{ validityWindows: true }`. The
|
|
1209
|
+
* default deliberately does not select, read or write `validFrom`/
|
|
1210
|
+
* `validUntil`, and therefore keeps working with the 0.6 schema. In the
|
|
1211
|
+
* enabled mode the repository expects both nullable columns to exist.
|
|
1001
1212
|
*
|
|
1002
|
-
*
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1213
|
+
* In validity-window mode `publishDraft` opens an internal transaction when
|
|
1214
|
+
* the caller did not provide one. This makes superseding the predecessor,
|
|
1215
|
+
* applying its auto-succession end date and publishing the draft atomic.
|
|
1216
|
+
* Legacy mode retains the 0.6 transaction behavior unchanged.
|
|
1005
1217
|
*/
|
|
1006
1218
|
declare class PrismaBundleRepository implements BundleRepository {
|
|
1007
1219
|
private readonly prisma;
|
|
1008
|
-
|
|
1220
|
+
private readonly validityWindows;
|
|
1221
|
+
/**
|
|
1222
|
+
* Present only when validity-window mode is enabled. This mirrors the
|
|
1223
|
+
* optional port capability and lets 0.6-schema consumers detect that an
|
|
1224
|
+
* active-at-time lookup is unavailable.
|
|
1225
|
+
*/
|
|
1226
|
+
readonly findActiveBundleVersion?: (bundleId: string, asOf?: Date, tx?: TransactionContext) => Promise<BundleVersionRow | null>;
|
|
1227
|
+
constructor(prisma: BundlePrismaClient, options?: PrismaBundleRepositoryOptions);
|
|
1009
1228
|
private db;
|
|
1229
|
+
private transaction;
|
|
1010
1230
|
list(filter: BundleListFilter): Promise<BundleRow[]>;
|
|
1011
1231
|
findById(bundleId: string): Promise<BundleRow | null>;
|
|
1012
1232
|
findByKey(projectKey: string, bundleKey: string): Promise<BundleRow | null>;
|
|
@@ -1017,6 +1237,7 @@ declare class PrismaBundleRepository implements BundleRepository {
|
|
|
1017
1237
|
findVersionById(versionId: string): Promise<BundleVersionRow | null>;
|
|
1018
1238
|
findCurrentDraft(bundleId: string): Promise<BundleVersionRow | null>;
|
|
1019
1239
|
findLatestLive(bundleId: string, tx?: TransactionContext): Promise<BundleVersionRow | null>;
|
|
1240
|
+
private findActiveBundleVersionWithValidity;
|
|
1020
1241
|
createDraft(data: CreateBundleVersionDraftData): Promise<BundleVersionRow>;
|
|
1021
1242
|
updateDraft(versionId: string, data: UpdateBundleVersionDraftData): Promise<BundleVersionRow>;
|
|
1022
1243
|
publishDraft(versionId: string, publishMeta: {
|
|
@@ -1026,9 +1247,15 @@ declare class PrismaBundleRepository implements BundleRepository {
|
|
|
1026
1247
|
validFrom: Date;
|
|
1027
1248
|
validUntil: Date | null;
|
|
1028
1249
|
}, tx?: TransactionContext): Promise<BundleVersionRow>;
|
|
1250
|
+
private publishDraftWithValidity;
|
|
1029
1251
|
deleteDraft(versionId: string): Promise<void>;
|
|
1030
1252
|
}
|
|
1031
1253
|
|
|
1254
|
+
interface CatalogEntryRepositoryClient {
|
|
1255
|
+
capabilityCatalogEntry: unknown;
|
|
1256
|
+
featureCatalogEntry: unknown;
|
|
1257
|
+
quotaCatalogEntry: unknown;
|
|
1258
|
+
}
|
|
1032
1259
|
/**
|
|
1033
1260
|
* `CatalogEntryRepository` against the canonical `capability_catalog_entries`,
|
|
1034
1261
|
* `feature_catalog_entries` and `quota_catalog_entries` tables (SPEC_V2 §6.3 —
|
|
@@ -1041,7 +1268,7 @@ declare class PrismaBundleRepository implements BundleRepository {
|
|
|
1041
1268
|
*/
|
|
1042
1269
|
declare class PrismaCatalogEntryRepository implements CatalogEntryRepository {
|
|
1043
1270
|
private readonly prisma;
|
|
1044
|
-
constructor(prisma:
|
|
1271
|
+
constructor(prisma: CatalogEntryRepositoryClient);
|
|
1045
1272
|
private get db();
|
|
1046
1273
|
listCapabilities(filter: CatalogEntryFilter): Promise<CapabilityCatalogEntryRow[]>;
|
|
1047
1274
|
listFeatures(filter: CatalogEntryFilter): Promise<FeatureCatalogEntryRow[]>;
|
|
@@ -1062,6 +1289,9 @@ declare class PrismaCatalogEntryRepository implements CatalogEntryRepository {
|
|
|
1062
1289
|
setQuotaBase(projectKey: string, quotaKey: string, data: UpdateCatalogEntryBaseData): Promise<QuotaCatalogEntryRow>;
|
|
1063
1290
|
}
|
|
1064
1291
|
|
|
1292
|
+
interface MarketingProjectionRepositoryClient {
|
|
1293
|
+
marketingProjection: unknown;
|
|
1294
|
+
}
|
|
1065
1295
|
/**
|
|
1066
1296
|
* `MarketingProjectionRepository` against the canonical `marketing_projections`
|
|
1067
1297
|
* table. Not versioned: per (`targetType`, `targetVersionId`, `locale`) there is
|
|
@@ -1070,7 +1300,7 @@ declare class PrismaCatalogEntryRepository implements CatalogEntryRepository {
|
|
|
1070
1300
|
*/
|
|
1071
1301
|
declare class PrismaMarketingProjectionRepository implements MarketingProjectionRepository {
|
|
1072
1302
|
private readonly prisma;
|
|
1073
|
-
constructor(prisma:
|
|
1303
|
+
constructor(prisma: MarketingProjectionRepositoryClient);
|
|
1074
1304
|
private get db();
|
|
1075
1305
|
list(filter: MarketingProjectionFilter): Promise<MarketingProjectionRow[]>;
|
|
1076
1306
|
findById(id: string): Promise<MarketingProjectionRow | null>;
|
|
@@ -1080,6 +1310,9 @@ declare class PrismaMarketingProjectionRepository implements MarketingProjection
|
|
|
1080
1310
|
delete(id: string): Promise<void>;
|
|
1081
1311
|
}
|
|
1082
1312
|
|
|
1313
|
+
interface MarketingSettingsRepositoryClient {
|
|
1314
|
+
marketingSettings: unknown;
|
|
1315
|
+
}
|
|
1083
1316
|
/**
|
|
1084
1317
|
* `MarketingSettingsRepository` against the canonical `marketing_settings`
|
|
1085
1318
|
* table (one row per project). A missing row means "full locale pool active",
|
|
@@ -1087,12 +1320,16 @@ declare class PrismaMarketingProjectionRepository implements MarketingProjection
|
|
|
1087
1320
|
*/
|
|
1088
1321
|
declare class PrismaMarketingSettingsRepository implements MarketingSettingsRepository {
|
|
1089
1322
|
private readonly prisma;
|
|
1090
|
-
constructor(prisma:
|
|
1323
|
+
constructor(prisma: MarketingSettingsRepositoryClient);
|
|
1091
1324
|
private get db();
|
|
1092
1325
|
get(projectKey: string): Promise<MarketingSettingsRow | null>;
|
|
1093
1326
|
upsert(projectKey: string, data: UpdateMarketingSettingsData): Promise<MarketingSettingsRow>;
|
|
1094
1327
|
}
|
|
1095
1328
|
|
|
1329
|
+
interface PromotionRepositoryClient {
|
|
1330
|
+
promotion: unknown;
|
|
1331
|
+
$executeRaw: unknown;
|
|
1332
|
+
}
|
|
1096
1333
|
/**
|
|
1097
1334
|
* `PromotionRepository` against the canonical `promotions` table. Not
|
|
1098
1335
|
* versioned: promotions are edited directly.
|
|
@@ -1105,7 +1342,7 @@ declare class PrismaMarketingSettingsRepository implements MarketingSettingsRepo
|
|
|
1105
1342
|
*/
|
|
1106
1343
|
declare class PrismaPromotionRepository implements PromotionRepository {
|
|
1107
1344
|
private readonly prisma;
|
|
1108
|
-
constructor(prisma:
|
|
1345
|
+
constructor(prisma: PromotionRepositoryClient);
|
|
1109
1346
|
private get db();
|
|
1110
1347
|
list(filter: PromotionFilter): Promise<PromotionRow[]>;
|
|
1111
1348
|
findById(id: string): Promise<PromotionRow | null>;
|
|
@@ -1132,4 +1369,4 @@ declare class PrismaSubscriptionContractRepository implements SubscriptionContra
|
|
|
1132
1369
|
terminate(contractId: string, data: TerminateSubscriptionContractData): Promise<SubscriptionContractRecord>;
|
|
1133
1370
|
}
|
|
1134
1371
|
|
|
1135
|
-
export { AsyncLocalRlsBypassAdapter, type DecimalLike, PASSWORD_HASHER_TOKEN, PRISMA_CLIENT_TOKEN, PrismaAuditAdapter, PrismaAuditQueryAdapter, PrismaAuditStatsAdapter, PrismaBundleRepository, PrismaCatalogEntryRepository, type PrismaLike, PrismaMarketingProjectionRepository, PrismaMarketingSettingsRepository, PrismaMfaAdapter, type PrismaModelDelegateLike, type PrismaPersistenceOptions, PrismaPlanCatalogImportSink, PrismaPlanCatalogReadSink, PrismaPlanRepository, PrismaPlanVersionRepository, PrismaPromoCodeRedemptionRepository, PrismaPromoCodeRepository, PrismaPromoCodeValidationLogRepository, PrismaPromoSubscriptionLookup, PrismaPromotionRepository, PrismaSubscriptionBundleRepository, PrismaSubscriptionContractRepository, PrismaSubscriptionRepository, PrismaSuperAdminBootstrapAdapter, PrismaTenantSubscriptionWriteAdapter, PrismaTransactionRunner, type PrismaTxLike, ZeroPromoRevenueDeductionAggregator, buildActorTag, prismaPersistence };
|
|
1372
|
+
export { AsyncLocalRlsBypassAdapter, type DecimalLike, PASSWORD_HASHER_TOKEN, PRISMA_BUNDLE_REPOSITORY_OPTIONS, PRISMA_CLIENT_TOKEN, PRISMA_SCHEMA_OPTIONS_TOKEN, PrismaAuditAdapter, PrismaAuditQueryAdapter, PrismaAuditStatsAdapter, PrismaBundleRepository, type PrismaBundleRepositoryOptions, PrismaCatalogEntryRepository, type PrismaLike, PrismaMarketingProjectionRepository, PrismaMarketingSettingsRepository, PrismaMfaAdapter, type PrismaModelDelegateLike, type PrismaPersistenceOptions, type PrismaPlanBindingMode, type PrismaPlanBindingOptions, type PrismaPlanBindingResolver, PrismaPlanCatalogImportSink, PrismaPlanCatalogReadSink, type PrismaPlanDelegateOptions, PrismaPlanRepository, type PrismaPlanVersionFieldCapabilities, type PrismaPlanVersionFieldOptions, PrismaPlanVersionRepository, PrismaPromoCodeRedemptionRepository, PrismaPromoCodeRepository, PrismaPromoCodeValidationLogRepository, PrismaPromoSubscriptionLookup, PrismaPromotionRepository, type PrismaSchemaOptions, PrismaSubscriptionBundleRepository, PrismaSubscriptionContractRepository, PrismaSubscriptionRepository, PrismaSuperAdminBootstrapAdapter, type PrismaTenantSubscriptionOptions, PrismaTenantSubscriptionWriteAdapter, PrismaTransactionRunner, type PrismaTxLike, type ResolvedPrismaSchemaOptions, ZeroPromoRevenueDeductionAggregator, buildActorTag, createPrismaPlanBindingResolver, getPrismaDelegate, prismaPersistence, resolvePrismaSchemaOptions };
|