@saasicat/core 1.0.0-rc.6 → 1.0.0-rc.7
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 +2 -1
- package/dist/.build-stamp +1 -1
- package/dist/index.cjs +229 -12
- package/dist/index.d.cts +679 -448
- package/dist/index.d.ts +679 -448
- package/dist/index.js +217 -11
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
/** Start of day (00:00 UTC) of the moment — for day-inclusive date comparisons. */
|
|
2
2
|
declare function startOfUtcDay(date: Date): Date;
|
|
3
|
+
/**
|
|
4
|
+
* The day before `value` — how a validity window closes when its successor
|
|
5
|
+
* opens (`validUntil = successor.validFrom − 1 day`, the rule this module's
|
|
6
|
+
* header states and `startOfUtcDay` above is the reading half of).
|
|
7
|
+
*
|
|
8
|
+
* It lived as three separate expressions before 2026-08-27: one in each
|
|
9
|
+
* adapter's publish path and one in the bundle repository, all agreeing by
|
|
10
|
+
* coincidence rather than by construction. Day arithmetic rather than
|
|
11
|
+
* `− 24 * 60 * 60 * 1000`: the subtraction is only equivalent while the value
|
|
12
|
+
* is a UTC midnight, and nothing in the type says it is.
|
|
13
|
+
*/
|
|
14
|
+
declare function previousUtcDay(value: Date): Date;
|
|
3
15
|
/** `<=` upper bound for a date (structurally Prisma-compatible). */
|
|
4
16
|
interface DateAtOrBefore {
|
|
5
17
|
lte: Date;
|
|
@@ -73,256 +85,6 @@ type ActiveVersionWhereWithEndsAt = ActivePlanVersionWhereWithEndsAt;
|
|
|
73
85
|
*/
|
|
74
86
|
declare const buildActiveVersionWhere: typeof buildActivePlanVersionWhere;
|
|
75
87
|
|
|
76
|
-
type FeatureKey = string;
|
|
77
|
-
type PlanId = string;
|
|
78
|
-
type QuotaKey = string;
|
|
79
|
-
interface FeatureDef {
|
|
80
|
-
key: FeatureKey;
|
|
81
|
-
label?: string;
|
|
82
|
-
icon?: string;
|
|
83
|
-
/** CORE / ADVANCED / PRO / BUSINESS / ENTERPRISE_ONLY — convention. */
|
|
84
|
-
tier?: string;
|
|
85
|
-
plannedOnly?: boolean;
|
|
86
|
-
}
|
|
87
|
-
interface PlanDef {
|
|
88
|
-
id: PlanId;
|
|
89
|
-
name?: string;
|
|
90
|
-
tagline?: string;
|
|
91
|
-
/** false = not selectable in self-service onboarding. Default: true. */
|
|
92
|
-
marketed?: boolean;
|
|
93
|
-
/** Highlighted card in onboarding (max. 1 per catalog). */
|
|
94
|
-
popular?: boolean;
|
|
95
|
-
/** Net monthly price. null = on request. */
|
|
96
|
-
monthlyNet?: number | null;
|
|
97
|
-
/** Net total amount per year. null = monthly only. */
|
|
98
|
-
yearlyNet?: number | null;
|
|
99
|
-
/** Map quotaKey → max value. -1 = unlimited. */
|
|
100
|
-
quotas: Record<QuotaKey, number>;
|
|
101
|
-
features: FeatureKey[];
|
|
102
|
-
}
|
|
103
|
-
/** App-wide marketing configuration. */
|
|
104
|
-
interface PlanCatalogMarketing {
|
|
105
|
-
/**
|
|
106
|
-
* Allowed language pool that the app may market. First = default
|
|
107
|
-
* locale. From it, the SuperAdmin activates a subset in the marketing
|
|
108
|
-
* catalog (LocaleManager).
|
|
109
|
-
*/
|
|
110
|
-
availableLocales: string[];
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* App identity block for branding + version. Consumed by the `AdminPublicBootController`
|
|
114
|
-
* and the `AdminManifestConfigFactory`; the SuperAdmin UI (platform
|
|
115
|
-
* LoginPage, AdminLayout brand block) reads the same fields via PublicBoot.
|
|
116
|
-
*
|
|
117
|
-
* `name` = brand display name (e.g. "DemoApp", "ClubApp").
|
|
118
|
-
* `label` = tag/subtitle in the brand block (e.g. "SuperAdmin").
|
|
119
|
-
* `version` = app version string (build info).
|
|
120
|
-
* `icon` = 2-character abbreviation for the logo badge (e.g. "ma", "da").
|
|
121
|
-
* `logoUrl` = optional URL to a PNG/SVG; if set, the UI renders an <img>
|
|
122
|
-
* instead of the initials badge.
|
|
123
|
-
*/
|
|
124
|
-
interface PlanCatalogApp {
|
|
125
|
-
name: string;
|
|
126
|
-
label?: string;
|
|
127
|
-
version?: string;
|
|
128
|
-
icon?: string;
|
|
129
|
-
logoUrl?: string;
|
|
130
|
-
}
|
|
131
|
-
interface PlanCatalog {
|
|
132
|
-
schemaVersion: 1;
|
|
133
|
-
projectKey: string;
|
|
134
|
-
/** App identity (branding + version), see PlanCatalogApp. Optional. */
|
|
135
|
-
app?: PlanCatalogApp;
|
|
136
|
-
/** ISO-4217 currency code. */
|
|
137
|
-
currency: string;
|
|
138
|
-
/** VAT rate in percent. */
|
|
139
|
-
vatRate: number;
|
|
140
|
-
/** App-wide marketing configuration. Optional. */
|
|
141
|
-
marketing?: PlanCatalogMarketing;
|
|
142
|
-
features?: FeatureDef[];
|
|
143
|
-
/**
|
|
144
|
-
* Optional. When omitted, plans come exclusively from the
|
|
145
|
-
* AdminUI / DB table (Plans/PlanVersions lifecycle).
|
|
146
|
-
*/
|
|
147
|
-
plans?: PlanDef[];
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/** Backend capability key, convention: domain.action[.action]. */
|
|
151
|
-
type CapabilityKey = string;
|
|
152
|
-
/** Frontend action-registry key. Same convention as CapabilityKey. */
|
|
153
|
-
type ActionKey = CapabilityKey;
|
|
154
|
-
/** Lookup key in the static extensions: map of the UI build. */
|
|
155
|
-
type ComponentKey = string;
|
|
156
|
-
interface AdminManifest {
|
|
157
|
-
schemaVersion: 1;
|
|
158
|
-
project: {
|
|
159
|
-
key: string;
|
|
160
|
-
displayName: string;
|
|
161
|
-
/** Tag/subtitle (e.g. "SuperAdmin"). From `saas.yaml#app.label`. */
|
|
162
|
-
label?: string;
|
|
163
|
-
/** Short abbreviation for the logo badge (e.g. "ma", "da"). From `saas.yaml#app.icon`. */
|
|
164
|
-
icon?: string;
|
|
165
|
-
logoUrl?: string;
|
|
166
|
-
environment?: 'production' | 'staging' | 'development';
|
|
167
|
-
/**
|
|
168
|
-
* Allowed locale pool from the app config (`saas.yaml`
|
|
169
|
-
* `marketing.availableLocales`). First = default..
|
|
170
|
-
*/
|
|
171
|
-
availableLocales?: string[];
|
|
172
|
-
/** Default locale; equals `availableLocales[0]`. */
|
|
173
|
-
defaultLocale?: string;
|
|
174
|
-
};
|
|
175
|
-
build: {
|
|
176
|
-
platformPackageVersion: string;
|
|
177
|
-
appVersion: string;
|
|
178
|
-
manifestHash: string;
|
|
179
|
-
};
|
|
180
|
-
planCatalogSnapshot: {
|
|
181
|
-
source: string;
|
|
182
|
-
hash: string;
|
|
183
|
-
currency: string;
|
|
184
|
-
vatRate: number;
|
|
185
|
-
features?: FeatureDef[];
|
|
186
|
-
plans: PlanDef[];
|
|
187
|
-
};
|
|
188
|
-
/** Map CapabilityKey → boolean. Manifest is never a security source. */
|
|
189
|
-
capabilities: Record<CapabilityKey, boolean>;
|
|
190
|
-
navigation: {
|
|
191
|
-
standardPages: Partial<Record<StandardPageKey, StandardPageDef>>;
|
|
192
|
-
projectPages?: ProjectPageDef[];
|
|
193
|
-
};
|
|
194
|
-
dashboard?: {
|
|
195
|
-
kpiCards?: KpiCardDef[];
|
|
196
|
-
};
|
|
197
|
-
tenants?: {
|
|
198
|
-
columns?: TenantColumnDef[];
|
|
199
|
-
actions?: TenantActionDef[];
|
|
200
|
-
};
|
|
201
|
-
audit?: {
|
|
202
|
-
actions?: AuditActionDef[];
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
type StandardPageKey = 'dashboard' | 'tenants' | 'subscriptions' | 'promoCodes' | 'plans' | 'audit' | 'users' | 'pilots' | 'discovery' | 'bundles' | 'marketingCatalog' | 'platformEmail' | 'platformEmailHistory';
|
|
206
|
-
interface StandardPageDef {
|
|
207
|
-
enabled: boolean;
|
|
208
|
-
requiredCapability?: CapabilityKey;
|
|
209
|
-
}
|
|
210
|
-
interface ProjectPageDef {
|
|
211
|
-
/** `<projectKey>.<area>`, e.g. `demoapp.datev`. */
|
|
212
|
-
id: string;
|
|
213
|
-
label: string;
|
|
214
|
-
icon?: string;
|
|
215
|
-
/** Frontend route, e.g. `/admin/datev`. */
|
|
216
|
-
route: string;
|
|
217
|
-
navSection?: string;
|
|
218
|
-
/** Lookup in the static extensions: map of the shell build. */
|
|
219
|
-
componentKey: ComponentKey;
|
|
220
|
-
requiredCapability?: CapabilityKey;
|
|
221
|
-
prefetchOnIdle?: boolean;
|
|
222
|
-
}
|
|
223
|
-
interface KpiCardDef {
|
|
224
|
-
id: string;
|
|
225
|
-
label: string;
|
|
226
|
-
/** Required path: /api/v1/admin/(extras|dashboard)/... */
|
|
227
|
-
endpoint: string;
|
|
228
|
-
displayHint: KpiDisplayHint;
|
|
229
|
-
/** 0–100; UI sorts descending. */
|
|
230
|
-
slotPriority?: number;
|
|
231
|
-
requiredCapability?: CapabilityKey;
|
|
232
|
-
}
|
|
233
|
-
interface KpiDisplayHint {
|
|
234
|
-
type: 'value' | 'value+timestamp' | 'value+spark8w' | 'value+delta';
|
|
235
|
-
icon?: string;
|
|
236
|
-
}
|
|
237
|
-
interface TenantColumnDef {
|
|
238
|
-
key: string;
|
|
239
|
-
label: string;
|
|
240
|
-
/** Required path: /api/v1/admin/extras/...; MUST be batch-capable, no {slug}/{tenantId}. */
|
|
241
|
-
endpoint: string;
|
|
242
|
-
requiredCapability?: CapabilityKey;
|
|
243
|
-
}
|
|
244
|
-
interface TenantActionDef {
|
|
245
|
-
/** `<projectKey>.<area>.<verb>`, e.g. `demoapp.datev.runExport`. */
|
|
246
|
-
id: string;
|
|
247
|
-
label: string;
|
|
248
|
-
/** Lookup in the static actions: map of the shell build. */
|
|
249
|
-
actionKey: ActionKey;
|
|
250
|
-
requiredCapability?: CapabilityKey;
|
|
251
|
-
requiresMfa?: boolean;
|
|
252
|
-
confirmType?: 'none' | 'simple' | 'typed-slug' | 'typed-production' | 'date';
|
|
253
|
-
}
|
|
254
|
-
interface AuditActionDef {
|
|
255
|
-
/** SCREAMING_SNAKE_CASE; matched to the AuditLog.action column. */
|
|
256
|
-
key: string;
|
|
257
|
-
label: string;
|
|
258
|
-
severity?: 'info' | 'low' | 'medium' | 'high';
|
|
259
|
-
}
|
|
260
|
-
interface ManifestContribution {
|
|
261
|
-
capabilities?: Record<CapabilityKey, boolean>;
|
|
262
|
-
navigation?: {
|
|
263
|
-
standardPages?: Partial<Record<StandardPageKey, StandardPageDef>>;
|
|
264
|
-
projectPages?: ProjectPageDef[];
|
|
265
|
-
};
|
|
266
|
-
dashboard?: {
|
|
267
|
-
kpiCards?: KpiCardDef[];
|
|
268
|
-
};
|
|
269
|
-
tenants?: {
|
|
270
|
-
columns?: TenantColumnDef[];
|
|
271
|
-
actions?: TenantActionDef[];
|
|
272
|
-
};
|
|
273
|
-
audit?: {
|
|
274
|
-
actions?: AuditActionDef[];
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
interface PublicBootResponse {
|
|
278
|
-
project: {
|
|
279
|
-
key: string;
|
|
280
|
-
displayName: string;
|
|
281
|
-
/** Tag/subtitle (e.g. "SuperAdmin"). From `saas.yaml#app.label`. */
|
|
282
|
-
label?: string;
|
|
283
|
-
/** Short abbreviation for the logo badge (e.g. "ma", "da"). From `saas.yaml#app.icon`. */
|
|
284
|
-
icon?: string;
|
|
285
|
-
logoUrl?: string;
|
|
286
|
-
environment?: 'production' | 'staging' | 'development';
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/** Format: 'web:<email>:<sessionId>' or 'cli:<email>:<host>'. */
|
|
291
|
-
type ActorTag = string;
|
|
292
|
-
interface AuditEntry {
|
|
293
|
-
id: string;
|
|
294
|
-
/** null = platform action without tenant context (SUPER_ADMIN). */
|
|
295
|
-
tenantId: string | null;
|
|
296
|
-
/** null = system / cron-triggered. */
|
|
297
|
-
userId: string | null;
|
|
298
|
-
/** Convenience field; backend resolves it from userId. */
|
|
299
|
-
userEmail: string | null;
|
|
300
|
-
/** e.g. 'Tenant', 'PromoCode', 'Subscription', 'PlanVersion', 'User'. */
|
|
301
|
-
entity: string;
|
|
302
|
-
entityId: string;
|
|
303
|
-
/** SCREAMING_SNAKE_CASE; past-tense oriented. */
|
|
304
|
-
action: string;
|
|
305
|
-
/** Freely structured. Convention: { field: { old, new } } or { reason, ... }. */
|
|
306
|
-
changes: Record<string, unknown> | null;
|
|
307
|
-
actorTag: ActorTag | null;
|
|
308
|
-
ipAddress: string | null;
|
|
309
|
-
userAgent: string | null;
|
|
310
|
-
createdAt: string;
|
|
311
|
-
}
|
|
312
|
-
interface AuditQuery {
|
|
313
|
-
tenantId?: string;
|
|
314
|
-
userId?: string;
|
|
315
|
-
entity?: string;
|
|
316
|
-
entityId?: string;
|
|
317
|
-
action?: string;
|
|
318
|
-
/** Wildcard-capable, e.g. 'cli:*'. */
|
|
319
|
-
actorTag?: string;
|
|
320
|
-
from?: string;
|
|
321
|
-
to?: string;
|
|
322
|
-
page?: number;
|
|
323
|
-
pageSize?: number;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
88
|
/**
|
|
327
89
|
* Approval lifecycle of a feature or a quota. Approval happens per
|
|
328
90
|
* FEATURE/QUOTA — not per capability (#20); only `approved` entries
|
|
@@ -385,7 +147,6 @@ type CatalogEntryI18n = Record<string, CatalogEntryI18nFields>;
|
|
|
385
147
|
*/
|
|
386
148
|
interface CapabilityCatalogEntryRow {
|
|
387
149
|
id: string;
|
|
388
|
-
projectKey: string;
|
|
389
150
|
capabilityKey: string;
|
|
390
151
|
label: string;
|
|
391
152
|
description: string | null;
|
|
@@ -422,7 +183,6 @@ type FeatureTier = 'CORE' | 'ADVANCED' | 'PRO' | 'ENTERPRISE' | string;
|
|
|
422
183
|
*/
|
|
423
184
|
interface FeatureCatalogEntryRow {
|
|
424
185
|
id: string;
|
|
425
|
-
projectKey: string;
|
|
426
186
|
featureKey: string;
|
|
427
187
|
label: string;
|
|
428
188
|
description: string | null;
|
|
@@ -477,7 +237,6 @@ interface FeatureCatalogEntryRow {
|
|
|
477
237
|
*/
|
|
478
238
|
interface QuotaCatalogEntryRow {
|
|
479
239
|
id: string;
|
|
480
|
-
projectKey: string;
|
|
481
240
|
quotaKey: string;
|
|
482
241
|
label: string;
|
|
483
242
|
description: string | null;
|
|
@@ -521,7 +280,6 @@ interface QuotaCatalogEntryRow {
|
|
|
521
280
|
* matching field is relevant.
|
|
522
281
|
*/
|
|
523
282
|
interface CatalogEntryFilter {
|
|
524
|
-
projectKey: string;
|
|
525
283
|
discoveryStatus?: DiscoveryStatus;
|
|
526
284
|
codeStatus?: CapabilityCodeStatus;
|
|
527
285
|
}
|
|
@@ -635,7 +393,6 @@ declare const MARKETING_PRIORITY_MAX = 10000;
|
|
|
635
393
|
*/
|
|
636
394
|
interface MarketingProjectionRow {
|
|
637
395
|
id: string;
|
|
638
|
-
projectKey: string;
|
|
639
396
|
targetType: MarketingTargetType;
|
|
640
397
|
targetVersionId: string;
|
|
641
398
|
/** ISO-639-1, optionally with region suffix (`de`, `en`, `de-AT`). */
|
|
@@ -680,15 +437,13 @@ interface MarketingProjectionRow {
|
|
|
680
437
|
createdAt: string;
|
|
681
438
|
updatedAt: string;
|
|
682
439
|
}
|
|
683
|
-
/** Filter for `MarketingProjectionRepository.list()`.
|
|
440
|
+
/** Filter for `MarketingProjectionRepository.list()`. */
|
|
684
441
|
interface MarketingProjectionFilter {
|
|
685
|
-
projectKey: string;
|
|
686
442
|
targetType?: MarketingTargetType;
|
|
687
443
|
targetVersionId?: string;
|
|
688
444
|
locale?: string;
|
|
689
445
|
}
|
|
690
446
|
interface CreateMarketingProjectionData {
|
|
691
|
-
projectKey: string;
|
|
692
447
|
targetType: MarketingTargetType;
|
|
693
448
|
targetVersionId: string;
|
|
694
449
|
locale?: string;
|
|
@@ -718,14 +473,87 @@ interface UpdateMarketingProjectionData {
|
|
|
718
473
|
highlight?: boolean;
|
|
719
474
|
}
|
|
720
475
|
|
|
721
|
-
type
|
|
722
|
-
type
|
|
723
|
-
type
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
/**
|
|
476
|
+
type FeatureKey = string;
|
|
477
|
+
type PlanId = string;
|
|
478
|
+
type QuotaKey = string;
|
|
479
|
+
interface FeatureDef {
|
|
480
|
+
key: FeatureKey;
|
|
481
|
+
label?: string;
|
|
482
|
+
icon?: string;
|
|
483
|
+
/** CORE / ADVANCED / PRO / BUSINESS / ENTERPRISE_ONLY — convention. */
|
|
484
|
+
tier?: string;
|
|
485
|
+
plannedOnly?: boolean;
|
|
486
|
+
}
|
|
487
|
+
interface PlanDef {
|
|
488
|
+
id: PlanId;
|
|
489
|
+
name?: string;
|
|
490
|
+
tagline?: string;
|
|
491
|
+
/** false = not selectable in self-service onboarding. Default: true. */
|
|
492
|
+
marketed?: boolean;
|
|
493
|
+
/** Highlighted card in onboarding (max. 1 per catalog). */
|
|
494
|
+
popular?: boolean;
|
|
495
|
+
/** Net monthly price. null = on request. */
|
|
496
|
+
monthlyNet?: number | null;
|
|
497
|
+
/** Net total amount per year. null = monthly only. */
|
|
498
|
+
yearlyNet?: number | null;
|
|
499
|
+
/** Map quotaKey → max value. -1 = unlimited. */
|
|
500
|
+
quotas: Record<QuotaKey, number>;
|
|
501
|
+
features: FeatureKey[];
|
|
502
|
+
}
|
|
503
|
+
/** App-wide marketing configuration. */
|
|
504
|
+
interface PlanCatalogMarketing {
|
|
505
|
+
/**
|
|
506
|
+
* Allowed language pool that the app may market. First = default
|
|
507
|
+
* locale. From it, the SuperAdmin activates a subset in the marketing
|
|
508
|
+
* catalog (LocaleManager).
|
|
509
|
+
*/
|
|
510
|
+
availableLocales: string[];
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* App identity block for branding + version. Consumed by the `AdminPublicBootController`
|
|
514
|
+
* and the `AdminManifestConfigFactory`; the SuperAdmin UI (platform
|
|
515
|
+
* LoginPage, AdminLayout brand block) reads the same fields via PublicBoot.
|
|
516
|
+
*
|
|
517
|
+
* `name` = brand display name (e.g. "DemoApp", "ClubApp").
|
|
518
|
+
* `label` = tag/subtitle in the brand block (e.g. "SuperAdmin").
|
|
519
|
+
* `version` = app version string (build info).
|
|
520
|
+
* `icon` = 2-character abbreviation for the logo badge (e.g. "ma", "da").
|
|
521
|
+
* `logoUrl` = optional URL to a PNG/SVG; if set, the UI renders an <img>
|
|
522
|
+
* instead of the initials badge.
|
|
523
|
+
*/
|
|
524
|
+
interface PlanCatalogApp {
|
|
525
|
+
name: string;
|
|
526
|
+
label?: string;
|
|
527
|
+
version?: string;
|
|
528
|
+
icon?: string;
|
|
529
|
+
logoUrl?: string;
|
|
530
|
+
}
|
|
531
|
+
interface PlanCatalog {
|
|
532
|
+
schemaVersion: 1;
|
|
533
|
+
/** App identity (branding + version), see PlanCatalogApp. */
|
|
534
|
+
app: PlanCatalogApp;
|
|
535
|
+
/** ISO-4217 currency code. */
|
|
536
|
+
currency: string;
|
|
537
|
+
/** VAT rate in percent. */
|
|
538
|
+
vatRate: number;
|
|
539
|
+
/** App-wide marketing configuration. Optional. */
|
|
540
|
+
marketing?: PlanCatalogMarketing;
|
|
541
|
+
features?: FeatureDef[];
|
|
542
|
+
/**
|
|
543
|
+
* Optional. When omitted, plans come exclusively from the
|
|
544
|
+
* AdminUI / DB table (Plans/PlanVersions lifecycle).
|
|
545
|
+
*/
|
|
546
|
+
plans?: PlanDef[];
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
type PromoCodeValueType = 'PERCENT' | 'ABSOLUTE';
|
|
550
|
+
type PromoCodeDurationType = 'ONCE' | 'MONTHS' | 'BILLING_CYCLES';
|
|
551
|
+
type PromoCodeStatus = 'ACTIVE' | 'PAUSED' | 'EXHAUSTED' | 'EXPIRED';
|
|
552
|
+
type PromoCodeRedemptionStatus = 'ACTIVE' | 'REVERSED' | 'EXPIRED';
|
|
553
|
+
type BillingCycle = 'MONTHLY' | 'YEARLY';
|
|
554
|
+
type PromoCodeValidationResult = 'VALID' | 'EXPIRED' | 'EXHAUSTED' | 'NOT_FOUND' | 'PAUSED' | 'NOT_APPLICABLE' | 'FIRST_TIME_ONLY' | 'ZERO_INVOICE_BLOCKED' | 'MIN_AMOUNT_NOT_REACHED' | 'RATE_LIMITED';
|
|
555
|
+
interface CreatePromoCodeRequest {
|
|
556
|
+
/** A–Z, 0–9, '-' and '_'; 4–32 characters; case-insensitive, stored in UPPER. */
|
|
729
557
|
code: string;
|
|
730
558
|
valueType: PromoCodeValueType;
|
|
731
559
|
/** For PERCENT: 0.01–100. For ABSOLUTE: > 0 in catalog currency. */
|
|
@@ -914,7 +742,7 @@ interface VersionedEntityBase {
|
|
|
914
742
|
* own migration).
|
|
915
743
|
* - `startedAt` is the contract start of this booking.
|
|
916
744
|
* - `minimumTermEndsAt` = end of the minimum term; `null` = no minimum term
|
|
917
|
-
* (platform default =
|
|
745
|
+
* (platform default = no commitment, set service-side).
|
|
918
746
|
* - `canceledAt` / `canceledEffectiveAt`: cancellation anchor vs. effective
|
|
919
747
|
* date. Before the minimum term ends, `canceledEffectiveAt =
|
|
920
748
|
* minimumTermEndsAt`, otherwise the subscription's period end.
|
|
@@ -931,6 +759,18 @@ interface SubscriptionBundleRecord {
|
|
|
931
759
|
minimumTermEndsAt: Date | null;
|
|
932
760
|
canceledAt: Date | null;
|
|
933
761
|
canceledEffectiveAt: Date | null;
|
|
762
|
+
/**
|
|
763
|
+
* The rhythm this booking is billed in, and the window it is billed for.
|
|
764
|
+
*
|
|
765
|
+
* A bundle's periods end on the day its plan's do — the first one short,
|
|
766
|
+
* from the booking to the next occurrence of that day, and every one after
|
|
767
|
+
* it anchor to anchor. Null on a booking made before these fields existed,
|
|
768
|
+
* or on one whose plan has no period; readers fall back to the plan's
|
|
769
|
+
* cycle, which is what every booking used before.
|
|
770
|
+
*/
|
|
771
|
+
billingCycle: string | null;
|
|
772
|
+
currentPeriodStart: Date | null;
|
|
773
|
+
currentPeriodEnd: Date | null;
|
|
934
774
|
createdAt: Date;
|
|
935
775
|
updatedAt: Date;
|
|
936
776
|
}
|
|
@@ -944,14 +784,27 @@ interface SubscriptionBundleRecord {
|
|
|
944
784
|
interface SubscriptionBundleView extends SubscriptionBundleRecord {
|
|
945
785
|
bundleKey: string | null;
|
|
946
786
|
label: string | null;
|
|
947
|
-
|
|
787
|
+
/**
|
|
788
|
+
* What this booking is billed at, in the rhythm it was booked in and with
|
|
789
|
+
* the plan's pricing override applied.
|
|
790
|
+
*
|
|
791
|
+
* It was `monthlyNet` until 2026-08-27 and carried the bundle's base
|
|
792
|
+
* monthly price whatever the booking was — so a yearly booking of a bundle
|
|
793
|
+
* priced 10 monthly and 100 yearly reported 10. The name was half the
|
|
794
|
+
* defect: a field called `monthlyNet` on a yearly booking cannot be right.
|
|
795
|
+
*/
|
|
796
|
+
priceNet: number | null;
|
|
948
797
|
}
|
|
949
798
|
interface CreateSubscriptionBundleData {
|
|
950
799
|
subscriptionId: string;
|
|
951
800
|
bundleVersionId: string;
|
|
952
801
|
startedAt: Date;
|
|
953
|
-
/**
|
|
802
|
+
/** Null unless a commitment was configured or asked for. */
|
|
954
803
|
minimumTermEndsAt?: Date | null;
|
|
804
|
+
/** The rhythm and window worked out above this port. */
|
|
805
|
+
billingCycle?: string | null;
|
|
806
|
+
currentPeriodStart?: Date | null;
|
|
807
|
+
currentPeriodEnd?: Date | null;
|
|
955
808
|
}
|
|
956
809
|
interface CancelSubscriptionBundleData {
|
|
957
810
|
canceledAt: Date;
|
|
@@ -1000,7 +853,6 @@ interface BundlePricingOverride {
|
|
|
1000
853
|
*/
|
|
1001
854
|
interface BundleRow {
|
|
1002
855
|
id: string;
|
|
1003
|
-
projectKey: string;
|
|
1004
856
|
bundleKey: string;
|
|
1005
857
|
label: string;
|
|
1006
858
|
description: string | null;
|
|
@@ -1039,7 +891,6 @@ interface BundleVersionRow extends VersionedEntityBase {
|
|
|
1039
891
|
* first BundleVersion via `CreateBundleVersionDraftData`.
|
|
1040
892
|
*/
|
|
1041
893
|
interface CreateBundleData {
|
|
1042
|
-
projectKey: string;
|
|
1043
894
|
bundleKey: string;
|
|
1044
895
|
label: string;
|
|
1045
896
|
description?: string | null;
|
|
@@ -1048,9 +899,9 @@ interface CreateBundleData {
|
|
|
1048
899
|
i18n?: CatalogEntryI18n;
|
|
1049
900
|
}
|
|
1050
901
|
/**
|
|
1051
|
-
* Fields that may be changed on the bundle master. `bundleKey`
|
|
1052
|
-
*
|
|
1053
|
-
*
|
|
902
|
+
* Fields that may be changed on the bundle master. `bundleKey` is
|
|
903
|
+
* intentionally not here — master identity is immutable; whoever wants to
|
|
904
|
+
* change it creates a new bundle and retires the old one.
|
|
1054
905
|
*/
|
|
1055
906
|
interface UpdateBundleData {
|
|
1056
907
|
label?: string;
|
|
@@ -1092,97 +943,354 @@ interface CreateBundleVersionDraftData {
|
|
|
1092
943
|
validUntil?: string | null;
|
|
1093
944
|
createdByUserId?: string | null;
|
|
1094
945
|
}
|
|
1095
|
-
/**
|
|
1096
|
-
* Fields of a draft BundleVersion that may still be changed.
|
|
1097
|
-
* With also for published-but-future versions
|
|
1098
|
-
* (latest-in-chain, 0 subs, validFrom > now) — see
|
|
1099
|
-
* `isVersionEditable`.
|
|
1100
|
-
*/
|
|
1101
|
-
interface UpdateBundleVersionDraftData {
|
|
1102
|
-
features?: FeatureKey[];
|
|
1103
|
-
quotas?: Record<QuotaKey, number>;
|
|
1104
|
-
compatibility?: BundleCompatibility;
|
|
1105
|
-
pricingOverrides?: BundlePricingOverride[];
|
|
1106
|
-
monthlyNet?: string | null;
|
|
1107
|
-
yearlyNet?: string | null;
|
|
1108
|
-
marketed?: boolean;
|
|
1109
|
-
changeNote?: string;
|
|
1110
|
-
/**
|
|
1111
|
-
* New `validFrom` for the version. Freely settable when updating a
|
|
1112
|
-
* draft; for a published-but-future version the new date must still
|
|
1113
|
-
* lie in the future — the service checks that with
|
|
1114
|
-
* `isVersionEditable` against the freshly loaded state.
|
|
1115
|
-
*/
|
|
1116
|
-
validFrom?: string | null;
|
|
1117
|
-
validUntil?: string | null;
|
|
946
|
+
/**
|
|
947
|
+
* Fields of a draft BundleVersion that may still be changed.
|
|
948
|
+
* With also for published-but-future versions
|
|
949
|
+
* (latest-in-chain, 0 subs, validFrom > now) — see
|
|
950
|
+
* `isVersionEditable`.
|
|
951
|
+
*/
|
|
952
|
+
interface UpdateBundleVersionDraftData {
|
|
953
|
+
features?: FeatureKey[];
|
|
954
|
+
quotas?: Record<QuotaKey, number>;
|
|
955
|
+
compatibility?: BundleCompatibility;
|
|
956
|
+
pricingOverrides?: BundlePricingOverride[];
|
|
957
|
+
monthlyNet?: string | null;
|
|
958
|
+
yearlyNet?: string | null;
|
|
959
|
+
marketed?: boolean;
|
|
960
|
+
changeNote?: string;
|
|
961
|
+
/**
|
|
962
|
+
* New `validFrom` for the version. Freely settable when updating a
|
|
963
|
+
* draft; for a published-but-future version the new date must still
|
|
964
|
+
* lie in the future — the service checks that with
|
|
965
|
+
* `isVersionEditable` against the freshly loaded state.
|
|
966
|
+
*/
|
|
967
|
+
validFrom?: string | null;
|
|
968
|
+
validUntil?: string | null;
|
|
969
|
+
}
|
|
970
|
+
/**
|
|
971
|
+
* Input for `publishBundleVersion()`. `nonRegressive` and
|
|
972
|
+
* `publishedChanges` are computed by the service from the diff against the
|
|
973
|
+
* predecessor version; the caller supplies only confirmation
|
|
974
|
+
* + user tag + validity dates.
|
|
975
|
+
*
|
|
976
|
+
* `validFrom` is **required** at publish (analogous to `PublishPlanVersionData`).
|
|
977
|
+
* If the draft already carries a `validFrom`, it is optional here. The
|
|
978
|
+
* service validates strictly > `validFrom` of the predecessor version and sets
|
|
979
|
+
* its `validUntil` via auto succession to `validFrom - 1 day`.
|
|
980
|
+
*/
|
|
981
|
+
interface PublishBundleVersionData {
|
|
982
|
+
publishedByUserId: string | null;
|
|
983
|
+
/**
|
|
984
|
+
* If true and the diff classifies the version as regressive,
|
|
985
|
+
* it is published anyway — relevant for bulk-publish MFA confirmation
|
|
986
|
+
* ( editor-UI obligations).
|
|
987
|
+
*/
|
|
988
|
+
forceRegressive?: boolean;
|
|
989
|
+
/**
|
|
990
|
+
* Allows publish despite an explicit price of 0.00. Default false: an
|
|
991
|
+
* explicit 0.00 publish is blocked (protection against seed placeholders).
|
|
992
|
+
* `null` prices (override resolution) are not affected.
|
|
993
|
+
*/
|
|
994
|
+
allowZeroPrice?: boolean;
|
|
995
|
+
/**
|
|
996
|
+
* Required at publish if the draft has no `validFrom`. Must lie
|
|
997
|
+
* strictly after `validFrom` of the predecessor version. ISO-8601
|
|
998
|
+
* (`YYYY-MM-DD` or full timestamp).
|
|
999
|
+
*/
|
|
1000
|
+
validFrom?: string | null;
|
|
1001
|
+
/**
|
|
1002
|
+
* Optional; null = valid indefinitely (fits the last version
|
|
1003
|
+
* of a bundle). When a successor version is created it is automatically
|
|
1004
|
+
* overwritten by the service.
|
|
1005
|
+
*/
|
|
1006
|
+
validUntil?: string | null;
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Code of a strict-mode violation. lists the eight rules
|
|
1010
|
+
* that are checked; each rule has its own code so the UI can show
|
|
1011
|
+
* focused help texts.
|
|
1012
|
+
*/
|
|
1013
|
+
type StrictModeWarningCode = 'CAPABILITY_MISSING' | 'CAPABILITY_RETIRED' | 'FEATURE_MISSING' | 'FEATURE_PLANNED_ONLY' | 'BUNDLE_FEATURE_UNKNOWN' | 'BUNDLE_PLAN_KEY_UNKNOWN' | 'PLAN_FEATURE_UNKNOWN' | 'PLAN_FEATURE_NOT_APPROVED' | 'BUNDLE_FEATURE_NOT_APPROVED' | 'PLAN_FEATURE_DEPENDENCY_UNSATISFIED' | 'BUNDLE_FEATURE_DEPENDENCY_UNSATISFIED' | 'QUOTA_MISSING' | 'QUOTA_NOT_APPROVED' | 'VERSION_PUBLISH_OVERLAP';
|
|
1014
|
+
/**
|
|
1015
|
+
* A strict-mode violation. `field` points to the violating field
|
|
1016
|
+
* (e.g. `'features[3]'`), `value` is the concrete value (e.g. `'INVENTORY'`).
|
|
1017
|
+
*/
|
|
1018
|
+
interface StrictModeWarning {
|
|
1019
|
+
code: StrictModeWarningCode;
|
|
1020
|
+
/** Human-readable reason (German). */
|
|
1021
|
+
message: string;
|
|
1022
|
+
/** Path to the violating field; optional. */
|
|
1023
|
+
field?: string;
|
|
1024
|
+
/** The concrete violating value; optional. */
|
|
1025
|
+
value?: string;
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Service result for mutating Bundle operations
|
|
1029
|
+
* (createDraft, updateDraft, publish): returns the persisted row plus
|
|
1030
|
+
* a list of strict-mode warnings. In `warn-only` mode the
|
|
1031
|
+
* warnings go into the UI as a banner; in `blocking` mode the service throws
|
|
1032
|
+
* HTTP 422 instead, with the same warning list as the body.
|
|
1033
|
+
*/
|
|
1034
|
+
interface BundleVersionMutationResult {
|
|
1035
|
+
bundleVersion: BundleVersionRow;
|
|
1036
|
+
warnings: StrictModeWarning[];
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* The column values a new BundleVersion draft starts from.
|
|
1041
|
+
*
|
|
1042
|
+
* Every adapter has to apply the same defaults — an absent quota map is `{}`,
|
|
1043
|
+
* an absent price is null rather than zero, an unstated `marketed` is true —
|
|
1044
|
+
* and two adapters spelling that out separately is the same decision written
|
|
1045
|
+
* twice. It is also the variant jscpd does catch, which is how this came out:
|
|
1046
|
+
* `adapter-drizzle` learning about bundles put a second copy beside
|
|
1047
|
+
* `adapter-prisma`'s.
|
|
1048
|
+
*
|
|
1049
|
+
* Validity windows are deliberately absent. Whether a draft carries
|
|
1050
|
+
* `validFrom`/`validUntil` is an adapter capability rather than a default, and
|
|
1051
|
+
* an adapter that does not maintain those columns must not write them.
|
|
1052
|
+
*/
|
|
1053
|
+
declare function bundleDraftDefaults(data: CreateBundleVersionDraftData): {
|
|
1054
|
+
baseVersionId: string | null;
|
|
1055
|
+
features: string[];
|
|
1056
|
+
quotas: Record<string, number>;
|
|
1057
|
+
compatibility: Record<string, unknown>;
|
|
1058
|
+
pricingOverrides: unknown[];
|
|
1059
|
+
monthlyNet: string | null;
|
|
1060
|
+
yearlyNet: string | null;
|
|
1061
|
+
marketed: boolean;
|
|
1062
|
+
changeNote: string;
|
|
1063
|
+
createdByUserId: string | null;
|
|
1064
|
+
};
|
|
1065
|
+
/**
|
|
1066
|
+
* The column values a new Bundle stem starts from.
|
|
1067
|
+
*
|
|
1068
|
+
* The same defaulting rule as above, one level up: an absent description or
|
|
1069
|
+
* icon is null rather than an empty string, an unstated sort order is 0, an
|
|
1070
|
+
* absent translation map is `{}`. Written out in five places before this — two
|
|
1071
|
+
* adapters and two fakes — which is four opportunities for one of them to
|
|
1072
|
+
* decide differently.
|
|
1073
|
+
*/
|
|
1074
|
+
declare function bundleStemDefaults(data: CreateBundleData): {
|
|
1075
|
+
bundleKey: string;
|
|
1076
|
+
label: string;
|
|
1077
|
+
description: string | null;
|
|
1078
|
+
icon: string | null;
|
|
1079
|
+
sortOrder: number;
|
|
1080
|
+
i18n: CatalogEntryI18n;
|
|
1081
|
+
};
|
|
1082
|
+
/** The stored shape both adapters read a bundle stem back from. */
|
|
1083
|
+
interface StoredBundleStem {
|
|
1084
|
+
id: string;
|
|
1085
|
+
bundleKey: string;
|
|
1086
|
+
label: string;
|
|
1087
|
+
description: string | null;
|
|
1088
|
+
icon: string | null;
|
|
1089
|
+
sortOrder: number;
|
|
1090
|
+
i18n: unknown;
|
|
1091
|
+
createdAt: Date;
|
|
1092
|
+
updatedAt: Date;
|
|
1093
|
+
deletedAt: Date | null;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* A stored bundle stem as the port describes it.
|
|
1097
|
+
*
|
|
1098
|
+
* The two stores spell the columns identically, so the mapping was identical
|
|
1099
|
+
* too — and an identical mapping in two files is one place for a field to be
|
|
1100
|
+
* forgotten when the row grows. `i18n` arrives as JSON of unknown shape from
|
|
1101
|
+
* both, and a non-object becomes `{}` rather than reaching a caller that
|
|
1102
|
+
* expects a map.
|
|
1103
|
+
*/
|
|
1104
|
+
declare function toBundleStemRow(row: StoredBundleStem): BundleRow;
|
|
1105
|
+
/**
|
|
1106
|
+
* The fields a caller actually gave, as a patch.
|
|
1107
|
+
*
|
|
1108
|
+
* The update DTOs in this codebase mean three different things by three
|
|
1109
|
+
* different values: a value changes the column, an explicit `null` clears it,
|
|
1110
|
+
* and an **omitted** field leaves it alone. Only the last one needs care, and
|
|
1111
|
+
* it was written out as `...(data.x !== undefined ? { x: data.x } : {})` more
|
|
1112
|
+
* than fifty times across five repositories — one decision, fifty
|
|
1113
|
+
* opportunities to spell it differently, and the duplication ratchet is what
|
|
1114
|
+
* finally pointed at it.
|
|
1115
|
+
*
|
|
1116
|
+
* `null` is deliberately kept: it is a value a caller chose, not an absence.
|
|
1117
|
+
*/
|
|
1118
|
+
declare function definedFields<T extends object, K extends keyof T>(data: T, keys: readonly K[]): Partial<Pick<T, K>>;
|
|
1119
|
+
|
|
1120
|
+
/** Backend capability key, convention: domain.action[.action]. */
|
|
1121
|
+
type CapabilityKey = string;
|
|
1122
|
+
/** Frontend action-registry key. Same convention as CapabilityKey. */
|
|
1123
|
+
type ActionKey = CapabilityKey;
|
|
1124
|
+
/** Lookup key in the static extensions: map of the UI build. */
|
|
1125
|
+
type ComponentKey = string;
|
|
1126
|
+
interface AdminManifest {
|
|
1127
|
+
schemaVersion: 1;
|
|
1128
|
+
project: {
|
|
1129
|
+
key: string;
|
|
1130
|
+
displayName: string;
|
|
1131
|
+
/** Tag/subtitle (e.g. "SuperAdmin"). From `saas.yaml#app.label`. */
|
|
1132
|
+
label?: string;
|
|
1133
|
+
/** Short abbreviation for the logo badge (e.g. "ma", "da"). From `saas.yaml#app.icon`. */
|
|
1134
|
+
icon?: string;
|
|
1135
|
+
logoUrl?: string;
|
|
1136
|
+
environment?: 'production' | 'staging' | 'development';
|
|
1137
|
+
/**
|
|
1138
|
+
* Allowed locale pool from the app config (`saas.yaml`
|
|
1139
|
+
* `marketing.availableLocales`). First = default..
|
|
1140
|
+
*/
|
|
1141
|
+
availableLocales?: string[];
|
|
1142
|
+
/** Default locale; equals `availableLocales[0]`. */
|
|
1143
|
+
defaultLocale?: string;
|
|
1144
|
+
};
|
|
1145
|
+
build: {
|
|
1146
|
+
platformPackageVersion: string;
|
|
1147
|
+
appVersion: string;
|
|
1148
|
+
manifestHash: string;
|
|
1149
|
+
};
|
|
1150
|
+
planCatalogSnapshot: {
|
|
1151
|
+
source: string;
|
|
1152
|
+
hash: string;
|
|
1153
|
+
currency: string;
|
|
1154
|
+
vatRate: number;
|
|
1155
|
+
features?: FeatureDef[];
|
|
1156
|
+
plans: PlanDef[];
|
|
1157
|
+
};
|
|
1158
|
+
/** Map CapabilityKey → boolean. Manifest is never a security source. */
|
|
1159
|
+
capabilities: Record<CapabilityKey, boolean>;
|
|
1160
|
+
navigation: {
|
|
1161
|
+
standardPages: Partial<Record<StandardPageKey, StandardPageDef>>;
|
|
1162
|
+
projectPages?: ProjectPageDef[];
|
|
1163
|
+
};
|
|
1164
|
+
dashboard?: {
|
|
1165
|
+
kpiCards?: KpiCardDef[];
|
|
1166
|
+
};
|
|
1167
|
+
tenants?: {
|
|
1168
|
+
columns?: TenantColumnDef[];
|
|
1169
|
+
actions?: TenantActionDef[];
|
|
1170
|
+
};
|
|
1171
|
+
audit?: {
|
|
1172
|
+
actions?: AuditActionDef[];
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
type StandardPageKey = 'dashboard' | 'tenants' | 'subscriptions' | 'promoCodes' | 'plans' | 'audit' | 'users' | 'pilots' | 'discovery' | 'bundles' | 'marketingCatalog' | 'platformEmail' | 'platformEmailHistory';
|
|
1176
|
+
interface StandardPageDef {
|
|
1177
|
+
enabled: boolean;
|
|
1178
|
+
requiredCapability?: CapabilityKey;
|
|
1179
|
+
}
|
|
1180
|
+
interface ProjectPageDef {
|
|
1181
|
+
/** `<app>.<area>`, e.g. `demoapp.datev`. */
|
|
1182
|
+
id: string;
|
|
1183
|
+
label: string;
|
|
1184
|
+
icon?: string;
|
|
1185
|
+
/** Frontend route, e.g. `/admin/datev`. */
|
|
1186
|
+
route: string;
|
|
1187
|
+
navSection?: string;
|
|
1188
|
+
/** Lookup in the static extensions: map of the shell build. */
|
|
1189
|
+
componentKey: ComponentKey;
|
|
1190
|
+
requiredCapability?: CapabilityKey;
|
|
1191
|
+
prefetchOnIdle?: boolean;
|
|
1192
|
+
}
|
|
1193
|
+
interface KpiCardDef {
|
|
1194
|
+
id: string;
|
|
1195
|
+
label: string;
|
|
1196
|
+
/** Required path: /api/v1/admin/(extras|dashboard)/... */
|
|
1197
|
+
endpoint: string;
|
|
1198
|
+
displayHint: KpiDisplayHint;
|
|
1199
|
+
/** 0–100; UI sorts descending. */
|
|
1200
|
+
slotPriority?: number;
|
|
1201
|
+
requiredCapability?: CapabilityKey;
|
|
1202
|
+
}
|
|
1203
|
+
interface KpiDisplayHint {
|
|
1204
|
+
type: 'value' | 'value+timestamp' | 'value+spark8w' | 'value+delta';
|
|
1205
|
+
icon?: string;
|
|
1206
|
+
}
|
|
1207
|
+
interface TenantColumnDef {
|
|
1208
|
+
key: string;
|
|
1209
|
+
label: string;
|
|
1210
|
+
/** Required path: /api/v1/admin/extras/...; MUST be batch-capable, no {slug}/{tenantId}. */
|
|
1211
|
+
endpoint: string;
|
|
1212
|
+
requiredCapability?: CapabilityKey;
|
|
1213
|
+
}
|
|
1214
|
+
interface TenantActionDef {
|
|
1215
|
+
/** `<app>.<area>.<verb>`, e.g. `demoapp.datev.runExport`. */
|
|
1216
|
+
id: string;
|
|
1217
|
+
label: string;
|
|
1218
|
+
/** Lookup in the static actions: map of the shell build. */
|
|
1219
|
+
actionKey: ActionKey;
|
|
1220
|
+
requiredCapability?: CapabilityKey;
|
|
1221
|
+
requiresMfa?: boolean;
|
|
1222
|
+
confirmType?: 'none' | 'simple' | 'typed-slug' | 'typed-production' | 'date';
|
|
1118
1223
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
*
|
|
1125
|
-
* `validFrom` is **required** at publish (analogous to `PublishPlanVersionData`).
|
|
1126
|
-
* If the draft already carries a `validFrom`, it is optional here. The
|
|
1127
|
-
* service validates strictly > `validFrom` of the predecessor version and sets
|
|
1128
|
-
* its `validUntil` via auto succession to `validFrom - 1 day`.
|
|
1129
|
-
*/
|
|
1130
|
-
interface PublishBundleVersionData {
|
|
1131
|
-
publishedByUserId: string | null;
|
|
1132
|
-
/**
|
|
1133
|
-
* If true and the diff classifies the version as regressive,
|
|
1134
|
-
* it is published anyway — relevant for bulk-publish MFA confirmation
|
|
1135
|
-
* ( editor-UI obligations).
|
|
1136
|
-
*/
|
|
1137
|
-
forceRegressive?: boolean;
|
|
1138
|
-
/**
|
|
1139
|
-
* Allows publish despite an explicit price of 0.00. Default false: an
|
|
1140
|
-
* explicit 0.00 publish is blocked (protection against seed placeholders).
|
|
1141
|
-
* `null` prices (override resolution) are not affected.
|
|
1142
|
-
*/
|
|
1143
|
-
allowZeroPrice?: boolean;
|
|
1144
|
-
/**
|
|
1145
|
-
* Required at publish if the draft has no `validFrom`. Must lie
|
|
1146
|
-
* strictly after `validFrom` of the predecessor version. ISO-8601
|
|
1147
|
-
* (`YYYY-MM-DD` or full timestamp).
|
|
1148
|
-
*/
|
|
1149
|
-
validFrom?: string | null;
|
|
1150
|
-
/**
|
|
1151
|
-
* Optional; null = valid indefinitely (fits the last version
|
|
1152
|
-
* of a bundle). When a successor version is created it is automatically
|
|
1153
|
-
* overwritten by the service.
|
|
1154
|
-
*/
|
|
1155
|
-
validUntil?: string | null;
|
|
1224
|
+
interface AuditActionDef {
|
|
1225
|
+
/** SCREAMING_SNAKE_CASE; matched to the AuditLog.action column. */
|
|
1226
|
+
key: string;
|
|
1227
|
+
label: string;
|
|
1228
|
+
severity?: 'info' | 'low' | 'medium' | 'high';
|
|
1156
1229
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
/** The concrete violating value; optional. */
|
|
1174
|
-
value?: string;
|
|
1230
|
+
interface ManifestContribution {
|
|
1231
|
+
capabilities?: Record<CapabilityKey, boolean>;
|
|
1232
|
+
navigation?: {
|
|
1233
|
+
standardPages?: Partial<Record<StandardPageKey, StandardPageDef>>;
|
|
1234
|
+
projectPages?: ProjectPageDef[];
|
|
1235
|
+
};
|
|
1236
|
+
dashboard?: {
|
|
1237
|
+
kpiCards?: KpiCardDef[];
|
|
1238
|
+
};
|
|
1239
|
+
tenants?: {
|
|
1240
|
+
columns?: TenantColumnDef[];
|
|
1241
|
+
actions?: TenantActionDef[];
|
|
1242
|
+
};
|
|
1243
|
+
audit?: {
|
|
1244
|
+
actions?: AuditActionDef[];
|
|
1245
|
+
};
|
|
1175
1246
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
*/
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1247
|
+
interface PublicBootResponse {
|
|
1248
|
+
project: {
|
|
1249
|
+
key: string;
|
|
1250
|
+
displayName: string;
|
|
1251
|
+
/** Tag/subtitle (e.g. "SuperAdmin"). From `saas.yaml#app.label`. */
|
|
1252
|
+
label?: string;
|
|
1253
|
+
/** Short abbreviation for the logo badge (e.g. "ma", "da"). From `saas.yaml#app.icon`. */
|
|
1254
|
+
icon?: string;
|
|
1255
|
+
logoUrl?: string;
|
|
1256
|
+
environment?: 'production' | 'staging' | 'development';
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
/** Format: 'web:<email>:<sessionId>' or 'cli:<email>:<host>'. */
|
|
1261
|
+
type ActorTag = string;
|
|
1262
|
+
interface AuditEntry {
|
|
1263
|
+
id: string;
|
|
1264
|
+
/** null = platform action without tenant context (SUPER_ADMIN). */
|
|
1265
|
+
tenantId: string | null;
|
|
1266
|
+
/** null = system / cron-triggered. */
|
|
1267
|
+
userId: string | null;
|
|
1268
|
+
/** Convenience field; backend resolves it from userId. */
|
|
1269
|
+
userEmail: string | null;
|
|
1270
|
+
/** e.g. 'Tenant', 'PromoCode', 'Subscription', 'PlanVersion', 'User'. */
|
|
1271
|
+
entity: string;
|
|
1272
|
+
entityId: string;
|
|
1273
|
+
/** SCREAMING_SNAKE_CASE; past-tense oriented. */
|
|
1274
|
+
action: string;
|
|
1275
|
+
/** Freely structured. Convention: { field: { old, new } } or { reason, ... }. */
|
|
1276
|
+
changes: Record<string, unknown> | null;
|
|
1277
|
+
actorTag: ActorTag | null;
|
|
1278
|
+
ipAddress: string | null;
|
|
1279
|
+
userAgent: string | null;
|
|
1280
|
+
createdAt: string;
|
|
1281
|
+
}
|
|
1282
|
+
interface AuditQuery {
|
|
1283
|
+
tenantId?: string;
|
|
1284
|
+
userId?: string;
|
|
1285
|
+
entity?: string;
|
|
1286
|
+
entityId?: string;
|
|
1287
|
+
action?: string;
|
|
1288
|
+
/** Wildcard-capable, e.g. 'cli:*'. */
|
|
1289
|
+
actorTag?: string;
|
|
1290
|
+
from?: string;
|
|
1291
|
+
to?: string;
|
|
1292
|
+
page?: number;
|
|
1293
|
+
pageSize?: number;
|
|
1186
1294
|
}
|
|
1187
1295
|
|
|
1188
1296
|
/** Promotion type. */
|
|
@@ -1213,7 +1321,6 @@ type PromotionI18n = Record<string, PromotionI18nFields>;
|
|
|
1213
1321
|
/** Wire format of a `promotions` row. */
|
|
1214
1322
|
interface PromotionRow {
|
|
1215
1323
|
id: string;
|
|
1216
|
-
projectKey: string;
|
|
1217
1324
|
/** Internal label (not public). */
|
|
1218
1325
|
internalLabel: string;
|
|
1219
1326
|
type: PromotionType;
|
|
@@ -1239,11 +1346,7 @@ interface PromotionRow {
|
|
|
1239
1346
|
createdAt: string;
|
|
1240
1347
|
updatedAt: string;
|
|
1241
1348
|
}
|
|
1242
|
-
interface PromotionFilter {
|
|
1243
|
-
projectKey: string;
|
|
1244
|
-
}
|
|
1245
1349
|
interface CreatePromotionData {
|
|
1246
|
-
projectKey: string;
|
|
1247
1350
|
internalLabel: string;
|
|
1248
1351
|
type: PromotionType;
|
|
1249
1352
|
value: PromotionValue;
|
|
@@ -1366,7 +1469,6 @@ type CheckoutOfferStatus = 'open' | 'consumed' | 'expired';
|
|
|
1366
1469
|
/** Wire format of a `checkout_offers` row. */
|
|
1367
1470
|
interface CheckoutOfferRow {
|
|
1368
1471
|
id: string;
|
|
1369
|
-
projectKey: string;
|
|
1370
1472
|
/** Plan selected on the website. */
|
|
1371
1473
|
planKey: string;
|
|
1372
1474
|
/** Resolved plan version, if known. */
|
|
@@ -1397,12 +1499,10 @@ interface CheckoutOfferRow {
|
|
|
1397
1499
|
updatedAt: string;
|
|
1398
1500
|
}
|
|
1399
1501
|
interface CheckoutOfferFilter {
|
|
1400
|
-
projectKey: string;
|
|
1401
1502
|
status?: CheckoutOfferStatus;
|
|
1402
1503
|
}
|
|
1403
1504
|
/** Body of `POST /public/checkout-offer` — called from the website. */
|
|
1404
1505
|
interface CreateCheckoutOfferData {
|
|
1405
|
-
projectKey: string;
|
|
1406
1506
|
planKey: string;
|
|
1407
1507
|
planVersionId?: string | null;
|
|
1408
1508
|
billingCycle: 'monthly' | 'yearly';
|
|
@@ -1438,7 +1538,6 @@ interface UpdateCheckoutOfferData {
|
|
|
1438
1538
|
|
|
1439
1539
|
/** Wire format of the `marketing_settings` row. */
|
|
1440
1540
|
interface MarketingSettingsRow {
|
|
1441
|
-
projectKey: string;
|
|
1442
1541
|
/** Runtime-activated subset of the `availableLocales` pool. */
|
|
1443
1542
|
activeLocales: string[];
|
|
1444
1543
|
updatedAt: string;
|
|
@@ -1556,7 +1655,6 @@ interface PublicComparisonRow {
|
|
|
1556
1655
|
}
|
|
1557
1656
|
/** Response of `GET /public/marketing-catalog`. */
|
|
1558
1657
|
interface PublicMarketingCatalogResponse {
|
|
1559
|
-
projectKey: string;
|
|
1560
1658
|
locale: string;
|
|
1561
1659
|
currency: string;
|
|
1562
1660
|
/** VAT rate in percent — for the CheckoutOffer price breakdown. */
|
|
@@ -1666,7 +1764,7 @@ interface DiscoverySnapshot {
|
|
|
1666
1764
|
/** ISO timestamp of the boot-time scan. */
|
|
1667
1765
|
scannedAt: string;
|
|
1668
1766
|
app: {
|
|
1669
|
-
/**
|
|
1767
|
+
/** The application's name, from `saas.yaml#app.name`. */
|
|
1670
1768
|
key: string;
|
|
1671
1769
|
/** Backend version, e.g. from package.json. */
|
|
1672
1770
|
version: string;
|
|
@@ -1838,7 +1936,6 @@ interface OnboardingPromoRedemption {
|
|
|
1838
1936
|
|
|
1839
1937
|
interface PlanRow {
|
|
1840
1938
|
id: string;
|
|
1841
|
-
projectKey: string;
|
|
1842
1939
|
planKey: string;
|
|
1843
1940
|
label: string;
|
|
1844
1941
|
description: string | null;
|
|
@@ -1855,7 +1952,6 @@ interface PlanRow {
|
|
|
1855
1952
|
* creation (follows in M6 Pack 2).
|
|
1856
1953
|
*/
|
|
1857
1954
|
interface CreatePlanData {
|
|
1858
|
-
projectKey: string;
|
|
1859
1955
|
planKey: string;
|
|
1860
1956
|
label: string;
|
|
1861
1957
|
description?: string | null;
|
|
@@ -1863,9 +1959,9 @@ interface CreatePlanData {
|
|
|
1863
1959
|
sortOrder?: number;
|
|
1864
1960
|
}
|
|
1865
1961
|
/**
|
|
1866
|
-
* Fields that may be changed on the plan stem. `planKey`
|
|
1867
|
-
*
|
|
1868
|
-
*
|
|
1962
|
+
* Fields that may be changed on the plan stem. `planKey` is deliberately not
|
|
1963
|
+
* here — stem identity is immutable; whoever wants to change it creates a new
|
|
1964
|
+
* plan and retires the old one.
|
|
1869
1965
|
*/
|
|
1870
1966
|
interface UpdatePlanData {
|
|
1871
1967
|
label?: string;
|
|
@@ -1929,7 +2025,6 @@ interface UpsertResult {
|
|
|
1929
2025
|
skipReason?: string;
|
|
1930
2026
|
}
|
|
1931
2027
|
interface UpsertPlanInput {
|
|
1932
|
-
projectKey: string;
|
|
1933
2028
|
planKey: string;
|
|
1934
2029
|
label: string;
|
|
1935
2030
|
description?: string | null;
|
|
@@ -1949,7 +2044,6 @@ interface UpsertPlanVersionInput {
|
|
|
1949
2044
|
changeNote: string;
|
|
1950
2045
|
}
|
|
1951
2046
|
interface UpsertFeatureCatalogEntryInput {
|
|
1952
|
-
projectKey: string;
|
|
1953
2047
|
featureKey: FeatureKey;
|
|
1954
2048
|
label?: string;
|
|
1955
2049
|
icon?: string;
|
|
@@ -1995,7 +2089,7 @@ interface PlanCatalogReadSnapshot {
|
|
|
1995
2089
|
* implement it against their Prisma tables.
|
|
1996
2090
|
*/
|
|
1997
2091
|
interface PlanCatalogReadSink {
|
|
1998
|
-
loadSnapshot(
|
|
2092
|
+
loadSnapshot(): Promise<PlanCatalogReadSnapshot>;
|
|
1999
2093
|
}
|
|
2000
2094
|
|
|
2001
2095
|
/**
|
|
@@ -2439,6 +2533,26 @@ interface PromoRevenueDeductionAggregator {
|
|
|
2439
2533
|
|
|
2440
2534
|
type ContractLineItemKind = 'plan' | 'bundle' | 'discount';
|
|
2441
2535
|
type SubscriptionContractStatus = 'active' | 'scheduled' | 'terminated' | 'superseded';
|
|
2536
|
+
/**
|
|
2537
|
+
* The statuses a contract is looked up under when asking "what is this tenant
|
|
2538
|
+
* on right now" — `scheduled` included, because a contract that starts today
|
|
2539
|
+
* and has not been switched to `active` yet is still the one in force at its
|
|
2540
|
+
* own `effectiveFrom`.
|
|
2541
|
+
*
|
|
2542
|
+
* One list rather than one per adapter: the two adapters have to answer
|
|
2543
|
+
* `findActiveByTenantId` the same way, and a status added here must not reach
|
|
2544
|
+
* only whichever of them somebody remembered.
|
|
2545
|
+
*/
|
|
2546
|
+
/**
|
|
2547
|
+
* How many bundle versions one price lookup may name.
|
|
2548
|
+
*
|
|
2549
|
+
* One number rather than two: the server validates against it and the client
|
|
2550
|
+
* batches to stay inside it, and a client that learned the cap by receiving a
|
|
2551
|
+
* 400 would fail silently — the lookup answers with an empty map, and every
|
|
2552
|
+
* card falls back to a catalogue price the tenant may not be charged.
|
|
2553
|
+
*/
|
|
2554
|
+
declare const BUNDLE_PRICE_LOOKUP_LIMIT = 200;
|
|
2555
|
+
declare const ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES: readonly SubscriptionContractStatus[];
|
|
2442
2556
|
interface ContractLineItemRecord {
|
|
2443
2557
|
id: string;
|
|
2444
2558
|
contractId: string;
|
|
@@ -2469,7 +2583,6 @@ interface SubscriptionContractPriceSnapshot {
|
|
|
2469
2583
|
}
|
|
2470
2584
|
interface SubscriptionContractRecord {
|
|
2471
2585
|
id: string;
|
|
2472
|
-
projectKey: string;
|
|
2473
2586
|
tenantId: string;
|
|
2474
2587
|
status: SubscriptionContractStatus;
|
|
2475
2588
|
effectiveFrom: Date;
|
|
@@ -2488,7 +2601,6 @@ interface SubscriptionContractRecord {
|
|
|
2488
2601
|
}
|
|
2489
2602
|
type NewContractLineItemData = Omit<ContractLineItemRecord, 'id' | 'contractId' | 'createdAt'>;
|
|
2490
2603
|
interface CreateSubscriptionContractData {
|
|
2491
|
-
projectKey: string;
|
|
2492
2604
|
tenantId: string;
|
|
2493
2605
|
status?: SubscriptionContractStatus;
|
|
2494
2606
|
effectiveFrom: Date;
|
|
@@ -2521,7 +2633,6 @@ interface TerminateSubscriptionContractData {
|
|
|
2521
2633
|
status: Extract<SubscriptionContractStatus, 'terminated' | 'superseded'> | null;
|
|
2522
2634
|
}
|
|
2523
2635
|
interface SubscriptionContractFilter {
|
|
2524
|
-
projectKey?: string;
|
|
2525
2636
|
tenantId?: string;
|
|
2526
2637
|
status?: SubscriptionContractStatus;
|
|
2527
2638
|
asOf?: Date;
|
|
@@ -2543,7 +2654,6 @@ interface InvoiceLineItemSnapshot {
|
|
|
2543
2654
|
}
|
|
2544
2655
|
interface SubscriptionContractInvoiceSnapshot {
|
|
2545
2656
|
contractId: string;
|
|
2546
|
-
projectKey: string;
|
|
2547
2657
|
tenantId: string;
|
|
2548
2658
|
originalOfferId: string | null;
|
|
2549
2659
|
currency: string;
|
|
@@ -2651,11 +2761,10 @@ interface SubscriptionRepository {
|
|
|
2651
2761
|
countByBundleVersionId?(bundleVersionId: string): Promise<number>;
|
|
2652
2762
|
/**
|
|
2653
2763
|
* Counts active subscriptions (status `ACTIVE` or `TRIAL`) per plan key,
|
|
2654
|
-
* platform-wide across
|
|
2655
|
-
*
|
|
2764
|
+
* platform-wide across every tenant — feeds the tenant column of the
|
|
2765
|
+
* SuperAdmin plan list (`GET /admin/catalog/plans/tenant-counts`).
|
|
2656
2766
|
* Cross-version: counts the plan, not a single PlanVersion
|
|
2657
|
-
* (subscriptions on superseded versions are included).
|
|
2658
|
-
* informational for single-project consumers.
|
|
2767
|
+
* (subscriptions on superseded versions are included).
|
|
2659
2768
|
*
|
|
2660
2769
|
* Returns a map `planKey → count`; plans without an active subscription
|
|
2661
2770
|
* are missing (UI defaults to 0). Platform-wide count across all tenants →
|
|
@@ -2663,7 +2772,7 @@ interface SubscriptionRepository {
|
|
|
2663
2772
|
*
|
|
2664
2773
|
* Optional — if not implemented, the tenant column stays 0.
|
|
2665
2774
|
*/
|
|
2666
|
-
countActiveByPlanKey?(
|
|
2775
|
+
countActiveByPlanKey?(): Promise<Record<string, number>>;
|
|
2667
2776
|
}
|
|
2668
2777
|
/**
|
|
2669
2778
|
* Adapter for the `subscription_bundles` junction.
|
|
@@ -2764,6 +2873,19 @@ interface SubscriptionUsageRecord {
|
|
|
2764
2873
|
* existed — readers treat that as "the period end is the answer".
|
|
2765
2874
|
*/
|
|
2766
2875
|
minimumTermUntil?: Date | null;
|
|
2876
|
+
/**
|
|
2877
|
+
* The day of the month the subscription is billed on, 1–31.
|
|
2878
|
+
*
|
|
2879
|
+
* Read by the cancellation rules: a declaration after the notice window
|
|
2880
|
+
* lands one period past the term end, and that step has to measure from the
|
|
2881
|
+
* billing day rather than from a term end that may already have been
|
|
2882
|
+
* clamped by a short month.
|
|
2883
|
+
*
|
|
2884
|
+
* Optional, because an adapter that does not store the column keeps today's
|
|
2885
|
+
* behaviour — the step then takes its day from the term end, which is
|
|
2886
|
+
* correct except in the month after a clamp.
|
|
2887
|
+
*/
|
|
2888
|
+
billingAnchorDay?: number | null;
|
|
2767
2889
|
/**
|
|
2768
2890
|
* When a cancellation was declared, and when it lands.
|
|
2769
2891
|
*
|
|
@@ -2927,6 +3049,34 @@ type RedeemPromoInTransactionCallback = (tx: TransactionContext, subscriptionId:
|
|
|
2927
3049
|
* app-specific. The platform service calls `invalidateTenant` in the
|
|
2928
3050
|
* EntitlementService after a successful adapter call.
|
|
2929
3051
|
*/
|
|
3052
|
+
/** What `cancelSubscription` is told to write. Named so both adapters spell
|
|
3053
|
+
* the same shape once rather than each restating it. */
|
|
3054
|
+
interface CancelSubscriptionInput {
|
|
3055
|
+
canceledAt: Date;
|
|
3056
|
+
effectiveAt: Date;
|
|
3057
|
+
terminateNow: boolean;
|
|
3058
|
+
minimumTermUntil?: Date;
|
|
3059
|
+
}
|
|
3060
|
+
/** What `cancelSubscription` answers with. */
|
|
3061
|
+
interface CancelSubscriptionResult {
|
|
3062
|
+
canceledAt: Date | null;
|
|
3063
|
+
canceledEffectiveAt: Date | null;
|
|
3064
|
+
status: string;
|
|
3065
|
+
/**
|
|
3066
|
+
* True when a cancellation was already recorded and this call changed
|
|
3067
|
+
* nothing — the stored dates are returned instead.
|
|
3068
|
+
*
|
|
3069
|
+
* The caller checks first, but a check and a write are two moments, and two
|
|
3070
|
+
* requests can pass the check before either writes. Straddling a notice
|
|
3071
|
+
* deadline that costs a billing cycle: the first declaration lands on time,
|
|
3072
|
+
* the second recomputes against a later `now`, and an unconditional write
|
|
3073
|
+
* replaces the first answer with one a period further out. An
|
|
3074
|
+
* implementation therefore claims the row only while both cancellation
|
|
3075
|
+
* fields are still empty, and answers `true` here when the claim finds
|
|
3076
|
+
* nothing to claim.
|
|
3077
|
+
*/
|
|
3078
|
+
alreadyCanceled: boolean;
|
|
3079
|
+
}
|
|
2930
3080
|
interface TenantSubscriptionWritePort {
|
|
2931
3081
|
/** Immediate change: set plan + cycle, clear pending fields, optionally reset the period. */
|
|
2932
3082
|
changePlanImmediate(tenantId: string, input: ImmediatePlanChangeInput): Promise<{
|
|
@@ -2974,30 +3124,7 @@ interface TenantSubscriptionWritePort {
|
|
|
2974
3124
|
* deadline buys the following period. Left unset the stored term end is
|
|
2975
3125
|
* unchanged, which is the ordinary case.
|
|
2976
3126
|
*/
|
|
2977
|
-
cancelSubscription(tenantId: string, input:
|
|
2978
|
-
canceledAt: Date;
|
|
2979
|
-
effectiveAt: Date;
|
|
2980
|
-
terminateNow: boolean;
|
|
2981
|
-
minimumTermUntil?: Date;
|
|
2982
|
-
}): Promise<{
|
|
2983
|
-
canceledAt: Date | null;
|
|
2984
|
-
canceledEffectiveAt: Date | null;
|
|
2985
|
-
status: string;
|
|
2986
|
-
/**
|
|
2987
|
-
* True when a cancellation was already recorded and this call changed
|
|
2988
|
-
* nothing — the stored dates are returned instead.
|
|
2989
|
-
*
|
|
2990
|
-
* The caller checks first, but a check and a write are two moments, and
|
|
2991
|
-
* two requests can pass the check before either writes. Straddling a
|
|
2992
|
-
* notice deadline that costs a billing cycle: the first declaration
|
|
2993
|
-
* lands on time, the second recomputes against a later `now`, and an
|
|
2994
|
-
* unconditional write replaces the first answer with one a period
|
|
2995
|
-
* further out. An implementation therefore claims the row only while
|
|
2996
|
-
* both cancellation fields are still empty, and answers `true` here
|
|
2997
|
-
* when the claim finds nothing to claim.
|
|
2998
|
-
*/
|
|
2999
|
-
alreadyCanceled: boolean;
|
|
3000
|
-
}>;
|
|
3127
|
+
cancelSubscription(tenantId: string, input: CancelSubscriptionInput): Promise<CancelSubscriptionResult>;
|
|
3001
3128
|
/**
|
|
3002
3129
|
* Atomic onboarding creation: sets plan + cycle + period window
|
|
3003
3130
|
* AND optionally calls a promo-redeem callback — all in a
|
|
@@ -3249,7 +3376,6 @@ interface RlsBypassPort {
|
|
|
3249
3376
|
|
|
3250
3377
|
/** Filter for `PlanRepository.list()`. */
|
|
3251
3378
|
interface PlanListFilter {
|
|
3252
|
-
projectKey: string;
|
|
3253
3379
|
/** Exclude soft-deleted plans — default `true`. */
|
|
3254
3380
|
excludeDeleted?: boolean;
|
|
3255
3381
|
/**
|
|
@@ -3283,7 +3409,7 @@ interface PlanListFilter {
|
|
|
3283
3409
|
interface PlanRepository {
|
|
3284
3410
|
list(filter: PlanListFilter): Promise<PlanRow[]>;
|
|
3285
3411
|
findById(planId: string): Promise<PlanRow | null>;
|
|
3286
|
-
findByKey(
|
|
3412
|
+
findByKey(planKey: string): Promise<PlanRow | null>;
|
|
3287
3413
|
create(data: CreatePlanData): Promise<PlanRow>;
|
|
3288
3414
|
update(planId: string, data: UpdatePlanData): Promise<PlanRow>;
|
|
3289
3415
|
/** Sets `deletedAt` to NOW(); soft-deleted plans are filtered from `list` by default. */
|
|
@@ -3384,10 +3510,24 @@ interface PlanRepository {
|
|
|
3384
3510
|
}
|
|
3385
3511
|
/** Filter for `BundleRepository.list()`. */
|
|
3386
3512
|
interface BundleListFilter {
|
|
3387
|
-
projectKey: string;
|
|
3388
3513
|
/** Exclude soft-deleted bundles — default `true`. */
|
|
3389
3514
|
excludeDeleted?: boolean;
|
|
3390
3515
|
}
|
|
3516
|
+
/**
|
|
3517
|
+
* What publishing a bundle draft records.
|
|
3518
|
+
*
|
|
3519
|
+
* Named because it was written out three times — the port, and each adapter's
|
|
3520
|
+
* implementation of it — and a signature restated is a contract restated: the
|
|
3521
|
+
* copies can drift, and nothing but a reader would notice.
|
|
3522
|
+
*/
|
|
3523
|
+
interface PublishBundleVersionMeta {
|
|
3524
|
+
publishedByUserId: string | null;
|
|
3525
|
+
publishedChanges: VersionChange[];
|
|
3526
|
+
nonRegressive: boolean;
|
|
3527
|
+
/** Required — validated by the service before the repository call. */
|
|
3528
|
+
validFrom: Date;
|
|
3529
|
+
validUntil: Date | null;
|
|
3530
|
+
}
|
|
3391
3531
|
/**
|
|
3392
3532
|
* Adapter for `Bundle` + `BundleVersion` persistence. Consumers implement
|
|
3393
3533
|
* this against their Prisma tables (`bundles` + `bundle_versions`).
|
|
@@ -3406,7 +3546,7 @@ interface BundleListFilter {
|
|
|
3406
3546
|
interface BundleRepository {
|
|
3407
3547
|
list(filter: BundleListFilter): Promise<BundleRow[]>;
|
|
3408
3548
|
findById(bundleId: string): Promise<BundleRow | null>;
|
|
3409
|
-
findByKey(
|
|
3549
|
+
findByKey(bundleKey: string): Promise<BundleRow | null>;
|
|
3410
3550
|
create(data: CreateBundleData): Promise<BundleRow>;
|
|
3411
3551
|
update(bundleId: string, data: UpdateBundleData): Promise<BundleRow>;
|
|
3412
3552
|
/** Sets `deletedAt` to NOW(); soft-deleted bundles are filtered from `list` by default. */
|
|
@@ -3465,14 +3605,7 @@ interface BundleRepository {
|
|
|
3465
3605
|
* if the predecessor carries a `validUntil` — the adapter only
|
|
3466
3606
|
* persists, it does not validate again.
|
|
3467
3607
|
*/
|
|
3468
|
-
publishDraft(versionId: string, publishMeta:
|
|
3469
|
-
publishedByUserId: string | null;
|
|
3470
|
-
publishedChanges: VersionChange[];
|
|
3471
|
-
nonRegressive: boolean;
|
|
3472
|
-
/** Required — validated by the service before the repository call. */
|
|
3473
|
-
validFrom: Date;
|
|
3474
|
-
validUntil: Date | null;
|
|
3475
|
-
}, tx?: TransactionContext): Promise<BundleVersionRow>;
|
|
3608
|
+
publishDraft(versionId: string, publishMeta: PublishBundleVersionMeta, tx?: TransactionContext): Promise<BundleVersionRow>;
|
|
3476
3609
|
/**
|
|
3477
3610
|
* Hard-discards a draft version (`publishedAt === null`) from the DB.
|
|
3478
3611
|
* Throws if the version was already published — published versions
|
|
@@ -3510,7 +3643,6 @@ interface MarketingProjectionRepository {
|
|
|
3510
3643
|
}
|
|
3511
3644
|
/** Upsert input for a capability from the discovery sync. */
|
|
3512
3645
|
interface UpsertCapabilityEntryData {
|
|
3513
|
-
projectKey: string;
|
|
3514
3646
|
capabilityKey: string;
|
|
3515
3647
|
label: string;
|
|
3516
3648
|
description: string | null;
|
|
@@ -3527,7 +3659,6 @@ interface UpsertCapabilityEntryData {
|
|
|
3527
3659
|
}
|
|
3528
3660
|
/** Upsert input for a feature from the discovery sync. */
|
|
3529
3661
|
interface UpsertFeatureEntryData {
|
|
3530
|
-
projectKey: string;
|
|
3531
3662
|
featureKey: string;
|
|
3532
3663
|
label: string;
|
|
3533
3664
|
description: string | null;
|
|
@@ -3541,7 +3672,6 @@ interface UpsertFeatureEntryData {
|
|
|
3541
3672
|
}
|
|
3542
3673
|
/** Upsert input for a quota from the discovery sync. */
|
|
3543
3674
|
interface UpsertQuotaEntryData {
|
|
3544
|
-
projectKey: string;
|
|
3545
3675
|
quotaKey: string;
|
|
3546
3676
|
label: string;
|
|
3547
3677
|
description: string | null;
|
|
@@ -3571,7 +3701,7 @@ interface SetCatalogEntryReviewData {
|
|
|
3571
3701
|
* Prisma tables.
|
|
3572
3702
|
*
|
|
3573
3703
|
* Binding:
|
|
3574
|
-
* - `upsert*` matches on
|
|
3704
|
+
* - `upsert*` matches on `<key>` and leaves `i18n`,
|
|
3575
3705
|
* `sortOrder`, `createdAt` as well as the approval fields (`approvedAt`/
|
|
3576
3706
|
* `approvedBy`/`approvedSignature`) **untouched** on an update —
|
|
3577
3707
|
* only the code-derived fields + the status (resolved by the service)
|
|
@@ -3587,7 +3717,7 @@ interface CatalogEntryRepository {
|
|
|
3587
3717
|
upsertCapability(data: UpsertCapabilityEntryData): Promise<CapabilityCatalogEntryRow>;
|
|
3588
3718
|
upsertFeature(data: UpsertFeatureEntryData): Promise<FeatureCatalogEntryRow>;
|
|
3589
3719
|
upsertQuota(data: UpsertQuotaEntryData): Promise<QuotaCatalogEntryRow>;
|
|
3590
|
-
retireMissing(
|
|
3720
|
+
retireMissing(type: 'capability' | 'feature' | 'quota', presentKeys: string[]): Promise<number>;
|
|
3591
3721
|
/**
|
|
3592
3722
|
* Sets or clears the successor pointer of a feature/quota
|
|
3593
3723
|
* (#39). The sync calls this when a key disappears from the snapshot
|
|
@@ -3596,17 +3726,17 @@ interface CatalogEntryRepository {
|
|
|
3596
3726
|
* adapters without a `successor_key` column omit the methods, and the sync
|
|
3597
3727
|
* then skips the pointers with a warn log.
|
|
3598
3728
|
*/
|
|
3599
|
-
setFeatureSuccessor?(
|
|
3600
|
-
setQuotaSuccessor?(
|
|
3601
|
-
findFeature(
|
|
3602
|
-
findQuota(
|
|
3603
|
-
setFeatureReview(
|
|
3604
|
-
setQuotaReview(
|
|
3605
|
-
setFeatureI18n(
|
|
3606
|
-
setQuotaI18n(
|
|
3729
|
+
setFeatureSuccessor?(featureKey: string, successorKey: string | null): Promise<FeatureCatalogEntryRow>;
|
|
3730
|
+
setQuotaSuccessor?(quotaKey: string, successorKey: string | null): Promise<QuotaCatalogEntryRow>;
|
|
3731
|
+
findFeature(featureKey: string): Promise<FeatureCatalogEntryRow | null>;
|
|
3732
|
+
findQuota(quotaKey: string): Promise<QuotaCatalogEntryRow | null>;
|
|
3733
|
+
setFeatureReview(featureKey: string, data: SetCatalogEntryReviewData): Promise<FeatureCatalogEntryRow>;
|
|
3734
|
+
setQuotaReview(quotaKey: string, data: SetCatalogEntryReviewData): Promise<QuotaCatalogEntryRow>;
|
|
3735
|
+
setFeatureI18n(featureKey: string, i18n: CatalogEntryI18n): Promise<FeatureCatalogEntryRow>;
|
|
3736
|
+
setQuotaI18n(quotaKey: string, i18n: CatalogEntryI18n): Promise<QuotaCatalogEntryRow>;
|
|
3607
3737
|
/** Sets the editable base fields (default locale `label`/`description`). */
|
|
3608
|
-
setFeatureBase(
|
|
3609
|
-
setQuotaBase(
|
|
3738
|
+
setFeatureBase(featureKey: string, data: UpdateCatalogEntryBaseData): Promise<FeatureCatalogEntryRow>;
|
|
3739
|
+
setQuotaBase(quotaKey: string, data: UpdateCatalogEntryBaseData): Promise<QuotaCatalogEntryRow>;
|
|
3610
3740
|
}
|
|
3611
3741
|
/**
|
|
3612
3742
|
* Adapter for `promotions`. **No versioning** — promotions are edited
|
|
@@ -3614,7 +3744,7 @@ interface CatalogEntryRepository {
|
|
|
3614
3744
|
* this against their `promotions` Prisma table.
|
|
3615
3745
|
*/
|
|
3616
3746
|
interface PromotionRepository {
|
|
3617
|
-
list(
|
|
3747
|
+
list(): Promise<PromotionRow[]>;
|
|
3618
3748
|
findById(id: string): Promise<PromotionRow | null>;
|
|
3619
3749
|
create(data: CreatePromotionData): Promise<PromotionRow>;
|
|
3620
3750
|
update(id: string, data: UpdatePromotionData): Promise<PromotionRow>;
|
|
@@ -3622,13 +3752,14 @@ interface PromotionRepository {
|
|
|
3622
3752
|
delete(id: string): Promise<void>;
|
|
3623
3753
|
}
|
|
3624
3754
|
/**
|
|
3625
|
-
* Adapter for `marketing_settings` — one row
|
|
3626
|
-
*
|
|
3627
|
-
*
|
|
3755
|
+
* Adapter for `marketing_settings` — at most one row, which a `CHECK` on the
|
|
3756
|
+
* canonical schema holds rather than convention. `get` returns `null` as long
|
|
3757
|
+
* as the SuperAdmin has saved nothing (then the full `availableLocales` pool
|
|
3758
|
+
* counts as active). `upsert` creates the row or replaces it.
|
|
3628
3759
|
*/
|
|
3629
3760
|
interface MarketingSettingsRepository {
|
|
3630
|
-
get(
|
|
3631
|
-
upsert(
|
|
3761
|
+
get(): Promise<MarketingSettingsRow | null>;
|
|
3762
|
+
upsert(data: UpdateMarketingSettingsData): Promise<MarketingSettingsRow>;
|
|
3632
3763
|
}
|
|
3633
3764
|
|
|
3634
3765
|
/**
|
|
@@ -3840,6 +3971,8 @@ declare const CATALOG_ERROR_CODES: {
|
|
|
3840
3971
|
readonly BUNDLE_VERSION_SUPERSEDED: "BUNDLE_VERSION_SUPERSEDED";
|
|
3841
3972
|
readonly BUNDLE_VERSION_REGRESSION: "BUNDLE_VERSION_REGRESSION";
|
|
3842
3973
|
readonly BUNDLE_VERSION_ZERO_PRICE: "BUNDLE_VERSION_ZERO_PRICE";
|
|
3974
|
+
readonly BUNDLE_VERSION_NO_PRICE: "BUNDLE_VERSION_NO_PRICE";
|
|
3975
|
+
readonly BUNDLE_VERSION_NOT_PRICED_FOR_PLAN: "BUNDLE_VERSION_NOT_PRICED_FOR_PLAN";
|
|
3843
3976
|
readonly BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED: "BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED";
|
|
3844
3977
|
readonly BUNDLE_VERSION_VALID_FROM_REQUIRED: "BUNDLE_VERSION_VALID_FROM_REQUIRED";
|
|
3845
3978
|
readonly BUNDLE_VERSION_VALID_FROM_INVALID: "BUNDLE_VERSION_VALID_FROM_INVALID";
|
|
@@ -3884,6 +4017,8 @@ declare const BILLING_ERROR_CODES: {
|
|
|
3884
4017
|
readonly BUNDLE_ALREADY_SUBSCRIBED: "BUNDLE_ALREADY_SUBSCRIBED";
|
|
3885
4018
|
readonly BUNDLE_INCOMPATIBLE_WITH_PLAN: "BUNDLE_INCOMPATIBLE_WITH_PLAN";
|
|
3886
4019
|
readonly BUNDLE_NOT_SELF_SERVICE: "BUNDLE_NOT_SELF_SERVICE";
|
|
4020
|
+
readonly BUNDLE_CYCLE_EXCEEDS_PLAN: "BUNDLE_CYCLE_EXCEEDS_PLAN";
|
|
4021
|
+
readonly BUNDLE_NOT_PRICED_FOR_THIS_PLAN: "BUNDLE_NOT_PRICED_FOR_THIS_PLAN";
|
|
3887
4022
|
readonly SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED: "SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED";
|
|
3888
4023
|
readonly SUBSCRIPTION_BUNDLE_NOT_CANCELLED: "SUBSCRIPTION_BUNDLE_NOT_CANCELLED";
|
|
3889
4024
|
readonly SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE: "SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE";
|
|
@@ -4040,6 +4175,8 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
4040
4175
|
readonly BUNDLE_ALREADY_SUBSCRIBED: "BUNDLE_ALREADY_SUBSCRIBED";
|
|
4041
4176
|
readonly BUNDLE_INCOMPATIBLE_WITH_PLAN: "BUNDLE_INCOMPATIBLE_WITH_PLAN";
|
|
4042
4177
|
readonly BUNDLE_NOT_SELF_SERVICE: "BUNDLE_NOT_SELF_SERVICE";
|
|
4178
|
+
readonly BUNDLE_CYCLE_EXCEEDS_PLAN: "BUNDLE_CYCLE_EXCEEDS_PLAN";
|
|
4179
|
+
readonly BUNDLE_NOT_PRICED_FOR_THIS_PLAN: "BUNDLE_NOT_PRICED_FOR_THIS_PLAN";
|
|
4043
4180
|
readonly SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED: "SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED";
|
|
4044
4181
|
readonly SUBSCRIPTION_BUNDLE_NOT_CANCELLED: "SUBSCRIPTION_BUNDLE_NOT_CANCELLED";
|
|
4045
4182
|
readonly SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE: "SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE";
|
|
@@ -4093,6 +4230,8 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
4093
4230
|
readonly BUNDLE_VERSION_SUPERSEDED: "BUNDLE_VERSION_SUPERSEDED";
|
|
4094
4231
|
readonly BUNDLE_VERSION_REGRESSION: "BUNDLE_VERSION_REGRESSION";
|
|
4095
4232
|
readonly BUNDLE_VERSION_ZERO_PRICE: "BUNDLE_VERSION_ZERO_PRICE";
|
|
4233
|
+
readonly BUNDLE_VERSION_NO_PRICE: "BUNDLE_VERSION_NO_PRICE";
|
|
4234
|
+
readonly BUNDLE_VERSION_NOT_PRICED_FOR_PLAN: "BUNDLE_VERSION_NOT_PRICED_FOR_PLAN";
|
|
4096
4235
|
readonly BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED: "BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED";
|
|
4097
4236
|
readonly BUNDLE_VERSION_VALID_FROM_REQUIRED: "BUNDLE_VERSION_VALID_FROM_REQUIRED";
|
|
4098
4237
|
readonly BUNDLE_VERSION_VALID_FROM_INVALID: "BUNDLE_VERSION_VALID_FROM_INVALID";
|
|
@@ -4911,6 +5050,98 @@ interface SetupConfirmMfaResponse {
|
|
|
4911
5050
|
ok: boolean;
|
|
4912
5051
|
}
|
|
4913
5052
|
|
|
5053
|
+
/** What the adapter's schema can actually answer about a version's dates. */
|
|
5054
|
+
interface PlanVersionMappingFields {
|
|
5055
|
+
/** `validFrom`/`validUntil` are maintained; otherwise both read as null. */
|
|
5056
|
+
validityWindows: boolean;
|
|
5057
|
+
/** `endsAt` exists; otherwise the field is left off the record entirely. */
|
|
5058
|
+
endsAt: boolean;
|
|
5059
|
+
}
|
|
5060
|
+
/** A `plans` row as either adapter reads it back. */
|
|
5061
|
+
interface CanonicalPlanRow {
|
|
5062
|
+
id: string;
|
|
5063
|
+
planKey: string;
|
|
5064
|
+
label: string;
|
|
5065
|
+
description: string | null;
|
|
5066
|
+
icon: string | null;
|
|
5067
|
+
sortOrder: number;
|
|
5068
|
+
createdAt: Date;
|
|
5069
|
+
updatedAt: Date;
|
|
5070
|
+
deletedAt: Date | null;
|
|
5071
|
+
}
|
|
5072
|
+
/** A `plan_versions` row as either adapter reads it back. */
|
|
5073
|
+
interface CanonicalPlanVersionRow {
|
|
5074
|
+
id: string;
|
|
5075
|
+
version: number;
|
|
5076
|
+
baseVersionId: string | null;
|
|
5077
|
+
features: unknown;
|
|
5078
|
+
quotas: unknown;
|
|
5079
|
+
monthlyNet: unknown;
|
|
5080
|
+
yearlyNet: unknown;
|
|
5081
|
+
marketed: boolean;
|
|
5082
|
+
publishedAt: Date | null;
|
|
5083
|
+
supersededAt: Date | null;
|
|
5084
|
+
publishedChanges: unknown;
|
|
5085
|
+
changeNote: string;
|
|
5086
|
+
nonRegressive: boolean;
|
|
5087
|
+
validFrom?: Date | null;
|
|
5088
|
+
validUntil?: Date | null;
|
|
5089
|
+
endsAt?: Date | null;
|
|
5090
|
+
createdByUserId: string | null;
|
|
5091
|
+
publishedByUserId: string | null;
|
|
5092
|
+
createdAt: Date;
|
|
5093
|
+
updatedAt: Date;
|
|
5094
|
+
}
|
|
5095
|
+
declare function toPlanRow(row: CanonicalPlanRow): PlanRow;
|
|
5096
|
+
/**
|
|
5097
|
+
* `planKey` is passed rather than read off the row: the canonical schema stores
|
|
5098
|
+
* the plan key in `planId`, but an adapter translating a consumer schema with a
|
|
5099
|
+
* real foreign key has to resolve it first, and only the adapter knows which
|
|
5100
|
+
* shape it is looking at.
|
|
5101
|
+
*/
|
|
5102
|
+
declare function toPlanVersionRow(row: CanonicalPlanVersionRow, planKey: string, fields: PlanVersionMappingFields): PlanVersionRow;
|
|
5103
|
+
|
|
5104
|
+
/** A `subscription_contracts` row as either adapter reads it back. */
|
|
5105
|
+
interface CanonicalContractRow {
|
|
5106
|
+
id: string;
|
|
5107
|
+
tenantId: string;
|
|
5108
|
+
status: string;
|
|
5109
|
+
effectiveFrom: Date;
|
|
5110
|
+
effectiveUntil: Date | null;
|
|
5111
|
+
originalOfferId: string | null;
|
|
5112
|
+
originalPlanVersionId: string | null;
|
|
5113
|
+
originalBundleVersionIds: unknown;
|
|
5114
|
+
entitlementSnapshot: unknown;
|
|
5115
|
+
priceSnapshot: unknown;
|
|
5116
|
+
promotionSnapshots: unknown;
|
|
5117
|
+
promoCodeSnapshots: unknown;
|
|
5118
|
+
termsSnapshot: unknown;
|
|
5119
|
+
createdAt: Date;
|
|
5120
|
+
updatedAt: Date;
|
|
5121
|
+
}
|
|
5122
|
+
/** A `contract_line_items` row as either adapter reads it back. */
|
|
5123
|
+
interface CanonicalContractLineItemRow {
|
|
5124
|
+
id: string;
|
|
5125
|
+
contractId: string;
|
|
5126
|
+
kind: string;
|
|
5127
|
+
sourceKey: string;
|
|
5128
|
+
sourceVersionId: string | null;
|
|
5129
|
+
titleSnapshot: string;
|
|
5130
|
+
descriptionSnapshot: string | null;
|
|
5131
|
+
quantity: number;
|
|
5132
|
+
unit: string | null;
|
|
5133
|
+
priceNet: unknown;
|
|
5134
|
+
priceGross: unknown;
|
|
5135
|
+
billingCycle: string;
|
|
5136
|
+
minimumTermUntil: Date | null;
|
|
5137
|
+
featuresSnapshot: unknown;
|
|
5138
|
+
quotaEffectsSnapshot: unknown;
|
|
5139
|
+
metadata: unknown;
|
|
5140
|
+
createdAt: Date;
|
|
5141
|
+
}
|
|
5142
|
+
declare function toSubscriptionContractRecord(row: CanonicalContractRow, lineItems: CanonicalContractLineItemRow[]): SubscriptionContractRecord;
|
|
5143
|
+
declare function toContractLineItemRecord(row: CanonicalContractLineItemRow): ContractLineItemRecord;
|
|
5144
|
+
|
|
4914
5145
|
/** Why a version is editable (for UI badges + audit logs). */
|
|
4915
5146
|
type VersionEditableReason = 'draft' | 'pre-active';
|
|
4916
5147
|
interface VersionEditability {
|
|
@@ -4951,4 +5182,4 @@ declare function resolveErrorMessage(body: Partial<PlatformErrorBody> & Record<s
|
|
|
4951
5182
|
|
|
4952
5183
|
declare const ERROR_MESSAGES_DE: Record<PlatformErrorCode, string>;
|
|
4953
5184
|
|
|
4954
|
-
export { AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminUserListFilter, type AdminUserListRow, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionRow, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, type CancelSubscriptionBundleData, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferStatus, type CheckoutSession, type CleanupResult, type CliUserRow, type ComponentKey, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ContractErrorCode, type ContractLineItemKind, type ContractLineItemRecord, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, type HandlePaymentEventInput, type HandlePaymentEventReason, type HandlePaymentEventResult, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type KpiCardDef, type KpiDisplayHint, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MfaPort, type NewContractLineItemData, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, PASSWORD_RESET_TTL_MINUTES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PasswordHasher, type PasswordResetCliResult, type PaymentEventLog, type PaymentEventStatus, type PaymentProvider, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionFilter, type PromotionI18n, type PromotionI18nFields, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicSignupPlan, type PublishBundleVersionData, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, type ReassignTenantAdminCliResult, type RedeemPromoInTransactionCallback, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResumeRegistrationInput, type ResumeRegistrationResult, type ReviewCatalogEntryData, type RlsBypassPort, SETUP_ERROR_CODES, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledPlanChangeInput, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SetCatalogEntryReviewData, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartRegistrationInput, type StartRegistrationResult, type StrictModeWarning, type StrictModeWarningCode, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SyncDiscoveryResult, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, classifyBundleVersionDiff, classifyPlanDiff, collectUnsatisfiedRequires, coverageExcludingSelf, formatErrorMessage, isBundleRedundant, isPlatformUserExistsError, isVersionEditable, missingRequiresFor, pickActivePromo, promoStatus, resolveBundleAvailability, resolveErrorMessage, selectChargeableBundles, startOfUtcDay };
|
|
5185
|
+
export { ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES, AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminUserListFilter, type AdminUserListRow, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, BUNDLE_PRICE_LOOKUP_LIMIT, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionRow, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, type CancelSubscriptionBundleData, type CancelSubscriptionInput, type CancelSubscriptionResult, type CanonicalContractLineItemRow, type CanonicalContractRow, type CanonicalPlanRow, type CanonicalPlanVersionRow, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferStatus, type CheckoutSession, type CleanupResult, type CliUserRow, type ComponentKey, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ContractErrorCode, type ContractLineItemKind, type ContractLineItemRecord, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, type HandlePaymentEventInput, type HandlePaymentEventReason, type HandlePaymentEventResult, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type KpiCardDef, type KpiDisplayHint, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MfaPort, type NewContractLineItemData, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, PASSWORD_RESET_TTL_MINUTES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PasswordHasher, type PasswordResetCliResult, type PaymentEventLog, type PaymentEventStatus, type PaymentProvider, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMappingFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionI18n, type PromotionI18nFields, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicSignupPlan, type PublishBundleVersionData, type PublishBundleVersionMeta, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, type ReassignTenantAdminCliResult, type RedeemPromoInTransactionCallback, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResumeRegistrationInput, type ResumeRegistrationResult, type ReviewCatalogEntryData, type RlsBypassPort, SETUP_ERROR_CODES, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledPlanChangeInput, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SetCatalogEntryReviewData, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartRegistrationInput, type StartRegistrationResult, type StoredBundleStem, type StrictModeWarning, type StrictModeWarningCode, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SyncDiscoveryResult, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, bundleDraftDefaults, bundleStemDefaults, classifyBundleVersionDiff, classifyPlanDiff, collectUnsatisfiedRequires, coverageExcludingSelf, definedFields, formatErrorMessage, isBundleRedundant, isPlatformUserExistsError, isVersionEditable, missingRequiresFor, pickActivePromo, previousUtcDay, promoStatus, resolveBundleAvailability, resolveErrorMessage, selectChargeableBundles, startOfUtcDay, toBundleStemRow, toContractLineItemRecord, toPlanRow, toPlanVersionRow, toSubscriptionContractRecord };
|