@saasicat/spec 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasicat/spec",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Language-neutral spec of the SaaS platform: JSON Schemas, OpenAPI contract, Prisma fragments, acceptance scenarios.",
5
5
  "type": "module",
6
6
  "main": "./index.cjs",
@@ -76,6 +76,12 @@ model PlanVersion {
76
76
  changeNote String
77
77
  nonRegressive Boolean @default(true)
78
78
 
79
+ // Booking window for new subscriptions. Nullable for backwards-compatible
80
+ // legacy rows; `endsAt` is an optional precise administrative termination.
81
+ validFrom DateTime?
82
+ validUntil DateTime?
83
+ endsAt DateTime?
84
+
79
85
  createdByUserId String?
80
86
  publishedByUserId String?
81
87
 
@@ -90,5 +96,6 @@ model PlanVersion {
90
96
  @@unique([planId, version])
91
97
  @@index([planId, supersededAt])
92
98
  @@index([planId, publishedAt])
99
+ @@index([planId, validFrom])
93
100
  @@map("plan_versions")
94
101
  }
@@ -76,6 +76,12 @@ model BundleVersion {
76
76
  changeNote String @default("")
77
77
  nonRegressive Boolean @default(true)
78
78
 
79
+ // Booking window for new subscriptions. Both columns are nullable so this
80
+ // schema change is additive and existing rows remain valid. Legacy adapters
81
+ // may ignore them; time-aware adapters opt in explicitly.
82
+ validFrom DateTime?
83
+ validUntil DateTime?
84
+
79
85
  createdByUserId String?
80
86
  publishedByUserId String?
81
87
 
@@ -92,5 +98,6 @@ model BundleVersion {
92
98
  @@unique([bundleId, version])
93
99
  @@index([bundleId, supersededAt])
94
100
  @@index([bundleId, publishedAt])
101
+ @@index([bundleId, validFrom])
95
102
  @@map("bundle_versions")
96
103
  }
@@ -28,18 +28,19 @@ regenerated after fragment changes (`tests/reference-sql-drift.test.js`).
28
28
 
29
29
  ## Files
30
30
 
31
- | File | Models |
32
- | -------------------------------------------------------------------- | ---------------------------------------------------------------------- |
33
- | [`01-subscription.prisma`](01-subscription.prisma) | `Subscription`, `SubscriptionPaymentMethod`, `CheckoutOffer` + Enums |
34
- | [`02-promo-code.prisma`](02-promo-code.prisma) | `PromoCode`, `PromoCodeRedemption`, `PromoCodeValidationLog` + Enums |
35
- | [`03-plan-versions.prisma`](03-plan-versions.prisma) | `Plan`, `PlanVersion` |
36
- | [`04-audit-log.prisma`](04-audit-log.prisma) | `AuditLog` |
37
- | [`05-bundle.prisma`](05-bundle.prisma) | `Bundle`, `BundleVersion` |
38
- | [`06-catalog-entries.prisma`](06-catalog-entries.prisma) | `CapabilityCatalogEntry`, `FeatureCatalogEntry`, `MarketingProjection` |
39
- | [`07-promotion.prisma`](07-promotion.prisma) | `Promotion` |
40
- | [`08-subscription-contract.prisma`](08-subscription-contract.prisma) | `SubscriptionContract`, `ContractLineItem` |
41
- | [`09-pending-registration.prisma`](09-pending-registration.prisma) | `PendingRegistration`, `PaymentEventLog` + `RegistrationStatus` |
42
- | [`10-super-admin.prisma`](10-super-admin.prisma) | `SuperAdminUser`, `SuperAdminMfa` |
31
+ | File | Models |
32
+ | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
33
+ | [`01-subscription.prisma`](01-subscription.prisma) | `Subscription`, `SubscriptionPaymentMethod`, `CheckoutOffer` + Enums |
34
+ | [`02-promo-code.prisma`](02-promo-code.prisma) | `PromoCode`, `PromoCodeRedemption`, `PromoCodeValidationLog` + Enums |
35
+ | [`03-plan-versions.prisma`](03-plan-versions.prisma) | `Plan`, `PlanVersion` |
36
+ | [`04-audit-log.prisma`](04-audit-log.prisma) | `AuditLog` |
37
+ | [`05-bundle.prisma`](05-bundle.prisma) | `Bundle`, `BundleVersion` |
38
+ | [`06-catalog-entries.prisma`](06-catalog-entries.prisma) | Capability, feature, quota and marketing catalog models |
39
+ | [`07-promotion.prisma`](07-promotion.prisma) | `Promotion` |
40
+ | [`08-subscription-contract.prisma`](08-subscription-contract.prisma) | `SubscriptionContract`, `ContractLineItem` |
41
+ | [`09-pending-registration.prisma`](09-pending-registration.prisma) | `PendingRegistration`, `PaymentEventLog` + `RegistrationStatus` |
42
+ | [`10-super-admin.prisma`](10-super-admin.prisma) | `SuperAdminUser`, `SuperAdminMfa` |
43
+ | [`11-subscription-bundle.prisma`](11-subscription-bundle.prisma) | `SubscriptionBundle` |
43
44
 
44
45
  ## How the consumer uses the fragments
45
46
 
@@ -83,10 +84,14 @@ comment. The consumer enables them using their own `Tenant`/`User` model names.
83
84
 
84
85
  ### 3. Table names (`@@map`) are canonical
85
86
 
86
- `subscriptions`, `plan_versions`, `promo_codes`, `promo_code_redemptions`,
87
+ `subscriptions`, `subscription_payment_methods`, `checkout_offers`, `plans`,
88
+ `plan_versions`, `promo_codes`, `promo_code_redemptions`,
87
89
  `promo_code_validation_logs`, `audit_logs`, `bundles`, `bundle_versions`,
88
90
  `capability_catalog_entries`, `feature_catalog_entries`,
89
- `marketing_projections`, `subscription_contracts`, `contract_line_items`.
91
+ `quota_catalog_entries`, `marketing_projections`, `marketing_settings`,
92
+ `promotions`, `subscription_contracts`, `contract_line_items`,
93
+ `pending_registrations`, `payment_event_logs`, `super_admin_users`,
94
+ `super_admin_mfa`, `subscription_bundles`.
90
95
  Please do **not change** them — otherwise platform migration scripts and the
91
96
  `@saasicat/cli` commands that rely on these names will break.
92
97
 
@@ -226,6 +226,9 @@ CREATE TABLE "plan_versions" (
226
226
  "publishedChanges" JSONB,
227
227
  "changeNote" TEXT NOT NULL,
228
228
  "nonRegressive" BOOLEAN NOT NULL DEFAULT true,
229
+ "validFrom" TIMESTAMP(3),
230
+ "validUntil" TIMESTAMP(3),
231
+ "endsAt" TIMESTAMP(3),
229
232
  "createdByUserId" TEXT,
230
233
  "publishedByUserId" TEXT,
231
234
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -286,6 +289,8 @@ CREATE TABLE "bundle_versions" (
286
289
  "publishedChanges" JSONB,
287
290
  "changeNote" TEXT NOT NULL DEFAULT '',
288
291
  "nonRegressive" BOOLEAN NOT NULL DEFAULT true,
292
+ "validFrom" TIMESTAMP(3),
293
+ "validUntil" TIMESTAMP(3),
289
294
  "createdByUserId" TEXT,
290
295
  "publishedByUserId" TEXT,
291
296
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -628,6 +633,9 @@ CREATE INDEX "plan_versions_planId_supersededAt_idx" ON "plan_versions"("planId"
628
633
  -- CreateIndex
629
634
  CREATE INDEX "plan_versions_planId_publishedAt_idx" ON "plan_versions"("planId", "publishedAt");
630
635
 
636
+ -- CreateIndex
637
+ CREATE INDEX "plan_versions_planId_validFrom_idx" ON "plan_versions"("planId", "validFrom");
638
+
631
639
  -- CreateIndex
632
640
  CREATE UNIQUE INDEX "plan_versions_planId_version_key" ON "plan_versions"("planId", "version");
633
641
 
@@ -655,6 +663,9 @@ CREATE INDEX "bundle_versions_bundleId_supersededAt_idx" ON "bundle_versions"("b
655
663
  -- CreateIndex
656
664
  CREATE INDEX "bundle_versions_bundleId_publishedAt_idx" ON "bundle_versions"("bundleId", "publishedAt");
657
665
 
666
+ -- CreateIndex
667
+ CREATE INDEX "bundle_versions_bundleId_validFrom_idx" ON "bundle_versions"("bundleId", "validFrom");
668
+
658
669
  -- CreateIndex
659
670
  CREATE UNIQUE INDEX "bundle_versions_bundleId_version_key" ON "bundle_versions"("bundleId", "version");
660
671