@saasicat/nest 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/_entries.cjs +17678 -0
  2. package/dist/admin/index.cjs +4 -1533
  3. package/dist/admin/index.d.cts +10 -173
  4. package/dist/admin/index.d.ts +10 -173
  5. package/dist/admin/index.js +3 -2
  6. package/dist/{admin-resources.module-BybEjZs-.d.cts → admin-resources.module-BZN_yBFj.d.cts} +1 -1
  7. package/dist/{admin-resources.module-CUCLlUAi.d.ts → admin-resources.module-Cms8MY6h.d.ts} +1 -1
  8. package/dist/admin-stats.module-15ac5KY3.d.ts +201 -0
  9. package/dist/admin-stats.module-v4SVvWzj.d.cts +201 -0
  10. package/dist/billing/index.cjs +4 -5130
  11. package/dist/billing/index.d.cts +8 -437
  12. package/dist/billing/index.d.ts +8 -437
  13. package/dist/billing/index.js +4 -4
  14. package/dist/catalog/index.cjs +4 -5624
  15. package/dist/catalog/index.d.cts +5 -328
  16. package/dist/catalog/index.d.ts +5 -328
  17. package/dist/catalog/index.js +4 -4
  18. package/dist/checkout-offer/index.cjs +4 -807
  19. package/dist/checkout-offer/index.d.cts +5 -84
  20. package/dist/checkout-offer/index.d.ts +5 -84
  21. package/dist/checkout-offer/index.js +3 -2
  22. package/dist/checkout-offer.module-Y0hDOVrq.d.ts +85 -0
  23. package/dist/checkout-offer.module-ZYF5IsDY.d.cts +85 -0
  24. package/dist/{chunk-PBQRPDO2.js → chunk-33TP26MR.js} +2 -2
  25. package/dist/{chunk-CK54YKVK.js → chunk-75JABGZK.js} +16 -16
  26. package/dist/{chunk-HRU3CP57.js → chunk-BOADBIGB.js} +1 -1
  27. package/dist/chunk-DBZGV3HC.js +0 -0
  28. package/dist/{chunk-ZLUGQE5D.js → chunk-E7AJ42AB.js} +8 -8
  29. package/dist/{chunk-HXAWPPFW.js → chunk-F3VV6EXG.js} +9 -9
  30. package/dist/{chunk-3M6VLT5N.js → chunk-FVT7KTUI.js} +2 -2
  31. package/dist/{chunk-GW2I3JZD.js → chunk-GBDUH6DO.js} +1 -1
  32. package/dist/{chunk-K3OPNVFR.js → chunk-HBFU5AN3.js} +5 -9
  33. package/dist/{chunk-OFBDEO45.js → chunk-IRWZC3GC.js} +1 -1
  34. package/dist/chunk-L4KTQ6CL.js +20 -0
  35. package/dist/{chunk-WGVTXSYW.js → chunk-LZHLGUQI.js} +1 -1
  36. package/dist/{chunk-ZZMAHX22.js → chunk-PUXLPUVH.js} +15 -12
  37. package/dist/{chunk-7K5PT2LX.js → chunk-TXDH4FUA.js} +1 -1
  38. package/dist/chunk-UF53DWWR.js +0 -0
  39. package/dist/{chunk-AJ3EPELS.js → chunk-V34AA7C7.js} +1 -1
  40. package/dist/chunk-WJ6BMDL3.js +313 -0
  41. package/dist/{chunk-M6CZQYPY.js → chunk-Z3FWN3HJ.js} +2 -2
  42. package/dist/discovery/index.cjs +4 -588
  43. package/dist/discovery/index.js +3 -3
  44. package/dist/{enforce-quota.interceptor-B3CL5MSw.d.ts → enforce-quota.interceptor-DMEvL-bE.d.ts} +43 -2
  45. package/dist/{enforce-quota.interceptor-SqrQVF91.d.cts → enforce-quota.interceptor-Dse3jSpU.d.cts} +43 -2
  46. package/dist/entitlement/index.cjs +4 -781
  47. package/dist/entitlement/index.js +2 -2
  48. package/dist/index.cjs +4 -15671
  49. package/dist/index.d.cts +21 -56
  50. package/dist/index.d.ts +21 -56
  51. package/dist/index.js +39 -334
  52. package/dist/{module-DeH_Jkcq.d.cts → module-CSN8j8Tp.d.cts} +1 -1
  53. package/dist/{module-B5m080F0.d.ts → module-DgYJur6f.d.ts} +1 -1
  54. package/dist/plan-versions.service-BB36Q1bg.d.ts +329 -0
  55. package/dist/plan-versions.service-CUR2Whyr.d.cts +329 -0
  56. package/dist/platform/index.cjs +4 -12925
  57. package/dist/platform/index.d.cts +17 -9
  58. package/dist/platform/index.d.ts +17 -9
  59. package/dist/platform/index.js +98 -14
  60. package/dist/promo/index.cjs +4 -1520
  61. package/dist/promo/index.d.cts +6 -21
  62. package/dist/promo/index.d.ts +6 -21
  63. package/dist/promo/index.js +2 -2
  64. package/dist/rate-limit.guard-dntqAlfZ.d.cts +19 -0
  65. package/dist/rate-limit.guard-dntqAlfZ.d.ts +19 -0
  66. package/dist/registration/index.cjs +4 -1655
  67. package/dist/registration/index.js +1 -1
  68. package/dist/{service-DlhMnYjW.d.ts → service-DX8KbGXl.d.cts} +1 -1
  69. package/dist/{service-DlhMnYjW.d.cts → service-DX8KbGXl.d.ts} +1 -1
  70. package/dist/setup.service-BPwJ7My_.d.cts +45 -0
  71. package/dist/setup.service-D2mrdDDB.d.ts +45 -0
  72. package/dist/subscription-bundle-preview.service-BkJXHAeP.d.cts +438 -0
  73. package/dist/subscription-bundle-preview.service-DBbrE_cw.d.ts +438 -0
  74. package/dist/subscription-contract/index.cjs +4 -471
  75. package/dist/subscription-contract/index.d.cts +5 -13
  76. package/dist/subscription-contract/index.d.ts +5 -13
  77. package/dist/subscription-contract.module-CG9fPKAr.d.cts +14 -0
  78. package/dist/subscription-contract.module-CVebZzHR.d.ts +14 -0
  79. package/dist/testing/index.cjs +4 -13888
  80. package/dist/testing/index.d.cts +5 -5
  81. package/dist/testing/index.d.ts +5 -5
  82. package/dist/testing/index.js +10 -10
  83. package/package.json +4 -4
  84. package/dist/admin-manifest.service-BMeSLRW4.d.ts +0 -33
  85. package/dist/admin-manifest.service-StAQe6QO.d.cts +0 -33
  86. package/dist/chunk-N3WANKSA.js +0 -20
