@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.cjs
CHANGED
|
@@ -23,24 +23,38 @@ var index_exports = {};
|
|
|
23
23
|
__export(index_exports, {
|
|
24
24
|
AsyncLocalRlsBypassAdapter: () => AsyncLocalRlsBypassAdapter,
|
|
25
25
|
PASSWORD_HASHER_TOKEN: () => PASSWORD_HASHER_TOKEN,
|
|
26
|
+
PRISMA_BUNDLE_REPOSITORY_OPTIONS: () => PRISMA_BUNDLE_REPOSITORY_OPTIONS,
|
|
26
27
|
PRISMA_CLIENT_TOKEN: () => PRISMA_CLIENT_TOKEN,
|
|
28
|
+
PRISMA_SCHEMA_OPTIONS_TOKEN: () => PRISMA_SCHEMA_OPTIONS_TOKEN,
|
|
27
29
|
PrismaAuditAdapter: () => PrismaAuditAdapter,
|
|
28
30
|
PrismaAuditQueryAdapter: () => PrismaAuditQueryAdapter,
|
|
29
31
|
PrismaAuditStatsAdapter: () => PrismaAuditStatsAdapter,
|
|
32
|
+
PrismaBundleRepository: () => PrismaBundleRepository,
|
|
33
|
+
PrismaCatalogEntryRepository: () => PrismaCatalogEntryRepository,
|
|
34
|
+
PrismaMarketingProjectionRepository: () => PrismaMarketingProjectionRepository,
|
|
35
|
+
PrismaMarketingSettingsRepository: () => PrismaMarketingSettingsRepository,
|
|
30
36
|
PrismaMfaAdapter: () => PrismaMfaAdapter,
|
|
31
37
|
PrismaPlanCatalogImportSink: () => PrismaPlanCatalogImportSink,
|
|
32
38
|
PrismaPlanCatalogReadSink: () => PrismaPlanCatalogReadSink,
|
|
39
|
+
PrismaPlanRepository: () => PrismaPlanRepository,
|
|
33
40
|
PrismaPlanVersionRepository: () => PrismaPlanVersionRepository,
|
|
34
41
|
PrismaPromoCodeRedemptionRepository: () => PrismaPromoCodeRedemptionRepository,
|
|
35
42
|
PrismaPromoCodeRepository: () => PrismaPromoCodeRepository,
|
|
36
43
|
PrismaPromoCodeValidationLogRepository: () => PrismaPromoCodeValidationLogRepository,
|
|
37
44
|
PrismaPromoSubscriptionLookup: () => PrismaPromoSubscriptionLookup,
|
|
45
|
+
PrismaPromotionRepository: () => PrismaPromotionRepository,
|
|
46
|
+
PrismaSubscriptionBundleRepository: () => PrismaSubscriptionBundleRepository,
|
|
47
|
+
PrismaSubscriptionContractRepository: () => PrismaSubscriptionContractRepository,
|
|
38
48
|
PrismaSubscriptionRepository: () => PrismaSubscriptionRepository,
|
|
39
49
|
PrismaSuperAdminBootstrapAdapter: () => PrismaSuperAdminBootstrapAdapter,
|
|
50
|
+
PrismaTenantSubscriptionWriteAdapter: () => PrismaTenantSubscriptionWriteAdapter,
|
|
40
51
|
PrismaTransactionRunner: () => PrismaTransactionRunner,
|
|
41
52
|
ZeroPromoRevenueDeductionAggregator: () => ZeroPromoRevenueDeductionAggregator,
|
|
42
53
|
buildActorTag: () => buildActorTag,
|
|
43
|
-
|
|
54
|
+
createPrismaPlanBindingResolver: () => createPrismaPlanBindingResolver,
|
|
55
|
+
getPrismaDelegate: () => getPrismaDelegate,
|
|
56
|
+
prismaPersistence: () => prismaPersistence,
|
|
57
|
+
resolvePrismaSchemaOptions: () => resolvePrismaSchemaOptions
|
|
44
58
|
});
|
|
45
59
|
module.exports = __toCommonJS(index_exports);
|
|
46
60
|
|
|
@@ -129,7 +143,7 @@ PrismaAuditAdapter = _ts_decorate2([
|
|
|
129
143
|
_ts_param(0, (0, import_common2.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
130
144
|
_ts_metadata("design:type", Function),
|
|
131
145
|
_ts_metadata("design:paramtypes", [
|
|
132
|
-
typeof
|
|
146
|
+
typeof Pick === "undefined" ? Object : Pick
|
|
133
147
|
])
|
|
134
148
|
], PrismaAuditAdapter);
|
|
135
149
|
|
|
@@ -192,7 +206,7 @@ PrismaAuditQueryAdapter = _ts_decorate3([
|
|
|
192
206
|
_ts_param2(0, (0, import_common3.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
193
207
|
_ts_metadata2("design:type", Function),
|
|
194
208
|
_ts_metadata2("design:paramtypes", [
|
|
195
|
-
typeof
|
|
209
|
+
typeof Pick === "undefined" ? Object : Pick
|
|
196
210
|
])
|
|
197
211
|
], PrismaAuditQueryAdapter);
|
|
198
212
|
function toActorTagFilter(actorTag) {
|
|
@@ -264,7 +278,7 @@ PrismaAuditStatsAdapter = _ts_decorate4([
|
|
|
264
278
|
_ts_param3(0, (0, import_common4.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
265
279
|
_ts_metadata3("design:type", Function),
|
|
266
280
|
_ts_metadata3("design:paramtypes", [
|
|
267
|
-
typeof
|
|
281
|
+
typeof Pick === "undefined" ? Object : Pick
|
|
268
282
|
])
|
|
269
283
|
], PrismaAuditStatsAdapter);
|
|
270
284
|
|
|
@@ -334,12 +348,149 @@ PrismaMfaAdapter = _ts_decorate5([
|
|
|
334
348
|
_ts_param4(0, (0, import_common5.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
335
349
|
_ts_metadata4("design:type", Function),
|
|
336
350
|
_ts_metadata4("design:paramtypes", [
|
|
337
|
-
typeof
|
|
351
|
+
typeof Pick === "undefined" ? Object : Pick
|
|
338
352
|
])
|
|
339
353
|
], PrismaMfaAdapter);
|
|
340
354
|
|
|
341
355
|
// src/prisma-plan-catalog-import-sink.ts
|
|
342
356
|
var import_common6 = require("@nestjs/common");
|
|
357
|
+
|
|
358
|
+
// src/prisma-plan-binding.ts
|
|
359
|
+
var PRISMA_SCHEMA_OPTIONS_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/adapter-prisma/PrismaSchemaOptions");
|
|
360
|
+
var DEFAULT_SCHEMA_OPTIONS = {
|
|
361
|
+
planBinding: {
|
|
362
|
+
mode: "legacy-plan-key"
|
|
363
|
+
},
|
|
364
|
+
delegates: {
|
|
365
|
+
catalogPlanVersion: "planVersion",
|
|
366
|
+
entitlementPlanVersion: "planVersion"
|
|
367
|
+
},
|
|
368
|
+
planVersionFields: {
|
|
369
|
+
catalog: {
|
|
370
|
+
validityWindows: false,
|
|
371
|
+
endsAt: false
|
|
372
|
+
},
|
|
373
|
+
entitlement: {
|
|
374
|
+
validityWindows: false,
|
|
375
|
+
endsAt: false
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
tenantSubscription: {
|
|
379
|
+
delegate: "subscription",
|
|
380
|
+
subscriptionBundleDelegate: false,
|
|
381
|
+
synchronizePlanVersion: false,
|
|
382
|
+
atomicOnboardingSelection: false,
|
|
383
|
+
activeVersionSelection: "latest-live",
|
|
384
|
+
withEndsAt: false
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
function resolvePrismaSchemaOptions(options) {
|
|
388
|
+
const mode = options?.planBinding?.mode ?? "legacy-plan-key";
|
|
389
|
+
const projectKey = options?.planBinding?.projectKey;
|
|
390
|
+
if (mode === "normalized-plan-id" && !projectKey?.trim()) {
|
|
391
|
+
throw new Error("Prisma plan binding mode 'normalized-plan-id' requires a non-empty projectKey.");
|
|
392
|
+
}
|
|
393
|
+
const sharedFields = options?.planVersionFields;
|
|
394
|
+
const catalogFields = sharedFields?.catalog;
|
|
395
|
+
const entitlementFields = sharedFields?.entitlement;
|
|
396
|
+
return {
|
|
397
|
+
planBinding: {
|
|
398
|
+
mode,
|
|
399
|
+
...projectKey ? {
|
|
400
|
+
projectKey
|
|
401
|
+
} : {}
|
|
402
|
+
},
|
|
403
|
+
delegates: {
|
|
404
|
+
catalogPlanVersion: options?.delegates?.catalogPlanVersion ?? DEFAULT_SCHEMA_OPTIONS.delegates.catalogPlanVersion,
|
|
405
|
+
entitlementPlanVersion: options?.delegates?.entitlementPlanVersion ?? DEFAULT_SCHEMA_OPTIONS.delegates.entitlementPlanVersion
|
|
406
|
+
},
|
|
407
|
+
planVersionFields: {
|
|
408
|
+
catalog: {
|
|
409
|
+
validityWindows: catalogFields?.validityWindows ?? sharedFields?.validityWindows ?? false,
|
|
410
|
+
endsAt: catalogFields?.endsAt ?? sharedFields?.endsAt ?? false
|
|
411
|
+
},
|
|
412
|
+
entitlement: {
|
|
413
|
+
validityWindows: entitlementFields?.validityWindows ?? sharedFields?.validityWindows ?? false,
|
|
414
|
+
endsAt: entitlementFields?.endsAt ?? sharedFields?.endsAt ?? false
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
tenantSubscription: {
|
|
418
|
+
delegate: options?.tenantSubscription?.delegate ?? DEFAULT_SCHEMA_OPTIONS.tenantSubscription.delegate,
|
|
419
|
+
subscriptionBundleDelegate: options?.tenantSubscription?.subscriptionBundleDelegate ?? DEFAULT_SCHEMA_OPTIONS.tenantSubscription.subscriptionBundleDelegate,
|
|
420
|
+
synchronizePlanVersion: options?.tenantSubscription?.synchronizePlanVersion ?? DEFAULT_SCHEMA_OPTIONS.tenantSubscription.synchronizePlanVersion,
|
|
421
|
+
atomicOnboardingSelection: options?.tenantSubscription?.atomicOnboardingSelection ?? DEFAULT_SCHEMA_OPTIONS.tenantSubscription.atomicOnboardingSelection,
|
|
422
|
+
activeVersionSelection: options?.tenantSubscription?.activeVersionSelection ?? DEFAULT_SCHEMA_OPTIONS.tenantSubscription.activeVersionSelection,
|
|
423
|
+
withEndsAt: options?.tenantSubscription?.withEndsAt ?? DEFAULT_SCHEMA_OPTIONS.tenantSubscription.withEndsAt
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
__name(resolvePrismaSchemaOptions, "resolvePrismaSchemaOptions");
|
|
428
|
+
function createPrismaPlanBindingResolver(options) {
|
|
429
|
+
const resolved = resolvePrismaSchemaOptions({
|
|
430
|
+
planBinding: options
|
|
431
|
+
}).planBinding;
|
|
432
|
+
return {
|
|
433
|
+
mode: resolved.mode,
|
|
434
|
+
projectKey: resolved.projectKey,
|
|
435
|
+
async toStoragePlanId(client, planKey, projectKey) {
|
|
436
|
+
if (resolved.mode === "legacy-plan-key") return planKey;
|
|
437
|
+
const scope = resolveProjectKey(resolved.projectKey, projectKey);
|
|
438
|
+
const plan = await asPlanIdentityClient(client).plan.findFirst({
|
|
439
|
+
where: {
|
|
440
|
+
projectKey: scope,
|
|
441
|
+
planKey,
|
|
442
|
+
deletedAt: null
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
if (!plan) {
|
|
446
|
+
throw new Error(`Plan '${planKey}' not found in project '${scope}'.`);
|
|
447
|
+
}
|
|
448
|
+
return plan.id;
|
|
449
|
+
},
|
|
450
|
+
async toPlanKey(client, storedPlanId, projectKey) {
|
|
451
|
+
if (resolved.mode === "legacy-plan-key") return storedPlanId;
|
|
452
|
+
const scope = resolveProjectKey(resolved.projectKey, projectKey);
|
|
453
|
+
const plan = await asPlanIdentityClient(client).plan.findUnique({
|
|
454
|
+
where: {
|
|
455
|
+
id: storedPlanId
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
if (!plan || plan.projectKey !== scope) {
|
|
459
|
+
throw new Error(`Plan id '${storedPlanId}' not found in project '${scope}'.`);
|
|
460
|
+
}
|
|
461
|
+
return plan.planKey;
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
__name(createPrismaPlanBindingResolver, "createPrismaPlanBindingResolver");
|
|
466
|
+
function getPrismaDelegate(client, delegateName) {
|
|
467
|
+
const delegate = client?.[delegateName];
|
|
468
|
+
if (!delegate || typeof delegate !== "object") {
|
|
469
|
+
throw new Error(`Prisma client has no '${delegateName}' delegate.`);
|
|
470
|
+
}
|
|
471
|
+
return delegate;
|
|
472
|
+
}
|
|
473
|
+
__name(getPrismaDelegate, "getPrismaDelegate");
|
|
474
|
+
function resolveProjectKey(configured, requested) {
|
|
475
|
+
const projectKey = requested ?? configured;
|
|
476
|
+
if (!projectKey) {
|
|
477
|
+
throw new Error("Prisma plan binding mode 'normalized-plan-id' requires a projectKey.");
|
|
478
|
+
}
|
|
479
|
+
if (configured && requested && configured !== requested) {
|
|
480
|
+
throw new Error(`Prisma plan binding is configured for project '${configured}', not '${requested}'.`);
|
|
481
|
+
}
|
|
482
|
+
return projectKey;
|
|
483
|
+
}
|
|
484
|
+
__name(resolveProjectKey, "resolveProjectKey");
|
|
485
|
+
function asPlanIdentityClient(client) {
|
|
486
|
+
if (!client || typeof client !== "object" || !("plan" in client)) {
|
|
487
|
+
throw new Error("Prisma client has no 'plan' delegate.");
|
|
488
|
+
}
|
|
489
|
+
return client;
|
|
490
|
+
}
|
|
491
|
+
__name(asPlanIdentityClient, "asPlanIdentityClient");
|
|
492
|
+
|
|
493
|
+
// src/prisma-plan-catalog-import-sink.ts
|
|
343
494
|
function _ts_decorate6(decorators, target, key, desc) {
|
|
344
495
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
345
496
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -362,11 +513,23 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
362
513
|
__name(this, "PrismaPlanCatalogImportSink");
|
|
363
514
|
}
|
|
364
515
|
prisma;
|
|
365
|
-
|
|
516
|
+
binding;
|
|
517
|
+
delegateName;
|
|
518
|
+
constructor(prisma, options) {
|
|
366
519
|
this.prisma = prisma;
|
|
520
|
+
const schema = resolvePrismaSchemaOptions(options);
|
|
521
|
+
this.binding = createPrismaPlanBindingResolver(options?.planBinding);
|
|
522
|
+
this.delegateName = schema.delegates.catalogPlanVersion;
|
|
523
|
+
}
|
|
524
|
+
db() {
|
|
525
|
+
return this.prisma;
|
|
367
526
|
}
|
|
368
527
|
async upsertPlan(input) {
|
|
369
|
-
|
|
528
|
+
if (this.binding.mode === "normalized-plan-id" && this.binding.projectKey !== input.projectKey) {
|
|
529
|
+
throw new Error(`Prisma plan binding is configured for project '${this.binding.projectKey}', not '${input.projectKey}'.`);
|
|
530
|
+
}
|
|
531
|
+
const db = this.db();
|
|
532
|
+
const existing = await db.plan.findFirst({
|
|
370
533
|
where: {
|
|
371
534
|
projectKey: input.projectKey,
|
|
372
535
|
planKey: input.planKey
|
|
@@ -376,7 +539,7 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
376
539
|
created: false,
|
|
377
540
|
skipReason: "exists"
|
|
378
541
|
};
|
|
379
|
-
await
|
|
542
|
+
await db.plan.create({
|
|
380
543
|
data: {
|
|
381
544
|
projectKey: input.projectKey,
|
|
382
545
|
planKey: input.planKey,
|
|
@@ -390,9 +553,11 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
390
553
|
};
|
|
391
554
|
}
|
|
392
555
|
async upsertPlanVersion(input) {
|
|
393
|
-
const
|
|
556
|
+
const planVersion = this.planVersions();
|
|
557
|
+
const storedPlanId = await this.binding.toStoragePlanId(this.prisma, input.planKey);
|
|
558
|
+
const existing = await planVersion.findFirst({
|
|
394
559
|
where: {
|
|
395
|
-
planId:
|
|
560
|
+
planId: storedPlanId,
|
|
396
561
|
version: input.version
|
|
397
562
|
}
|
|
398
563
|
});
|
|
@@ -402,9 +567,9 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
402
567
|
};
|
|
403
568
|
const now = /* @__PURE__ */ new Date();
|
|
404
569
|
if (input.publish) {
|
|
405
|
-
await
|
|
570
|
+
await planVersion.updateMany({
|
|
406
571
|
where: {
|
|
407
|
-
planId:
|
|
572
|
+
planId: storedPlanId,
|
|
408
573
|
publishedAt: {
|
|
409
574
|
not: null
|
|
410
575
|
},
|
|
@@ -418,9 +583,9 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
418
583
|
}
|
|
419
584
|
});
|
|
420
585
|
}
|
|
421
|
-
await
|
|
586
|
+
await planVersion.create({
|
|
422
587
|
data: {
|
|
423
|
-
planId:
|
|
588
|
+
planId: storedPlanId,
|
|
424
589
|
version: input.version,
|
|
425
590
|
features: input.features,
|
|
426
591
|
quotas: input.quotas,
|
|
@@ -435,8 +600,12 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
435
600
|
created: true
|
|
436
601
|
};
|
|
437
602
|
}
|
|
603
|
+
planVersions() {
|
|
604
|
+
return getPrismaDelegate(this.prisma, this.delegateName);
|
|
605
|
+
}
|
|
438
606
|
async upsertFeatureCatalogEntry(input) {
|
|
439
|
-
const
|
|
607
|
+
const db = this.db();
|
|
608
|
+
const existing = await db.featureCatalogEntry.findFirst({
|
|
440
609
|
where: {
|
|
441
610
|
projectKey: input.projectKey,
|
|
442
611
|
featureKey: input.featureKey
|
|
@@ -446,7 +615,7 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
446
615
|
created: false,
|
|
447
616
|
skipReason: "exists"
|
|
448
617
|
};
|
|
449
|
-
await
|
|
618
|
+
await db.featureCatalogEntry.create({
|
|
450
619
|
data: {
|
|
451
620
|
projectKey: input.projectKey,
|
|
452
621
|
featureKey: input.featureKey,
|
|
@@ -465,9 +634,12 @@ var PrismaPlanCatalogImportSink = class {
|
|
|
465
634
|
PrismaPlanCatalogImportSink = _ts_decorate6([
|
|
466
635
|
(0, import_common6.Injectable)(),
|
|
467
636
|
_ts_param5(0, (0, import_common6.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
637
|
+
_ts_param5(1, (0, import_common6.Optional)()),
|
|
638
|
+
_ts_param5(1, (0, import_common6.Inject)(PRISMA_SCHEMA_OPTIONS_TOKEN)),
|
|
468
639
|
_ts_metadata5("design:type", Function),
|
|
469
640
|
_ts_metadata5("design:paramtypes", [
|
|
470
|
-
typeof
|
|
641
|
+
typeof PlanCatalogImportClient === "undefined" ? Object : PlanCatalogImportClient,
|
|
642
|
+
typeof PrismaSchemaOptions === "undefined" ? Object : PrismaSchemaOptions
|
|
471
643
|
])
|
|
472
644
|
], PrismaPlanCatalogImportSink);
|
|
473
645
|
|
|
@@ -514,11 +686,25 @@ var PrismaPlanCatalogReadSink = class {
|
|
|
514
686
|
__name(this, "PrismaPlanCatalogReadSink");
|
|
515
687
|
}
|
|
516
688
|
prisma;
|
|
517
|
-
|
|
689
|
+
binding;
|
|
690
|
+
delegateName;
|
|
691
|
+
fields;
|
|
692
|
+
constructor(prisma, options) {
|
|
518
693
|
this.prisma = prisma;
|
|
694
|
+
const schema = resolvePrismaSchemaOptions(options);
|
|
695
|
+
this.binding = createPrismaPlanBindingResolver(options?.planBinding);
|
|
696
|
+
this.delegateName = schema.delegates.catalogPlanVersion;
|
|
697
|
+
this.fields = schema.planVersionFields.catalog;
|
|
698
|
+
}
|
|
699
|
+
db() {
|
|
700
|
+
return this.prisma;
|
|
519
701
|
}
|
|
520
702
|
async loadSnapshot(projectKey) {
|
|
521
|
-
|
|
703
|
+
if (this.binding.mode === "normalized-plan-id" && this.binding.projectKey !== projectKey) {
|
|
704
|
+
throw new Error(`Prisma plan binding is configured for project '${this.binding.projectKey}', not '${projectKey}'.`);
|
|
705
|
+
}
|
|
706
|
+
const db = this.db();
|
|
707
|
+
const plans = await db.plan.findMany({
|
|
522
708
|
where: {
|
|
523
709
|
projectKey,
|
|
524
710
|
deletedAt: null
|
|
@@ -527,11 +713,17 @@ var PrismaPlanCatalogReadSink = class {
|
|
|
527
713
|
sortOrder: "asc"
|
|
528
714
|
}
|
|
529
715
|
});
|
|
530
|
-
const
|
|
531
|
-
|
|
716
|
+
const planKeysByStoredId = new Map(plans.map((plan) => [
|
|
717
|
+
this.binding.mode === "normalized-plan-id" ? plan.id : plan.planKey,
|
|
718
|
+
plan.planKey
|
|
719
|
+
]));
|
|
720
|
+
const storedPlanIds = [
|
|
721
|
+
...planKeysByStoredId.keys()
|
|
722
|
+
];
|
|
723
|
+
const livePlanVersions = storedPlanIds.length === 0 ? [] : await this.planVersions().findMany({
|
|
532
724
|
where: {
|
|
533
725
|
planId: {
|
|
534
|
-
in:
|
|
726
|
+
in: storedPlanIds
|
|
535
727
|
},
|
|
536
728
|
publishedAt: {
|
|
537
729
|
not: null
|
|
@@ -539,7 +731,7 @@ var PrismaPlanCatalogReadSink = class {
|
|
|
539
731
|
supersededAt: null
|
|
540
732
|
}
|
|
541
733
|
});
|
|
542
|
-
const featureEntries = await
|
|
734
|
+
const featureEntries = await db.featureCatalogEntry.findMany({
|
|
543
735
|
where: {
|
|
544
736
|
projectKey,
|
|
545
737
|
deletedAt: null
|
|
@@ -550,17 +742,29 @@ var PrismaPlanCatalogReadSink = class {
|
|
|
550
742
|
});
|
|
551
743
|
return {
|
|
552
744
|
plans: plans.map(toPlanRow),
|
|
553
|
-
livePlanVersions: livePlanVersions.map(
|
|
745
|
+
livePlanVersions: livePlanVersions.map((row) => {
|
|
746
|
+
const planKey = planKeysByStoredId.get(row.planId);
|
|
747
|
+
if (!planKey) {
|
|
748
|
+
throw new Error(`PlanVersion ${row.id} references plan '${row.planId}' outside project '${projectKey}'.`);
|
|
749
|
+
}
|
|
750
|
+
return toPlanVersionRow(row, planKey, this.fields);
|
|
751
|
+
}),
|
|
554
752
|
featureEntries: featureEntries.map(toFeatureCatalogEntryRow)
|
|
555
753
|
};
|
|
556
754
|
}
|
|
755
|
+
planVersions() {
|
|
756
|
+
return getPrismaDelegate(this.prisma, this.delegateName);
|
|
757
|
+
}
|
|
557
758
|
};
|
|
558
759
|
PrismaPlanCatalogReadSink = _ts_decorate7([
|
|
559
760
|
(0, import_common7.Injectable)(),
|
|
560
761
|
_ts_param6(0, (0, import_common7.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
762
|
+
_ts_param6(1, (0, import_common7.Optional)()),
|
|
763
|
+
_ts_param6(1, (0, import_common7.Inject)(PRISMA_SCHEMA_OPTIONS_TOKEN)),
|
|
561
764
|
_ts_metadata6("design:type", Function),
|
|
562
765
|
_ts_metadata6("design:paramtypes", [
|
|
563
|
-
typeof
|
|
766
|
+
typeof PlanCatalogReadClient === "undefined" ? Object : PlanCatalogReadClient,
|
|
767
|
+
typeof PrismaSchemaOptions === "undefined" ? Object : PrismaSchemaOptions
|
|
564
768
|
])
|
|
565
769
|
], PrismaPlanCatalogReadSink);
|
|
566
770
|
function toPlanRow(row) {
|
|
@@ -578,10 +782,10 @@ function toPlanRow(row) {
|
|
|
578
782
|
};
|
|
579
783
|
}
|
|
580
784
|
__name(toPlanRow, "toPlanRow");
|
|
581
|
-
function toPlanVersionRow(row) {
|
|
582
|
-
|
|
785
|
+
function toPlanVersionRow(row, planKey, fields) {
|
|
786
|
+
const mapped = {
|
|
583
787
|
id: row.id,
|
|
584
|
-
planId:
|
|
788
|
+
planId: planKey,
|
|
585
789
|
version: row.version,
|
|
586
790
|
baseVersionId: row.baseVersionId,
|
|
587
791
|
publishedAt: row.publishedAt ? row.publishedAt.toISOString() : null,
|
|
@@ -589,8 +793,8 @@ function toPlanVersionRow(row) {
|
|
|
589
793
|
publishedChanges: row.publishedChanges ?? null,
|
|
590
794
|
changeNote: row.changeNote,
|
|
591
795
|
nonRegressive: row.nonRegressive,
|
|
592
|
-
validFrom: null,
|
|
593
|
-
validUntil: null,
|
|
796
|
+
validFrom: fields.validityWindows && row.validFrom ? row.validFrom.toISOString() : null,
|
|
797
|
+
validUntil: fields.validityWindows && row.validUntil ? row.validUntil.toISOString() : null,
|
|
594
798
|
createdByUserId: row.createdByUserId,
|
|
595
799
|
publishedByUserId: row.publishedByUserId,
|
|
596
800
|
createdAt: row.createdAt.toISOString(),
|
|
@@ -601,6 +805,10 @@ function toPlanVersionRow(row) {
|
|
|
601
805
|
yearlyNet: String(row.yearlyNet),
|
|
602
806
|
marketed: row.marketed
|
|
603
807
|
};
|
|
808
|
+
if (fields.endsAt) {
|
|
809
|
+
mapped.endsAt = row.endsAt?.toISOString() ?? null;
|
|
810
|
+
}
|
|
811
|
+
return mapped;
|
|
604
812
|
}
|
|
605
813
|
__name(toPlanVersionRow, "toPlanVersionRow");
|
|
606
814
|
function toFeatureCatalogEntryRow(row) {
|
|
@@ -634,6 +842,7 @@ __name(toFeatureCatalogEntryRow, "toFeatureCatalogEntryRow");
|
|
|
634
842
|
|
|
635
843
|
// src/prisma-plan-version.repository.ts
|
|
636
844
|
var import_common8 = require("@nestjs/common");
|
|
845
|
+
var import_types = require("@saasicat/types");
|
|
637
846
|
function _ts_decorate8(decorators, target, key, desc) {
|
|
638
847
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
639
848
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -656,14 +865,29 @@ var PrismaPlanVersionRepository = class {
|
|
|
656
865
|
__name(this, "PrismaPlanVersionRepository");
|
|
657
866
|
}
|
|
658
867
|
prisma;
|
|
659
|
-
|
|
868
|
+
findActive;
|
|
869
|
+
binding;
|
|
870
|
+
delegateName;
|
|
871
|
+
fields;
|
|
872
|
+
constructor(prisma, options) {
|
|
660
873
|
this.prisma = prisma;
|
|
874
|
+
const schema = resolvePrismaSchemaOptions(options);
|
|
875
|
+
this.binding = createPrismaPlanBindingResolver(options?.planBinding);
|
|
876
|
+
this.delegateName = schema.delegates.entitlementPlanVersion;
|
|
877
|
+
this.fields = schema.planVersionFields.entitlement;
|
|
878
|
+
if (this.fields.validityWindows) {
|
|
879
|
+
this.findActive = (planId, asOf = /* @__PURE__ */ new Date(), tx) => this.findActivePlanVersion(planId, asOf, tx);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
db(tx) {
|
|
883
|
+
return tx ?? this.prisma;
|
|
661
884
|
}
|
|
662
885
|
async findLatestLive(planId, tx) {
|
|
663
|
-
const db =
|
|
664
|
-
const
|
|
886
|
+
const db = this.db(tx);
|
|
887
|
+
const storedPlanId = await this.binding.toStoragePlanId(db, planId);
|
|
888
|
+
const row = await this.versions(db).findFirst({
|
|
665
889
|
where: {
|
|
666
|
-
planId,
|
|
890
|
+
planId: storedPlanId,
|
|
667
891
|
publishedAt: {
|
|
668
892
|
not: null
|
|
669
893
|
},
|
|
@@ -674,8 +898,40 @@ var PrismaPlanVersionRepository = class {
|
|
|
674
898
|
}
|
|
675
899
|
});
|
|
676
900
|
if (!row) return null;
|
|
901
|
+
return this.toRecord(db, row);
|
|
902
|
+
}
|
|
903
|
+
async findActivePlanVersion(planId, asOf, tx) {
|
|
904
|
+
const db = this.db(tx);
|
|
905
|
+
const storedPlanId = await this.binding.toStoragePlanId(db, planId);
|
|
906
|
+
const activeWhere = this.fields.endsAt ? (0, import_types.buildActivePlanVersionWhere)(asOf, {
|
|
907
|
+
withEndsAt: true
|
|
908
|
+
}) : (0, import_types.buildActivePlanVersionWhere)(asOf);
|
|
909
|
+
const row = await this.versions(db).findFirst({
|
|
910
|
+
where: {
|
|
911
|
+
planId: storedPlanId,
|
|
912
|
+
...activeWhere
|
|
913
|
+
},
|
|
914
|
+
orderBy: [
|
|
915
|
+
{
|
|
916
|
+
validFrom: {
|
|
917
|
+
sort: "desc",
|
|
918
|
+
nulls: "last"
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
version: "desc"
|
|
923
|
+
}
|
|
924
|
+
]
|
|
925
|
+
});
|
|
926
|
+
if (!row) return null;
|
|
927
|
+
return this.toRecord(db, row);
|
|
928
|
+
}
|
|
929
|
+
versions(client) {
|
|
930
|
+
return getPrismaDelegate(client, this.delegateName);
|
|
931
|
+
}
|
|
932
|
+
async toRecord(client, row) {
|
|
677
933
|
return {
|
|
678
|
-
planId: row.planId,
|
|
934
|
+
planId: await this.binding.toPlanKey(client, row.planId),
|
|
679
935
|
quotas: toQuotaMap(row.quotas),
|
|
680
936
|
features: toStringArray(row.features)
|
|
681
937
|
};
|
|
@@ -684,9 +940,12 @@ var PrismaPlanVersionRepository = class {
|
|
|
684
940
|
PrismaPlanVersionRepository = _ts_decorate8([
|
|
685
941
|
(0, import_common8.Injectable)(),
|
|
686
942
|
_ts_param7(0, (0, import_common8.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
943
|
+
_ts_param7(1, (0, import_common8.Optional)()),
|
|
944
|
+
_ts_param7(1, (0, import_common8.Inject)(PRISMA_SCHEMA_OPTIONS_TOKEN)),
|
|
687
945
|
_ts_metadata7("design:type", Function),
|
|
688
946
|
_ts_metadata7("design:paramtypes", [
|
|
689
|
-
typeof
|
|
947
|
+
typeof PlanVersionRepositoryClient === "undefined" ? Object : PlanVersionRepositoryClient,
|
|
948
|
+
typeof PrismaSchemaOptions === "undefined" ? Object : PrismaSchemaOptions
|
|
690
949
|
])
|
|
691
950
|
], PrismaPlanVersionRepository);
|
|
692
951
|
|
|
@@ -1154,19 +1413,35 @@ var PrismaSubscriptionRepository = class {
|
|
|
1154
1413
|
__name(this, "PrismaSubscriptionRepository");
|
|
1155
1414
|
}
|
|
1156
1415
|
prisma;
|
|
1157
|
-
|
|
1416
|
+
countByBundleVersionId;
|
|
1417
|
+
binding;
|
|
1418
|
+
planVersionDelegateName;
|
|
1419
|
+
subscriptionDelegateName;
|
|
1420
|
+
subscriptionBundleDelegateName;
|
|
1421
|
+
constructor(prisma, options) {
|
|
1158
1422
|
this.prisma = prisma;
|
|
1423
|
+
const schema = resolvePrismaSchemaOptions(options);
|
|
1424
|
+
this.binding = createPrismaPlanBindingResolver(options?.planBinding);
|
|
1425
|
+
this.planVersionDelegateName = schema.delegates.entitlementPlanVersion;
|
|
1426
|
+
this.subscriptionDelegateName = schema.tenantSubscription.delegate;
|
|
1427
|
+
this.subscriptionBundleDelegateName = schema.tenantSubscription.subscriptionBundleDelegate;
|
|
1428
|
+
if (this.subscriptionBundleDelegateName) {
|
|
1429
|
+
this.countByBundleVersionId = (bundleVersionId) => this.countActiveBundleBindings(bundleVersionId);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
db(tx) {
|
|
1433
|
+
return tx ?? this.prisma;
|
|
1159
1434
|
}
|
|
1160
1435
|
async findByTenantId(tenantId) {
|
|
1161
|
-
return this.loadByTenantId(this.
|
|
1436
|
+
return this.loadByTenantId(this.db(), tenantId);
|
|
1162
1437
|
}
|
|
1163
1438
|
async findByTenantIdLocked(tenantId, tx) {
|
|
1164
|
-
const db =
|
|
1439
|
+
const db = this.db(tx);
|
|
1165
1440
|
await db.$queryRaw`SELECT id FROM subscriptions WHERE "tenantId" = ${tenantId} FOR UPDATE`;
|
|
1166
1441
|
return this.loadByTenantId(db, tenantId);
|
|
1167
1442
|
}
|
|
1168
1443
|
async countByPlanVersionId(planVersionId) {
|
|
1169
|
-
return this.
|
|
1444
|
+
return this.subscriptions(this.db()).count({
|
|
1170
1445
|
where: {
|
|
1171
1446
|
OR: [
|
|
1172
1447
|
{
|
|
@@ -1179,22 +1454,72 @@ var PrismaSubscriptionRepository = class {
|
|
|
1179
1454
|
}
|
|
1180
1455
|
});
|
|
1181
1456
|
}
|
|
1182
|
-
async countActiveByPlanKey(
|
|
1183
|
-
const
|
|
1457
|
+
async countActiveByPlanKey(projectKey) {
|
|
1458
|
+
const db = this.db();
|
|
1459
|
+
const subscriptions = await this.subscriptions(db).findMany({
|
|
1184
1460
|
where: {
|
|
1185
1461
|
status: {
|
|
1186
1462
|
in: ACTIVE_STATUSES
|
|
1187
1463
|
}
|
|
1464
|
+
},
|
|
1465
|
+
select: {
|
|
1466
|
+
planVersionId: true
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
const versionIds = [
|
|
1470
|
+
...new Set(subscriptions.map((subscription) => subscription.planVersionId))
|
|
1471
|
+
];
|
|
1472
|
+
if (versionIds.length === 0) return {};
|
|
1473
|
+
const planVersions = await this.planVersions(db).findMany({
|
|
1474
|
+
where: {
|
|
1475
|
+
id: {
|
|
1476
|
+
in: versionIds
|
|
1477
|
+
}
|
|
1478
|
+
},
|
|
1479
|
+
select: {
|
|
1480
|
+
id: true,
|
|
1481
|
+
planId: true
|
|
1188
1482
|
}
|
|
1189
1483
|
});
|
|
1484
|
+
const planVersionById = new Map(planVersions.map((planVersion) => [
|
|
1485
|
+
planVersion.id,
|
|
1486
|
+
planVersion
|
|
1487
|
+
]));
|
|
1488
|
+
const storedPlanIds = [
|
|
1489
|
+
...new Set(planVersions.map((planVersion) => planVersion.planId))
|
|
1490
|
+
];
|
|
1491
|
+
const planKeyByStoredId = await this.planKeysForProject(db, storedPlanIds, projectKey);
|
|
1190
1492
|
const counts = {};
|
|
1191
|
-
for (const
|
|
1192
|
-
|
|
1493
|
+
for (const subscription of subscriptions) {
|
|
1494
|
+
const planVersion = planVersionById.get(subscription.planVersionId);
|
|
1495
|
+
const planKey = planVersion ? planKeyByStoredId.get(planVersion.planId) : void 0;
|
|
1496
|
+
if (!planKey) continue;
|
|
1497
|
+
counts[planKey] = (counts[planKey] ?? 0) + 1;
|
|
1193
1498
|
}
|
|
1194
1499
|
return counts;
|
|
1195
1500
|
}
|
|
1501
|
+
async countActiveBundleBindings(bundleVersionId) {
|
|
1502
|
+
if (!this.subscriptionBundleDelegateName) {
|
|
1503
|
+
throw new Error("SubscriptionBundle counting is not configured.");
|
|
1504
|
+
}
|
|
1505
|
+
return getPrismaDelegate(this.prisma, this.subscriptionBundleDelegateName).count({
|
|
1506
|
+
where: {
|
|
1507
|
+
bundleVersionId,
|
|
1508
|
+
OR: [
|
|
1509
|
+
{
|
|
1510
|
+
canceledAt: null
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
canceledEffectiveAt: {
|
|
1514
|
+
gt: /* @__PURE__ */ new Date()
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
]
|
|
1518
|
+
}
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1196
1521
|
async loadByTenantId(db, tenantId) {
|
|
1197
|
-
const row = await db.
|
|
1522
|
+
const row = await this.subscriptions(db).findUnique({
|
|
1198
1523
|
where: {
|
|
1199
1524
|
tenantId
|
|
1200
1525
|
}
|
|
@@ -1203,10 +1528,7 @@ var PrismaSubscriptionRepository = class {
|
|
|
1203
1528
|
return this.toRecord(db, row);
|
|
1204
1529
|
}
|
|
1205
1530
|
async toRecord(db, row) {
|
|
1206
|
-
|
|
1207
|
-
throw new Error(`Subscription ${row.id} binds no planVersionId (businessType-only composition). The shipped @saasicat/adapter-prisma SubscriptionRepository does not support BusinessType aggregation \u2014 provide a custom SubscriptionRepository adapter.`);
|
|
1208
|
-
}
|
|
1209
|
-
const planVersion = await db.planVersion.findUnique({
|
|
1531
|
+
const planVersion = await this.planVersions(db).findUnique({
|
|
1210
1532
|
where: {
|
|
1211
1533
|
id: row.planVersionId
|
|
1212
1534
|
}
|
|
@@ -1214,10 +1536,13 @@ var PrismaSubscriptionRepository = class {
|
|
|
1214
1536
|
if (!planVersion) {
|
|
1215
1537
|
throw new Error(`Subscription ${row.id} references missing PlanVersion ${row.planVersionId}.`);
|
|
1216
1538
|
}
|
|
1539
|
+
const planKey = await this.binding.toPlanKey(db, planVersion.planId);
|
|
1217
1540
|
return {
|
|
1218
1541
|
id: row.id,
|
|
1219
1542
|
tenantId: row.tenantId,
|
|
1220
|
-
|
|
1543
|
+
// The concrete PlanVersion is authoritative. This also normalizes
|
|
1544
|
+
// legacy rows whose denormalized `Subscription.plan` drifted.
|
|
1545
|
+
plan: planKey,
|
|
1221
1546
|
status: row.status,
|
|
1222
1547
|
isPilot: row.isPilot,
|
|
1223
1548
|
trialEntitlementPlan: row.trialEntitlementPlan,
|
|
@@ -1226,25 +1551,84 @@ var PrismaSubscriptionRepository = class {
|
|
|
1226
1551
|
customLimits: row.customLimits ?? null,
|
|
1227
1552
|
planVersionId: row.planVersionId,
|
|
1228
1553
|
planVersion: {
|
|
1229
|
-
planId:
|
|
1554
|
+
planId: planKey,
|
|
1230
1555
|
quotas: toQuotaMap(planVersion.quotas),
|
|
1231
1556
|
features: toStringArray(planVersion.features)
|
|
1232
1557
|
}
|
|
1233
1558
|
};
|
|
1234
1559
|
}
|
|
1560
|
+
planVersions(client) {
|
|
1561
|
+
return getPrismaDelegate(client, this.planVersionDelegateName);
|
|
1562
|
+
}
|
|
1563
|
+
subscriptions(client) {
|
|
1564
|
+
return getPrismaDelegate(client, this.subscriptionDelegateName);
|
|
1565
|
+
}
|
|
1566
|
+
async planKeysForProject(db, storedPlanIds, projectKey) {
|
|
1567
|
+
if (storedPlanIds.length === 0) return /* @__PURE__ */ new Map();
|
|
1568
|
+
if (this.binding.mode === "normalized-plan-id") {
|
|
1569
|
+
if (this.binding.projectKey && this.binding.projectKey !== projectKey) {
|
|
1570
|
+
throw new Error(`Prisma plan binding is configured for project '${this.binding.projectKey}', not '${projectKey}'.`);
|
|
1571
|
+
}
|
|
1572
|
+
const plans2 = await db.plan.findMany({
|
|
1573
|
+
where: {
|
|
1574
|
+
projectKey,
|
|
1575
|
+
id: {
|
|
1576
|
+
in: storedPlanIds
|
|
1577
|
+
}
|
|
1578
|
+
},
|
|
1579
|
+
select: {
|
|
1580
|
+
id: true,
|
|
1581
|
+
planKey: true
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1584
|
+
return new Map(plans2.map((plan) => [
|
|
1585
|
+
plan.id,
|
|
1586
|
+
plan.planKey
|
|
1587
|
+
]));
|
|
1588
|
+
}
|
|
1589
|
+
const plans = await db.plan.findMany({
|
|
1590
|
+
where: {
|
|
1591
|
+
planKey: {
|
|
1592
|
+
in: storedPlanIds
|
|
1593
|
+
}
|
|
1594
|
+
},
|
|
1595
|
+
select: {
|
|
1596
|
+
projectKey: true,
|
|
1597
|
+
planKey: true
|
|
1598
|
+
}
|
|
1599
|
+
});
|
|
1600
|
+
const projectsByPlanKey = /* @__PURE__ */ new Map();
|
|
1601
|
+
for (const plan of plans) {
|
|
1602
|
+
const projects = projectsByPlanKey.get(plan.planKey) ?? /* @__PURE__ */ new Set();
|
|
1603
|
+
projects.add(plan.projectKey);
|
|
1604
|
+
projectsByPlanKey.set(plan.planKey, projects);
|
|
1605
|
+
}
|
|
1606
|
+
return new Map(storedPlanIds.flatMap((planKey) => {
|
|
1607
|
+
const projects = projectsByPlanKey.get(planKey);
|
|
1608
|
+
return projects?.size === 1 && projects.has(projectKey) ? [
|
|
1609
|
+
[
|
|
1610
|
+
planKey,
|
|
1611
|
+
planKey
|
|
1612
|
+
]
|
|
1613
|
+
] : [];
|
|
1614
|
+
}));
|
|
1615
|
+
}
|
|
1235
1616
|
};
|
|
1236
1617
|
PrismaSubscriptionRepository = _ts_decorate13([
|
|
1237
1618
|
(0, import_common13.Injectable)(),
|
|
1238
1619
|
_ts_param12(0, (0, import_common13.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
1620
|
+
_ts_param12(1, (0, import_common13.Optional)()),
|
|
1621
|
+
_ts_param12(1, (0, import_common13.Inject)(PRISMA_SCHEMA_OPTIONS_TOKEN)),
|
|
1239
1622
|
_ts_metadata12("design:type", Function),
|
|
1240
1623
|
_ts_metadata12("design:paramtypes", [
|
|
1241
|
-
typeof
|
|
1624
|
+
typeof SubscriptionRepositoryClient === "undefined" ? Object : SubscriptionRepositoryClient,
|
|
1625
|
+
typeof PrismaSchemaOptions === "undefined" ? Object : PrismaSchemaOptions
|
|
1242
1626
|
])
|
|
1243
1627
|
], PrismaSubscriptionRepository);
|
|
1244
1628
|
|
|
1245
1629
|
// src/prisma-super-admin-bootstrap.adapter.ts
|
|
1246
1630
|
var import_common14 = require("@nestjs/common");
|
|
1247
|
-
var
|
|
1631
|
+
var import_types2 = require("@saasicat/types");
|
|
1248
1632
|
function _ts_decorate14(decorators, target, key, desc) {
|
|
1249
1633
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1250
1634
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1289,7 +1673,7 @@ var PrismaSuperAdminBootstrapAdapter = class {
|
|
|
1289
1673
|
}
|
|
1290
1674
|
});
|
|
1291
1675
|
if (existing) {
|
|
1292
|
-
throw new
|
|
1676
|
+
throw new import_types2.PlatformUserExistsError(email, existing.platformRole);
|
|
1293
1677
|
}
|
|
1294
1678
|
const row = await this.prisma.superAdminUser.create({
|
|
1295
1679
|
data: {
|
|
@@ -1350,7 +1734,8 @@ var PrismaTransactionRunner = class {
|
|
|
1350
1734
|
this.prisma = prisma;
|
|
1351
1735
|
}
|
|
1352
1736
|
async run(fn) {
|
|
1353
|
-
|
|
1737
|
+
const transaction = this.prisma.$transaction.bind(this.prisma);
|
|
1738
|
+
return transaction((tx) => fn(tx));
|
|
1354
1739
|
}
|
|
1355
1740
|
};
|
|
1356
1741
|
PrismaTransactionRunner = _ts_decorate15([
|
|
@@ -1358,7 +1743,7 @@ PrismaTransactionRunner = _ts_decorate15([
|
|
|
1358
1743
|
_ts_param14(0, (0, import_common15.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
1359
1744
|
_ts_metadata14("design:type", Function),
|
|
1360
1745
|
_ts_metadata14("design:paramtypes", [
|
|
1361
|
-
typeof
|
|
1746
|
+
typeof Record === "undefined" ? Object : Record
|
|
1362
1747
|
])
|
|
1363
1748
|
], PrismaTransactionRunner);
|
|
1364
1749
|
|
|
@@ -1409,8 +1794,8 @@ function prismaPersistence(options) {
|
|
|
1409
1794
|
superAdminProvisioning: buildProvisioning(client, options.passwordHasher)
|
|
1410
1795
|
},
|
|
1411
1796
|
entitlement: {
|
|
1412
|
-
subscriptionRepository: provide((prisma) => new PrismaSubscriptionRepository(prisma)),
|
|
1413
|
-
planVersionRepository: provide((prisma) => new PrismaPlanVersionRepository(prisma))
|
|
1797
|
+
subscriptionRepository: provide((prisma) => new PrismaSubscriptionRepository(prisma, options.schema)),
|
|
1798
|
+
planVersionRepository: provide((prisma) => new PrismaPlanVersionRepository(prisma, options.schema))
|
|
1414
1799
|
},
|
|
1415
1800
|
promo: {
|
|
1416
1801
|
promoCodeRepository: provide((prisma) => new PrismaPromoCodeRepository(prisma)),
|
|
@@ -1419,8 +1804,8 @@ function prismaPersistence(options) {
|
|
|
1419
1804
|
subscriptionLookup: provide((prisma) => new PrismaPromoSubscriptionLookup(prisma)),
|
|
1420
1805
|
revenueAggregator: new ZeroPromoRevenueDeductionAggregator()
|
|
1421
1806
|
},
|
|
1422
|
-
planCatalogReadSink: provide((prisma) => new PrismaPlanCatalogReadSink(prisma)),
|
|
1423
|
-
planCatalogImportSink: provide((prisma) => new PrismaPlanCatalogImportSink(prisma))
|
|
1807
|
+
planCatalogReadSink: provide((prisma) => new PrismaPlanCatalogReadSink(prisma, options.schema)),
|
|
1808
|
+
planCatalogImportSink: provide((prisma) => new PrismaPlanCatalogImportSink(prisma, options.schema))
|
|
1424
1809
|
};
|
|
1425
1810
|
}
|
|
1426
1811
|
__name(prismaPersistence, "prismaPersistence");
|
|
@@ -1460,26 +1845,2747 @@ function buildProvisioning(client, hasher) {
|
|
|
1460
1845
|
return new PrismaSuperAdminBootstrapAdapter(client, hasher);
|
|
1461
1846
|
}
|
|
1462
1847
|
__name(buildProvisioning, "buildProvisioning");
|
|
1848
|
+
|
|
1849
|
+
// src/prisma-subscription-bundle.repository.ts
|
|
1850
|
+
var import_common17 = require("@nestjs/common");
|
|
1851
|
+
function _ts_decorate17(decorators, target, key, desc) {
|
|
1852
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1853
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1854
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1855
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1856
|
+
}
|
|
1857
|
+
__name(_ts_decorate17, "_ts_decorate");
|
|
1858
|
+
function _ts_metadata15(k, v) {
|
|
1859
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1860
|
+
}
|
|
1861
|
+
__name(_ts_metadata15, "_ts_metadata");
|
|
1862
|
+
function _ts_param15(paramIndex, decorator) {
|
|
1863
|
+
return function(target, key) {
|
|
1864
|
+
decorator(target, key, paramIndex);
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
__name(_ts_param15, "_ts_param");
|
|
1868
|
+
var PrismaSubscriptionBundleRepository = class {
|
|
1869
|
+
static {
|
|
1870
|
+
__name(this, "PrismaSubscriptionBundleRepository");
|
|
1871
|
+
}
|
|
1872
|
+
prisma;
|
|
1873
|
+
constructor(prisma) {
|
|
1874
|
+
this.prisma = prisma;
|
|
1875
|
+
}
|
|
1876
|
+
db(tx) {
|
|
1877
|
+
return tx ?? this.prisma;
|
|
1878
|
+
}
|
|
1879
|
+
async listBySubscription(subscriptionId) {
|
|
1880
|
+
const rows = await this.db().subscriptionBundle.findMany({
|
|
1881
|
+
where: {
|
|
1882
|
+
subscriptionId
|
|
1883
|
+
},
|
|
1884
|
+
orderBy: {
|
|
1885
|
+
startedAt: "desc"
|
|
1886
|
+
}
|
|
1887
|
+
});
|
|
1888
|
+
return rows.map(toRecord3);
|
|
1889
|
+
}
|
|
1890
|
+
async findById(subscriptionBundleId) {
|
|
1891
|
+
const row = await this.db().subscriptionBundle.findUnique({
|
|
1892
|
+
where: {
|
|
1893
|
+
id: subscriptionBundleId
|
|
1894
|
+
}
|
|
1895
|
+
});
|
|
1896
|
+
return row ? toRecord3(row) : null;
|
|
1897
|
+
}
|
|
1898
|
+
async listActiveBySubscription(subscriptionId, asOf = /* @__PURE__ */ new Date()) {
|
|
1899
|
+
const rows = await this.db().subscriptionBundle.findMany({
|
|
1900
|
+
where: {
|
|
1901
|
+
subscriptionId,
|
|
1902
|
+
OR: [
|
|
1903
|
+
{
|
|
1904
|
+
canceledAt: null
|
|
1905
|
+
},
|
|
1906
|
+
{
|
|
1907
|
+
canceledEffectiveAt: {
|
|
1908
|
+
gt: asOf
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
]
|
|
1912
|
+
},
|
|
1913
|
+
orderBy: {
|
|
1914
|
+
startedAt: "desc"
|
|
1915
|
+
}
|
|
1916
|
+
});
|
|
1917
|
+
return rows.map(toRecord3);
|
|
1918
|
+
}
|
|
1919
|
+
async add(data) {
|
|
1920
|
+
const row = await this.db().subscriptionBundle.create({
|
|
1921
|
+
data: {
|
|
1922
|
+
subscriptionId: data.subscriptionId,
|
|
1923
|
+
bundleVersionId: data.bundleVersionId,
|
|
1924
|
+
startedAt: data.startedAt,
|
|
1925
|
+
minimumTermEndsAt: data.minimumTermEndsAt ?? null
|
|
1926
|
+
}
|
|
1927
|
+
});
|
|
1928
|
+
return toRecord3(row);
|
|
1929
|
+
}
|
|
1930
|
+
async cancel(subscriptionBundleId, data) {
|
|
1931
|
+
const row = await this.db().subscriptionBundle.update({
|
|
1932
|
+
where: {
|
|
1933
|
+
id: subscriptionBundleId
|
|
1934
|
+
},
|
|
1935
|
+
data: {
|
|
1936
|
+
canceledAt: data.canceledAt,
|
|
1937
|
+
canceledEffectiveAt: data.canceledEffectiveAt
|
|
1938
|
+
}
|
|
1939
|
+
});
|
|
1940
|
+
return toRecord3(row);
|
|
1941
|
+
}
|
|
1942
|
+
async reactivate(subscriptionBundleId) {
|
|
1943
|
+
const row = await this.db().subscriptionBundle.update({
|
|
1944
|
+
where: {
|
|
1945
|
+
id: subscriptionBundleId
|
|
1946
|
+
},
|
|
1947
|
+
data: {
|
|
1948
|
+
canceledAt: null,
|
|
1949
|
+
canceledEffectiveAt: null
|
|
1950
|
+
}
|
|
1951
|
+
});
|
|
1952
|
+
return toRecord3(row);
|
|
1953
|
+
}
|
|
1954
|
+
async countActiveByBundleVersionId(bundleVersionId, asOf = /* @__PURE__ */ new Date()) {
|
|
1955
|
+
return this.db().subscriptionBundle.count({
|
|
1956
|
+
where: {
|
|
1957
|
+
bundleVersionId,
|
|
1958
|
+
OR: [
|
|
1959
|
+
{
|
|
1960
|
+
canceledAt: null
|
|
1961
|
+
},
|
|
1962
|
+
{
|
|
1963
|
+
canceledEffectiveAt: {
|
|
1964
|
+
gt: asOf
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
]
|
|
1968
|
+
}
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
};
|
|
1972
|
+
PrismaSubscriptionBundleRepository = _ts_decorate17([
|
|
1973
|
+
(0, import_common17.Injectable)(),
|
|
1974
|
+
_ts_param15(0, (0, import_common17.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
1975
|
+
_ts_metadata15("design:type", Function),
|
|
1976
|
+
_ts_metadata15("design:paramtypes", [
|
|
1977
|
+
typeof SubscriptionBundleClient === "undefined" ? Object : SubscriptionBundleClient
|
|
1978
|
+
])
|
|
1979
|
+
], PrismaSubscriptionBundleRepository);
|
|
1980
|
+
function toRecord3(row) {
|
|
1981
|
+
return {
|
|
1982
|
+
id: row.id,
|
|
1983
|
+
subscriptionId: row.subscriptionId,
|
|
1984
|
+
bundleVersionId: row.bundleVersionId,
|
|
1985
|
+
startedAt: row.startedAt,
|
|
1986
|
+
minimumTermEndsAt: row.minimumTermEndsAt,
|
|
1987
|
+
canceledAt: row.canceledAt,
|
|
1988
|
+
canceledEffectiveAt: row.canceledEffectiveAt,
|
|
1989
|
+
createdAt: row.createdAt,
|
|
1990
|
+
updatedAt: row.updatedAt
|
|
1991
|
+
};
|
|
1992
|
+
}
|
|
1993
|
+
__name(toRecord3, "toRecord");
|
|
1994
|
+
|
|
1995
|
+
// src/prisma-tenant-subscription-write.adapter.ts
|
|
1996
|
+
var import_common18 = require("@nestjs/common");
|
|
1997
|
+
var import_types3 = require("@saasicat/types");
|
|
1998
|
+
function _ts_decorate18(decorators, target, key, desc) {
|
|
1999
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2000
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2001
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2002
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2003
|
+
}
|
|
2004
|
+
__name(_ts_decorate18, "_ts_decorate");
|
|
2005
|
+
function _ts_metadata16(k, v) {
|
|
2006
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2007
|
+
}
|
|
2008
|
+
__name(_ts_metadata16, "_ts_metadata");
|
|
2009
|
+
function _ts_param16(paramIndex, decorator) {
|
|
2010
|
+
return function(target, key) {
|
|
2011
|
+
decorator(target, key, paramIndex);
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
2014
|
+
__name(_ts_param16, "_ts_param");
|
|
2015
|
+
var PrismaTenantSubscriptionWriteAdapter = class {
|
|
2016
|
+
static {
|
|
2017
|
+
__name(this, "PrismaTenantSubscriptionWriteAdapter");
|
|
2018
|
+
}
|
|
2019
|
+
prisma;
|
|
2020
|
+
applyOnboardingSelection;
|
|
2021
|
+
schema;
|
|
2022
|
+
planBinding;
|
|
2023
|
+
constructor(prisma, options) {
|
|
2024
|
+
this.prisma = prisma;
|
|
2025
|
+
this.schema = resolvePrismaSchemaOptions(options);
|
|
2026
|
+
this.planBinding = createPrismaPlanBindingResolver(options?.planBinding);
|
|
2027
|
+
this.assertConfiguration();
|
|
2028
|
+
if (this.schema.tenantSubscription.atomicOnboardingSelection) {
|
|
2029
|
+
this.applyOnboardingSelection = (tenantId, input, redeemPromo) => this.applyOnboardingSelectionAtomic(tenantId, input, redeemPromo);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
async changePlanImmediate(tenantId, input) {
|
|
2033
|
+
if (this.schema.tenantSubscription.synchronizePlanVersion) {
|
|
2034
|
+
return this.prisma.$transaction((tx) => this.changePlanImmediateInClient(tx, tenantId, input));
|
|
2035
|
+
}
|
|
2036
|
+
return this.changePlanImmediateInClient(this.prisma, tenantId, input);
|
|
2037
|
+
}
|
|
2038
|
+
async changePlanImmediateInClient(client, tenantId, input) {
|
|
2039
|
+
const subscription = this.subscription(client);
|
|
2040
|
+
const data = {
|
|
2041
|
+
plan: input.planId,
|
|
2042
|
+
billingCycle: input.cycle,
|
|
2043
|
+
pendingPlan: null,
|
|
2044
|
+
pendingBillingCycle: null,
|
|
2045
|
+
pendingEffectiveAt: null,
|
|
2046
|
+
...input.nextStatus ? {
|
|
2047
|
+
status: input.nextStatus
|
|
2048
|
+
} : {},
|
|
2049
|
+
...input.periodStart && input.periodEnd ? {
|
|
2050
|
+
currentPeriodStart: input.periodStart,
|
|
2051
|
+
currentPeriodEnd: input.periodEnd
|
|
2052
|
+
} : {},
|
|
2053
|
+
// #17: the platform changePlan path computes the carried-over
|
|
2054
|
+
// trial end and passes it through; null/undefined leaves the
|
|
2055
|
+
// existing trialEndsAt untouched.
|
|
2056
|
+
...input.trialEndsAt ? {
|
|
2057
|
+
trialEndsAt: input.trialEndsAt
|
|
2058
|
+
} : {}
|
|
2059
|
+
};
|
|
2060
|
+
if (this.schema.tenantSubscription.synchronizePlanVersion) {
|
|
2061
|
+
const current = await subscription.findUnique({
|
|
2062
|
+
where: {
|
|
2063
|
+
tenantId
|
|
2064
|
+
}
|
|
2065
|
+
});
|
|
2066
|
+
if (!current) {
|
|
2067
|
+
throw new Error(`No subscription for tenant ${tenantId}.`);
|
|
2068
|
+
}
|
|
2069
|
+
const storagePlanId = await this.planBinding.toStoragePlanId(client, input.planId);
|
|
2070
|
+
data.planVersionId = await this.findTargetPlanVersionId(client, storagePlanId, input.periodStart ?? /* @__PURE__ */ new Date());
|
|
2071
|
+
if (await this.pendingVersionBelongsToAnotherPlan(client, current.pendingPlanVersionId, storagePlanId)) {
|
|
2072
|
+
Object.assign(data, clearedPendingVersionData());
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
const updated = await subscription.update({
|
|
2076
|
+
where: {
|
|
2077
|
+
tenantId
|
|
2078
|
+
},
|
|
2079
|
+
data
|
|
2080
|
+
});
|
|
2081
|
+
return {
|
|
2082
|
+
plan: updated.plan,
|
|
2083
|
+
billingCycle: updated.billingCycle
|
|
2084
|
+
};
|
|
2085
|
+
}
|
|
2086
|
+
async schedulePlanChange(tenantId, input) {
|
|
2087
|
+
await this.subscription(this.prisma).update({
|
|
2088
|
+
where: {
|
|
2089
|
+
tenantId
|
|
2090
|
+
},
|
|
2091
|
+
data: {
|
|
2092
|
+
pendingPlan: input.pendingPlan,
|
|
2093
|
+
pendingBillingCycle: input.pendingBillingCycle,
|
|
2094
|
+
pendingEffectiveAt: input.pendingEffectiveAt
|
|
2095
|
+
}
|
|
2096
|
+
});
|
|
2097
|
+
}
|
|
2098
|
+
async acceptPendingPlanVersion(tenantId, userId, now) {
|
|
2099
|
+
const subscription = this.subscription(this.prisma);
|
|
2100
|
+
const sub = await subscription.findUnique({
|
|
2101
|
+
where: {
|
|
2102
|
+
tenantId
|
|
2103
|
+
}
|
|
2104
|
+
});
|
|
2105
|
+
if (!sub) {
|
|
2106
|
+
throw new Error(`No subscription for tenant ${tenantId}.`);
|
|
2107
|
+
}
|
|
2108
|
+
if (!sub.pendingPlanVersionId) {
|
|
2109
|
+
throw new Error(`No pending PlanVersion for tenant ${tenantId}.`);
|
|
2110
|
+
}
|
|
2111
|
+
const pendingPlanVersionId = sub.pendingPlanVersionId;
|
|
2112
|
+
const claimed = await subscription.updateMany({
|
|
2113
|
+
where: {
|
|
2114
|
+
id: sub.id,
|
|
2115
|
+
pendingPlanVersionId,
|
|
2116
|
+
pendingPlanVersionAccepted: false
|
|
2117
|
+
},
|
|
2118
|
+
data: {
|
|
2119
|
+
pendingPlanVersionAccepted: true,
|
|
2120
|
+
pendingPlanVersionAcceptedAt: now,
|
|
2121
|
+
pendingPlanVersionAcceptedByUserId: userId
|
|
2122
|
+
}
|
|
2123
|
+
});
|
|
2124
|
+
const updated = await subscription.findUnique({
|
|
2125
|
+
where: {
|
|
2126
|
+
id: sub.id
|
|
2127
|
+
}
|
|
2128
|
+
});
|
|
2129
|
+
if (!updated) {
|
|
2130
|
+
throw new Error(`No subscription for tenant ${tenantId}.`);
|
|
2131
|
+
}
|
|
2132
|
+
if (claimed.count === 0 && (updated.pendingPlanVersionId !== pendingPlanVersionId || !updated.pendingPlanVersionAccepted)) {
|
|
2133
|
+
throw new Error(`Pending PlanVersion changed while accepting it for tenant ${tenantId}.`);
|
|
2134
|
+
}
|
|
2135
|
+
return {
|
|
2136
|
+
accepted: true,
|
|
2137
|
+
acceptedAt: updated.pendingPlanVersionAcceptedAt,
|
|
2138
|
+
effectiveAt: updated.pendingPlanVersionEffectiveAt,
|
|
2139
|
+
alreadyAccepted: claimed.count === 0
|
|
2140
|
+
};
|
|
2141
|
+
}
|
|
2142
|
+
async applyOnboardingSelectionAtomic(tenantId, input, redeemPromo) {
|
|
2143
|
+
return this.prisma.$transaction(async (tx) => {
|
|
2144
|
+
const data = {
|
|
2145
|
+
plan: input.planId,
|
|
2146
|
+
billingCycle: input.cycle,
|
|
2147
|
+
pendingPlan: null,
|
|
2148
|
+
pendingBillingCycle: null,
|
|
2149
|
+
pendingEffectiveAt: null,
|
|
2150
|
+
...clearedPendingVersionData(),
|
|
2151
|
+
...input.nextStatus ? {
|
|
2152
|
+
status: input.nextStatus
|
|
2153
|
+
} : {},
|
|
2154
|
+
...input.periodStart && input.periodEnd ? {
|
|
2155
|
+
currentPeriodStart: input.periodStart,
|
|
2156
|
+
currentPeriodEnd: input.periodEnd
|
|
2157
|
+
} : {}
|
|
2158
|
+
};
|
|
2159
|
+
if (this.schema.tenantSubscription.synchronizePlanVersion) {
|
|
2160
|
+
const storagePlanId = await this.planBinding.toStoragePlanId(tx, input.planId);
|
|
2161
|
+
data.planVersionId = await this.findTargetPlanVersionId(tx, storagePlanId, input.periodStart ?? /* @__PURE__ */ new Date());
|
|
2162
|
+
}
|
|
2163
|
+
const updated = await this.subscription(tx).update({
|
|
2164
|
+
where: {
|
|
2165
|
+
tenantId
|
|
2166
|
+
},
|
|
2167
|
+
data
|
|
2168
|
+
});
|
|
2169
|
+
let promoRedemption = null;
|
|
2170
|
+
if (redeemPromo) {
|
|
2171
|
+
promoRedemption = await redeemPromo(tx, updated.id);
|
|
2172
|
+
}
|
|
2173
|
+
return {
|
|
2174
|
+
plan: updated.plan,
|
|
2175
|
+
billingCycle: updated.billingCycle,
|
|
2176
|
+
subscriptionId: updated.id,
|
|
2177
|
+
promoRedemption
|
|
2178
|
+
};
|
|
2179
|
+
});
|
|
2180
|
+
}
|
|
2181
|
+
async cancelSubscription(tenantId, immediate, now) {
|
|
2182
|
+
const subscription = this.subscription(this.prisma);
|
|
2183
|
+
const sub = await subscription.findUnique({
|
|
2184
|
+
where: {
|
|
2185
|
+
tenantId
|
|
2186
|
+
}
|
|
2187
|
+
});
|
|
2188
|
+
if (!sub) {
|
|
2189
|
+
throw new Error(`No subscription for tenant ${tenantId}.`);
|
|
2190
|
+
}
|
|
2191
|
+
const canceledAt = immediate ? now : sub.currentPeriodEnd ?? now;
|
|
2192
|
+
const updated = await subscription.update({
|
|
2193
|
+
where: {
|
|
2194
|
+
tenantId
|
|
2195
|
+
},
|
|
2196
|
+
data: {
|
|
2197
|
+
canceledAt,
|
|
2198
|
+
status: immediate ? "CANCELED" : sub.status
|
|
2199
|
+
}
|
|
2200
|
+
});
|
|
2201
|
+
return {
|
|
2202
|
+
canceledAt: updated.canceledAt,
|
|
2203
|
+
status: updated.status
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
subscription(client) {
|
|
2207
|
+
return getPrismaDelegate(client, this.schema.tenantSubscription.delegate);
|
|
2208
|
+
}
|
|
2209
|
+
planVersions(client) {
|
|
2210
|
+
return getPrismaDelegate(client, this.schema.delegates.entitlementPlanVersion);
|
|
2211
|
+
}
|
|
2212
|
+
async findTargetPlanVersionId(client, storagePlanId, asOf) {
|
|
2213
|
+
const activeWindow = this.schema.tenantSubscription.activeVersionSelection === "validity-window";
|
|
2214
|
+
const activeVersionWhere = this.schema.tenantSubscription.withEndsAt ? (0, import_types3.buildActivePlanVersionWhere)(asOf, {
|
|
2215
|
+
withEndsAt: true
|
|
2216
|
+
}) : (0, import_types3.buildActivePlanVersionWhere)(asOf);
|
|
2217
|
+
const where = activeWindow ? {
|
|
2218
|
+
planId: storagePlanId,
|
|
2219
|
+
...activeVersionWhere
|
|
2220
|
+
} : {
|
|
2221
|
+
planId: storagePlanId,
|
|
2222
|
+
publishedAt: {
|
|
2223
|
+
not: null
|
|
2224
|
+
},
|
|
2225
|
+
supersededAt: null,
|
|
2226
|
+
...this.schema.tenantSubscription.withEndsAt ? {
|
|
2227
|
+
OR: [
|
|
2228
|
+
{
|
|
2229
|
+
endsAt: null
|
|
2230
|
+
},
|
|
2231
|
+
{
|
|
2232
|
+
endsAt: {
|
|
2233
|
+
gt: asOf
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
]
|
|
2237
|
+
} : {}
|
|
2238
|
+
};
|
|
2239
|
+
const target = await this.planVersions(client).findFirst({
|
|
2240
|
+
where,
|
|
2241
|
+
orderBy: activeWindow ? [
|
|
2242
|
+
{
|
|
2243
|
+
validFrom: {
|
|
2244
|
+
sort: "desc",
|
|
2245
|
+
nulls: "last"
|
|
2246
|
+
}
|
|
2247
|
+
},
|
|
2248
|
+
{
|
|
2249
|
+
version: "desc"
|
|
2250
|
+
}
|
|
2251
|
+
] : {
|
|
2252
|
+
version: "desc"
|
|
2253
|
+
}
|
|
2254
|
+
});
|
|
2255
|
+
if (!target) {
|
|
2256
|
+
throw new Error(`No active PlanVersion for plan '${storagePlanId}'.`);
|
|
2257
|
+
}
|
|
2258
|
+
return target.id;
|
|
2259
|
+
}
|
|
2260
|
+
async pendingVersionBelongsToAnotherPlan(client, pendingPlanVersionId, targetStoragePlanId) {
|
|
2261
|
+
if (!pendingPlanVersionId) return false;
|
|
2262
|
+
const pending = await this.planVersions(client).findUnique({
|
|
2263
|
+
where: {
|
|
2264
|
+
id: pendingPlanVersionId
|
|
2265
|
+
}
|
|
2266
|
+
});
|
|
2267
|
+
return !pending || pending.planId !== targetStoragePlanId;
|
|
2268
|
+
}
|
|
2269
|
+
assertConfiguration() {
|
|
2270
|
+
if (!this.schema.tenantSubscription.synchronizePlanVersion) return;
|
|
2271
|
+
const entitlementFields = this.schema.planVersionFields.entitlement;
|
|
2272
|
+
if (this.schema.tenantSubscription.activeVersionSelection === "validity-window" && !entitlementFields.validityWindows) {
|
|
2273
|
+
throw new Error("tenantSubscription.activeVersionSelection='validity-window' requires planVersionFields.entitlement.validityWindows=true.");
|
|
2274
|
+
}
|
|
2275
|
+
if (this.schema.tenantSubscription.withEndsAt && !entitlementFields.endsAt) {
|
|
2276
|
+
throw new Error("tenantSubscription.withEndsAt=true requires planVersionFields.entitlement.endsAt=true.");
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
};
|
|
2280
|
+
PrismaTenantSubscriptionWriteAdapter = _ts_decorate18([
|
|
2281
|
+
(0, import_common18.Injectable)(),
|
|
2282
|
+
_ts_param16(0, (0, import_common18.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
2283
|
+
_ts_param16(1, (0, import_common18.Optional)()),
|
|
2284
|
+
_ts_param16(1, (0, import_common18.Inject)(PRISMA_SCHEMA_OPTIONS_TOKEN)),
|
|
2285
|
+
_ts_metadata16("design:type", Function),
|
|
2286
|
+
_ts_metadata16("design:paramtypes", [
|
|
2287
|
+
typeof TransactionalPrismaClient === "undefined" ? Object : TransactionalPrismaClient,
|
|
2288
|
+
typeof PrismaSchemaOptions === "undefined" ? Object : PrismaSchemaOptions
|
|
2289
|
+
])
|
|
2290
|
+
], PrismaTenantSubscriptionWriteAdapter);
|
|
2291
|
+
function clearedPendingVersionData() {
|
|
2292
|
+
return {
|
|
2293
|
+
pendingPlanVersionId: null,
|
|
2294
|
+
pendingPlanVersionEffectiveAt: null,
|
|
2295
|
+
pendingPlanVersionAccepted: false,
|
|
2296
|
+
pendingPlanVersionAcceptedAt: null,
|
|
2297
|
+
pendingPlanVersionAcceptedByUserId: null,
|
|
2298
|
+
pendingPlanVersionNotifiedAt: null,
|
|
2299
|
+
pendingPlanVersionReminderSentAt: null
|
|
2300
|
+
};
|
|
2301
|
+
}
|
|
2302
|
+
__name(clearedPendingVersionData, "clearedPendingVersionData");
|
|
2303
|
+
|
|
2304
|
+
// src/prisma-plan.repository.ts
|
|
2305
|
+
var import_common19 = require("@nestjs/common");
|
|
2306
|
+
var import_types4 = require("@saasicat/types");
|
|
2307
|
+
function _ts_decorate19(decorators, target, key, desc) {
|
|
2308
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2309
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2310
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2311
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2312
|
+
}
|
|
2313
|
+
__name(_ts_decorate19, "_ts_decorate");
|
|
2314
|
+
function _ts_metadata17(k, v) {
|
|
2315
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2316
|
+
}
|
|
2317
|
+
__name(_ts_metadata17, "_ts_metadata");
|
|
2318
|
+
function _ts_param17(paramIndex, decorator) {
|
|
2319
|
+
return function(target, key) {
|
|
2320
|
+
decorator(target, key, paramIndex);
|
|
2321
|
+
};
|
|
2322
|
+
}
|
|
2323
|
+
__name(_ts_param17, "_ts_param");
|
|
2324
|
+
var PrismaPlanRepository = class {
|
|
2325
|
+
static {
|
|
2326
|
+
__name(this, "PrismaPlanRepository");
|
|
2327
|
+
}
|
|
2328
|
+
prisma;
|
|
2329
|
+
binding;
|
|
2330
|
+
delegateName;
|
|
2331
|
+
fields;
|
|
2332
|
+
constructor(prisma, options) {
|
|
2333
|
+
this.prisma = prisma;
|
|
2334
|
+
const schema = resolvePrismaSchemaOptions(options);
|
|
2335
|
+
this.binding = createPrismaPlanBindingResolver(options?.planBinding);
|
|
2336
|
+
this.delegateName = schema.delegates.catalogPlanVersion;
|
|
2337
|
+
this.fields = schema.planVersionFields.catalog;
|
|
2338
|
+
}
|
|
2339
|
+
db(tx) {
|
|
2340
|
+
return tx ?? this.prisma;
|
|
2341
|
+
}
|
|
2342
|
+
versions(client) {
|
|
2343
|
+
return getPrismaDelegate(client, this.delegateName);
|
|
2344
|
+
}
|
|
2345
|
+
// ─── Stem operations (Pack 1) ───
|
|
2346
|
+
async list(filter) {
|
|
2347
|
+
const excludeDeleted = filter.excludeDeleted ?? true;
|
|
2348
|
+
const db = this.db();
|
|
2349
|
+
let publishedKeys = null;
|
|
2350
|
+
if (filter.onlyPublished) {
|
|
2351
|
+
if (this.binding.mode === "legacy-plan-key") {
|
|
2352
|
+
const projectPlans = await db.plan.findMany({
|
|
2353
|
+
where: {
|
|
2354
|
+
projectKey: filter.projectKey,
|
|
2355
|
+
...excludeDeleted ? {
|
|
2356
|
+
deletedAt: null
|
|
2357
|
+
} : {}
|
|
2358
|
+
}
|
|
2359
|
+
});
|
|
2360
|
+
const candidateKeys = [
|
|
2361
|
+
...new Set(projectPlans.map((plan) => plan.planKey))
|
|
2362
|
+
];
|
|
2363
|
+
const allMatchingPlans = candidateKeys.length === 0 ? [] : await db.plan.findMany({
|
|
2364
|
+
where: {
|
|
2365
|
+
planKey: {
|
|
2366
|
+
in: candidateKeys
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
});
|
|
2370
|
+
const projectsByKey = /* @__PURE__ */ new Map();
|
|
2371
|
+
for (const plan of allMatchingPlans) {
|
|
2372
|
+
const projects = projectsByKey.get(plan.planKey) ?? /* @__PURE__ */ new Set();
|
|
2373
|
+
projects.add(plan.projectKey);
|
|
2374
|
+
projectsByKey.set(plan.planKey, projects);
|
|
2375
|
+
}
|
|
2376
|
+
const unambiguousKeys = candidateKeys.filter((planKey) => projectsByKey.get(planKey)?.size === 1);
|
|
2377
|
+
const live = await this.versions(db).findMany({
|
|
2378
|
+
where: {
|
|
2379
|
+
planId: {
|
|
2380
|
+
in: unambiguousKeys
|
|
2381
|
+
},
|
|
2382
|
+
publishedAt: {
|
|
2383
|
+
not: null
|
|
2384
|
+
},
|
|
2385
|
+
supersededAt: null
|
|
2386
|
+
}
|
|
2387
|
+
});
|
|
2388
|
+
publishedKeys = [
|
|
2389
|
+
...new Set(live.map((version) => version.planId))
|
|
2390
|
+
];
|
|
2391
|
+
} else {
|
|
2392
|
+
const projectPlans = await db.plan.findMany({
|
|
2393
|
+
where: {
|
|
2394
|
+
projectKey: filter.projectKey,
|
|
2395
|
+
...excludeDeleted ? {
|
|
2396
|
+
deletedAt: null
|
|
2397
|
+
} : {}
|
|
2398
|
+
}
|
|
2399
|
+
});
|
|
2400
|
+
const planKeyById = new Map(projectPlans.map((plan) => [
|
|
2401
|
+
plan.id,
|
|
2402
|
+
plan.planKey
|
|
2403
|
+
]));
|
|
2404
|
+
const live = await this.versions(db).findMany({
|
|
2405
|
+
where: {
|
|
2406
|
+
planId: {
|
|
2407
|
+
in: [
|
|
2408
|
+
...planKeyById.keys()
|
|
2409
|
+
]
|
|
2410
|
+
},
|
|
2411
|
+
publishedAt: {
|
|
2412
|
+
not: null
|
|
2413
|
+
},
|
|
2414
|
+
supersededAt: null
|
|
2415
|
+
}
|
|
2416
|
+
});
|
|
2417
|
+
publishedKeys = [
|
|
2418
|
+
...new Set(live.flatMap((version) => {
|
|
2419
|
+
const planKey = planKeyById.get(version.planId);
|
|
2420
|
+
return planKey ? [
|
|
2421
|
+
planKey
|
|
2422
|
+
] : [];
|
|
2423
|
+
}))
|
|
2424
|
+
];
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
const rows = await db.plan.findMany({
|
|
2428
|
+
where: {
|
|
2429
|
+
projectKey: filter.projectKey,
|
|
2430
|
+
...excludeDeleted ? {
|
|
2431
|
+
deletedAt: null
|
|
2432
|
+
} : {},
|
|
2433
|
+
...publishedKeys ? {
|
|
2434
|
+
planKey: {
|
|
2435
|
+
in: publishedKeys
|
|
2436
|
+
}
|
|
2437
|
+
} : {}
|
|
2438
|
+
},
|
|
2439
|
+
orderBy: [
|
|
2440
|
+
{
|
|
2441
|
+
sortOrder: "asc"
|
|
2442
|
+
},
|
|
2443
|
+
{
|
|
2444
|
+
planKey: "asc"
|
|
2445
|
+
}
|
|
2446
|
+
]
|
|
2447
|
+
});
|
|
2448
|
+
return rows.map(toPlanRow2);
|
|
2449
|
+
}
|
|
2450
|
+
async findById(planId) {
|
|
2451
|
+
const row = await this.db().plan.findUnique({
|
|
2452
|
+
where: {
|
|
2453
|
+
id: planId
|
|
2454
|
+
}
|
|
2455
|
+
});
|
|
2456
|
+
return row ? toPlanRow2(row) : null;
|
|
2457
|
+
}
|
|
2458
|
+
async findByKey(projectKey, planKey) {
|
|
2459
|
+
const row = await this.db().plan.findFirst({
|
|
2460
|
+
where: {
|
|
2461
|
+
projectKey,
|
|
2462
|
+
planKey,
|
|
2463
|
+
deletedAt: null
|
|
2464
|
+
}
|
|
2465
|
+
});
|
|
2466
|
+
return row ? toPlanRow2(row) : null;
|
|
2467
|
+
}
|
|
2468
|
+
async create(data) {
|
|
2469
|
+
const created = await this.db().plan.create({
|
|
2470
|
+
data: {
|
|
2471
|
+
projectKey: data.projectKey,
|
|
2472
|
+
planKey: data.planKey,
|
|
2473
|
+
label: data.label,
|
|
2474
|
+
description: data.description ?? null,
|
|
2475
|
+
icon: data.icon ?? null,
|
|
2476
|
+
sortOrder: data.sortOrder ?? 0
|
|
2477
|
+
}
|
|
2478
|
+
});
|
|
2479
|
+
return toPlanRow2(created);
|
|
2480
|
+
}
|
|
2481
|
+
async update(planId, data) {
|
|
2482
|
+
const updated = await this.db().plan.update({
|
|
2483
|
+
where: {
|
|
2484
|
+
id: planId
|
|
2485
|
+
},
|
|
2486
|
+
data: {
|
|
2487
|
+
...data.label !== void 0 ? {
|
|
2488
|
+
label: data.label
|
|
2489
|
+
} : {},
|
|
2490
|
+
...data.description !== void 0 ? {
|
|
2491
|
+
description: data.description
|
|
2492
|
+
} : {},
|
|
2493
|
+
...data.icon !== void 0 ? {
|
|
2494
|
+
icon: data.icon
|
|
2495
|
+
} : {},
|
|
2496
|
+
...data.sortOrder !== void 0 ? {
|
|
2497
|
+
sortOrder: data.sortOrder
|
|
2498
|
+
} : {}
|
|
2499
|
+
}
|
|
2500
|
+
});
|
|
2501
|
+
return toPlanRow2(updated);
|
|
2502
|
+
}
|
|
2503
|
+
async softDelete(planId) {
|
|
2504
|
+
await this.db().plan.update({
|
|
2505
|
+
where: {
|
|
2506
|
+
id: planId
|
|
2507
|
+
},
|
|
2508
|
+
data: {
|
|
2509
|
+
deletedAt: /* @__PURE__ */ new Date()
|
|
2510
|
+
}
|
|
2511
|
+
});
|
|
2512
|
+
}
|
|
2513
|
+
async hardDelete(planId) {
|
|
2514
|
+
await this.db().plan.deleteMany({
|
|
2515
|
+
where: {
|
|
2516
|
+
id: planId
|
|
2517
|
+
}
|
|
2518
|
+
});
|
|
2519
|
+
}
|
|
2520
|
+
// ─── Lifecycle operations (Pack 2a) — keyed by planKey ───
|
|
2521
|
+
async listVersions(planKey) {
|
|
2522
|
+
const db = this.db();
|
|
2523
|
+
const storedPlanId = await this.binding.toStoragePlanId(db, planKey);
|
|
2524
|
+
const rows = await this.versions(db).findMany({
|
|
2525
|
+
where: {
|
|
2526
|
+
planId: storedPlanId
|
|
2527
|
+
},
|
|
2528
|
+
orderBy: {
|
|
2529
|
+
version: "asc"
|
|
2530
|
+
}
|
|
2531
|
+
});
|
|
2532
|
+
return rows.map((row) => this.toPlanVersionRow(row, planKey));
|
|
2533
|
+
}
|
|
2534
|
+
async findVersionById(versionId) {
|
|
2535
|
+
const db = this.db();
|
|
2536
|
+
const row = await this.versions(db).findUnique({
|
|
2537
|
+
where: {
|
|
2538
|
+
id: versionId
|
|
2539
|
+
}
|
|
2540
|
+
});
|
|
2541
|
+
return row ? this.toPlanVersionRow(row, await this.binding.toPlanKey(db, row.planId)) : null;
|
|
2542
|
+
}
|
|
2543
|
+
async findCurrentDraft(planKey) {
|
|
2544
|
+
const db = this.db();
|
|
2545
|
+
const storedPlanId = await this.binding.toStoragePlanId(db, planKey);
|
|
2546
|
+
const row = await this.versions(db).findFirst({
|
|
2547
|
+
where: {
|
|
2548
|
+
planId: storedPlanId,
|
|
2549
|
+
publishedAt: null
|
|
2550
|
+
}
|
|
2551
|
+
});
|
|
2552
|
+
return row ? this.toPlanVersionRow(row, planKey) : null;
|
|
2553
|
+
}
|
|
2554
|
+
async findLatestLivePlanVersion(planKey, tx) {
|
|
2555
|
+
const db = this.db(tx);
|
|
2556
|
+
const storedPlanId = await this.binding.toStoragePlanId(db, planKey);
|
|
2557
|
+
const row = await this.versions(db).findFirst({
|
|
2558
|
+
where: {
|
|
2559
|
+
planId: storedPlanId,
|
|
2560
|
+
publishedAt: {
|
|
2561
|
+
not: null
|
|
2562
|
+
},
|
|
2563
|
+
supersededAt: null,
|
|
2564
|
+
...this.fields.endsAt ? {
|
|
2565
|
+
OR: [
|
|
2566
|
+
{
|
|
2567
|
+
endsAt: null
|
|
2568
|
+
},
|
|
2569
|
+
{
|
|
2570
|
+
endsAt: {
|
|
2571
|
+
gt: /* @__PURE__ */ new Date()
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
]
|
|
2575
|
+
} : {}
|
|
2576
|
+
},
|
|
2577
|
+
orderBy: {
|
|
2578
|
+
version: "desc"
|
|
2579
|
+
}
|
|
2580
|
+
});
|
|
2581
|
+
return row ? this.toPlanVersionRow(row, planKey) : null;
|
|
2582
|
+
}
|
|
2583
|
+
async findActivePlanVersion(planKey, asOf = /* @__PURE__ */ new Date(), tx) {
|
|
2584
|
+
if (!this.fields.validityWindows) {
|
|
2585
|
+
throw new Error("findActivePlanVersion requires schema.planVersionFields.catalog.validityWindows=true and the current @saasicat/spec PlanVersion validity columns. Apply the additive schema first, or use findLatestLivePlanVersion for a 0.6-compatible newest-live lookup.");
|
|
2586
|
+
}
|
|
2587
|
+
const db = this.db(tx);
|
|
2588
|
+
const storedPlanId = await this.binding.toStoragePlanId(db, planKey);
|
|
2589
|
+
const activeWhere = this.fields.endsAt ? (0, import_types4.buildActivePlanVersionWhere)(asOf, {
|
|
2590
|
+
withEndsAt: true
|
|
2591
|
+
}) : (0, import_types4.buildActivePlanVersionWhere)(asOf);
|
|
2592
|
+
const row = await this.versions(db).findFirst({
|
|
2593
|
+
where: {
|
|
2594
|
+
planId: storedPlanId,
|
|
2595
|
+
...activeWhere
|
|
2596
|
+
},
|
|
2597
|
+
orderBy: [
|
|
2598
|
+
{
|
|
2599
|
+
validFrom: {
|
|
2600
|
+
sort: "desc",
|
|
2601
|
+
nulls: "last"
|
|
2602
|
+
}
|
|
2603
|
+
},
|
|
2604
|
+
{
|
|
2605
|
+
version: "desc"
|
|
2606
|
+
}
|
|
2607
|
+
]
|
|
2608
|
+
});
|
|
2609
|
+
return row ? this.toPlanVersionRow(row, planKey) : null;
|
|
2610
|
+
}
|
|
2611
|
+
async createPlanVersionDraft(data) {
|
|
2612
|
+
const planKey = data.planId;
|
|
2613
|
+
const db = this.db();
|
|
2614
|
+
const planVersion = this.versions(db);
|
|
2615
|
+
const storedPlanId = await this.binding.toStoragePlanId(db, planKey);
|
|
2616
|
+
const latest = await planVersion.findFirst({
|
|
2617
|
+
where: {
|
|
2618
|
+
planId: storedPlanId
|
|
2619
|
+
},
|
|
2620
|
+
orderBy: {
|
|
2621
|
+
version: "desc"
|
|
2622
|
+
}
|
|
2623
|
+
});
|
|
2624
|
+
const nextVersion = (latest?.version ?? 0) + 1;
|
|
2625
|
+
const created = await planVersion.create({
|
|
2626
|
+
data: {
|
|
2627
|
+
planId: storedPlanId,
|
|
2628
|
+
version: nextVersion,
|
|
2629
|
+
baseVersionId: data.baseVersionId ?? null,
|
|
2630
|
+
features: data.features,
|
|
2631
|
+
quotas: data.quotas,
|
|
2632
|
+
monthlyNet: data.monthlyNet,
|
|
2633
|
+
yearlyNet: data.yearlyNet,
|
|
2634
|
+
marketed: data.marketed ?? true,
|
|
2635
|
+
changeNote: data.changeNote ?? "",
|
|
2636
|
+
createdByUserId: data.createdByUserId ?? null,
|
|
2637
|
+
...this.fields.validityWindows ? {
|
|
2638
|
+
validFrom: data.validFrom ? new Date(data.validFrom) : null,
|
|
2639
|
+
validUntil: data.validUntil ? new Date(data.validUntil) : null
|
|
2640
|
+
} : {}
|
|
2641
|
+
}
|
|
2642
|
+
});
|
|
2643
|
+
return this.toPlanVersionRow(created, planKey);
|
|
2644
|
+
}
|
|
2645
|
+
async updatePlanVersionDraft(versionId, data) {
|
|
2646
|
+
const updated = await this.versions(this.db()).update({
|
|
2647
|
+
where: {
|
|
2648
|
+
id: versionId
|
|
2649
|
+
},
|
|
2650
|
+
data: {
|
|
2651
|
+
...data.features !== void 0 ? {
|
|
2652
|
+
features: data.features
|
|
2653
|
+
} : {},
|
|
2654
|
+
...data.quotas !== void 0 ? {
|
|
2655
|
+
quotas: data.quotas
|
|
2656
|
+
} : {},
|
|
2657
|
+
...data.monthlyNet !== void 0 ? {
|
|
2658
|
+
monthlyNet: data.monthlyNet
|
|
2659
|
+
} : {},
|
|
2660
|
+
...data.yearlyNet !== void 0 ? {
|
|
2661
|
+
yearlyNet: data.yearlyNet
|
|
2662
|
+
} : {},
|
|
2663
|
+
...data.marketed !== void 0 ? {
|
|
2664
|
+
marketed: data.marketed
|
|
2665
|
+
} : {},
|
|
2666
|
+
...data.changeNote !== void 0 ? {
|
|
2667
|
+
changeNote: data.changeNote
|
|
2668
|
+
} : {},
|
|
2669
|
+
...this.fields.validityWindows && data.validFrom !== void 0 ? {
|
|
2670
|
+
validFrom: data.validFrom ? new Date(data.validFrom) : null
|
|
2671
|
+
} : {},
|
|
2672
|
+
...this.fields.validityWindows && data.validUntil !== void 0 ? {
|
|
2673
|
+
validUntil: data.validUntil ? new Date(data.validUntil) : null
|
|
2674
|
+
} : {}
|
|
2675
|
+
}
|
|
2676
|
+
});
|
|
2677
|
+
const planKey = await this.binding.toPlanKey(this.db(), updated.planId);
|
|
2678
|
+
return this.toPlanVersionRow(updated, planKey);
|
|
2679
|
+
}
|
|
2680
|
+
async publishPlanVersionDraft(versionId, publishMeta, tx) {
|
|
2681
|
+
const operationDb = this.db(tx);
|
|
2682
|
+
const draft = await this.versions(operationDb).findUnique({
|
|
2683
|
+
where: {
|
|
2684
|
+
id: versionId
|
|
2685
|
+
}
|
|
2686
|
+
});
|
|
2687
|
+
if (!draft) {
|
|
2688
|
+
throw new Error(`PlanVersion ${versionId} not found.`);
|
|
2689
|
+
}
|
|
2690
|
+
const storedPlanId = draft.planId;
|
|
2691
|
+
const publish = /* @__PURE__ */ __name(async (db) => {
|
|
2692
|
+
const planVersion = this.versions(db);
|
|
2693
|
+
const previous = await planVersion.findFirst({
|
|
2694
|
+
where: {
|
|
2695
|
+
planId: storedPlanId,
|
|
2696
|
+
publishedAt: {
|
|
2697
|
+
not: null
|
|
2698
|
+
},
|
|
2699
|
+
supersededAt: null,
|
|
2700
|
+
id: {
|
|
2701
|
+
not: versionId
|
|
2702
|
+
}
|
|
2703
|
+
},
|
|
2704
|
+
orderBy: {
|
|
2705
|
+
version: "desc"
|
|
2706
|
+
}
|
|
2707
|
+
});
|
|
2708
|
+
const now = /* @__PURE__ */ new Date();
|
|
2709
|
+
if (previous) {
|
|
2710
|
+
const predecessorValidUntil = new Date(publishMeta.validFrom.getTime() - 24 * 60 * 60 * 1e3);
|
|
2711
|
+
await planVersion.update({
|
|
2712
|
+
where: {
|
|
2713
|
+
id: previous.id
|
|
2714
|
+
},
|
|
2715
|
+
data: {
|
|
2716
|
+
supersededAt: now,
|
|
2717
|
+
...this.fields.validityWindows ? {
|
|
2718
|
+
validUntil: predecessorValidUntil
|
|
2719
|
+
} : {}
|
|
2720
|
+
}
|
|
2721
|
+
});
|
|
2722
|
+
}
|
|
2723
|
+
return planVersion.update({
|
|
2724
|
+
where: {
|
|
2725
|
+
id: versionId
|
|
2726
|
+
},
|
|
2727
|
+
data: {
|
|
2728
|
+
publishedAt: now,
|
|
2729
|
+
publishedChanges: publishMeta.publishedChanges,
|
|
2730
|
+
nonRegressive: publishMeta.nonRegressive,
|
|
2731
|
+
publishedByUserId: publishMeta.publishedByUserId,
|
|
2732
|
+
...this.fields.validityWindows ? {
|
|
2733
|
+
validFrom: publishMeta.validFrom,
|
|
2734
|
+
validUntil: publishMeta.validUntil
|
|
2735
|
+
} : {}
|
|
2736
|
+
}
|
|
2737
|
+
});
|
|
2738
|
+
}, "publish");
|
|
2739
|
+
const published = tx ? await publish(this.db(tx)) : await this.prisma.$transaction((txClient) => publish(txClient));
|
|
2740
|
+
const planKey = await this.binding.toPlanKey(operationDb, storedPlanId);
|
|
2741
|
+
return this.toPlanVersionRow(published, planKey);
|
|
2742
|
+
}
|
|
2743
|
+
async deletePlanVersionDraft(versionId) {
|
|
2744
|
+
const planVersion = this.versions(this.db());
|
|
2745
|
+
const row = await planVersion.findUnique({
|
|
2746
|
+
where: {
|
|
2747
|
+
id: versionId
|
|
2748
|
+
}
|
|
2749
|
+
});
|
|
2750
|
+
if (!row) return;
|
|
2751
|
+
if (row.publishedAt !== null) {
|
|
2752
|
+
throw new Error(`PlanVersion ${versionId} is already published and cannot be discarded (published versions are immutable \u2014 contract protection P1).`);
|
|
2753
|
+
}
|
|
2754
|
+
await planVersion.deleteMany({
|
|
2755
|
+
where: {
|
|
2756
|
+
id: versionId,
|
|
2757
|
+
publishedAt: null
|
|
2758
|
+
}
|
|
2759
|
+
});
|
|
2760
|
+
}
|
|
2761
|
+
async terminate(versionId, endsAt) {
|
|
2762
|
+
if (!this.fields.endsAt) {
|
|
2763
|
+
throw new Error("terminate requires schema.planVersionFields.catalog.endsAt=true and the current @saasicat/spec PlanVersion.endsAt column. Apply the additive schema before enabling SuperAdmin-initiated plan-version termination.");
|
|
2764
|
+
}
|
|
2765
|
+
const db = this.db();
|
|
2766
|
+
const updated = await this.versions(db).update({
|
|
2767
|
+
where: {
|
|
2768
|
+
id: versionId
|
|
2769
|
+
},
|
|
2770
|
+
data: {
|
|
2771
|
+
endsAt
|
|
2772
|
+
}
|
|
2773
|
+
});
|
|
2774
|
+
const planKey = await this.binding.toPlanKey(db, updated.planId);
|
|
2775
|
+
return this.toPlanVersionRow(updated, planKey);
|
|
2776
|
+
}
|
|
2777
|
+
toPlanVersionRow(row, planKey) {
|
|
2778
|
+
return toPlanVersionRow2(row, planKey, this.fields);
|
|
2779
|
+
}
|
|
2780
|
+
};
|
|
2781
|
+
PrismaPlanRepository = _ts_decorate19([
|
|
2782
|
+
(0, import_common19.Injectable)(),
|
|
2783
|
+
_ts_param17(0, (0, import_common19.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
2784
|
+
_ts_param17(1, (0, import_common19.Optional)()),
|
|
2785
|
+
_ts_param17(1, (0, import_common19.Inject)(PRISMA_SCHEMA_OPTIONS_TOKEN)),
|
|
2786
|
+
_ts_metadata17("design:type", Function),
|
|
2787
|
+
_ts_metadata17("design:paramtypes", [
|
|
2788
|
+
typeof PlanRepositoryClient === "undefined" ? Object : PlanRepositoryClient,
|
|
2789
|
+
typeof PrismaSchemaOptions === "undefined" ? Object : PrismaSchemaOptions
|
|
2790
|
+
])
|
|
2791
|
+
], PrismaPlanRepository);
|
|
2792
|
+
function toPlanRow2(row) {
|
|
2793
|
+
return {
|
|
2794
|
+
id: row.id,
|
|
2795
|
+
projectKey: row.projectKey,
|
|
2796
|
+
planKey: row.planKey,
|
|
2797
|
+
label: row.label,
|
|
2798
|
+
description: row.description,
|
|
2799
|
+
icon: row.icon,
|
|
2800
|
+
sortOrder: row.sortOrder,
|
|
2801
|
+
createdAt: row.createdAt.toISOString(),
|
|
2802
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
2803
|
+
deletedAt: row.deletedAt?.toISOString() ?? null
|
|
2804
|
+
};
|
|
2805
|
+
}
|
|
2806
|
+
__name(toPlanRow2, "toPlanRow");
|
|
2807
|
+
function toPlanVersionRow2(row, planKey, fields) {
|
|
2808
|
+
const mapped = {
|
|
2809
|
+
id: row.id,
|
|
2810
|
+
version: row.version,
|
|
2811
|
+
baseVersionId: row.baseVersionId,
|
|
2812
|
+
planId: planKey,
|
|
2813
|
+
features: toStringArray(row.features),
|
|
2814
|
+
quotas: toQuotaMap(row.quotas),
|
|
2815
|
+
monthlyNet: row.monthlyNet.toString(),
|
|
2816
|
+
yearlyNet: row.yearlyNet.toString(),
|
|
2817
|
+
marketed: row.marketed,
|
|
2818
|
+
publishedAt: row.publishedAt?.toISOString() ?? null,
|
|
2819
|
+
supersededAt: row.supersededAt?.toISOString() ?? null,
|
|
2820
|
+
publishedChanges: Array.isArray(row.publishedChanges) ? row.publishedChanges : null,
|
|
2821
|
+
changeNote: row.changeNote,
|
|
2822
|
+
nonRegressive: row.nonRegressive,
|
|
2823
|
+
validFrom: fields.validityWindows && row.validFrom ? row.validFrom.toISOString() : null,
|
|
2824
|
+
validUntil: fields.validityWindows && row.validUntil ? row.validUntil.toISOString() : null,
|
|
2825
|
+
createdByUserId: row.createdByUserId,
|
|
2826
|
+
publishedByUserId: row.publishedByUserId,
|
|
2827
|
+
createdAt: row.createdAt.toISOString(),
|
|
2828
|
+
updatedAt: row.updatedAt.toISOString()
|
|
2829
|
+
};
|
|
2830
|
+
if (fields.endsAt) {
|
|
2831
|
+
mapped.endsAt = row.endsAt?.toISOString() ?? null;
|
|
2832
|
+
}
|
|
2833
|
+
return mapped;
|
|
2834
|
+
}
|
|
2835
|
+
__name(toPlanVersionRow2, "toPlanVersionRow");
|
|
2836
|
+
|
|
2837
|
+
// src/prisma-bundle.repository.ts
|
|
2838
|
+
var import_common20 = require("@nestjs/common");
|
|
2839
|
+
var import_types5 = require("@saasicat/types");
|
|
2840
|
+
function _ts_decorate20(decorators, target, key, desc) {
|
|
2841
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2842
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2843
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2844
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2845
|
+
}
|
|
2846
|
+
__name(_ts_decorate20, "_ts_decorate");
|
|
2847
|
+
function _ts_metadata18(k, v) {
|
|
2848
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2849
|
+
}
|
|
2850
|
+
__name(_ts_metadata18, "_ts_metadata");
|
|
2851
|
+
function _ts_param18(paramIndex, decorator) {
|
|
2852
|
+
return function(target, key) {
|
|
2853
|
+
decorator(target, key, paramIndex);
|
|
2854
|
+
};
|
|
2855
|
+
}
|
|
2856
|
+
__name(_ts_param18, "_ts_param");
|
|
2857
|
+
var PRISMA_BUNDLE_REPOSITORY_OPTIONS = /* @__PURE__ */ Symbol.for("saasicat/adapter-prisma/PrismaBundleRepositoryOptions");
|
|
2858
|
+
var PrismaBundleRepository = class {
|
|
2859
|
+
static {
|
|
2860
|
+
__name(this, "PrismaBundleRepository");
|
|
2861
|
+
}
|
|
2862
|
+
prisma;
|
|
2863
|
+
validityWindows;
|
|
2864
|
+
/**
|
|
2865
|
+
* Present only when validity-window mode is enabled. This mirrors the
|
|
2866
|
+
* optional port capability and lets 0.6-schema consumers detect that an
|
|
2867
|
+
* active-at-time lookup is unavailable.
|
|
2868
|
+
*/
|
|
2869
|
+
findActiveBundleVersion;
|
|
2870
|
+
constructor(prisma, options = {}) {
|
|
2871
|
+
this.prisma = prisma;
|
|
2872
|
+
this.validityWindows = options.validityWindows ?? false;
|
|
2873
|
+
if (this.validityWindows) {
|
|
2874
|
+
this.findActiveBundleVersion = (bundleId, asOf, tx) => this.findActiveBundleVersionWithValidity(bundleId, asOf ?? /* @__PURE__ */ new Date(), tx);
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
db(tx) {
|
|
2878
|
+
return tx ?? this.prisma;
|
|
2879
|
+
}
|
|
2880
|
+
transaction(work) {
|
|
2881
|
+
const transaction = this.prisma.$transaction;
|
|
2882
|
+
return transaction.call(this.prisma, (tx) => work(tx));
|
|
2883
|
+
}
|
|
2884
|
+
// ─── Stem operations ───
|
|
2885
|
+
async list(filter) {
|
|
2886
|
+
const excludeDeleted = filter.excludeDeleted ?? true;
|
|
2887
|
+
const rows = await this.db().bundle.findMany({
|
|
2888
|
+
where: {
|
|
2889
|
+
projectKey: filter.projectKey,
|
|
2890
|
+
...excludeDeleted ? {
|
|
2891
|
+
deletedAt: null
|
|
2892
|
+
} : {}
|
|
2893
|
+
},
|
|
2894
|
+
orderBy: [
|
|
2895
|
+
{
|
|
2896
|
+
sortOrder: "asc"
|
|
2897
|
+
},
|
|
2898
|
+
{
|
|
2899
|
+
bundleKey: "asc"
|
|
2900
|
+
}
|
|
2901
|
+
]
|
|
2902
|
+
});
|
|
2903
|
+
return rows.map(toBundleRow);
|
|
2904
|
+
}
|
|
2905
|
+
async findById(bundleId) {
|
|
2906
|
+
const row = await this.db().bundle.findUnique({
|
|
2907
|
+
where: {
|
|
2908
|
+
id: bundleId
|
|
2909
|
+
}
|
|
2910
|
+
});
|
|
2911
|
+
return row ? toBundleRow(row) : null;
|
|
2912
|
+
}
|
|
2913
|
+
async findByKey(projectKey, bundleKey) {
|
|
2914
|
+
const row = await this.db().bundle.findFirst({
|
|
2915
|
+
where: {
|
|
2916
|
+
projectKey,
|
|
2917
|
+
bundleKey,
|
|
2918
|
+
deletedAt: null
|
|
2919
|
+
}
|
|
2920
|
+
});
|
|
2921
|
+
return row ? toBundleRow(row) : null;
|
|
2922
|
+
}
|
|
2923
|
+
async create(data) {
|
|
2924
|
+
const created = await this.db().bundle.create({
|
|
2925
|
+
data: {
|
|
2926
|
+
projectKey: data.projectKey,
|
|
2927
|
+
bundleKey: data.bundleKey,
|
|
2928
|
+
label: data.label,
|
|
2929
|
+
description: data.description ?? null,
|
|
2930
|
+
icon: data.icon ?? null,
|
|
2931
|
+
sortOrder: data.sortOrder ?? 0,
|
|
2932
|
+
i18n: data.i18n ?? {}
|
|
2933
|
+
}
|
|
2934
|
+
});
|
|
2935
|
+
return toBundleRow(created);
|
|
2936
|
+
}
|
|
2937
|
+
async update(bundleId, data) {
|
|
2938
|
+
const updated = await this.db().bundle.update({
|
|
2939
|
+
where: {
|
|
2940
|
+
id: bundleId
|
|
2941
|
+
},
|
|
2942
|
+
data: {
|
|
2943
|
+
...data.label !== void 0 ? {
|
|
2944
|
+
label: data.label
|
|
2945
|
+
} : {},
|
|
2946
|
+
...data.description !== void 0 ? {
|
|
2947
|
+
description: data.description
|
|
2948
|
+
} : {},
|
|
2949
|
+
...data.icon !== void 0 ? {
|
|
2950
|
+
icon: data.icon
|
|
2951
|
+
} : {},
|
|
2952
|
+
...data.sortOrder !== void 0 ? {
|
|
2953
|
+
sortOrder: data.sortOrder
|
|
2954
|
+
} : {},
|
|
2955
|
+
...data.i18n !== void 0 ? {
|
|
2956
|
+
i18n: data.i18n
|
|
2957
|
+
} : {}
|
|
2958
|
+
}
|
|
2959
|
+
});
|
|
2960
|
+
return toBundleRow(updated);
|
|
2961
|
+
}
|
|
2962
|
+
async softDelete(bundleId) {
|
|
2963
|
+
await this.db().bundle.update({
|
|
2964
|
+
where: {
|
|
2965
|
+
id: bundleId
|
|
2966
|
+
},
|
|
2967
|
+
data: {
|
|
2968
|
+
deletedAt: /* @__PURE__ */ new Date()
|
|
2969
|
+
}
|
|
2970
|
+
});
|
|
2971
|
+
}
|
|
2972
|
+
// ─── Version operations ───
|
|
2973
|
+
async listVersions(bundleId) {
|
|
2974
|
+
const bundle = await this.db().bundle.findUnique({
|
|
2975
|
+
where: {
|
|
2976
|
+
id: bundleId
|
|
2977
|
+
}
|
|
2978
|
+
});
|
|
2979
|
+
if (!bundle) return [];
|
|
2980
|
+
const rows = await this.db().bundleVersion.findMany({
|
|
2981
|
+
where: {
|
|
2982
|
+
bundleId
|
|
2983
|
+
},
|
|
2984
|
+
orderBy: {
|
|
2985
|
+
version: "asc"
|
|
2986
|
+
}
|
|
2987
|
+
});
|
|
2988
|
+
return rows.map((row) => toBundleVersionRow(row, bundle, this.validityWindows));
|
|
2989
|
+
}
|
|
2990
|
+
async findVersionById(versionId) {
|
|
2991
|
+
const row = await this.db().bundleVersion.findUnique({
|
|
2992
|
+
where: {
|
|
2993
|
+
id: versionId
|
|
2994
|
+
}
|
|
2995
|
+
});
|
|
2996
|
+
if (!row) return null;
|
|
2997
|
+
const bundle = await this.db().bundle.findUnique({
|
|
2998
|
+
where: {
|
|
2999
|
+
id: row.bundleId
|
|
3000
|
+
}
|
|
3001
|
+
});
|
|
3002
|
+
return toBundleVersionRow(row, bundle, this.validityWindows);
|
|
3003
|
+
}
|
|
3004
|
+
async findCurrentDraft(bundleId) {
|
|
3005
|
+
const row = await this.db().bundleVersion.findFirst({
|
|
3006
|
+
where: {
|
|
3007
|
+
bundleId,
|
|
3008
|
+
publishedAt: null
|
|
3009
|
+
}
|
|
3010
|
+
});
|
|
3011
|
+
if (!row) return null;
|
|
3012
|
+
const bundle = await this.db().bundle.findUnique({
|
|
3013
|
+
where: {
|
|
3014
|
+
id: bundleId
|
|
3015
|
+
}
|
|
3016
|
+
});
|
|
3017
|
+
return toBundleVersionRow(row, bundle, this.validityWindows);
|
|
3018
|
+
}
|
|
3019
|
+
async findLatestLive(bundleId, tx) {
|
|
3020
|
+
const db = this.db(tx);
|
|
3021
|
+
const row = await db.bundleVersion.findFirst({
|
|
3022
|
+
where: {
|
|
3023
|
+
bundleId,
|
|
3024
|
+
publishedAt: {
|
|
3025
|
+
not: null
|
|
3026
|
+
},
|
|
3027
|
+
supersededAt: null
|
|
3028
|
+
},
|
|
3029
|
+
orderBy: {
|
|
3030
|
+
version: "desc"
|
|
3031
|
+
}
|
|
3032
|
+
});
|
|
3033
|
+
if (!row) return null;
|
|
3034
|
+
const bundle = await db.bundle.findUnique({
|
|
3035
|
+
where: {
|
|
3036
|
+
id: bundleId
|
|
3037
|
+
}
|
|
3038
|
+
});
|
|
3039
|
+
return toBundleVersionRow(row, bundle, this.validityWindows);
|
|
3040
|
+
}
|
|
3041
|
+
async findActiveBundleVersionWithValidity(bundleId, asOf, tx) {
|
|
3042
|
+
const db = this.db(tx);
|
|
3043
|
+
const row = await db.bundleVersion.findFirst({
|
|
3044
|
+
where: {
|
|
3045
|
+
bundleId,
|
|
3046
|
+
...(0, import_types5.buildActiveVersionWhere)(asOf)
|
|
3047
|
+
},
|
|
3048
|
+
orderBy: [
|
|
3049
|
+
{
|
|
3050
|
+
validFrom: {
|
|
3051
|
+
sort: "desc",
|
|
3052
|
+
nulls: "last"
|
|
3053
|
+
}
|
|
3054
|
+
},
|
|
3055
|
+
{
|
|
3056
|
+
version: "desc"
|
|
3057
|
+
}
|
|
3058
|
+
]
|
|
3059
|
+
});
|
|
3060
|
+
if (!row) return null;
|
|
3061
|
+
const bundle = await db.bundle.findUnique({
|
|
3062
|
+
where: {
|
|
3063
|
+
id: bundleId
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
3066
|
+
return toBundleVersionRow(row, bundle, true);
|
|
3067
|
+
}
|
|
3068
|
+
async createDraft(data) {
|
|
3069
|
+
const db = this.db();
|
|
3070
|
+
const existingDraft = await db.bundleVersion.findFirst({
|
|
3071
|
+
where: {
|
|
3072
|
+
bundleId: data.bundleId,
|
|
3073
|
+
publishedAt: null
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
3076
|
+
if (existingDraft) {
|
|
3077
|
+
throw new Error(`Bundle '${data.bundleId}' already has a draft version (v${existingDraft.version}); only one draft per bundle is allowed.`);
|
|
3078
|
+
}
|
|
3079
|
+
const latest = await db.bundleVersion.findFirst({
|
|
3080
|
+
where: {
|
|
3081
|
+
bundleId: data.bundleId
|
|
3082
|
+
},
|
|
3083
|
+
orderBy: {
|
|
3084
|
+
version: "desc"
|
|
3085
|
+
}
|
|
3086
|
+
});
|
|
3087
|
+
const nextVersion = latest ? latest.version + 1 : 1;
|
|
3088
|
+
const created = await db.bundleVersion.create({
|
|
3089
|
+
data: {
|
|
3090
|
+
bundleId: data.bundleId,
|
|
3091
|
+
version: nextVersion,
|
|
3092
|
+
baseVersionId: data.baseVersionId ?? null,
|
|
3093
|
+
features: data.features,
|
|
3094
|
+
quotas: data.quotas ?? {},
|
|
3095
|
+
compatibility: data.compatibility ?? {},
|
|
3096
|
+
pricingOverrides: data.pricingOverrides ?? [],
|
|
3097
|
+
monthlyNet: data.monthlyNet ?? null,
|
|
3098
|
+
yearlyNet: data.yearlyNet ?? null,
|
|
3099
|
+
marketed: data.marketed ?? true,
|
|
3100
|
+
changeNote: data.changeNote ?? "",
|
|
3101
|
+
createdByUserId: data.createdByUserId ?? null,
|
|
3102
|
+
...this.validityWindows ? {
|
|
3103
|
+
validFrom: toNullableDate(data.validFrom),
|
|
3104
|
+
validUntil: toNullableDate(data.validUntil)
|
|
3105
|
+
} : {}
|
|
3106
|
+
}
|
|
3107
|
+
});
|
|
3108
|
+
const bundle = await db.bundle.findUnique({
|
|
3109
|
+
where: {
|
|
3110
|
+
id: data.bundleId
|
|
3111
|
+
}
|
|
3112
|
+
});
|
|
3113
|
+
return toBundleVersionRow(created, bundle, this.validityWindows);
|
|
3114
|
+
}
|
|
3115
|
+
async updateDraft(versionId, data) {
|
|
3116
|
+
const db = this.db();
|
|
3117
|
+
const updated = await db.bundleVersion.update({
|
|
3118
|
+
where: {
|
|
3119
|
+
id: versionId
|
|
3120
|
+
},
|
|
3121
|
+
data: {
|
|
3122
|
+
...data.features !== void 0 ? {
|
|
3123
|
+
features: data.features
|
|
3124
|
+
} : {},
|
|
3125
|
+
...data.quotas !== void 0 ? {
|
|
3126
|
+
quotas: data.quotas
|
|
3127
|
+
} : {},
|
|
3128
|
+
...data.compatibility !== void 0 ? {
|
|
3129
|
+
compatibility: data.compatibility
|
|
3130
|
+
} : {},
|
|
3131
|
+
...data.pricingOverrides !== void 0 ? {
|
|
3132
|
+
pricingOverrides: data.pricingOverrides
|
|
3133
|
+
} : {},
|
|
3134
|
+
...data.monthlyNet !== void 0 ? {
|
|
3135
|
+
monthlyNet: data.monthlyNet
|
|
3136
|
+
} : {},
|
|
3137
|
+
...data.yearlyNet !== void 0 ? {
|
|
3138
|
+
yearlyNet: data.yearlyNet
|
|
3139
|
+
} : {},
|
|
3140
|
+
...data.marketed !== void 0 ? {
|
|
3141
|
+
marketed: data.marketed
|
|
3142
|
+
} : {},
|
|
3143
|
+
...data.changeNote !== void 0 ? {
|
|
3144
|
+
changeNote: data.changeNote
|
|
3145
|
+
} : {},
|
|
3146
|
+
...this.validityWindows && data.validFrom !== void 0 ? {
|
|
3147
|
+
validFrom: toNullableDate(data.validFrom)
|
|
3148
|
+
} : {},
|
|
3149
|
+
...this.validityWindows && data.validUntil !== void 0 ? {
|
|
3150
|
+
validUntil: toNullableDate(data.validUntil)
|
|
3151
|
+
} : {}
|
|
3152
|
+
}
|
|
3153
|
+
});
|
|
3154
|
+
const bundle = await db.bundle.findUnique({
|
|
3155
|
+
where: {
|
|
3156
|
+
id: updated.bundleId
|
|
3157
|
+
}
|
|
3158
|
+
});
|
|
3159
|
+
return toBundleVersionRow(updated, bundle, this.validityWindows);
|
|
3160
|
+
}
|
|
3161
|
+
async publishDraft(versionId, publishMeta, tx) {
|
|
3162
|
+
if (this.validityWindows && tx === void 0) {
|
|
3163
|
+
return this.transaction((transaction) => this.publishDraftWithValidity(transaction, versionId, publishMeta));
|
|
3164
|
+
}
|
|
3165
|
+
if (this.validityWindows) {
|
|
3166
|
+
return this.publishDraftWithValidity(this.db(tx), versionId, publishMeta);
|
|
3167
|
+
}
|
|
3168
|
+
const db = this.db(tx);
|
|
3169
|
+
const draft = await db.bundleVersion.findUnique({
|
|
3170
|
+
where: {
|
|
3171
|
+
id: versionId
|
|
3172
|
+
}
|
|
3173
|
+
});
|
|
3174
|
+
if (!draft) {
|
|
3175
|
+
throw new Error(`BundleVersion '${versionId}' not found.`);
|
|
3176
|
+
}
|
|
3177
|
+
await db.bundleVersion.updateMany({
|
|
3178
|
+
where: {
|
|
3179
|
+
bundleId: draft.bundleId,
|
|
3180
|
+
publishedAt: {
|
|
3181
|
+
not: null
|
|
3182
|
+
},
|
|
3183
|
+
supersededAt: null,
|
|
3184
|
+
NOT: {
|
|
3185
|
+
id: versionId
|
|
3186
|
+
}
|
|
3187
|
+
},
|
|
3188
|
+
data: {
|
|
3189
|
+
supersededAt: /* @__PURE__ */ new Date()
|
|
3190
|
+
}
|
|
3191
|
+
});
|
|
3192
|
+
const published = await db.bundleVersion.update({
|
|
3193
|
+
where: {
|
|
3194
|
+
id: versionId
|
|
3195
|
+
},
|
|
3196
|
+
data: {
|
|
3197
|
+
publishedAt: /* @__PURE__ */ new Date(),
|
|
3198
|
+
publishedByUserId: publishMeta.publishedByUserId,
|
|
3199
|
+
publishedChanges: publishMeta.publishedChanges,
|
|
3200
|
+
nonRegressive: publishMeta.nonRegressive
|
|
3201
|
+
}
|
|
3202
|
+
});
|
|
3203
|
+
const bundle = await db.bundle.findUnique({
|
|
3204
|
+
where: {
|
|
3205
|
+
id: published.bundleId
|
|
3206
|
+
}
|
|
3207
|
+
});
|
|
3208
|
+
return toBundleVersionRow(published, bundle, false);
|
|
3209
|
+
}
|
|
3210
|
+
async publishDraftWithValidity(db, versionId, publishMeta) {
|
|
3211
|
+
const draft = await db.bundleVersion.findUnique({
|
|
3212
|
+
where: {
|
|
3213
|
+
id: versionId
|
|
3214
|
+
}
|
|
3215
|
+
});
|
|
3216
|
+
if (!draft) {
|
|
3217
|
+
throw new Error(`BundleVersion '${versionId}' not found.`);
|
|
3218
|
+
}
|
|
3219
|
+
const now = /* @__PURE__ */ new Date();
|
|
3220
|
+
await db.bundleVersion.updateMany({
|
|
3221
|
+
where: {
|
|
3222
|
+
bundleId: draft.bundleId,
|
|
3223
|
+
publishedAt: {
|
|
3224
|
+
not: null
|
|
3225
|
+
},
|
|
3226
|
+
supersededAt: null,
|
|
3227
|
+
NOT: {
|
|
3228
|
+
id: versionId
|
|
3229
|
+
}
|
|
3230
|
+
},
|
|
3231
|
+
data: {
|
|
3232
|
+
supersededAt: now,
|
|
3233
|
+
validUntil: previousUtcDay(publishMeta.validFrom)
|
|
3234
|
+
}
|
|
3235
|
+
});
|
|
3236
|
+
const published = await db.bundleVersion.update({
|
|
3237
|
+
where: {
|
|
3238
|
+
id: versionId
|
|
3239
|
+
},
|
|
3240
|
+
data: {
|
|
3241
|
+
publishedAt: now,
|
|
3242
|
+
publishedByUserId: publishMeta.publishedByUserId,
|
|
3243
|
+
publishedChanges: publishMeta.publishedChanges,
|
|
3244
|
+
nonRegressive: publishMeta.nonRegressive,
|
|
3245
|
+
validFrom: publishMeta.validFrom,
|
|
3246
|
+
validUntil: publishMeta.validUntil
|
|
3247
|
+
}
|
|
3248
|
+
});
|
|
3249
|
+
const bundle = await db.bundle.findUnique({
|
|
3250
|
+
where: {
|
|
3251
|
+
id: published.bundleId
|
|
3252
|
+
}
|
|
3253
|
+
});
|
|
3254
|
+
return toBundleVersionRow(published, bundle, true);
|
|
3255
|
+
}
|
|
3256
|
+
async deleteDraft(versionId) {
|
|
3257
|
+
const db = this.db();
|
|
3258
|
+
const row = await db.bundleVersion.findUnique({
|
|
3259
|
+
where: {
|
|
3260
|
+
id: versionId
|
|
3261
|
+
}
|
|
3262
|
+
});
|
|
3263
|
+
if (!row) return;
|
|
3264
|
+
if (row.publishedAt !== null) {
|
|
3265
|
+
throw new Error(`BundleVersion '${versionId}' is already published and cannot be discarded (published versions are immutable \u2014 contract protection P1).`);
|
|
3266
|
+
}
|
|
3267
|
+
try {
|
|
3268
|
+
await db.bundleVersion.delete({
|
|
3269
|
+
where: {
|
|
3270
|
+
id: versionId
|
|
3271
|
+
}
|
|
3272
|
+
});
|
|
3273
|
+
} catch (err) {
|
|
3274
|
+
if (err?.code === "P2025") return;
|
|
3275
|
+
throw err;
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
};
|
|
3279
|
+
PrismaBundleRepository = _ts_decorate20([
|
|
3280
|
+
(0, import_common20.Injectable)(),
|
|
3281
|
+
_ts_param18(0, (0, import_common20.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
3282
|
+
_ts_param18(1, (0, import_common20.Optional)()),
|
|
3283
|
+
_ts_param18(1, (0, import_common20.Inject)(PRISMA_BUNDLE_REPOSITORY_OPTIONS)),
|
|
3284
|
+
_ts_metadata18("design:type", Function),
|
|
3285
|
+
_ts_metadata18("design:paramtypes", [
|
|
3286
|
+
typeof BundlePrismaClient === "undefined" ? Object : BundlePrismaClient,
|
|
3287
|
+
typeof PrismaBundleRepositoryOptions === "undefined" ? Object : PrismaBundleRepositoryOptions
|
|
3288
|
+
])
|
|
3289
|
+
], PrismaBundleRepository);
|
|
3290
|
+
function isPlainObject(value) {
|
|
3291
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3292
|
+
}
|
|
3293
|
+
__name(isPlainObject, "isPlainObject");
|
|
3294
|
+
function toDecimalString(value) {
|
|
3295
|
+
return value == null ? null : value.toString();
|
|
3296
|
+
}
|
|
3297
|
+
__name(toDecimalString, "toDecimalString");
|
|
3298
|
+
function toNullableDate(value) {
|
|
3299
|
+
return value ? new Date(value) : null;
|
|
3300
|
+
}
|
|
3301
|
+
__name(toNullableDate, "toNullableDate");
|
|
3302
|
+
function previousUtcDay(value) {
|
|
3303
|
+
const result = new Date(value);
|
|
3304
|
+
result.setUTCDate(result.getUTCDate() - 1);
|
|
3305
|
+
return result;
|
|
3306
|
+
}
|
|
3307
|
+
__name(previousUtcDay, "previousUtcDay");
|
|
3308
|
+
function toVersionChanges(value) {
|
|
3309
|
+
return Array.isArray(value) ? value : null;
|
|
3310
|
+
}
|
|
3311
|
+
__name(toVersionChanges, "toVersionChanges");
|
|
3312
|
+
function toCompatibility(value) {
|
|
3313
|
+
return isPlainObject(value) ? value : {};
|
|
3314
|
+
}
|
|
3315
|
+
__name(toCompatibility, "toCompatibility");
|
|
3316
|
+
function toPricingOverrides(value) {
|
|
3317
|
+
return Array.isArray(value) ? value : [];
|
|
3318
|
+
}
|
|
3319
|
+
__name(toPricingOverrides, "toPricingOverrides");
|
|
3320
|
+
function toI18n(value) {
|
|
3321
|
+
return isPlainObject(value) ? value : {};
|
|
3322
|
+
}
|
|
3323
|
+
__name(toI18n, "toI18n");
|
|
3324
|
+
function toBundleRow(row) {
|
|
3325
|
+
return {
|
|
3326
|
+
id: row.id,
|
|
3327
|
+
projectKey: row.projectKey,
|
|
3328
|
+
bundleKey: row.bundleKey,
|
|
3329
|
+
label: row.label,
|
|
3330
|
+
description: row.description,
|
|
3331
|
+
icon: row.icon,
|
|
3332
|
+
sortOrder: row.sortOrder,
|
|
3333
|
+
i18n: toI18n(row.i18n),
|
|
3334
|
+
createdAt: row.createdAt.toISOString(),
|
|
3335
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
3336
|
+
deletedAt: row.deletedAt?.toISOString() ?? null
|
|
3337
|
+
};
|
|
3338
|
+
}
|
|
3339
|
+
__name(toBundleRow, "toBundleRow");
|
|
3340
|
+
function toBundleVersionRow(row, bundle, validityWindows) {
|
|
3341
|
+
return {
|
|
3342
|
+
id: row.id,
|
|
3343
|
+
bundleId: row.bundleId,
|
|
3344
|
+
bundleKey: bundle?.bundleKey ?? "",
|
|
3345
|
+
label: bundle?.label ?? "",
|
|
3346
|
+
version: row.version,
|
|
3347
|
+
baseVersionId: row.baseVersionId,
|
|
3348
|
+
features: toStringArray(row.features),
|
|
3349
|
+
quotas: toQuotaMap(row.quotas),
|
|
3350
|
+
compatibility: toCompatibility(row.compatibility),
|
|
3351
|
+
pricingOverrides: toPricingOverrides(row.pricingOverrides),
|
|
3352
|
+
monthlyNet: toDecimalString(row.monthlyNet),
|
|
3353
|
+
yearlyNet: toDecimalString(row.yearlyNet),
|
|
3354
|
+
marketed: row.marketed,
|
|
3355
|
+
publishedAt: row.publishedAt?.toISOString() ?? null,
|
|
3356
|
+
supersededAt: row.supersededAt?.toISOString() ?? null,
|
|
3357
|
+
validFrom: validityWindows && row.validFrom instanceof Date ? row.validFrom.toISOString() : null,
|
|
3358
|
+
validUntil: validityWindows && row.validUntil instanceof Date ? row.validUntil.toISOString() : null,
|
|
3359
|
+
publishedChanges: toVersionChanges(row.publishedChanges),
|
|
3360
|
+
changeNote: row.changeNote,
|
|
3361
|
+
nonRegressive: row.nonRegressive,
|
|
3362
|
+
createdByUserId: row.createdByUserId,
|
|
3363
|
+
publishedByUserId: row.publishedByUserId,
|
|
3364
|
+
createdAt: row.createdAt.toISOString(),
|
|
3365
|
+
updatedAt: row.updatedAt.toISOString()
|
|
3366
|
+
};
|
|
3367
|
+
}
|
|
3368
|
+
__name(toBundleVersionRow, "toBundleVersionRow");
|
|
3369
|
+
|
|
3370
|
+
// src/prisma-catalog-entry.repository.ts
|
|
3371
|
+
var import_common21 = require("@nestjs/common");
|
|
3372
|
+
function _ts_decorate21(decorators, target, key, desc) {
|
|
3373
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3374
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3375
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3376
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3377
|
+
}
|
|
3378
|
+
__name(_ts_decorate21, "_ts_decorate");
|
|
3379
|
+
function _ts_metadata19(k, v) {
|
|
3380
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3381
|
+
}
|
|
3382
|
+
__name(_ts_metadata19, "_ts_metadata");
|
|
3383
|
+
function _ts_param19(paramIndex, decorator) {
|
|
3384
|
+
return function(target, key) {
|
|
3385
|
+
decorator(target, key, paramIndex);
|
|
3386
|
+
};
|
|
3387
|
+
}
|
|
3388
|
+
__name(_ts_param19, "_ts_param");
|
|
3389
|
+
var PrismaCatalogEntryRepository = class {
|
|
3390
|
+
static {
|
|
3391
|
+
__name(this, "PrismaCatalogEntryRepository");
|
|
3392
|
+
}
|
|
3393
|
+
prisma;
|
|
3394
|
+
constructor(prisma) {
|
|
3395
|
+
this.prisma = prisma;
|
|
3396
|
+
}
|
|
3397
|
+
get db() {
|
|
3398
|
+
return this.prisma;
|
|
3399
|
+
}
|
|
3400
|
+
async listCapabilities(filter) {
|
|
3401
|
+
const rows = await this.db.capabilityCatalogEntry.findMany({
|
|
3402
|
+
where: {
|
|
3403
|
+
projectKey: filter.projectKey,
|
|
3404
|
+
deletedAt: null,
|
|
3405
|
+
...filter.codeStatus ? {
|
|
3406
|
+
codeStatus: filter.codeStatus
|
|
3407
|
+
} : {}
|
|
3408
|
+
},
|
|
3409
|
+
orderBy: [
|
|
3410
|
+
{
|
|
3411
|
+
sortOrder: "asc"
|
|
3412
|
+
},
|
|
3413
|
+
{
|
|
3414
|
+
capabilityKey: "asc"
|
|
3415
|
+
}
|
|
3416
|
+
]
|
|
3417
|
+
});
|
|
3418
|
+
return rows.map(toCapabilityRow);
|
|
3419
|
+
}
|
|
3420
|
+
async listFeatures(filter) {
|
|
3421
|
+
const rows = await this.db.featureCatalogEntry.findMany({
|
|
3422
|
+
where: {
|
|
3423
|
+
projectKey: filter.projectKey,
|
|
3424
|
+
deletedAt: null,
|
|
3425
|
+
...filter.discoveryStatus ? {
|
|
3426
|
+
discoveryStatus: filter.discoveryStatus
|
|
3427
|
+
} : {}
|
|
3428
|
+
},
|
|
3429
|
+
orderBy: [
|
|
3430
|
+
{
|
|
3431
|
+
sortOrder: "asc"
|
|
3432
|
+
},
|
|
3433
|
+
{
|
|
3434
|
+
featureKey: "asc"
|
|
3435
|
+
}
|
|
3436
|
+
]
|
|
3437
|
+
});
|
|
3438
|
+
return rows.map(toFeatureRow);
|
|
3439
|
+
}
|
|
3440
|
+
async listQuotas(filter) {
|
|
3441
|
+
const rows = await this.db.quotaCatalogEntry.findMany({
|
|
3442
|
+
where: {
|
|
3443
|
+
projectKey: filter.projectKey,
|
|
3444
|
+
deletedAt: null,
|
|
3445
|
+
...filter.discoveryStatus ? {
|
|
3446
|
+
discoveryStatus: filter.discoveryStatus
|
|
3447
|
+
} : {}
|
|
3448
|
+
},
|
|
3449
|
+
orderBy: [
|
|
3450
|
+
{
|
|
3451
|
+
sortOrder: "asc"
|
|
3452
|
+
},
|
|
3453
|
+
{
|
|
3454
|
+
quotaKey: "asc"
|
|
3455
|
+
}
|
|
3456
|
+
]
|
|
3457
|
+
});
|
|
3458
|
+
return rows.map(toQuotaRow);
|
|
3459
|
+
}
|
|
3460
|
+
async upsertCapability(data) {
|
|
3461
|
+
const codeFields = {
|
|
3462
|
+
label: data.label,
|
|
3463
|
+
description: data.description,
|
|
3464
|
+
featureKey: data.featureKey,
|
|
3465
|
+
bundleKey: data.bundleKey,
|
|
3466
|
+
codeStatus: data.codeStatus,
|
|
3467
|
+
owner: data.owner,
|
|
3468
|
+
kind: data.kind,
|
|
3469
|
+
replacementKey: data.replacementKey,
|
|
3470
|
+
deprecatedAt: data.deprecatedAt ? new Date(data.deprecatedAt) : null,
|
|
3471
|
+
removalPlannedAt: data.removalPlannedAt ? new Date(data.removalPlannedAt) : null,
|
|
3472
|
+
reason: data.reason
|
|
3473
|
+
};
|
|
3474
|
+
const row = await this.db.capabilityCatalogEntry.upsert({
|
|
3475
|
+
where: {
|
|
3476
|
+
projectKey_capabilityKey: {
|
|
3477
|
+
projectKey: data.projectKey,
|
|
3478
|
+
capabilityKey: data.capabilityKey
|
|
3479
|
+
}
|
|
3480
|
+
},
|
|
3481
|
+
create: {
|
|
3482
|
+
projectKey: data.projectKey,
|
|
3483
|
+
capabilityKey: data.capabilityKey,
|
|
3484
|
+
...codeFields
|
|
3485
|
+
},
|
|
3486
|
+
update: codeFields
|
|
3487
|
+
});
|
|
3488
|
+
return toCapabilityRow(row);
|
|
3489
|
+
}
|
|
3490
|
+
async upsertFeature(data) {
|
|
3491
|
+
const codeFields = {
|
|
3492
|
+
label: data.label,
|
|
3493
|
+
description: data.description,
|
|
3494
|
+
discoveryStatus: data.discoveryStatus,
|
|
3495
|
+
requires: data.requires,
|
|
3496
|
+
replaces: data.replaces,
|
|
3497
|
+
...data.core !== void 0 ? {
|
|
3498
|
+
core: data.core
|
|
3499
|
+
} : {}
|
|
3500
|
+
};
|
|
3501
|
+
const row = await this.db.featureCatalogEntry.upsert({
|
|
3502
|
+
where: {
|
|
3503
|
+
projectKey_featureKey: {
|
|
3504
|
+
projectKey: data.projectKey,
|
|
3505
|
+
featureKey: data.featureKey
|
|
3506
|
+
}
|
|
3507
|
+
},
|
|
3508
|
+
create: {
|
|
3509
|
+
projectKey: data.projectKey,
|
|
3510
|
+
featureKey: data.featureKey,
|
|
3511
|
+
...codeFields
|
|
3512
|
+
},
|
|
3513
|
+
update: codeFields
|
|
3514
|
+
});
|
|
3515
|
+
return toFeatureRow(row);
|
|
3516
|
+
}
|
|
3517
|
+
async upsertQuota(data) {
|
|
3518
|
+
const codeFields = {
|
|
3519
|
+
label: data.label,
|
|
3520
|
+
description: data.description,
|
|
3521
|
+
unit: data.unit,
|
|
3522
|
+
featureKey: data.featureKey,
|
|
3523
|
+
usageProvider: data.usageProvider,
|
|
3524
|
+
enforcementMode: data.enforcementMode,
|
|
3525
|
+
discoveryStatus: data.discoveryStatus,
|
|
3526
|
+
replaces: data.replaces
|
|
3527
|
+
};
|
|
3528
|
+
const row = await this.db.quotaCatalogEntry.upsert({
|
|
3529
|
+
where: {
|
|
3530
|
+
projectKey_quotaKey: {
|
|
3531
|
+
projectKey: data.projectKey,
|
|
3532
|
+
quotaKey: data.quotaKey
|
|
3533
|
+
}
|
|
3534
|
+
},
|
|
3535
|
+
create: {
|
|
3536
|
+
projectKey: data.projectKey,
|
|
3537
|
+
quotaKey: data.quotaKey,
|
|
3538
|
+
...codeFields
|
|
3539
|
+
},
|
|
3540
|
+
update: codeFields
|
|
3541
|
+
});
|
|
3542
|
+
return toQuotaRow(row);
|
|
3543
|
+
}
|
|
3544
|
+
async retireMissing(projectKey, type, presentKeys) {
|
|
3545
|
+
if (type === "capability") {
|
|
3546
|
+
const res2 = await this.db.capabilityCatalogEntry.updateMany({
|
|
3547
|
+
where: {
|
|
3548
|
+
projectKey,
|
|
3549
|
+
deletedAt: null,
|
|
3550
|
+
codeStatus: {
|
|
3551
|
+
not: "retired"
|
|
3552
|
+
},
|
|
3553
|
+
capabilityKey: {
|
|
3554
|
+
notIn: presentKeys
|
|
3555
|
+
}
|
|
3556
|
+
},
|
|
3557
|
+
data: {
|
|
3558
|
+
codeStatus: "retired"
|
|
3559
|
+
}
|
|
3560
|
+
});
|
|
3561
|
+
return res2.count;
|
|
3562
|
+
}
|
|
3563
|
+
if (type === "feature") {
|
|
3564
|
+
const res2 = await this.db.featureCatalogEntry.updateMany({
|
|
3565
|
+
where: {
|
|
3566
|
+
projectKey,
|
|
3567
|
+
deletedAt: null,
|
|
3568
|
+
discoveryStatus: {
|
|
3569
|
+
not: "obsolete"
|
|
3570
|
+
},
|
|
3571
|
+
featureKey: {
|
|
3572
|
+
notIn: presentKeys
|
|
3573
|
+
}
|
|
3574
|
+
},
|
|
3575
|
+
data: {
|
|
3576
|
+
discoveryStatus: "obsolete"
|
|
3577
|
+
}
|
|
3578
|
+
});
|
|
3579
|
+
return res2.count;
|
|
3580
|
+
}
|
|
3581
|
+
const res = await this.db.quotaCatalogEntry.updateMany({
|
|
3582
|
+
where: {
|
|
3583
|
+
projectKey,
|
|
3584
|
+
deletedAt: null,
|
|
3585
|
+
discoveryStatus: {
|
|
3586
|
+
not: "obsolete"
|
|
3587
|
+
},
|
|
3588
|
+
quotaKey: {
|
|
3589
|
+
notIn: presentKeys
|
|
3590
|
+
}
|
|
3591
|
+
},
|
|
3592
|
+
data: {
|
|
3593
|
+
discoveryStatus: "obsolete"
|
|
3594
|
+
}
|
|
3595
|
+
});
|
|
3596
|
+
return res.count;
|
|
3597
|
+
}
|
|
3598
|
+
async setFeatureSuccessor(projectKey, featureKey, successorKey) {
|
|
3599
|
+
const row = await this.db.featureCatalogEntry.update({
|
|
3600
|
+
where: {
|
|
3601
|
+
projectKey_featureKey: {
|
|
3602
|
+
projectKey,
|
|
3603
|
+
featureKey
|
|
3604
|
+
}
|
|
3605
|
+
},
|
|
3606
|
+
data: {
|
|
3607
|
+
successorKey
|
|
3608
|
+
}
|
|
3609
|
+
});
|
|
3610
|
+
return toFeatureRow(row);
|
|
3611
|
+
}
|
|
3612
|
+
async setQuotaSuccessor(projectKey, quotaKey, successorKey) {
|
|
3613
|
+
const row = await this.db.quotaCatalogEntry.update({
|
|
3614
|
+
where: {
|
|
3615
|
+
projectKey_quotaKey: {
|
|
3616
|
+
projectKey,
|
|
3617
|
+
quotaKey
|
|
3618
|
+
}
|
|
3619
|
+
},
|
|
3620
|
+
data: {
|
|
3621
|
+
successorKey
|
|
3622
|
+
}
|
|
3623
|
+
});
|
|
3624
|
+
return toQuotaRow(row);
|
|
3625
|
+
}
|
|
3626
|
+
async findFeature(projectKey, featureKey) {
|
|
3627
|
+
const row = await this.db.featureCatalogEntry.findUnique({
|
|
3628
|
+
where: {
|
|
3629
|
+
projectKey_featureKey: {
|
|
3630
|
+
projectKey,
|
|
3631
|
+
featureKey
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
});
|
|
3635
|
+
return row ? toFeatureRow(row) : null;
|
|
3636
|
+
}
|
|
3637
|
+
async findQuota(projectKey, quotaKey) {
|
|
3638
|
+
const row = await this.db.quotaCatalogEntry.findUnique({
|
|
3639
|
+
where: {
|
|
3640
|
+
projectKey_quotaKey: {
|
|
3641
|
+
projectKey,
|
|
3642
|
+
quotaKey
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
});
|
|
3646
|
+
return row ? toQuotaRow(row) : null;
|
|
3647
|
+
}
|
|
3648
|
+
async setFeatureReview(projectKey, featureKey, data) {
|
|
3649
|
+
const row = await this.db.featureCatalogEntry.update({
|
|
3650
|
+
where: {
|
|
3651
|
+
projectKey_featureKey: {
|
|
3652
|
+
projectKey,
|
|
3653
|
+
featureKey
|
|
3654
|
+
}
|
|
3655
|
+
},
|
|
3656
|
+
data: {
|
|
3657
|
+
discoveryStatus: data.discoveryStatus,
|
|
3658
|
+
approvedAt: data.approvedAt ? new Date(data.approvedAt) : null,
|
|
3659
|
+
approvedBy: data.approvedBy,
|
|
3660
|
+
approvedSignature: data.approvedSignature
|
|
3661
|
+
}
|
|
3662
|
+
});
|
|
3663
|
+
return toFeatureRow(row);
|
|
3664
|
+
}
|
|
3665
|
+
async setQuotaReview(projectKey, quotaKey, data) {
|
|
3666
|
+
const row = await this.db.quotaCatalogEntry.update({
|
|
3667
|
+
where: {
|
|
3668
|
+
projectKey_quotaKey: {
|
|
3669
|
+
projectKey,
|
|
3670
|
+
quotaKey
|
|
3671
|
+
}
|
|
3672
|
+
},
|
|
3673
|
+
data: {
|
|
3674
|
+
discoveryStatus: data.discoveryStatus,
|
|
3675
|
+
approvedAt: data.approvedAt ? new Date(data.approvedAt) : null,
|
|
3676
|
+
approvedBy: data.approvedBy,
|
|
3677
|
+
approvedSignature: data.approvedSignature
|
|
3678
|
+
}
|
|
3679
|
+
});
|
|
3680
|
+
return toQuotaRow(row);
|
|
3681
|
+
}
|
|
3682
|
+
async setFeatureI18n(projectKey, featureKey, i18n) {
|
|
3683
|
+
const row = await this.db.featureCatalogEntry.update({
|
|
3684
|
+
where: {
|
|
3685
|
+
projectKey_featureKey: {
|
|
3686
|
+
projectKey,
|
|
3687
|
+
featureKey
|
|
3688
|
+
}
|
|
3689
|
+
},
|
|
3690
|
+
data: {
|
|
3691
|
+
i18n
|
|
3692
|
+
}
|
|
3693
|
+
});
|
|
3694
|
+
return toFeatureRow(row);
|
|
3695
|
+
}
|
|
3696
|
+
async setQuotaI18n(projectKey, quotaKey, i18n) {
|
|
3697
|
+
const row = await this.db.quotaCatalogEntry.update({
|
|
3698
|
+
where: {
|
|
3699
|
+
projectKey_quotaKey: {
|
|
3700
|
+
projectKey,
|
|
3701
|
+
quotaKey
|
|
3702
|
+
}
|
|
3703
|
+
},
|
|
3704
|
+
data: {
|
|
3705
|
+
i18n
|
|
3706
|
+
}
|
|
3707
|
+
});
|
|
3708
|
+
return toQuotaRow(row);
|
|
3709
|
+
}
|
|
3710
|
+
async setFeatureBase(projectKey, featureKey, data) {
|
|
3711
|
+
const row = await this.db.featureCatalogEntry.update({
|
|
3712
|
+
where: {
|
|
3713
|
+
projectKey_featureKey: {
|
|
3714
|
+
projectKey,
|
|
3715
|
+
featureKey
|
|
3716
|
+
}
|
|
3717
|
+
},
|
|
3718
|
+
data: {
|
|
3719
|
+
...data.label !== void 0 ? {
|
|
3720
|
+
label: data.label
|
|
3721
|
+
} : {},
|
|
3722
|
+
...data.description !== void 0 ? {
|
|
3723
|
+
description: data.description
|
|
3724
|
+
} : {},
|
|
3725
|
+
...data.icon !== void 0 ? {
|
|
3726
|
+
icon: data.icon
|
|
3727
|
+
} : {},
|
|
3728
|
+
...data.tier !== void 0 ? {
|
|
3729
|
+
tier: data.tier
|
|
3730
|
+
} : {}
|
|
3731
|
+
}
|
|
3732
|
+
});
|
|
3733
|
+
return toFeatureRow(row);
|
|
3734
|
+
}
|
|
3735
|
+
async setQuotaBase(projectKey, quotaKey, data) {
|
|
3736
|
+
const row = await this.db.quotaCatalogEntry.update({
|
|
3737
|
+
where: {
|
|
3738
|
+
projectKey_quotaKey: {
|
|
3739
|
+
projectKey,
|
|
3740
|
+
quotaKey
|
|
3741
|
+
}
|
|
3742
|
+
},
|
|
3743
|
+
data: {
|
|
3744
|
+
...data.label !== void 0 ? {
|
|
3745
|
+
label: data.label
|
|
3746
|
+
} : {},
|
|
3747
|
+
...data.description !== void 0 ? {
|
|
3748
|
+
description: data.description
|
|
3749
|
+
} : {}
|
|
3750
|
+
}
|
|
3751
|
+
});
|
|
3752
|
+
return toQuotaRow(row);
|
|
3753
|
+
}
|
|
3754
|
+
};
|
|
3755
|
+
PrismaCatalogEntryRepository = _ts_decorate21([
|
|
3756
|
+
(0, import_common21.Injectable)(),
|
|
3757
|
+
_ts_param19(0, (0, import_common21.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
3758
|
+
_ts_metadata19("design:type", Function),
|
|
3759
|
+
_ts_metadata19("design:paramtypes", [
|
|
3760
|
+
typeof CatalogEntryRepositoryClient === "undefined" ? Object : CatalogEntryRepositoryClient
|
|
3761
|
+
])
|
|
3762
|
+
], PrismaCatalogEntryRepository);
|
|
3763
|
+
function toI18n2(value) {
|
|
3764
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
3765
|
+
return value;
|
|
3766
|
+
}
|
|
3767
|
+
return {};
|
|
3768
|
+
}
|
|
3769
|
+
__name(toI18n2, "toI18n");
|
|
3770
|
+
function toCapabilityRow(row) {
|
|
3771
|
+
return {
|
|
3772
|
+
id: row.id,
|
|
3773
|
+
projectKey: row.projectKey,
|
|
3774
|
+
capabilityKey: row.capabilityKey,
|
|
3775
|
+
label: row.label,
|
|
3776
|
+
description: row.description,
|
|
3777
|
+
featureKey: row.featureKey,
|
|
3778
|
+
bundleKey: row.bundleKey,
|
|
3779
|
+
codeStatus: row.codeStatus,
|
|
3780
|
+
owner: row.owner,
|
|
3781
|
+
kind: row.kind,
|
|
3782
|
+
replacementKey: row.replacementKey,
|
|
3783
|
+
deprecatedAt: row.deprecatedAt ? row.deprecatedAt.toISOString() : null,
|
|
3784
|
+
removalPlannedAt: row.removalPlannedAt ? row.removalPlannedAt.toISOString() : null,
|
|
3785
|
+
reason: row.reason,
|
|
3786
|
+
i18n: toI18n2(row.i18n),
|
|
3787
|
+
sortOrder: row.sortOrder,
|
|
3788
|
+
createdAt: row.createdAt.toISOString(),
|
|
3789
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
3790
|
+
deletedAt: row.deletedAt ? row.deletedAt.toISOString() : null
|
|
3791
|
+
};
|
|
3792
|
+
}
|
|
3793
|
+
__name(toCapabilityRow, "toCapabilityRow");
|
|
3794
|
+
function toFeatureRow(row) {
|
|
3795
|
+
return {
|
|
3796
|
+
id: row.id,
|
|
3797
|
+
projectKey: row.projectKey,
|
|
3798
|
+
featureKey: row.featureKey,
|
|
3799
|
+
label: row.label,
|
|
3800
|
+
description: row.description,
|
|
3801
|
+
marketingLabel: row.marketingLabel,
|
|
3802
|
+
marketingDescription: row.marketingDescription,
|
|
3803
|
+
icon: row.icon,
|
|
3804
|
+
tier: row.tier,
|
|
3805
|
+
discoveryStatus: row.discoveryStatus,
|
|
3806
|
+
requires: row.requires,
|
|
3807
|
+
replaces: row.replaces,
|
|
3808
|
+
successorKey: row.successorKey,
|
|
3809
|
+
approvedAt: row.approvedAt ? row.approvedAt.toISOString() : null,
|
|
3810
|
+
approvedBy: row.approvedBy,
|
|
3811
|
+
approvedSignature: row.approvedSignature,
|
|
3812
|
+
plannedOnly: row.plannedOnly,
|
|
3813
|
+
core: row.core,
|
|
3814
|
+
i18n: toI18n2(row.i18n),
|
|
3815
|
+
sortOrder: row.sortOrder,
|
|
3816
|
+
createdAt: row.createdAt.toISOString(),
|
|
3817
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
3818
|
+
deletedAt: row.deletedAt ? row.deletedAt.toISOString() : null
|
|
3819
|
+
};
|
|
3820
|
+
}
|
|
3821
|
+
__name(toFeatureRow, "toFeatureRow");
|
|
3822
|
+
function toQuotaRow(row) {
|
|
3823
|
+
return {
|
|
3824
|
+
id: row.id,
|
|
3825
|
+
projectKey: row.projectKey,
|
|
3826
|
+
quotaKey: row.quotaKey,
|
|
3827
|
+
label: row.label,
|
|
3828
|
+
description: row.description,
|
|
3829
|
+
unit: row.unit,
|
|
3830
|
+
featureKey: row.featureKey,
|
|
3831
|
+
usageProvider: row.usageProvider,
|
|
3832
|
+
enforcementMode: row.enforcementMode,
|
|
3833
|
+
discoveryStatus: row.discoveryStatus,
|
|
3834
|
+
replaces: row.replaces,
|
|
3835
|
+
successorKey: row.successorKey,
|
|
3836
|
+
approvedAt: row.approvedAt ? row.approvedAt.toISOString() : null,
|
|
3837
|
+
approvedBy: row.approvedBy,
|
|
3838
|
+
approvedSignature: row.approvedSignature,
|
|
3839
|
+
i18n: toI18n2(row.i18n),
|
|
3840
|
+
sortOrder: row.sortOrder,
|
|
3841
|
+
createdAt: row.createdAt.toISOString(),
|
|
3842
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
3843
|
+
deletedAt: row.deletedAt ? row.deletedAt.toISOString() : null
|
|
3844
|
+
};
|
|
3845
|
+
}
|
|
3846
|
+
__name(toQuotaRow, "toQuotaRow");
|
|
3847
|
+
|
|
3848
|
+
// src/prisma-marketing-projection.repository.ts
|
|
3849
|
+
var import_common22 = require("@nestjs/common");
|
|
3850
|
+
function _ts_decorate22(decorators, target, key, desc) {
|
|
3851
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3852
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3853
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3854
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3855
|
+
}
|
|
3856
|
+
__name(_ts_decorate22, "_ts_decorate");
|
|
3857
|
+
function _ts_metadata20(k, v) {
|
|
3858
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3859
|
+
}
|
|
3860
|
+
__name(_ts_metadata20, "_ts_metadata");
|
|
3861
|
+
function _ts_param20(paramIndex, decorator) {
|
|
3862
|
+
return function(target, key) {
|
|
3863
|
+
decorator(target, key, paramIndex);
|
|
3864
|
+
};
|
|
3865
|
+
}
|
|
3866
|
+
__name(_ts_param20, "_ts_param");
|
|
3867
|
+
var PrismaMarketingProjectionRepository = class {
|
|
3868
|
+
static {
|
|
3869
|
+
__name(this, "PrismaMarketingProjectionRepository");
|
|
3870
|
+
}
|
|
3871
|
+
prisma;
|
|
3872
|
+
constructor(prisma) {
|
|
3873
|
+
this.prisma = prisma;
|
|
3874
|
+
}
|
|
3875
|
+
get db() {
|
|
3876
|
+
return this.prisma;
|
|
3877
|
+
}
|
|
3878
|
+
async list(filter) {
|
|
3879
|
+
const rows = await this.db.marketingProjection.findMany({
|
|
3880
|
+
where: {
|
|
3881
|
+
projectKey: filter.projectKey,
|
|
3882
|
+
...filter.targetType ? {
|
|
3883
|
+
targetType: filter.targetType
|
|
3884
|
+
} : {},
|
|
3885
|
+
...filter.targetVersionId ? {
|
|
3886
|
+
targetVersionId: filter.targetVersionId
|
|
3887
|
+
} : {},
|
|
3888
|
+
...filter.locale ? {
|
|
3889
|
+
locale: filter.locale
|
|
3890
|
+
} : {}
|
|
3891
|
+
},
|
|
3892
|
+
orderBy: [
|
|
3893
|
+
{
|
|
3894
|
+
priority: "desc"
|
|
3895
|
+
},
|
|
3896
|
+
{
|
|
3897
|
+
displayLabel: "asc"
|
|
3898
|
+
}
|
|
3899
|
+
]
|
|
3900
|
+
});
|
|
3901
|
+
return rows.map(toRow);
|
|
3902
|
+
}
|
|
3903
|
+
async findById(id) {
|
|
3904
|
+
const row = await this.db.marketingProjection.findUnique({
|
|
3905
|
+
where: {
|
|
3906
|
+
id
|
|
3907
|
+
}
|
|
3908
|
+
});
|
|
3909
|
+
return row ? toRow(row) : null;
|
|
3910
|
+
}
|
|
3911
|
+
async findByTarget(targetType, targetVersionId, locale) {
|
|
3912
|
+
const row = await this.db.marketingProjection.findUnique({
|
|
3913
|
+
where: {
|
|
3914
|
+
targetType_targetVersionId_locale: {
|
|
3915
|
+
targetType,
|
|
3916
|
+
targetVersionId,
|
|
3917
|
+
locale
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
});
|
|
3921
|
+
return row ? toRow(row) : null;
|
|
3922
|
+
}
|
|
3923
|
+
async create(data) {
|
|
3924
|
+
const row = await this.db.marketingProjection.create({
|
|
3925
|
+
data: {
|
|
3926
|
+
projectKey: data.projectKey,
|
|
3927
|
+
targetType: data.targetType,
|
|
3928
|
+
targetVersionId: data.targetVersionId,
|
|
3929
|
+
locale: data.locale ?? "de",
|
|
3930
|
+
displayLabel: data.displayLabel,
|
|
3931
|
+
description: data.description,
|
|
3932
|
+
visible: data.visible ?? true,
|
|
3933
|
+
badge: data.badge ?? "",
|
|
3934
|
+
topFeatures: data.topFeatures ?? [],
|
|
3935
|
+
trialEnabled: data.trialEnabled ?? false,
|
|
3936
|
+
trialDays: data.trialDays ?? 30,
|
|
3937
|
+
priceTag: data.priceTag ?? null,
|
|
3938
|
+
ctaLabel: data.ctaLabel ?? null,
|
|
3939
|
+
priority: data.priority ?? 0,
|
|
3940
|
+
highlight: data.highlight ?? false
|
|
3941
|
+
}
|
|
3942
|
+
});
|
|
3943
|
+
return toRow(row);
|
|
3944
|
+
}
|
|
3945
|
+
async update(id, data) {
|
|
3946
|
+
const row = await this.db.marketingProjection.update({
|
|
3947
|
+
where: {
|
|
3948
|
+
id
|
|
3949
|
+
},
|
|
3950
|
+
data: {
|
|
3951
|
+
...data.displayLabel !== void 0 ? {
|
|
3952
|
+
displayLabel: data.displayLabel
|
|
3953
|
+
} : {},
|
|
3954
|
+
...data.description !== void 0 ? {
|
|
3955
|
+
description: data.description
|
|
3956
|
+
} : {},
|
|
3957
|
+
...data.visible !== void 0 ? {
|
|
3958
|
+
visible: data.visible
|
|
3959
|
+
} : {},
|
|
3960
|
+
...data.badge !== void 0 ? {
|
|
3961
|
+
badge: data.badge
|
|
3962
|
+
} : {},
|
|
3963
|
+
...data.topFeatures !== void 0 ? {
|
|
3964
|
+
topFeatures: data.topFeatures
|
|
3965
|
+
} : {},
|
|
3966
|
+
...data.trialEnabled !== void 0 ? {
|
|
3967
|
+
trialEnabled: data.trialEnabled
|
|
3968
|
+
} : {},
|
|
3969
|
+
...data.trialDays !== void 0 ? {
|
|
3970
|
+
trialDays: data.trialDays
|
|
3971
|
+
} : {},
|
|
3972
|
+
...data.priceTag !== void 0 ? {
|
|
3973
|
+
priceTag: data.priceTag
|
|
3974
|
+
} : {},
|
|
3975
|
+
...data.ctaLabel !== void 0 ? {
|
|
3976
|
+
ctaLabel: data.ctaLabel
|
|
3977
|
+
} : {},
|
|
3978
|
+
...data.priority !== void 0 ? {
|
|
3979
|
+
priority: data.priority
|
|
3980
|
+
} : {},
|
|
3981
|
+
...data.highlight !== void 0 ? {
|
|
3982
|
+
highlight: data.highlight
|
|
3983
|
+
} : {}
|
|
3984
|
+
}
|
|
3985
|
+
});
|
|
3986
|
+
return toRow(row);
|
|
3987
|
+
}
|
|
3988
|
+
async delete(id) {
|
|
3989
|
+
await this.db.marketingProjection.delete({
|
|
3990
|
+
where: {
|
|
3991
|
+
id
|
|
3992
|
+
}
|
|
3993
|
+
});
|
|
3994
|
+
}
|
|
3995
|
+
};
|
|
3996
|
+
PrismaMarketingProjectionRepository = _ts_decorate22([
|
|
3997
|
+
(0, import_common22.Injectable)(),
|
|
3998
|
+
_ts_param20(0, (0, import_common22.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
3999
|
+
_ts_metadata20("design:type", Function),
|
|
4000
|
+
_ts_metadata20("design:paramtypes", [
|
|
4001
|
+
typeof MarketingProjectionRepositoryClient === "undefined" ? Object : MarketingProjectionRepositoryClient
|
|
4002
|
+
])
|
|
4003
|
+
], PrismaMarketingProjectionRepository);
|
|
4004
|
+
function toTopFeatures(value) {
|
|
4005
|
+
return Array.isArray(value) ? value : [];
|
|
4006
|
+
}
|
|
4007
|
+
__name(toTopFeatures, "toTopFeatures");
|
|
4008
|
+
function toRow(row) {
|
|
4009
|
+
return {
|
|
4010
|
+
id: row.id,
|
|
4011
|
+
projectKey: row.projectKey,
|
|
4012
|
+
targetType: row.targetType,
|
|
4013
|
+
targetVersionId: row.targetVersionId,
|
|
4014
|
+
locale: row.locale,
|
|
4015
|
+
displayLabel: row.displayLabel,
|
|
4016
|
+
description: row.description,
|
|
4017
|
+
visible: row.visible,
|
|
4018
|
+
badge: row.badge,
|
|
4019
|
+
topFeatures: toTopFeatures(row.topFeatures),
|
|
4020
|
+
trialEnabled: row.trialEnabled,
|
|
4021
|
+
trialDays: row.trialDays,
|
|
4022
|
+
priceTag: row.priceTag,
|
|
4023
|
+
ctaLabel: row.ctaLabel,
|
|
4024
|
+
priority: row.priority,
|
|
4025
|
+
highlight: row.highlight,
|
|
4026
|
+
createdAt: row.createdAt.toISOString(),
|
|
4027
|
+
updatedAt: row.updatedAt.toISOString()
|
|
4028
|
+
};
|
|
4029
|
+
}
|
|
4030
|
+
__name(toRow, "toRow");
|
|
4031
|
+
|
|
4032
|
+
// src/prisma-marketing-settings.repository.ts
|
|
4033
|
+
var import_common23 = require("@nestjs/common");
|
|
4034
|
+
function _ts_decorate23(decorators, target, key, desc) {
|
|
4035
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4036
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4037
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4038
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4039
|
+
}
|
|
4040
|
+
__name(_ts_decorate23, "_ts_decorate");
|
|
4041
|
+
function _ts_metadata21(k, v) {
|
|
4042
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4043
|
+
}
|
|
4044
|
+
__name(_ts_metadata21, "_ts_metadata");
|
|
4045
|
+
function _ts_param21(paramIndex, decorator) {
|
|
4046
|
+
return function(target, key) {
|
|
4047
|
+
decorator(target, key, paramIndex);
|
|
4048
|
+
};
|
|
4049
|
+
}
|
|
4050
|
+
__name(_ts_param21, "_ts_param");
|
|
4051
|
+
var PrismaMarketingSettingsRepository = class {
|
|
4052
|
+
static {
|
|
4053
|
+
__name(this, "PrismaMarketingSettingsRepository");
|
|
4054
|
+
}
|
|
4055
|
+
prisma;
|
|
4056
|
+
constructor(prisma) {
|
|
4057
|
+
this.prisma = prisma;
|
|
4058
|
+
}
|
|
4059
|
+
get db() {
|
|
4060
|
+
return this.prisma;
|
|
4061
|
+
}
|
|
4062
|
+
async get(projectKey) {
|
|
4063
|
+
const row = await this.db.marketingSettings.findUnique({
|
|
4064
|
+
where: {
|
|
4065
|
+
projectKey
|
|
4066
|
+
}
|
|
4067
|
+
});
|
|
4068
|
+
return row ? toRow2(row) : null;
|
|
4069
|
+
}
|
|
4070
|
+
async upsert(projectKey, data) {
|
|
4071
|
+
const row = await this.db.marketingSettings.upsert({
|
|
4072
|
+
where: {
|
|
4073
|
+
projectKey
|
|
4074
|
+
},
|
|
4075
|
+
create: {
|
|
4076
|
+
projectKey,
|
|
4077
|
+
activeLocales: data.activeLocales
|
|
4078
|
+
},
|
|
4079
|
+
update: {
|
|
4080
|
+
activeLocales: data.activeLocales
|
|
4081
|
+
}
|
|
4082
|
+
});
|
|
4083
|
+
return toRow2(row);
|
|
4084
|
+
}
|
|
4085
|
+
};
|
|
4086
|
+
PrismaMarketingSettingsRepository = _ts_decorate23([
|
|
4087
|
+
(0, import_common23.Injectable)(),
|
|
4088
|
+
_ts_param21(0, (0, import_common23.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
4089
|
+
_ts_metadata21("design:type", Function),
|
|
4090
|
+
_ts_metadata21("design:paramtypes", [
|
|
4091
|
+
typeof MarketingSettingsRepositoryClient === "undefined" ? Object : MarketingSettingsRepositoryClient
|
|
4092
|
+
])
|
|
4093
|
+
], PrismaMarketingSettingsRepository);
|
|
4094
|
+
function toRow2(row) {
|
|
4095
|
+
return {
|
|
4096
|
+
projectKey: row.projectKey,
|
|
4097
|
+
activeLocales: toStringArray(row.activeLocales),
|
|
4098
|
+
updatedAt: row.updatedAt.toISOString()
|
|
4099
|
+
};
|
|
4100
|
+
}
|
|
4101
|
+
__name(toRow2, "toRow");
|
|
4102
|
+
|
|
4103
|
+
// src/prisma-promotion.repository.ts
|
|
4104
|
+
var import_common24 = require("@nestjs/common");
|
|
4105
|
+
function _ts_decorate24(decorators, target, key, desc) {
|
|
4106
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4107
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4108
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4109
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4110
|
+
}
|
|
4111
|
+
__name(_ts_decorate24, "_ts_decorate");
|
|
4112
|
+
function _ts_metadata22(k, v) {
|
|
4113
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4114
|
+
}
|
|
4115
|
+
__name(_ts_metadata22, "_ts_metadata");
|
|
4116
|
+
function _ts_param22(paramIndex, decorator) {
|
|
4117
|
+
return function(target, key) {
|
|
4118
|
+
decorator(target, key, paramIndex);
|
|
4119
|
+
};
|
|
4120
|
+
}
|
|
4121
|
+
__name(_ts_param22, "_ts_param");
|
|
4122
|
+
var PrismaPromotionRepository = class {
|
|
4123
|
+
static {
|
|
4124
|
+
__name(this, "PrismaPromotionRepository");
|
|
4125
|
+
}
|
|
4126
|
+
prisma;
|
|
4127
|
+
constructor(prisma) {
|
|
4128
|
+
this.prisma = prisma;
|
|
4129
|
+
}
|
|
4130
|
+
get db() {
|
|
4131
|
+
return this.prisma;
|
|
4132
|
+
}
|
|
4133
|
+
async list(filter) {
|
|
4134
|
+
const rows = await this.db.promotion.findMany({
|
|
4135
|
+
where: {
|
|
4136
|
+
projectKey: filter.projectKey
|
|
4137
|
+
},
|
|
4138
|
+
orderBy: [
|
|
4139
|
+
{
|
|
4140
|
+
validFrom: "desc"
|
|
4141
|
+
}
|
|
4142
|
+
]
|
|
4143
|
+
});
|
|
4144
|
+
return rows.map(toRow3);
|
|
4145
|
+
}
|
|
4146
|
+
async findById(id) {
|
|
4147
|
+
const row = await this.db.promotion.findUnique({
|
|
4148
|
+
where: {
|
|
4149
|
+
id
|
|
4150
|
+
}
|
|
4151
|
+
});
|
|
4152
|
+
return row ? toRow3(row) : null;
|
|
4153
|
+
}
|
|
4154
|
+
async create(data) {
|
|
4155
|
+
const row = await this.db.promotion.create({
|
|
4156
|
+
data: {
|
|
4157
|
+
projectKey: data.projectKey,
|
|
4158
|
+
internalLabel: data.internalLabel,
|
|
4159
|
+
type: data.type,
|
|
4160
|
+
value: data.value,
|
|
4161
|
+
targetType: data.targetType ?? "PLAN",
|
|
4162
|
+
appliesTo: data.appliesTo ?? [],
|
|
4163
|
+
billingCycle: data.billingCycle ?? "both",
|
|
4164
|
+
validFrom: new Date(data.validFrom),
|
|
4165
|
+
validTo: new Date(data.validTo),
|
|
4166
|
+
priority: data.priority ?? 0,
|
|
4167
|
+
requiresCoupon: data.requiresCoupon ?? false,
|
|
4168
|
+
codes: data.codes ?? [],
|
|
4169
|
+
color: data.color ?? "#2563eb",
|
|
4170
|
+
i18n: data.i18n ?? {},
|
|
4171
|
+
// Null/undefined restriction is left off so the nullable column
|
|
4172
|
+
// stays SQL NULL (= all locales).
|
|
4173
|
+
...Array.isArray(data.onlyLocales) ? {
|
|
4174
|
+
onlyLocales: data.onlyLocales
|
|
4175
|
+
} : {}
|
|
4176
|
+
}
|
|
4177
|
+
});
|
|
4178
|
+
return toRow3(row);
|
|
4179
|
+
}
|
|
4180
|
+
async update(id, data) {
|
|
4181
|
+
if (data.onlyLocales === null) {
|
|
4182
|
+
const executeRaw = this.prisma.$executeRaw.bind(this.prisma);
|
|
4183
|
+
await executeRaw`
|
|
4184
|
+
UPDATE promotions SET "onlyLocales" = NULL, "updatedAt" = NOW() WHERE id = ${id}`;
|
|
4185
|
+
}
|
|
4186
|
+
const row = await this.db.promotion.update({
|
|
4187
|
+
where: {
|
|
4188
|
+
id
|
|
4189
|
+
},
|
|
4190
|
+
data: {
|
|
4191
|
+
...data.internalLabel !== void 0 ? {
|
|
4192
|
+
internalLabel: data.internalLabel
|
|
4193
|
+
} : {},
|
|
4194
|
+
...data.type !== void 0 ? {
|
|
4195
|
+
type: data.type
|
|
4196
|
+
} : {},
|
|
4197
|
+
...data.value !== void 0 ? {
|
|
4198
|
+
value: data.value
|
|
4199
|
+
} : {},
|
|
4200
|
+
...data.appliesTo !== void 0 ? {
|
|
4201
|
+
appliesTo: data.appliesTo
|
|
4202
|
+
} : {},
|
|
4203
|
+
...data.targetType !== void 0 ? {
|
|
4204
|
+
targetType: data.targetType
|
|
4205
|
+
} : {},
|
|
4206
|
+
...data.billingCycle !== void 0 ? {
|
|
4207
|
+
billingCycle: data.billingCycle
|
|
4208
|
+
} : {},
|
|
4209
|
+
...data.validFrom !== void 0 ? {
|
|
4210
|
+
validFrom: new Date(data.validFrom)
|
|
4211
|
+
} : {},
|
|
4212
|
+
...data.validTo !== void 0 ? {
|
|
4213
|
+
validTo: new Date(data.validTo)
|
|
4214
|
+
} : {},
|
|
4215
|
+
...data.priority !== void 0 ? {
|
|
4216
|
+
priority: data.priority
|
|
4217
|
+
} : {},
|
|
4218
|
+
...data.requiresCoupon !== void 0 ? {
|
|
4219
|
+
requiresCoupon: data.requiresCoupon
|
|
4220
|
+
} : {},
|
|
4221
|
+
...data.codes !== void 0 ? {
|
|
4222
|
+
codes: data.codes
|
|
4223
|
+
} : {},
|
|
4224
|
+
...data.color !== void 0 ? {
|
|
4225
|
+
color: data.color
|
|
4226
|
+
} : {},
|
|
4227
|
+
...data.i18n !== void 0 ? {
|
|
4228
|
+
i18n: data.i18n
|
|
4229
|
+
} : {},
|
|
4230
|
+
...Array.isArray(data.onlyLocales) ? {
|
|
4231
|
+
onlyLocales: data.onlyLocales
|
|
4232
|
+
} : {}
|
|
4233
|
+
}
|
|
4234
|
+
});
|
|
4235
|
+
return toRow3(row);
|
|
4236
|
+
}
|
|
4237
|
+
async delete(id) {
|
|
4238
|
+
await this.db.promotion.delete({
|
|
4239
|
+
where: {
|
|
4240
|
+
id
|
|
4241
|
+
}
|
|
4242
|
+
});
|
|
4243
|
+
}
|
|
4244
|
+
};
|
|
4245
|
+
PrismaPromotionRepository = _ts_decorate24([
|
|
4246
|
+
(0, import_common24.Injectable)(),
|
|
4247
|
+
_ts_param22(0, (0, import_common24.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
4248
|
+
_ts_metadata22("design:type", Function),
|
|
4249
|
+
_ts_metadata22("design:paramtypes", [
|
|
4250
|
+
typeof PromotionRepositoryClient === "undefined" ? Object : PromotionRepositoryClient
|
|
4251
|
+
])
|
|
4252
|
+
], PrismaPromotionRepository);
|
|
4253
|
+
function toPromotionValue(value) {
|
|
4254
|
+
if (typeof value === "number") return value;
|
|
4255
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
4256
|
+
const obj = value;
|
|
4257
|
+
return {
|
|
4258
|
+
price: Number(obj.price),
|
|
4259
|
+
months: Number(obj.months)
|
|
4260
|
+
};
|
|
4261
|
+
}
|
|
4262
|
+
throw new Error(`Promotion.value has an unexpected shape: ${JSON.stringify(value)}`);
|
|
4263
|
+
}
|
|
4264
|
+
__name(toPromotionValue, "toPromotionValue");
|
|
4265
|
+
function toNullableStringArray(value) {
|
|
4266
|
+
return Array.isArray(value) ? value : null;
|
|
4267
|
+
}
|
|
4268
|
+
__name(toNullableStringArray, "toNullableStringArray");
|
|
4269
|
+
function toPromotionI18n(value) {
|
|
4270
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
4271
|
+
return value;
|
|
4272
|
+
}
|
|
4273
|
+
return {};
|
|
4274
|
+
}
|
|
4275
|
+
__name(toPromotionI18n, "toPromotionI18n");
|
|
4276
|
+
function toRow3(row) {
|
|
4277
|
+
return {
|
|
4278
|
+
id: row.id,
|
|
4279
|
+
projectKey: row.projectKey,
|
|
4280
|
+
internalLabel: row.internalLabel,
|
|
4281
|
+
type: row.type,
|
|
4282
|
+
value: toPromotionValue(row.value),
|
|
4283
|
+
appliesTo: toStringArray(row.appliesTo),
|
|
4284
|
+
targetType: row.targetType,
|
|
4285
|
+
billingCycle: row.billingCycle,
|
|
4286
|
+
validFrom: row.validFrom.toISOString().slice(0, 10),
|
|
4287
|
+
validTo: row.validTo.toISOString().slice(0, 10),
|
|
4288
|
+
priority: row.priority,
|
|
4289
|
+
onlyLocales: toNullableStringArray(row.onlyLocales),
|
|
4290
|
+
requiresCoupon: row.requiresCoupon,
|
|
4291
|
+
codes: toStringArray(row.codes),
|
|
4292
|
+
color: row.color,
|
|
4293
|
+
i18n: toPromotionI18n(row.i18n),
|
|
4294
|
+
createdAt: row.createdAt.toISOString(),
|
|
4295
|
+
updatedAt: row.updatedAt.toISOString()
|
|
4296
|
+
};
|
|
4297
|
+
}
|
|
4298
|
+
__name(toRow3, "toRow");
|
|
4299
|
+
|
|
4300
|
+
// src/prisma-subscription-contract.repository.ts
|
|
4301
|
+
var import_common25 = require("@nestjs/common");
|
|
4302
|
+
function _ts_decorate25(decorators, target, key, desc) {
|
|
4303
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4304
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4305
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4306
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4307
|
+
}
|
|
4308
|
+
__name(_ts_decorate25, "_ts_decorate");
|
|
4309
|
+
function _ts_metadata23(k, v) {
|
|
4310
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4311
|
+
}
|
|
4312
|
+
__name(_ts_metadata23, "_ts_metadata");
|
|
4313
|
+
function _ts_param23(paramIndex, decorator) {
|
|
4314
|
+
return function(target, key) {
|
|
4315
|
+
decorator(target, key, paramIndex);
|
|
4316
|
+
};
|
|
4317
|
+
}
|
|
4318
|
+
__name(_ts_param23, "_ts_param");
|
|
4319
|
+
var ACTIVE_CONTRACT_STATUSES = [
|
|
4320
|
+
"active",
|
|
4321
|
+
"scheduled"
|
|
4322
|
+
];
|
|
4323
|
+
var PrismaSubscriptionContractRepository = class {
|
|
4324
|
+
static {
|
|
4325
|
+
__name(this, "PrismaSubscriptionContractRepository");
|
|
4326
|
+
}
|
|
4327
|
+
prisma;
|
|
4328
|
+
constructor(prisma) {
|
|
4329
|
+
this.prisma = prisma;
|
|
4330
|
+
}
|
|
4331
|
+
get db() {
|
|
4332
|
+
return this.prisma;
|
|
4333
|
+
}
|
|
4334
|
+
async list(filter) {
|
|
4335
|
+
const rows = await this.db.subscriptionContract.findMany({
|
|
4336
|
+
where: {
|
|
4337
|
+
...filter.projectKey ? {
|
|
4338
|
+
projectKey: filter.projectKey
|
|
4339
|
+
} : {},
|
|
4340
|
+
...filter.tenantId ? {
|
|
4341
|
+
tenantId: filter.tenantId
|
|
4342
|
+
} : {},
|
|
4343
|
+
...filter.status ? {
|
|
4344
|
+
status: filter.status
|
|
4345
|
+
} : {},
|
|
4346
|
+
...filter.asOf ? {
|
|
4347
|
+
effectiveFrom: {
|
|
4348
|
+
lte: filter.asOf
|
|
4349
|
+
},
|
|
4350
|
+
OR: [
|
|
4351
|
+
{
|
|
4352
|
+
effectiveUntil: null
|
|
4353
|
+
},
|
|
4354
|
+
{
|
|
4355
|
+
effectiveUntil: {
|
|
4356
|
+
gt: filter.asOf
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
]
|
|
4360
|
+
} : {}
|
|
4361
|
+
},
|
|
4362
|
+
include: {
|
|
4363
|
+
lineItems: true
|
|
4364
|
+
},
|
|
4365
|
+
orderBy: [
|
|
4366
|
+
{
|
|
4367
|
+
effectiveFrom: "desc"
|
|
4368
|
+
},
|
|
4369
|
+
{
|
|
4370
|
+
createdAt: "desc"
|
|
4371
|
+
}
|
|
4372
|
+
]
|
|
4373
|
+
});
|
|
4374
|
+
return rows.map(toRecord4);
|
|
4375
|
+
}
|
|
4376
|
+
async findById(contractId) {
|
|
4377
|
+
const row = await this.db.subscriptionContract.findUnique({
|
|
4378
|
+
where: {
|
|
4379
|
+
id: contractId
|
|
4380
|
+
},
|
|
4381
|
+
include: {
|
|
4382
|
+
lineItems: true
|
|
4383
|
+
}
|
|
4384
|
+
});
|
|
4385
|
+
return row ? toRecord4(row) : null;
|
|
4386
|
+
}
|
|
4387
|
+
async findActiveByTenantId(tenantId, asOf = /* @__PURE__ */ new Date()) {
|
|
4388
|
+
const row = await this.db.subscriptionContract.findFirst({
|
|
4389
|
+
where: {
|
|
4390
|
+
tenantId,
|
|
4391
|
+
status: {
|
|
4392
|
+
in: ACTIVE_CONTRACT_STATUSES
|
|
4393
|
+
},
|
|
4394
|
+
effectiveFrom: {
|
|
4395
|
+
lte: asOf
|
|
4396
|
+
},
|
|
4397
|
+
OR: [
|
|
4398
|
+
{
|
|
4399
|
+
effectiveUntil: null
|
|
4400
|
+
},
|
|
4401
|
+
{
|
|
4402
|
+
effectiveUntil: {
|
|
4403
|
+
gt: asOf
|
|
4404
|
+
}
|
|
4405
|
+
}
|
|
4406
|
+
]
|
|
4407
|
+
},
|
|
4408
|
+
include: {
|
|
4409
|
+
lineItems: true
|
|
4410
|
+
},
|
|
4411
|
+
orderBy: [
|
|
4412
|
+
{
|
|
4413
|
+
effectiveFrom: "desc"
|
|
4414
|
+
},
|
|
4415
|
+
{
|
|
4416
|
+
createdAt: "desc"
|
|
4417
|
+
}
|
|
4418
|
+
]
|
|
4419
|
+
});
|
|
4420
|
+
return row ? toRecord4(row) : null;
|
|
4421
|
+
}
|
|
4422
|
+
async create(data) {
|
|
4423
|
+
const row = await this.db.subscriptionContract.create({
|
|
4424
|
+
data: {
|
|
4425
|
+
projectKey: data.projectKey,
|
|
4426
|
+
tenantId: data.tenantId,
|
|
4427
|
+
status: data.status ?? "active",
|
|
4428
|
+
effectiveFrom: data.effectiveFrom,
|
|
4429
|
+
effectiveUntil: data.effectiveUntil ?? null,
|
|
4430
|
+
originalOfferId: data.originalOfferId ?? null,
|
|
4431
|
+
originalPlanVersionId: data.originalPlanVersionId ?? null,
|
|
4432
|
+
originalBundleVersionIds: data.originalBundleVersionIds ?? [],
|
|
4433
|
+
priceSnapshot: data.priceSnapshot,
|
|
4434
|
+
promotionSnapshots: data.promotionSnapshots ?? [],
|
|
4435
|
+
promoCodeSnapshots: data.promoCodeSnapshots ?? [],
|
|
4436
|
+
// Nullable JSON columns are omitted when absent so they stay SQL
|
|
4437
|
+
// NULL (the DbNull sentinel is not available in this package).
|
|
4438
|
+
...data.entitlementSnapshot != null ? {
|
|
4439
|
+
entitlementSnapshot: data.entitlementSnapshot
|
|
4440
|
+
} : {},
|
|
4441
|
+
...data.termsSnapshot != null ? {
|
|
4442
|
+
termsSnapshot: data.termsSnapshot
|
|
4443
|
+
} : {},
|
|
4444
|
+
lineItems: {
|
|
4445
|
+
create: data.lineItems.map(toLineItemCreate)
|
|
4446
|
+
}
|
|
4447
|
+
},
|
|
4448
|
+
include: {
|
|
4449
|
+
lineItems: true
|
|
4450
|
+
}
|
|
4451
|
+
});
|
|
4452
|
+
return toRecord4(row);
|
|
4453
|
+
}
|
|
4454
|
+
async terminate(contractId, data) {
|
|
4455
|
+
const row = await this.db.subscriptionContract.update({
|
|
4456
|
+
where: {
|
|
4457
|
+
id: contractId
|
|
4458
|
+
},
|
|
4459
|
+
data: {
|
|
4460
|
+
effectiveUntil: data.effectiveUntil,
|
|
4461
|
+
status: data.status
|
|
4462
|
+
},
|
|
4463
|
+
include: {
|
|
4464
|
+
lineItems: true
|
|
4465
|
+
}
|
|
4466
|
+
});
|
|
4467
|
+
return toRecord4(row);
|
|
4468
|
+
}
|
|
4469
|
+
};
|
|
4470
|
+
PrismaSubscriptionContractRepository = _ts_decorate25([
|
|
4471
|
+
(0, import_common25.Injectable)(),
|
|
4472
|
+
_ts_param23(0, (0, import_common25.Inject)(PRISMA_CLIENT_TOKEN)),
|
|
4473
|
+
_ts_metadata23("design:type", Function),
|
|
4474
|
+
_ts_metadata23("design:paramtypes", [
|
|
4475
|
+
typeof PrismaLike === "undefined" ? Object : PrismaLike
|
|
4476
|
+
])
|
|
4477
|
+
], PrismaSubscriptionContractRepository);
|
|
4478
|
+
function toLineItemCreate(item) {
|
|
4479
|
+
return {
|
|
4480
|
+
kind: item.kind,
|
|
4481
|
+
sourceKey: item.sourceKey,
|
|
4482
|
+
sourceVersionId: item.sourceVersionId ?? null,
|
|
4483
|
+
titleSnapshot: item.titleSnapshot,
|
|
4484
|
+
descriptionSnapshot: item.descriptionSnapshot ?? null,
|
|
4485
|
+
quantity: item.quantity,
|
|
4486
|
+
unit: item.unit ?? null,
|
|
4487
|
+
priceNet: item.priceNet,
|
|
4488
|
+
priceGross: item.priceGross,
|
|
4489
|
+
billingCycle: item.billingCycle,
|
|
4490
|
+
minimumTermUntil: item.minimumTermUntil ?? null,
|
|
4491
|
+
featuresSnapshot: item.featuresSnapshot,
|
|
4492
|
+
quotaEffectsSnapshot: item.quotaEffectsSnapshot,
|
|
4493
|
+
...item.metadata != null ? {
|
|
4494
|
+
metadata: item.metadata
|
|
4495
|
+
} : {}
|
|
4496
|
+
};
|
|
4497
|
+
}
|
|
4498
|
+
__name(toLineItemCreate, "toLineItemCreate");
|
|
4499
|
+
function isPlainObject2(value) {
|
|
4500
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4501
|
+
}
|
|
4502
|
+
__name(isPlainObject2, "isPlainObject");
|
|
4503
|
+
function toUnknownArray(value) {
|
|
4504
|
+
return Array.isArray(value) ? value : [];
|
|
4505
|
+
}
|
|
4506
|
+
__name(toUnknownArray, "toUnknownArray");
|
|
4507
|
+
function toRecordOrNull(value) {
|
|
4508
|
+
return isPlainObject2(value) ? value : null;
|
|
4509
|
+
}
|
|
4510
|
+
__name(toRecordOrNull, "toRecordOrNull");
|
|
4511
|
+
function toLineItem(row) {
|
|
4512
|
+
return {
|
|
4513
|
+
id: row.id,
|
|
4514
|
+
contractId: row.contractId,
|
|
4515
|
+
kind: row.kind,
|
|
4516
|
+
sourceKey: row.sourceKey,
|
|
4517
|
+
sourceVersionId: row.sourceVersionId,
|
|
4518
|
+
titleSnapshot: row.titleSnapshot,
|
|
4519
|
+
descriptionSnapshot: row.descriptionSnapshot,
|
|
4520
|
+
quantity: row.quantity,
|
|
4521
|
+
unit: row.unit,
|
|
4522
|
+
priceNet: Number(row.priceNet),
|
|
4523
|
+
priceGross: Number(row.priceGross),
|
|
4524
|
+
billingCycle: row.billingCycle,
|
|
4525
|
+
minimumTermUntil: row.minimumTermUntil,
|
|
4526
|
+
featuresSnapshot: toStringArray(row.featuresSnapshot),
|
|
4527
|
+
quotaEffectsSnapshot: toQuotaMap(row.quotaEffectsSnapshot),
|
|
4528
|
+
metadata: toRecordOrNull(row.metadata),
|
|
4529
|
+
createdAt: row.createdAt
|
|
4530
|
+
};
|
|
4531
|
+
}
|
|
4532
|
+
__name(toLineItem, "toLineItem");
|
|
4533
|
+
function toRecord4(row) {
|
|
4534
|
+
return {
|
|
4535
|
+
id: row.id,
|
|
4536
|
+
projectKey: row.projectKey,
|
|
4537
|
+
tenantId: row.tenantId,
|
|
4538
|
+
status: row.status,
|
|
4539
|
+
effectiveFrom: row.effectiveFrom,
|
|
4540
|
+
effectiveUntil: row.effectiveUntil,
|
|
4541
|
+
originalOfferId: row.originalOfferId,
|
|
4542
|
+
originalPlanVersionId: row.originalPlanVersionId,
|
|
4543
|
+
originalBundleVersionIds: toStringArray(row.originalBundleVersionIds),
|
|
4544
|
+
entitlementSnapshot: isPlainObject2(row.entitlementSnapshot) ? row.entitlementSnapshot : null,
|
|
4545
|
+
priceSnapshot: row.priceSnapshot,
|
|
4546
|
+
promotionSnapshots: toUnknownArray(row.promotionSnapshots),
|
|
4547
|
+
promoCodeSnapshots: toUnknownArray(row.promoCodeSnapshots),
|
|
4548
|
+
termsSnapshot: toRecordOrNull(row.termsSnapshot),
|
|
4549
|
+
lineItems: row.lineItems.map(toLineItem),
|
|
4550
|
+
createdAt: row.createdAt,
|
|
4551
|
+
updatedAt: row.updatedAt
|
|
4552
|
+
};
|
|
4553
|
+
}
|
|
4554
|
+
__name(toRecord4, "toRecord");
|
|
1463
4555
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1464
4556
|
0 && (module.exports = {
|
|
1465
4557
|
AsyncLocalRlsBypassAdapter,
|
|
1466
4558
|
PASSWORD_HASHER_TOKEN,
|
|
4559
|
+
PRISMA_BUNDLE_REPOSITORY_OPTIONS,
|
|
1467
4560
|
PRISMA_CLIENT_TOKEN,
|
|
4561
|
+
PRISMA_SCHEMA_OPTIONS_TOKEN,
|
|
1468
4562
|
PrismaAuditAdapter,
|
|
1469
4563
|
PrismaAuditQueryAdapter,
|
|
1470
4564
|
PrismaAuditStatsAdapter,
|
|
4565
|
+
PrismaBundleRepository,
|
|
4566
|
+
PrismaCatalogEntryRepository,
|
|
4567
|
+
PrismaMarketingProjectionRepository,
|
|
4568
|
+
PrismaMarketingSettingsRepository,
|
|
1471
4569
|
PrismaMfaAdapter,
|
|
1472
4570
|
PrismaPlanCatalogImportSink,
|
|
1473
4571
|
PrismaPlanCatalogReadSink,
|
|
4572
|
+
PrismaPlanRepository,
|
|
1474
4573
|
PrismaPlanVersionRepository,
|
|
1475
4574
|
PrismaPromoCodeRedemptionRepository,
|
|
1476
4575
|
PrismaPromoCodeRepository,
|
|
1477
4576
|
PrismaPromoCodeValidationLogRepository,
|
|
1478
4577
|
PrismaPromoSubscriptionLookup,
|
|
4578
|
+
PrismaPromotionRepository,
|
|
4579
|
+
PrismaSubscriptionBundleRepository,
|
|
4580
|
+
PrismaSubscriptionContractRepository,
|
|
1479
4581
|
PrismaSubscriptionRepository,
|
|
1480
4582
|
PrismaSuperAdminBootstrapAdapter,
|
|
4583
|
+
PrismaTenantSubscriptionWriteAdapter,
|
|
1481
4584
|
PrismaTransactionRunner,
|
|
1482
4585
|
ZeroPromoRevenueDeductionAggregator,
|
|
1483
4586
|
buildActorTag,
|
|
1484
|
-
|
|
4587
|
+
createPrismaPlanBindingResolver,
|
|
4588
|
+
getPrismaDelegate,
|
|
4589
|
+
prismaPersistence,
|
|
4590
|
+
resolvePrismaSchemaOptions
|
|
1485
4591
|
});
|