@saasicat/spec 1.0.0-rc.2 → 1.0.0-rc.20

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 (33) hide show
  1. package/README.md +30 -0
  2. package/acceptance/README.md +3 -3
  3. package/acceptance/mfa/totp-verify-good-and-bad-code.yaml +6 -6
  4. package/admin-api.openapi.yaml +328 -77
  5. package/cli-conventions.md +19 -19
  6. package/index.cjs +3 -0
  7. package/index.d.cts +3 -1
  8. package/index.d.ts +2 -0
  9. package/index.js +9 -1
  10. package/package.json +4 -2
  11. package/prisma-fragments/01-subscription.prisma +34 -47
  12. package/prisma-fragments/03-plan-versions.prisma +3 -4
  13. package/prisma-fragments/05-bundle.prisma +4 -5
  14. package/prisma-fragments/06-catalog-entries.prisma +24 -24
  15. package/prisma-fragments/07-promotion.prisma +2 -3
  16. package/prisma-fragments/08-subscription-contract.prisma +42 -5
  17. package/prisma-fragments/09-pending-registration.prisma +32 -27
  18. package/prisma-fragments/11-subscription-bundle.prisma +17 -0
  19. package/prisma-fragments/12-applied-settings.prisma +55 -0
  20. package/prisma-fragments/13-subscriber.prisma +94 -0
  21. package/prisma-fragments/14-payments.prisma +100 -0
  22. package/prisma-fragments/README.md +40 -22
  23. package/schemas/admin-manifest.schema.json +9 -2
  24. package/schemas/plan-catalog.schema.json +239 -18
  25. package/schemas/tenant-ledger.schema.json +236 -0
  26. package/sql/1.0-a-contract-names-its-subscriber.postgres.sql +383 -0
  27. package/sql/1.0-a-payment-method-is-a-gateway-reference.postgres.sql +177 -0
  28. package/sql/1.0-a-settings-change-carries-its-order.postgres.sql +73 -0
  29. package/sql/1.0-line-items-record-their-money.postgres.sql +134 -0
  30. package/sql/1.0-remove-project-key.postgres.sql +203 -0
  31. package/sql/1.0-the-applied-settings-are-recorded.postgres.sql +67 -0
  32. package/sql/constraints.postgres.sql +76 -0
  33. package/sql/reference-schema.postgres.sql +299 -77
package/README.md CHANGED
@@ -1,8 +1,30 @@
1
1
  # @saasicat/spec
2
2
 
3
+ ## What this is
4
+
3
5
  Language-neutral spec of the SaaS platform — JSON Schemas, OpenAPI and
4
6
  acceptance test scenarios.
5
7
 
8
+ ## What this is not
9
+
10
+ Not runnable code. JSON Schemas, an OpenAPI document, Prisma fragments and SQL
11
+ constraints — a contract any language can implement, which is why the reference
12
+ implementation is a separate package.
13
+
14
+ Not a migration tool. The fragments are merged into your own `schema.prisma`
15
+ by `saasicat schema apply`, and your Prisma or Drizzle migration flow takes it
16
+ from there.
17
+
18
+ ## Entry points
19
+
20
+ | Entry | What is in it |
21
+ | ----------------------------- | ----------------------------------------------------------------------------------------------------------- |
22
+ | `.` | The hand-written index: constants and helpers over the schemas. |
23
+ | `./schemas/*.json` | The JSON Schemas — the source of truth for every wire format. |
24
+ | `./prisma-fragments/*.prisma` | One fragment per table group, merged by `saasicat schema apply`. |
25
+ | `./prisma-fragments/` | The directory itself, for tooling that enumerates the fragments. |
26
+ | `./sql/*.sql` | The reference schema, the constraints Prisma cannot express, and the migrations a consumer applies by hand. |
27
+
6
28
  ## Contents
7
29
 
8
30
  | File | Purpose |
@@ -11,6 +33,7 @@ acceptance test scenarios.
11
33
  | `schemas/plan-catalog.schema.json` | App identity config format (`config/saas.yaml`) |
12
34
  | `schemas/promo-code.schema.json` | Promo code format incl. redemption lifecycle |