@@ -1,342 +1,19 @@
1
- import { BundleRepository, DiscoverySnapshot, SubscriptionRepository, PlanRepository, CatalogEntryRepository, BundleRow, BundleVersionRow, CreateBundleData, UpdateBundleData, CreateBundleVersionDraftData, BundleVersionMutationResult, UpdateBundleVersionDraftData, PublishBundleVersionData, MarketingProjectionRepository, MarketingProjectionFilter, MarketingProjectionRow, CreateMarketingProjectionData, UpdateMarketingProjectionData, FeatureUiRegistry, CapabilityCatalogEntryRow, FeatureCatalogEntryRow, QuotaCatalogEntryRow, ReviewCatalogEntryData, CatalogEntryI18n, UpdateCatalogEntryBaseData, SyncDiscoveryResult, PromotionRepository, PromotionRow, CreatePromotionData, UpdatePromotionData, MarketingSettingsRepository, MarketingSettingsRow, UpdateMarketingSettingsData, PublicMarketingCatalogResponse, PlanRow, CreatePlanData, UpdatePlanData, PlanVersionRow, CreatePlanVersionDraftData, PlanVersionMutationResult, UpdatePlanVersionDraftData, PublishPlanVersionData, StrictModeWarningCode, StrictModeWarning, ApprovedCatalogKeys, DiscoveredQuota, DiscoveryStatus, PromotionType, PromotionValue, PromotionTargetType, PromotionBillingCycle, PromotionI18n } from '@saasicat/types';
2
- import { c as DiscoveryScanner } from '../discovery.scanner-DLgEvuoy.cjs';
3
- import { OnApplicationBootstrap, Type, CanActivate } from '@nestjs/common';
1
+ export { B as BundlesService, C as CatalogEntriesService, a as CatalogServiceConfig, M as MarketingProjectionsService, b as MarketingSettingsService, P as PlanVersionsService, c as PlansService, d as PromotionsService, e as PublicMarketingCatalogService } from '../plan-versions.service-CUR2Whyr.cjs';
2
+ import { Type, CanActivate } from '@nestjs/common';
4
3
  export { C as CatalogControllerConfig, a as CatalogModule, b as CatalogModuleOptions } from '../catalog.module-Dw2Hrbyu.cjs';
4
+ import { StrictModeWarningCode, StrictModeWarning, DiscoverySnapshot, ApprovedCatalogKeys, DiscoveredQuota, CatalogEntryRepository, PlanVersionRow, BundleVersionRow, DiscoveryStatus, CatalogEntryI18n, PromotionType, PromotionValue, PromotionTargetType, PromotionBillingCycle, PromotionI18n } from '@saasicat/types';
5
+ import '../discovery.scanner-DLgEvuoy.cjs';
5
6
  import '@nestjs/core';
6
7
  import '../di-CcNeq9v-.cjs';
7
8
 
8
- /**
9
- * Configuration for the mutating operations.
10
- */
11
- interface CatalogServiceConfig {
12
- /** Active mode for the strict-mode check. Default `'blocking'` (#12). */
13
- strictModeCheckMode?: 'warn-only' | 'blocking';
14
- /**
15
- * Discovery→Catalog auto-sync at boot (#12). Default `true` — runs when a
16
- * `DiscoverySnapshot` is available. Set to `false` to disable the boot
17
- * sync; the manual `POST /admin/catalog/discovery/sync` is unaffected.
18
- */
19
- autoSyncDiscoveryAtBoot?: boolean;
20
- /**
21
- * Feature keys the catalog is deliberately allowed to carry WITHOUT them
22
- * existing in the discovery snapshot (= in code via @ImplementsCapability) —
23
- * marketed non-code features such as support SLAs (e.g. PRIORITY_SUPPORT).
24
- * The strict-mode check does NOT report them as BUNDLE_/PLAN_FEATURE_UNKNOWN.
25
- * Use sparingly: this is the only legitimate exception to "code is the
26
- * source of truth"; not-yet-built features do NOT belong here but should be
27
- * removed from the catalog until they are implemented.
28
- */
29
- marketedOnlyFeatures?: string[];
30
- }
31
- declare class BundlesService {
32
- private readonly repo;
33
- private readonly snapshot;
34
- private readonly subscriptions;
35
- private readonly planRepo;
36
- private readonly scanner;
37
- private readonly catalogEntries;
38
- private readonly logger;
39
- private mode;
40
- private readonly marketedOnly;
41
- constructor(repo: BundleRepository, snapshot?: DiscoverySnapshot | null, config?: CatalogServiceConfig, subscriptions?: SubscriptionRepository | null, planRepo?: PlanRepository | null, scanner?: DiscoveryScanner | null, catalogEntries?: CatalogEntryRepository | null);
42
- listBundles(projectKey: string): Promise<BundleRow[]>;
43
- getBundle(bundleId: string): Promise<{
44
- bundle: BundleRow;
45
- versions: BundleVersionRow[];
46
- }>;
47
- createBundle(data: CreateBundleData): Promise<BundleRow>;
48
- updateBundle(bundleId: string, data: UpdateBundleData): Promise<BundleRow>;
49
- softDeleteBundle(bundleId: string): Promise<void>;
50
- /**
51
- * Hard-deletes a draft BundleVersion (`publishedAt === null`) from the
52
- * DB. Published versions stay immutable (contract-protection P1) — the
53
- * service throws 422 with code `BUNDLE_VERSION_ALREADY_PUBLISHED`.
54
- */
55
- discardBundleDraft(versionId: string): Promise<void>;
56
- listBundleVersions(bundleId: string): Promise<BundleVersionRow[]>;
57
- getBundleVersion(versionId: string): Promise<BundleVersionRow>;
58
- /**
59
- * Annotates each BundleVersion with `isLatestInChain` (highest version
60
- * number in the chain) + `subscriptionCount` so that UI and backend make
61
- * the same editability decision. `subscriptionCount` stays `undefined`
62
- * when no SubscriptionRepository is registered or the method was not
63
- * implemented — `isVersionEditable` interprets that fail-closed
64
- * (= frozen).
65
- */
66
- private annotateEditability;
67
- /**
68
- * Creates a new draft BundleVersion. Throws when a draft already exists
69
- * for the same bundle (repository constraint).
70
- *
71
- * The strict-mode check runs on the input; in `warn-only` warnings are
72
- * returned, in `blocking` the service throws HTTP 422.
73
- */
74
- createBundleDraft(data: CreateBundleVersionDraftData): Promise<BundleVersionMutationResult>;
75
- /**
76
- * Updates a draft version or — as a deliberate relaxation of
77
- * contract-protection P1 — a published-but-future BundleVersion that is
78
- * latest-in-chain and does not yet bind any subscription. Once
79
- * `validFrom` is reached or a booking references it, the version freezes
80
- * again. The concrete decision is made by the `isVersionEditable` helper,
81
- * which is mirrored by the UI.
82
- */
83
- updateBundleDraft(versionId: string, data: UpdateBundleVersionDraftData): Promise<BundleVersionMutationResult>;
84
- /**
85
- * Publishes a draft version atomically. Steps:
86
- * 1. Strict check on the draft definition (warn-only or blocking)
87
- * 2. Enforce validFrom requirement + ordering against the predecessor
88
- * (SPEC_V2 §4.2 + §11.1 M6 Pack 2c, analogous to PlanVersion)
89
- * 3. Compute the diff against the predecessor version (latest live) →
90
- * `publishedChanges` + `nonRegressive` via `classifyBundleVersionDiff`
91
- * 4. Call Repository.publishDraft with the diff result + validity dates
92
- * (transaction; auto-succession sets the previous validUntil)
93
- */
94
- publishBundleVersion(versionId: string, publishMeta: PublishBundleVersionData): Promise<BundleVersionMutationResult>;
95
- private runStrictCheck;
96
- private gateOrPass;
97
- private assertBundleVersionWindowUpdate;
98
- private findPreviousBundleVersion;
99
- private parseOptionalBundleDate;
100
- private parseRequiredBundleDate;
101
- }
102
-
103
- declare class MarketingProjectionsService {
104
- private readonly repo;
105
- constructor(repo: MarketingProjectionRepository);
106
- list(filter: MarketingProjectionFilter): Promise<MarketingProjectionRow[]>;
107
- getById(id: string): Promise<MarketingProjectionRow>;
108
- create(data: CreateMarketingProjectionData): Promise<MarketingProjectionRow>;
109
- update(id: string, data: UpdateMarketingProjectionData): Promise<MarketingProjectionRow>;
110
- delete(id: string): Promise<void>;
111
- }
112
-
113
- declare class CatalogEntriesService implements OnApplicationBootstrap {
114
- private readonly repo;
115
- private readonly snapshot;
116
- private readonly scanner;
117
- private readonly featureUiRegistry;
118
- private readonly logger;
119
- private readonly autoSyncAtBoot;
120
- constructor(repo: CatalogEntryRepository, snapshot?: DiscoverySnapshot | null, config?: CatalogServiceConfig, scanner?: DiscoveryScanner | null, featureUiRegistry?: FeatureUiRegistry | null);
121
- /**
122
- * Mirrors the discovery snapshot into the catalog entries at boot
123
- * (discovery-as-SSOT, #12). Runs only when a snapshot is available and
124
- * the kill switch `autoSyncDiscoveryAtBoot` is not set to `false`. A
125
- * sync error deliberately does not abort the boot — the manual endpoint
126
- * `POST /admin/catalog/discovery/sync` remains as a fallback.
127
- */
128
- onApplicationBootstrap(): Promise<void>;
129
- listCapabilities(projectKey: string, codeStatus?: string): Promise<CapabilityCatalogEntryRow[]>;
130
- listFeatures(projectKey: string, discoveryStatus?: string): Promise<FeatureCatalogEntryRow[]>;
131
- listQuotas(projectKey: string, discoveryStatus?: string): Promise<QuotaCatalogEntryRow[]>;
132
- /**
133
- * Approval transition of a feature (#20). Validates the state machine;
134
- * `approved` persists the approval signature from the current
135
- * snapshot, `pending` (revoke/reactivate) deletes it, `outdated`/
136
- * `obsolete` keep the last approval as history.
137
- */
138
- reviewFeature(projectKey: string, featureKey: string, data: ReviewCatalogEntryData, reviewedBy: string | null): Promise<FeatureCatalogEntryRow>;
139
- /** Approval transition of a quota — same state machine as features (#20). */
140
- reviewQuota(projectKey: string, quotaKey: string, data: ReviewCatalogEntryData, reviewedBy: string | null): Promise<QuotaCatalogEntryRow>;
141
- private resolveReviewUpdate;
142
- setFeatureI18n(projectKey: string, featureKey: string, i18n: CatalogEntryI18n): Promise<FeatureCatalogEntryRow>;
143
- setQuotaI18n(projectKey: string, quotaKey: string, i18n: CatalogEntryI18n): Promise<QuotaCatalogEntryRow>;
144
- /** Sets the editable default-locale label/description of a feature. */
145
- setFeatureBase(projectKey: string, featureKey: string, data: UpdateCatalogEntryBaseData): Promise<FeatureCatalogEntryRow>;
146
- /** Sets the editable default-locale label/description of a quota. */
147
- setQuotaBase(projectKey: string, quotaKey: string, data: UpdateCatalogEntryBaseData): Promise<QuotaCatalogEntryRow>;
148
- /**
149
- * Synchronizes the catalog entries from a discovery snapshot.
150
- * Idempotent — can run against the same snapshot any number of times.
151
- */
152
- syncFromSnapshot(snapshot: DiscoverySnapshot): Promise<SyncDiscoveryResult>;
153
- /**
154
- * `replaced` semantics (#39): if a key disappears from the snapshot AND
155
- * another snapshot key claims it via `replaces`, the old entry gets
156
- * the successor pointer — `obsolete` (from `retireMissing`)
157
- * + `successorKey` instead of a bare `obsolete`. If a key reappears in
158
- * the code, an existing pointer is deleted. A missing key
159
- * without a claimant remains untouched (deleted without replacement).
160
- */
161
- private applySuccessorPointers;
162
- }
163
-
164
9
  declare function buildCatalogEntriesController(guards: Array<Type<CanActivate>>): Type;
165
10
 
166
- declare class PromotionsService {
167
- private readonly repo;
168
- constructor(repo: PromotionRepository);
169
- list(projectKey: string): Promise<PromotionRow[]>;
170
- getById(id: string): Promise<PromotionRow>;
171
- create(data: CreatePromotionData): Promise<PromotionRow>;
172
- update(id: string, data: UpdatePromotionData): Promise<PromotionRow>;
173
- delete(id: string): Promise<void>;
174
- }
175
-
176
11
  declare function buildPromotionsController(guards: Array<Type<CanActivate>>): Type;
177
12
 
178
- declare class MarketingSettingsService {
179
- private readonly repo;
180
- constructor(repo: MarketingSettingsRepository);
181
- /** Returns the stored config or `null` (in which case the full pool applies). */
182
- get(projectKey: string): Promise<MarketingSettingsRow | null>;
183
- upsert(projectKey: string, data: UpdateMarketingSettingsData): Promise<MarketingSettingsRow>;
184
- }
185
-
186
13
  declare function buildMarketingSettingsController(guards: Array<Type<CanActivate>>): Type;
187
14
 
188
- declare class PublicMarketingCatalogService {
189
- private readonly planRepo;
190
- private readonly marketingRepo;
191
- private readonly promotionRepo;
192
- private readonly catalogEntryRepo;
193
- private readonly bundleRepo;
194
- constructor(planRepo: PlanRepository, marketingRepo: MarketingProjectionRepository, promotionRepo: PromotionRepository, catalogEntryRepo?: CatalogEntryRepository | null, bundleRepo?: BundleRepository | null);
195
- getCatalog(projectKey: string, locale: string, currency: string, vatRate: number, asOf?: Date): Promise<PublicMarketingCatalogResponse>;
196
- /**
197
- * Loads all published-and-live bundle versions for a project and
198
- * filters on `marketed === true`. Without a registered
199
- * `BundleRepository` (apps without the SuperAdmin bundle editor) the
200
- * list is empty — the public catalog stays plan-only.
201
- */
202
- private loadMarketedBundles;
203
- /**
204
- * Maps BundleVersionRow → PublicMarketingBundle. Locale resolution
205
- * runs via `MarketingProjectionRepository.findByTarget('BUNDLE',
206
- * bundleVersionId, locale)` — on a miss it falls back to
207
- * `DEFAULT_LOCALE`. If the fallback is missing too, label/description
208
- * come directly from the bundle root (denormalized in `BundleVersionRow`).
209
- *
210
- * If the marketing projection is `visible === false`, the bundle is
211
- * hidden from the public response (preparation phase).
212
- */
213
- private toPublicBundle;
214
- /**
215
- * Labels for bundle features ∪ their requires (#48): `comparison.features`
216
- * only covers the plan-feature union — bundle-only features would
217
- * otherwise get no label in the public payload. Curated keys only;
218
- * without a CatalogEntryRepository the map stays empty (frontends fall
219
- * back to the key).
220
- */
221
- private resolveBundleFeatureLabels;
222
- /** Loads the translated feature/quota labels (+ sortOrder) for a locale. */
223
- private loadLabelMeta;
224
- /**
225
- * Resolves the displayed label of a top feature: the `label` override
226
- * wins; otherwise the translated label of the referenced `key`.
227
- */
228
- private resolveTopFeature;
229
- /** Row definitions of the comparison matrix (feature/quota union + labels). */
230
- private buildComparison;
231
- private resolvePromo;
232
- }
233
-
234
15
  declare function buildPublicMarketingCatalogController(guards: Array<Type<CanActivate>>, projectKey: string, currency: string, vatRate: number): Type;
235
16
 
236
- declare class PlansService {
237
- private readonly repo;
238
- private readonly subscriptions;
239
- constructor(repo: PlanRepository, subscriptions?: SubscriptionRepository | null);
240
- /**
241
- * Platform-wide count of active (ACTIVE/TRIAL) subscriptions per `planKey`,
242
- * across versions and across all tenants (RLS-exempt). Plans without a
243
- * subscription are absent from the map. Returns `{}` when no
244
- * `SubscriptionRepository` is registered or it does not implement
245
- * `countActiveByPlanKey`.
246
- */
247
- getTenantCounts(projectKey: string): Promise<Record<string, number>>;
248
- listPlans(projectKey: string, opts?: {
249
- onlyPublished?: boolean;
250
- }): Promise<PlanRow[]>;
251
- getPlan(planId: string): Promise<PlanRow>;
252
- createPlan(data: CreatePlanData): Promise<PlanRow>;
253
- updatePlan(planId: string, data: UpdatePlanData): Promise<PlanRow>;
254
- softDeletePlan(planId: string): Promise<void>;
255
- /**
256
- * Hard-deletes the plan master record. Only allowed for plans without
257
- * `PlanVersion` entries — published versions are immutable under
258
- * contract protection P1 (existing subscriptions reference them). The
259
- * caller must discard drafts beforehand via `DELETE plan-versions/:id`.
260
- *
261
- * If the repository does not implement `hardDelete`, the endpoint
262
- * responds with 422 `PLAN_HARD_DELETE_NOT_IMPLEMENTED` — consumers can
263
- * then fall back to `softDelete`.
264
- */
265
- hardDeletePlan(planId: string): Promise<void>;
266
- /**
267
- * Platform invariant (contract protection P1): once a plan has ever had a
268
- * published version, its plan master record is retained — regardless of
269
- * whether the version has since been superseded. Subscriptions still
270
- * reference it via the version, and the audit log must be able to resolve
271
- * the plan.
272
- */
273
- private assertNoPublishedVersions;
274
- private assertNoDrafts;
275
- }
276
-
277
- declare class PlanVersionsService {
278
- private readonly repo;
279
- private readonly snapshot;
280
- private readonly subscriptions;
281
- private readonly scanner;
282
- private readonly catalogEntries;
283
- private readonly logger;
284
- private mode;
285
- private readonly marketedOnly;
286
- constructor(repo: PlanRepository, snapshot?: DiscoverySnapshot | null, config?: CatalogServiceConfig, subscriptions?: SubscriptionRepository | null, scanner?: DiscoveryScanner | null, catalogEntries?: CatalogEntryRepository | null);
287
- /**
288
- * Discards a draft version. Allowed only while the version has not yet
289
- * been published — published versions are preserved immutably,
290
- * because existing subscriptions reference them (contract protection P1).
291
- *
292
- * If the repository does not implement the method, the endpoint
293
- * responds with 501 Not Implemented (consumers without the editor stack
294
- * should not register `PlanVersionsService` anyway).
295
- */
296
- discardPlanDraft(versionId: string): Promise<void>;
297
- /**
298
- * @param planUuid UUID of the plan root (Plan.id) — resolved to planKey
299
- * before the repo call (lifecycle methods work with planKey because
300
- * PlanVersion.planId is a string in the schema).
301
- */
302
- listPlanVersions(planUuid: string): Promise<PlanVersionRow[]>;
303
- getPlanVersion(versionId: string): Promise<PlanVersionRow>;
304
- /**
305
- * Annotates each version with `isLatestInChain` (highest version number
306
- * in the root) + `subscriptionCount` so that UI and backend make the same
307
- * editability decision. `subscriptionCount` stays
308
- * `undefined` when no SubscriptionRepository is registered —
309
- * `isVersionEditable` interprets that fail-closed (= frozen).
310
- */
311
- private annotateEditability;
312
- /**
313
- * @param data.planId — the plan UUID from the controller. Resolved to
314
- * planKey before the repo call.
315
- */
316
- createPlanDraft(data: CreatePlanVersionDraftData): Promise<PlanVersionMutationResult>;
317
- updatePlanDraft(versionId: string, data: UpdatePlanVersionDraftData): Promise<PlanVersionMutationResult>;
318
- publishPlanVersion(versionId: string, publishMeta: PublishPlanVersionData): Promise<PlanVersionMutationResult>;
319
- /**
320
- * Terminates a **live** PlanVersion by setting `endsAt`.
321
- * Unlike auto-succession (validUntil), this is an explicit
322
- * user action: the version is not replaced by a successor version
323
- * but expires on the chosen date. Existing subscriptions
324
- * (P1) stay bound — this only affects new bookings.
325
- *
326
- * Idempotent — a second call with a different date overwrites.
327
- *
328
- * Preconditions:
329
- * - Version must be live (`publishedAt != null && supersededAt == null`).
330
- * - `endsAt` must lie in the future (`endsAt > now`).
331
- *
332
- * If the repository does not implement the method, the endpoint
333
- * responds with 422 `PLAN_TERMINATE_NOT_IMPLEMENTED`.
334
- */
335
- terminatePlanVersion(versionId: string, endsAt: Date): Promise<PlanVersionRow>;
336
- private runStrictCheck;
337
- private gateOrPass;
338
- }
339
-
340
17
  /**
341
18
  * Builds the controller class at boot time with the guards configured by the
342
19
  * consumer. Pattern analogous to `buildDiscoveryController`.
@@ -858,4 +535,4 @@ declare class PublishPlanVersionDto {
858
535
  validUntil?: string | null;
859
536
  }
860
537
 
861
- export { ADVISORY_STRICT_MODE_CODES, BUNDLE_REPOSITORY_TOKEN, BundlesService, CATALOG_ENTRY_REPOSITORY_TOKEN, CATALOG_SERVICE_CONFIG_TOKEN, CatalogEntriesService, type CatalogServiceConfig, CreateBundleDto, CreateBundleVersionDraftDto, CreateMarketingProjectionDto, CreatePlanDto, CreatePlanVersionDraftDto, CreatePromotionDto, ListCatalogEntriesQueryDto, ListMarketingProjectionsQueryDto, ListMarketingSettingsQueryDto, ListPromotionsQueryDto, MARKETING_PROJECTION_REPOSITORY_TOKEN, MARKETING_SETTINGS_REPOSITORY_TOKEN, MarketingProjectionsService, MarketingSettingsService, PLAN_REPOSITORY_TOKEN, PROMOTION_REPOSITORY_TOKEN, PlanVersionsService, PlansService, type PreflightFinding, type PreflightInput, type PreflightReport, PromotionsService, PublicMarketingCatalogService, PublishBundleVersionDto, PublishPlanVersionDto, ReviewCatalogEntryDto, type SeedBundleDraft, type SeedGateFinding, type SeedGateInput, type SeedGateMode, type SeedGateReport, type SeedGateRunOptions, type SeedPlanDraft, SyncDiscoveryDto, UpdateBundleDto, UpdateBundleVersionDraftDto, UpdateCatalogEntryI18nDto, UpdateMarketingProjectionDto, UpdateMarketingSettingsDto, UpdatePlanDto, UpdatePlanVersionDraftDto, UpdatePromotionDto, blockingStrictModeWarnings, buildBundleVersionsController, buildBundlesController, buildCatalogEntriesController, buildMarketingProjectionsController, buildMarketingSettingsController, buildPlanVersionsController, buildPlansController, buildPromotionsController, buildPublicMarketingCatalogController, featureApprovalSignature, formatPreflightReport, formatSeedGateReport, loadApprovedCatalogKeys, preflightExitCode, quotaApprovalSignature, runPreflight, runSeedGateFromFile, seedGateExitCode, validateBundleDraft, validatePlanDraft, validateSeedAgainstSnapshot };
538
+ export { ADVISORY_STRICT_MODE_CODES, BUNDLE_REPOSITORY_TOKEN, CATALOG_ENTRY_REPOSITORY_TOKEN, CATALOG_SERVICE_CONFIG_TOKEN, CreateBundleDto, CreateBundleVersionDraftDto, CreateMarketingProjectionDto, CreatePlanDto, CreatePlanVersionDraftDto, CreatePromotionDto, ListCatalogEntriesQueryDto, ListMarketingProjectionsQueryDto, ListMarketingSettingsQueryDto, ListPromotionsQueryDto, MARKETING_PROJECTION_REPOSITORY_TOKEN, MARKETING_SETTINGS_REPOSITORY_TOKEN, PLAN_REPOSITORY_TOKEN, PROMOTION_REPOSITORY_TOKEN, type PreflightFinding, type PreflightInput, type PreflightReport, PublishBundleVersionDto, PublishPlanVersionDto, ReviewCatalogEntryDto, type SeedBundleDraft, type SeedGateFinding, type SeedGateInput, type SeedGateMode, type SeedGateReport, type SeedGateRunOptions, type SeedPlanDraft, SyncDiscoveryDto, UpdateBundleDto, UpdateBundleVersionDraftDto, UpdateCatalogEntryI18nDto, UpdateMarketingProjectionDto, UpdateMarketingSettingsDto, UpdatePlanDto, UpdatePlanVersionDraftDto, UpdatePromotionDto, blockingStrictModeWarnings, buildBundleVersionsController, buildBundlesController, buildCatalogEntriesController, buildMarketingProjectionsController, buildMarketingSettingsController, buildPlanVersionsController, buildPlansController, buildPromotionsController, buildPublicMarketingCatalogController, featureApprovalSignature, formatPreflightReport, formatSeedGateReport, loadApprovedCatalogKeys, preflightExitCode, quotaApprovalSignature, runPreflight, runSeedGateFromFile, seedGateExitCode, validateBundleDraft, validatePlanDraft, validateSeedAgainstSnapshot };