@saasicat/adapter-prisma 0.5.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 -27
- package/dist/index.cjs +3167 -61
- package/dist/index.d.cts +544 -31
- package/dist/index.d.ts +544 -31
- package/dist/index.js +3154 -62
- 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, 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 } from '@saasicat/types';
|
|
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. */
|
|
@@ -16,7 +16,7 @@ interface SubscriptionRowLike {
|
|
|
16
16
|
pendingPlan: string | null;
|
|
17
17
|
pendingEffectiveAt: Date | null;
|
|
18
18
|
customLimits: unknown;
|
|
19
|
-
planVersionId: string
|
|
19
|
+
planVersionId: string;
|
|
20
20
|
pendingPlanVersionId: string | null;
|
|
21
21
|
startedAt: Date | null;
|
|
22
22
|
}
|
|
@@ -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
|
}
|
|
@@ -547,6 +550,132 @@ interface PrismaTxLike {
|
|
|
547
550
|
interface PrismaLike extends PrismaTxLike {
|
|
548
551
|
$transaction<T>(fn: (tx: PrismaTxLike) => Promise<T>): Promise<T>;
|
|
549
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* Generic structural minimum of a Prisma model delegate. The catalog-plane
|
|
555
|
+
* repositories (bundle, plan, catalog-entry, marketing,
|
|
556
|
+
* promotion, contract) declare their own DB-row interfaces and view the
|
|
557
|
+
* injected client through `{ model: PrismaModelDelegateLike<Row> }` casts —
|
|
558
|
+
* this keeps each repo self-contained and avoids hard-coding every delegate on
|
|
559
|
+
* `PrismaTxLike`. Args mirror Prisma's `where`/`data`/`select`/`orderBy` shapes
|
|
560
|
+
* and are typed `unknown`: the repos build them inline and Prisma validates
|
|
561
|
+
* them at runtime; only the results are typed, matching the package's
|
|
562
|
+
* structural-minimum philosophy.
|
|
563
|
+
*/
|
|
564
|
+
interface PrismaModelDelegateLike<Row> {
|
|
565
|
+
findMany(args?: unknown): Promise<Row[]>;
|
|
566
|
+
findUnique(args: unknown): Promise<Row | null>;
|
|
567
|
+
findFirst(args?: unknown): Promise<Row | null>;
|
|
568
|
+
create(args: unknown): Promise<Row>;
|
|
569
|
+
update(args: unknown): Promise<Row>;
|
|
570
|
+
delete(args: unknown): Promise<Row>;
|
|
571
|
+
upsert(args: unknown): Promise<Row>;
|
|
572
|
+
updateMany(args: unknown): Promise<{
|
|
573
|
+
count: number;
|
|
574
|
+
}>;
|
|
575
|
+
createMany(args: unknown): Promise<{
|
|
576
|
+
count: number;
|
|
577
|
+
}>;
|
|
578
|
+
deleteMany(args: unknown): Promise<{
|
|
579
|
+
count: number;
|
|
580
|
+
}>;
|
|
581
|
+
count(args?: unknown): Promise<number>;
|
|
582
|
+
}
|
|
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>;
|
|
550
679
|
|
|
551
680
|
interface PrismaPersistenceOptions {
|
|
552
681
|
/**
|
|
@@ -569,6 +698,12 @@ interface PrismaPersistenceOptions {
|
|
|
569
698
|
* middleware. Default false.
|
|
570
699
|
*/
|
|
571
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;
|
|
572
707
|
}
|
|
573
708
|
/**
|
|
574
709
|
* Builds the `SaasicatPersistenceAdapter` bundle for Prisma + PostgreSQL on
|
|
@@ -581,9 +716,14 @@ interface PrismaPersistenceOptions {
|
|
|
581
716
|
* });
|
|
582
717
|
* ```
|
|
583
718
|
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
719
|
+
* This bundle covers the core/entitlement/promo/plan-catalog slices consumed
|
|
720
|
+
* by `SaasPlatformModule`. The catalog plane (CatalogModule) and the V3
|
|
721
|
+
* contract loop take their repositories directly as `forRoot` options — wire
|
|
722
|
+
* the standalone `PrismaPlanRepository` / `PrismaBundleRepository` /
|
|
723
|
+
* `PrismaCatalogEntryRepository` /
|
|
724
|
+
* `PrismaMarketingProjectionRepository` / `PrismaMarketingSettingsRepository` /
|
|
725
|
+
* `PrismaPromotionRepository` / `PrismaSubscriptionContractRepository` exports
|
|
726
|
+
* there. The registration and tenant-billing write ports remain app-specific.
|
|
587
727
|
*/
|
|
588
728
|
declare function prismaPersistence(options: PrismaPersistenceOptions): SaasicatPersistenceAdapter;
|
|
589
729
|
|
|
@@ -594,7 +734,7 @@ declare function prismaPersistence(options: PrismaPersistenceOptions): SaasicatP
|
|
|
594
734
|
*/
|
|
595
735
|
declare class PrismaTransactionRunner implements TransactionRunner {
|
|
596
736
|
private readonly prisma;
|
|
597
|
-
constructor(prisma:
|
|
737
|
+
constructor(prisma: Record<'$transaction', unknown>);
|
|
598
738
|
run<T>(fn: (tx: TransactionContext) => Promise<T>): Promise<T>;
|
|
599
739
|
}
|
|
600
740
|
|
|
@@ -615,7 +755,7 @@ declare class PrismaTransactionRunner implements TransactionRunner {
|
|
|
615
755
|
*/
|
|
616
756
|
declare class PrismaMfaAdapter implements MfaPort {
|
|
617
757
|
private readonly prisma;
|
|
618
|
-
constructor(prisma: PrismaLike);
|
|
758
|
+
constructor(prisma: Pick<PrismaLike, 'superAdminMfa'>);
|
|
619
759
|
getSecret(userId: string): Promise<string | null>;
|
|
620
760
|
setSecret(userId: string, secret: string | null): Promise<void>;
|
|
621
761
|
isEnabled(userId: string): Promise<boolean>;
|
|
@@ -632,7 +772,7 @@ declare function buildActorTag(actor: AdminActor): string;
|
|
|
632
772
|
*/
|
|
633
773
|
declare class PrismaAuditAdapter implements AuditPort {
|
|
634
774
|
private readonly prisma;
|
|
635
|
-
constructor(prisma: PrismaLike);
|
|
775
|
+
constructor(prisma: Pick<PrismaLike, 'auditLog'>);
|
|
636
776
|
write(input: {
|
|
637
777
|
actor: AdminActor;
|
|
638
778
|
entity: string;
|
|
@@ -648,14 +788,14 @@ declare class PrismaAuditAdapter implements AuditPort {
|
|
|
648
788
|
*/
|
|
649
789
|
declare class PrismaAuditQueryAdapter implements AuditQueryPort {
|
|
650
790
|
private readonly prisma;
|
|
651
|
-
constructor(prisma: PrismaLike);
|
|
791
|
+
constructor(prisma: Pick<PrismaLike, 'auditLog'>);
|
|
652
792
|
list(filter: AuditQuery): Promise<AuditEntry[]>;
|
|
653
793
|
}
|
|
654
794
|
|
|
655
795
|
/** `AuditStatsPort` against the canonical `audit_logs` table. */
|
|
656
796
|
declare class PrismaAuditStatsAdapter implements AuditStatsPort {
|
|
657
797
|
private readonly prisma;
|
|
658
|
-
constructor(prisma: PrismaLike);
|
|
798
|
+
constructor(prisma: Pick<PrismaLike, 'auditLog'>);
|
|
659
799
|
countSince(since: Date): Promise<number>;
|
|
660
800
|
}
|
|
661
801
|
|
|
@@ -692,42 +832,146 @@ declare class AsyncLocalRlsBypassAdapter implements RlsBypassPort {
|
|
|
692
832
|
isBypassActive(): boolean;
|
|
693
833
|
}
|
|
694
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
|
+
}
|
|
695
840
|
/**
|
|
696
841
|
* `SubscriptionRepository` against the canonical `subscriptions` +
|
|
697
842
|
* `plan_versions` tables.
|
|
698
843
|
*
|
|
699
|
-
*
|
|
700
|
-
* `
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
704
|
-
* `countByBundleVersionId` is deliberately not implemented (the
|
|
705
|
-
* `subscription_bundles` junction is not part of this adapter's slice);
|
|
706
|
-
* the platform then treats affected bundle versions as frozen (fail-closed).
|
|
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).
|
|
707
848
|
*/
|
|
708
849
|
declare class PrismaSubscriptionRepository implements SubscriptionRepository {
|
|
709
850
|
private readonly prisma;
|
|
710
|
-
|
|
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;
|
|
711
858
|
findByTenantId(tenantId: string): Promise<SubscriptionRecord | null>;
|
|
712
859
|
findByTenantIdLocked(tenantId: string, tx: TransactionContext): Promise<SubscriptionRecord | null>;
|
|
713
860
|
countByPlanVersionId(planVersionId: string): Promise<number>;
|
|
714
|
-
countActiveByPlanKey(
|
|
861
|
+
countActiveByPlanKey(projectKey: string): Promise<Record<string, number>>;
|
|
862
|
+
private countActiveBundleBindings;
|
|
715
863
|
private loadByTenantId;
|
|
716
864
|
private toRecord;
|
|
865
|
+
private planVersions;
|
|
866
|
+
private subscriptions;
|
|
867
|
+
private planKeysForProject;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
interface SubscriptionBundleClient {
|
|
871
|
+
subscriptionBundle: unknown;
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* `SubscriptionBundleRepository` against the canonical `subscription_bundles`
|
|
875
|
+
* junction (SPEC_V2 §11.1 M6 Pack 2e). Dumb persistence: domain constraints
|
|
876
|
+
* (plan compatibility, minimum-term default, cancellation-window computation)
|
|
877
|
+
* live in the platform's `SubscriptionBundlesService`; `add`/`cancel` here only
|
|
878
|
+
* write what they are handed. "Active" is `canceledAt IS NULL OR
|
|
879
|
+
* canceledEffectiveAt > asOf`, mirroring the port contract.
|
|
880
|
+
*/
|
|
881
|
+
declare class PrismaSubscriptionBundleRepository implements SubscriptionBundleRepository {
|
|
882
|
+
private readonly prisma;
|
|
883
|
+
constructor(prisma: SubscriptionBundleClient);
|
|
884
|
+
private db;
|
|
885
|
+
listBySubscription(subscriptionId: string): Promise<SubscriptionBundleRecord[]>;
|
|
886
|
+
findById(subscriptionBundleId: string): Promise<SubscriptionBundleRecord | null>;
|
|
887
|
+
listActiveBySubscription(subscriptionId: string, asOf?: Date): Promise<SubscriptionBundleRecord[]>;
|
|
888
|
+
add(data: CreateSubscriptionBundleData): Promise<SubscriptionBundleRecord>;
|
|
889
|
+
cancel(subscriptionBundleId: string, data: CancelSubscriptionBundleData): Promise<SubscriptionBundleRecord>;
|
|
890
|
+
reactivate(subscriptionBundleId: string): Promise<SubscriptionBundleRecord>;
|
|
891
|
+
countActiveByBundleVersionId(bundleVersionId: string, asOf?: Date): Promise<number>;
|
|
717
892
|
}
|
|
718
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
|
+
}
|
|
898
|
+
/**
|
|
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
|
+
*
|
|
909
|
+
* Pure persistence: trial carry-over (#17) and contract freeze (#18) are
|
|
910
|
+
* resolved in the platform `changePlan` path and handed down as plain values —
|
|
911
|
+
* this adapter only writes what it receives.
|
|
912
|
+
*
|
|
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.
|
|
918
|
+
*/
|
|
919
|
+
declare class PrismaTenantSubscriptionWriteAdapter implements TenantSubscriptionWritePort {
|
|
920
|
+
private readonly prisma;
|
|
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);
|
|
925
|
+
changePlanImmediate(tenantId: string, input: ImmediatePlanChangeInput): Promise<{
|
|
926
|
+
plan: string;
|
|
927
|
+
billingCycle: string;
|
|
928
|
+
}>;
|
|
929
|
+
private changePlanImmediateInClient;
|
|
930
|
+
schedulePlanChange(tenantId: string, input: ScheduledPlanChangeInput): Promise<void>;
|
|
931
|
+
acceptPendingPlanVersion(tenantId: string, userId: string, now: Date): Promise<{
|
|
932
|
+
accepted: boolean;
|
|
933
|
+
acceptedAt: Date | null;
|
|
934
|
+
effectiveAt: Date | null;
|
|
935
|
+
alreadyAccepted: boolean;
|
|
936
|
+
}>;
|
|
937
|
+
private applyOnboardingSelectionAtomic;
|
|
938
|
+
cancelSubscription(tenantId: string, immediate: boolean, now: Date): Promise<{
|
|
939
|
+
canceledAt: Date | null;
|
|
940
|
+
status: string;
|
|
941
|
+
}>;
|
|
942
|
+
private subscription;
|
|
943
|
+
private planVersions;
|
|
944
|
+
private findTargetPlanVersionId;
|
|
945
|
+
private pendingVersionBelongsToAnotherPlan;
|
|
946
|
+
private assertConfiguration;
|
|
947
|
+
}
|
|
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
|
+
}
|
|
719
956
|
/**
|
|
720
957
|
* `PlanVersionRepository` against the canonical `plan_versions` table.
|
|
721
958
|
*
|
|
722
|
-
* `findActive`
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
* 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.
|
|
726
962
|
*/
|
|
727
963
|
declare class PrismaPlanVersionRepository implements PlanVersionRepository {
|
|
728
964
|
private readonly prisma;
|
|
729
|
-
|
|
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;
|
|
730
971
|
findLatestLive(planId: string, tx?: TransactionContext): Promise<PlanVersionRecord | null>;
|
|
972
|
+
private findActivePlanVersion;
|
|
973
|
+
private versions;
|
|
974
|
+
private toRecord;
|
|
731
975
|
}
|
|
732
976
|
|
|
733
977
|
/**
|
|
@@ -827,33 +1071,302 @@ declare class PrismaSuperAdminBootstrapAdapter implements SuperAdminProvisioning
|
|
|
827
1071
|
createSuperAdmin(input: CreateSuperAdminCliInput): Promise<PlatformUserDto>;
|
|
828
1072
|
}
|
|
829
1073
|
|
|
1074
|
+
/** Root-client fields used directly; the PlanVersion delegate is configurable. */
|
|
1075
|
+
interface PlanCatalogReadClient {
|
|
1076
|
+
plan: unknown;
|
|
1077
|
+
featureCatalogEntry: unknown;
|
|
1078
|
+
}
|
|
830
1079
|
/**
|
|
831
1080
|
* `PlanCatalogReadSink` against the canonical `plans`, `plan_versions` and
|
|
832
1081
|
* `feature_catalog_entries` tables — DB hydration of the plan catalog at
|
|
833
1082
|
* boot (`PlanCatalogModule.forRoot({ sink })`).
|
|
834
1083
|
*
|
|
835
|
-
*
|
|
836
|
-
*
|
|
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.
|
|
837
1087
|
*/
|
|
838
1088
|
declare class PrismaPlanCatalogReadSink implements PlanCatalogReadSink {
|
|
839
1089
|
private readonly prisma;
|
|
840
|
-
|
|
1090
|
+
private readonly binding;
|
|
1091
|
+
private readonly delegateName;
|
|
1092
|
+
private readonly fields;
|
|
1093
|
+
constructor(prisma: PlanCatalogReadClient, options?: PrismaSchemaOptions);
|
|
1094
|
+
private db;
|
|
841
1095
|
loadSnapshot(projectKey: string): Promise<PlanCatalogReadSnapshot>;
|
|
1096
|
+
private planVersions;
|
|
842
1097
|
}
|
|
843
1098
|
|
|
1099
|
+
/** Root-client fields used directly; the PlanVersion delegate is configurable. */
|
|
1100
|
+
interface PlanCatalogImportClient {
|
|
1101
|
+
plan: unknown;
|
|
1102
|
+
featureCatalogEntry: unknown;
|
|
1103
|
+
}
|
|
844
1104
|
/**
|
|
845
1105
|
* `PlanCatalogImportSink` against the canonical catalog tables — the
|
|
846
1106
|
* one-shot `saas.yaml → DB` import at boot.
|
|
847
1107
|
*
|
|
848
1108
|
* Idempotency per the port contract: existing rows (identity match) are
|
|
849
|
-
* 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`.
|
|
850
1111
|
*/
|
|
851
1112
|
declare class PrismaPlanCatalogImportSink implements PlanCatalogImportSink {
|
|
852
1113
|
private readonly prisma;
|
|
853
|
-
|
|
1114
|
+
private readonly binding;
|
|
1115
|
+
private readonly delegateName;
|
|
1116
|
+
constructor(prisma: PlanCatalogImportClient, options?: PrismaSchemaOptions);
|
|
1117
|
+
private db;
|
|
854
1118
|
upsertPlan(input: UpsertPlanInput): Promise<UpsertResult>;
|
|
855
1119
|
upsertPlanVersion(input: UpsertPlanVersionInput): Promise<UpsertResult>;
|
|
1120
|
+
private planVersions;
|
|
856
1121
|
upsertFeatureCatalogEntry(input: UpsertFeatureCatalogEntryInput): Promise<UpsertResult>;
|
|
857
1122
|
}
|
|
858
1123
|
|
|
859
|
-
|
|
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
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* `PlanRepository` against the canonical `plans` + `plan_versions` tables
|
|
1131
|
+
* (SPEC_V2 §11.1 M6). Plan stem CRUD (Pack 1) and PlanVersion lifecycle
|
|
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.
|
|
1136
|
+
*
|
|
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`.
|
|
1141
|
+
*/
|
|
1142
|
+
declare class PrismaPlanRepository implements PlanRepository {
|
|
1143
|
+
private readonly prisma;
|
|
1144
|
+
private readonly binding;
|
|
1145
|
+
private readonly delegateName;
|
|
1146
|
+
private readonly fields;
|
|
1147
|
+
constructor(prisma: PlanRepositoryClient, options?: PrismaSchemaOptions);
|
|
1148
|
+
private db;
|
|
1149
|
+
private versions;
|
|
1150
|
+
list(filter: PlanListFilter): Promise<PlanRow[]>;
|
|
1151
|
+
findById(planId: string): Promise<PlanRow | null>;
|
|
1152
|
+
findByKey(projectKey: string, planKey: string): Promise<PlanRow | null>;
|
|
1153
|
+
create(data: CreatePlanData): Promise<PlanRow>;
|
|
1154
|
+
update(planId: string, data: UpdatePlanData): Promise<PlanRow>;
|
|
1155
|
+
softDelete(planId: string): Promise<void>;
|
|
1156
|
+
hardDelete(planId: string): Promise<void>;
|
|
1157
|
+
listVersions(planKey: string): Promise<PlanVersionRow[]>;
|
|
1158
|
+
findVersionById(versionId: string): Promise<PlanVersionRow | null>;
|
|
1159
|
+
findCurrentDraft(planKey: string): Promise<PlanVersionRow | null>;
|
|
1160
|
+
findLatestLivePlanVersion(planKey: string, tx?: TransactionContext): Promise<PlanVersionRow | null>;
|
|
1161
|
+
findActivePlanVersion(planKey: string, asOf?: Date, tx?: TransactionContext): Promise<PlanVersionRow | null>;
|
|
1162
|
+
createPlanVersionDraft(data: CreatePlanVersionDraftData): Promise<PlanVersionRow>;
|
|
1163
|
+
updatePlanVersionDraft(versionId: string, data: UpdatePlanVersionDraftData): Promise<PlanVersionRow>;
|
|
1164
|
+
publishPlanVersionDraft(versionId: string, publishMeta: {
|
|
1165
|
+
publishedByUserId: string | null;
|
|
1166
|
+
publishedChanges: VersionChange[];
|
|
1167
|
+
nonRegressive: boolean;
|
|
1168
|
+
validFrom: Date;
|
|
1169
|
+
validUntil: Date | null;
|
|
1170
|
+
}, tx?: TransactionContext): Promise<PlanVersionRow>;
|
|
1171
|
+
deletePlanVersionDraft(versionId: string): Promise<void>;
|
|
1172
|
+
terminate(versionId: string, endsAt: Date): Promise<PlanVersionRow>;
|
|
1173
|
+
private toPlanVersionRow;
|
|
1174
|
+
}
|
|
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
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* `BundleRepository` against the canonical `bundles` + `bundle_versions`
|
|
1204
|
+
* tables (SPEC_V2 §5 + §11.1 M3). Versioning mirrors `PlanVersion`: at most one
|
|
1205
|
+
* draft (`publishedAt IS NULL`) per bundle, monotonically incrementing
|
|
1206
|
+
* `version`, `supersededAt` marking the previous live version on publish.
|
|
1207
|
+
*
|
|
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.
|
|
1212
|
+
*
|
|
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.
|
|
1217
|
+
*/
|
|
1218
|
+
declare class PrismaBundleRepository implements BundleRepository {
|
|
1219
|
+
private readonly prisma;
|
|
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);
|
|
1228
|
+
private db;
|
|
1229
|
+
private transaction;
|
|
1230
|
+
list(filter: BundleListFilter): Promise<BundleRow[]>;
|
|
1231
|
+
findById(bundleId: string): Promise<BundleRow | null>;
|
|
1232
|
+
findByKey(projectKey: string, bundleKey: string): Promise<BundleRow | null>;
|
|
1233
|
+
create(data: CreateBundleData): Promise<BundleRow>;
|
|
1234
|
+
update(bundleId: string, data: UpdateBundleData): Promise<BundleRow>;
|
|
1235
|
+
softDelete(bundleId: string): Promise<void>;
|
|
1236
|
+
listVersions(bundleId: string): Promise<BundleVersionRow[]>;
|
|
1237
|
+
findVersionById(versionId: string): Promise<BundleVersionRow | null>;
|
|
1238
|
+
findCurrentDraft(bundleId: string): Promise<BundleVersionRow | null>;
|
|
1239
|
+
findLatestLive(bundleId: string, tx?: TransactionContext): Promise<BundleVersionRow | null>;
|
|
1240
|
+
private findActiveBundleVersionWithValidity;
|
|
1241
|
+
createDraft(data: CreateBundleVersionDraftData): Promise<BundleVersionRow>;
|
|
1242
|
+
updateDraft(versionId: string, data: UpdateBundleVersionDraftData): Promise<BundleVersionRow>;
|
|
1243
|
+
publishDraft(versionId: string, publishMeta: {
|
|
1244
|
+
publishedByUserId: string | null;
|
|
1245
|
+
publishedChanges: VersionChange[];
|
|
1246
|
+
nonRegressive: boolean;
|
|
1247
|
+
validFrom: Date;
|
|
1248
|
+
validUntil: Date | null;
|
|
1249
|
+
}, tx?: TransactionContext): Promise<BundleVersionRow>;
|
|
1250
|
+
private publishDraftWithValidity;
|
|
1251
|
+
deleteDraft(versionId: string): Promise<void>;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
interface CatalogEntryRepositoryClient {
|
|
1255
|
+
capabilityCatalogEntry: unknown;
|
|
1256
|
+
featureCatalogEntry: unknown;
|
|
1257
|
+
quotaCatalogEntry: unknown;
|
|
1258
|
+
}
|
|
1259
|
+
/**
|
|
1260
|
+
* `CatalogEntryRepository` against the canonical `capability_catalog_entries`,
|
|
1261
|
+
* `feature_catalog_entries` and `quota_catalog_entries` tables (SPEC_V2 §6.3 —
|
|
1262
|
+
* discovery review workflow).
|
|
1263
|
+
*
|
|
1264
|
+
* `upsert*` writes only the code-derived fields + the service-resolved status
|
|
1265
|
+
* and leaves `i18n`, `sortOrder`, `createdAt` and the approval fields untouched
|
|
1266
|
+
* on update (Prisma's `update` payload simply omits them). `retireMissing`
|
|
1267
|
+
* marks entries whose key vanished from the code snapshot.
|
|
1268
|
+
*/
|
|
1269
|
+
declare class PrismaCatalogEntryRepository implements CatalogEntryRepository {
|
|
1270
|
+
private readonly prisma;
|
|
1271
|
+
constructor(prisma: CatalogEntryRepositoryClient);
|
|
1272
|
+
private get db();
|
|
1273
|
+
listCapabilities(filter: CatalogEntryFilter): Promise<CapabilityCatalogEntryRow[]>;
|
|
1274
|
+
listFeatures(filter: CatalogEntryFilter): Promise<FeatureCatalogEntryRow[]>;
|
|
1275
|
+
listQuotas(filter: CatalogEntryFilter): Promise<QuotaCatalogEntryRow[]>;
|
|
1276
|
+
upsertCapability(data: UpsertCapabilityEntryData): Promise<CapabilityCatalogEntryRow>;
|
|
1277
|
+
upsertFeature(data: UpsertFeatureEntryData): Promise<FeatureCatalogEntryRow>;
|
|
1278
|
+
upsertQuota(data: UpsertQuotaEntryData): Promise<QuotaCatalogEntryRow>;
|
|
1279
|
+
retireMissing(projectKey: string, type: 'capability' | 'feature' | 'quota', presentKeys: string[]): Promise<number>;
|
|
1280
|
+
setFeatureSuccessor(projectKey: string, featureKey: string, successorKey: string | null): Promise<FeatureCatalogEntryRow>;
|
|
1281
|
+
setQuotaSuccessor(projectKey: string, quotaKey: string, successorKey: string | null): Promise<QuotaCatalogEntryRow>;
|
|
1282
|
+
findFeature(projectKey: string, featureKey: string): Promise<FeatureCatalogEntryRow | null>;
|
|
1283
|
+
findQuota(projectKey: string, quotaKey: string): Promise<QuotaCatalogEntryRow | null>;
|
|
1284
|
+
setFeatureReview(projectKey: string, featureKey: string, data: SetCatalogEntryReviewData): Promise<FeatureCatalogEntryRow>;
|
|
1285
|
+
setQuotaReview(projectKey: string, quotaKey: string, data: SetCatalogEntryReviewData): Promise<QuotaCatalogEntryRow>;
|
|
1286
|
+
setFeatureI18n(projectKey: string, featureKey: string, i18n: CatalogEntryI18n): Promise<FeatureCatalogEntryRow>;
|
|
1287
|
+
setQuotaI18n(projectKey: string, quotaKey: string, i18n: CatalogEntryI18n): Promise<QuotaCatalogEntryRow>;
|
|
1288
|
+
setFeatureBase(projectKey: string, featureKey: string, data: UpdateCatalogEntryBaseData): Promise<FeatureCatalogEntryRow>;
|
|
1289
|
+
setQuotaBase(projectKey: string, quotaKey: string, data: UpdateCatalogEntryBaseData): Promise<QuotaCatalogEntryRow>;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
interface MarketingProjectionRepositoryClient {
|
|
1293
|
+
marketingProjection: unknown;
|
|
1294
|
+
}
|
|
1295
|
+
/**
|
|
1296
|
+
* `MarketingProjectionRepository` against the canonical `marketing_projections`
|
|
1297
|
+
* table. Not versioned: per (`targetType`, `targetVersionId`, `locale`) there is
|
|
1298
|
+
* exactly one row (enforced by a unique index), edited directly. `create` on a
|
|
1299
|
+
* duplicate triple therefore raises the DB unique-constraint error.
|
|
1300
|
+
*/
|
|
1301
|
+
declare class PrismaMarketingProjectionRepository implements MarketingProjectionRepository {
|
|
1302
|
+
private readonly prisma;
|
|
1303
|
+
constructor(prisma: MarketingProjectionRepositoryClient);
|
|
1304
|
+
private get db();
|
|
1305
|
+
list(filter: MarketingProjectionFilter): Promise<MarketingProjectionRow[]>;
|
|
1306
|
+
findById(id: string): Promise<MarketingProjectionRow | null>;
|
|
1307
|
+
findByTarget(targetType: string, targetVersionId: string, locale: string): Promise<MarketingProjectionRow | null>;
|
|
1308
|
+
create(data: CreateMarketingProjectionData): Promise<MarketingProjectionRow>;
|
|
1309
|
+
update(id: string, data: UpdateMarketingProjectionData): Promise<MarketingProjectionRow>;
|
|
1310
|
+
delete(id: string): Promise<void>;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
interface MarketingSettingsRepositoryClient {
|
|
1314
|
+
marketingSettings: unknown;
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* `MarketingSettingsRepository` against the canonical `marketing_settings`
|
|
1318
|
+
* table (one row per project). A missing row means "full locale pool active",
|
|
1319
|
+
* so `get` returns null and the platform falls back to the pool.
|
|
1320
|
+
*/
|
|
1321
|
+
declare class PrismaMarketingSettingsRepository implements MarketingSettingsRepository {
|
|
1322
|
+
private readonly prisma;
|
|
1323
|
+
constructor(prisma: MarketingSettingsRepositoryClient);
|
|
1324
|
+
private get db();
|
|
1325
|
+
get(projectKey: string): Promise<MarketingSettingsRow | null>;
|
|
1326
|
+
upsert(projectKey: string, data: UpdateMarketingSettingsData): Promise<MarketingSettingsRow>;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
interface PromotionRepositoryClient {
|
|
1330
|
+
promotion: unknown;
|
|
1331
|
+
$executeRaw: unknown;
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* `PromotionRepository` against the canonical `promotions` table. Not
|
|
1335
|
+
* versioned: promotions are edited directly.
|
|
1336
|
+
*
|
|
1337
|
+
* The nullable `onlyLocales` JSON column cannot be set to null through Prisma's
|
|
1338
|
+
* query API without the `Prisma.DbNull` sentinel — which this Prisma-agnostic
|
|
1339
|
+
* package deliberately does not import. On `create` a null restriction is
|
|
1340
|
+
* therefore written by omission (the column defaults to SQL NULL); on `update`
|
|
1341
|
+
* an explicit null clear runs as a raw statement.
|
|
1342
|
+
*/
|
|
1343
|
+
declare class PrismaPromotionRepository implements PromotionRepository {
|
|
1344
|
+
private readonly prisma;
|
|
1345
|
+
constructor(prisma: PromotionRepositoryClient);
|
|
1346
|
+
private get db();
|
|
1347
|
+
list(filter: PromotionFilter): Promise<PromotionRow[]>;
|
|
1348
|
+
findById(id: string): Promise<PromotionRow | null>;
|
|
1349
|
+
create(data: CreatePromotionData): Promise<PromotionRow>;
|
|
1350
|
+
update(id: string, data: UpdatePromotionData): Promise<PromotionRow>;
|
|
1351
|
+
delete(id: string): Promise<void>;
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
/**
|
|
1355
|
+
* Append-only `SubscriptionContractRepository` against the canonical
|
|
1356
|
+
* `subscription_contracts` + `contract_line_items` tables. Contracts store full
|
|
1357
|
+
* snapshots and are never rewritten: `create` writes the contract and its line
|
|
1358
|
+
* items atomically via a single nested-create, and `terminate` only closes a
|
|
1359
|
+
* contract (sets `effectiveUntil` + `status`). There is no line-item mutation.
|
|
1360
|
+
*/
|
|
1361
|
+
declare class PrismaSubscriptionContractRepository implements SubscriptionContractRepository {
|
|
1362
|
+
private readonly prisma;
|
|
1363
|
+
constructor(prisma: PrismaLike);
|
|
1364
|
+
private get db();
|
|
1365
|
+
list(filter: SubscriptionContractFilter): Promise<SubscriptionContractRecord[]>;
|
|
1366
|
+
findById(contractId: string): Promise<SubscriptionContractRecord | null>;
|
|
1367
|
+
findActiveByTenantId(tenantId: string, asOf?: Date): Promise<SubscriptionContractRecord | null>;
|
|
1368
|
+
create(data: CreateSubscriptionContractData): Promise<SubscriptionContractRecord>;
|
|
1369
|
+
terminate(contractId: string, data: TerminateSubscriptionContractData): Promise<SubscriptionContractRecord>;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
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 };
|