13
35
  | `schemas/audit-event.schema.json` | Audit log entry format |
36
+ | `schemas/tenant-ledger.schema.json` | A tenant's account: charges, payments, balance |
14
37
  | `admin-api.openapi.yaml` | NORMATIVE REST contract of the SuperAdmin backend |
15
38
  | `acceptance/` | HTTP test scenarios (stubs; runner planned) |
16
39
  | `index.js` / `index.cjs` / `index.d.ts` | Re-exports for JS/TS consumers |
@@ -57,3 +80,10 @@ pnpm add @saasicat/spec
57
80
  live in the DB, curated via the SuperAdmin UI.
58
81
  - **`schemaVersion` is required** in every top-level schema. Major bumps
59
82
  break — that is allowed, but must be documented in a migration note.
83
+
84
+ ## Next
85
+
86
+ - [Data model](../../docs/explanation/data-model.md) — the tables the fragments declare
87
+ - [From capability to contract](../../docs/explanation/capability-to-contract.md) — what the schemas
88
+ describe
89
+ - [Codegen](../../docs/explanation/adr/0006-spec-to-types-codegen.md) — how types are derived from them
@@ -10,10 +10,10 @@ document, but an executable set of guarantees.
10
10
  Each scenario is a YAML file with the structure:
11
11
 
12
12
  ```yaml
13
- scenario: 'Kurzbeschreibung des Verhaltens (1 Satz)'
13
+ scenario: 'What the behaviour is, in one sentence'
14
14
  description: |
15
- Längere Beschreibungwas wird hier abgesichert, warum ist es wichtig.
16
- Verweise auf SPEC-Sektion oder offene Frage.
15
+ The longer version what this holds, and why it matters.
16
+ Point at the SPEC section, or at the question still open.
17
17
 
18
18
  setup: # state setup via Admin API calls
19
19
  - createTenant: { slug: '...', email: '...' }
@@ -18,26 +18,26 @@ cases:
18
18
  - name: 'valid TOTP code'
19
19
  request:
20
20
  method: POST
21
- path: /api/v1/admin/tenants/test-mandant/suspend
21
+ path: /api/v1/admin/tenants/test-tenant/suspend
22
22
  auth: { as: 'super@platform.example' }
23
23
  headers:
24
24
  X-Mfa-Code: '{{generateTotpFor: super@platform.example}}'
25
25
  body: { reason: 'test reason' }
26
26
  pre:
27
- - createTenant: { slug: 'test-mandant', email: 'x@test-mandant.example' }
27
+ - createTenant: { slug: 'test-tenant', email: 'x@test-tenant.example' }
28
28
  then:
29
29
  status: 200
30
30
 
31
31
  - name: 'invalid TOTP code'
32
32
  request:
33
33
  method: POST
34
- path: /api/v1/admin/tenants/test-mandant/suspend
34
+ path: /api/v1/admin/tenants/test-tenant/suspend
35
35
  auth: { as: 'super@platform.example' }
36
36
  headers:
37
37
  X-Mfa-Code: '000000'
38
38
  body: { reason: 'test reason' }
39
39
  pre:
40
- - createTenant: { slug: 'test-mandant-2', email: 'y@test-mandant-2.example' }
40
+ - createTenant: { slug: 'test-tenant-2', email: 'y@test-tenant-2.example' }
41
41
  then:
42
42
  status: 401
43
43
  body:
@@ -46,11 +46,11 @@ cases:
46
46
  - name: 'missing TOTP header'
47
47
  request:
48
48
  method: POST
49
- path: /api/v1/admin/tenants/test-mandant-3/suspend
49
+ path: /api/v1/admin/tenants/test-tenant-3/suspend
50
50
  auth: { as: 'super@platform.example' }
51
51
  body: { reason: 'test reason' }
52
52
  pre:
53
- - createTenant: { slug: 'test-mandant-3', email: 'z@test-mandant-3.example' }
53
+ - createTenant: { slug: 'test-tenant-3', email: 'z@test-tenant-3.example' }
54
54
  then:
55
55
  status: 401
56
56
  body: