@saasicat/persistence-testing 1.0.0-rc.0 → 1.0.0-rc.10

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/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { PersistenceCapabilities, TransactionRunner, SubscriptionRepository, PlanVersionRepository, PromoCodeRepository, PromoCodeRedemptionRepository, MfaPort, AuditPort, AuditQueryPort, SubscriptionContractRepository, TenantSubscriptionWritePort, BundleRepository, PlanRepository, PromoSubscriptionLookup } from '@saasicat/types';
1
+ import { PersistenceCapabilities, TransactionRunner, SubscriptionRepository, PlanVersionRepository, PromoCodeRepository, PromoCodeRedemptionRepository, MfaPort, AuditPort, AuditQueryPort, SubscriptionContractRepository, TenantSubscriptionWritePort, BundleRepository, SubscriptionBundleRepository, PlanRepository, PromoSubscriptionLookup, AppliedSettingsPort } from '@saasicat/core';
2
2
 
3
3
  /**
4
4
  * Port instances under test. Required members define the minimum an adapter
@@ -25,6 +25,14 @@ interface ContractAdapterInstances {
25
25
  tenantSubscriptionWrite?: TenantSubscriptionWritePort;
26
26
  /** Enables BundleVersion validity-window and auto-succession scenarios. */
27
27
  bundleRepository?: BundleRepository;
28
+ /**
29
+ * Enables the booking scenarios — the junction a tenant's bundles hang off.
30
+ *
31
+ * Separate from `bundleRepository`, which is the catalog: one answers what
32
+ * may be sold, the other what a tenant actually bought and for which
33
+ * period. `adapter-drizzle` has neither yet.
34
+ */
35
+ subscriptionBundleRepository?: SubscriptionBundleRepository;
28
36
  /** Enables PlanVersion lifecycle, identity and validity-window scenarios. */
29
37
  planRepository?: PlanRepository;
30
38
  /**
@@ -37,6 +45,16 @@ interface ContractAdapterInstances {
37
45
  * tenant, which is what makes selecting the wrong row possible at all.
38
46
  */
39
47
  promoSubscriptionLookup?: PromoSubscriptionLookup;
48
+ /**
49
+ * Enables the applied-settings scenarios: the one row an installation keeps
50
+ * about the configuration it runs on, and the changes noticed between
51
+ * starts. The singleton and the guard are the parts worth a contract — two
52
+ * adapters that upsert differently would leave one of them with two rows
53
+ * and a reader picking one at random, and one whose write ignores the
54
+ * fingerprint it was given lets every replica of a deployment record the
55
+ * same change.
56
+ */
57
+ appliedSettings?: AppliedSettingsPort;
40
58
  }
41
59
  /** Fixture writers — implemented per adapter against its own schema. */
42
60
  interface ContractSeed {
@@ -63,6 +81,34 @@ interface ContractSeed {
63
81
  }): Promise<{
64
82
  subscriptionId: string;
65
83
  }>;
84
+ /**
85
+ * A published BundleVersion to book against.
86
+ *
87
+ * A fixture writer rather than a call into `bundleRepository`: the catalog
88
+ * repository is a subject of the suite, not a tool for setting up someone
89
+ * else's scenario, and a booking scenario that failed because the catalog
90
+ * did would say the wrong thing.
91
+ *
92
+ * Optional because an adapter may not carry the catalog tables at all —
93
+ * `adapter-drizzle` does not. A required writer nobody can implement is a
94
+ * contract that lies about what conformance means; the booking scenarios
95
+ * gate on this and report the gap as a skip instead.
96
+ */
97
+ createBundleVersion?(input: {
98
+ bundleKey: string;
99
+ features: string[];
100
+ }): Promise<{
101
+ bundleVersionId: string;
102
+ }>;
103
+ /**
104
+ * Clears a booking's `canceledAt` while leaving `canceledEffectiveAt`.
105
+ *
106
+ * A shape no repository method produces, and one the nullable columns
107
+ * nonetheless permit — so the adapters have to agree on how to read it.
108
+ * Optional: a harness that cannot reach its store directly says so and the
109
+ * scenario skips, rather than the scenario inventing a way in.
110
+ */
111
+ clearBookingRequestDate?(subscriptionBundleId: string): Promise<void>;
66
112
  createPromoCode(input: {
67
113
  code: string;
68
114
  maxRedemptions: number | null;
@@ -82,8 +128,6 @@ interface PersistenceContractHarness {
82
128
  interface PersistenceAdapterContractOptions {
83
129
  /** Display name in the test output, e.g. `'adapter-prisma @ postgres16'`. */
84
130
  name: string;
85
- /** Project identity used by catalog lifecycle scenarios. */
86
- projectKey: string;
87
131
  /** Builds the harness once for the whole suite. */
88
132
  create(): Promise<PersistenceContractHarness>;
89
133
  }
@@ -94,7 +138,6 @@ interface PersistenceAdapterContractOptions {
94
138
  * ```ts
95
139
  * persistenceAdapterContract({
96
140
  * name: 'adapter-prisma @ postgres',
97
- * projectKey: 'my-app',
98
141
  * create: () => createPrismaHarness(),
99
142
  * });
100
143
  * ```
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { PersistenceCapabilities, TransactionRunner, SubscriptionRepository, PlanVersionRepository, PromoCodeRepository, PromoCodeRedemptionRepository, MfaPort, AuditPort, AuditQueryPort, SubscriptionContractRepository, TenantSubscriptionWritePort, BundleRepository, PlanRepository, PromoSubscriptionLookup } from '@saasicat/types';
1
+ import { PersistenceCapabilities, TransactionRunner, SubscriptionRepository, PlanVersionRepository, PromoCodeRepository, PromoCodeRedemptionRepository, MfaPort, AuditPort, AuditQueryPort, SubscriptionContractRepository, TenantSubscriptionWritePort, BundleRepository, SubscriptionBundleRepository, PlanRepository, PromoSubscriptionLookup, AppliedSettingsPort } from '@saasicat/core';
2
2
 
3
3
  /**
4
4
  * Port instances under test. Required members define the minimum an adapter
@@ -25,6 +25,14 @@ interface ContractAdapterInstances {
25
25
  tenantSubscriptionWrite?: TenantSubscriptionWritePort;
26
26
  /** Enables BundleVersion validity-window and auto-succession scenarios. */
27
27
  bundleRepository?: BundleRepository;
28
+ /**
29
+ * Enables the booking scenarios — the junction a tenant's bundles hang off.
30
+ *
31
+ * Separate from `bundleRepository`, which is the catalog: one answers what
32
+ * may be sold, the other what a tenant actually bought and for which
33
+ * period. `adapter-drizzle` has neither yet.
34
+ */
35
+ subscriptionBundleRepository?: SubscriptionBundleRepository;
28
36
  /** Enables PlanVersion lifecycle, identity and validity-window scenarios. */
29
37
  planRepository?: PlanRepository;
30
38
  /**
@@ -37,6 +45,16 @@ interface ContractAdapterInstances {
37
45
  * tenant, which is what makes selecting the wrong row possible at all.
38
46
  */
39
47
  promoSubscriptionLookup?: PromoSubscriptionLookup;
48
+ /**
49
+ * Enables the applied-settings scenarios: the one row an installation keeps
50
+ * about the configuration it runs on, and the changes noticed between
51
+ * starts. The singleton and the guard are the parts worth a contract — two
52
+ * adapters that upsert differently would leave one of them with two rows
53
+ * and a reader picking one at random, and one whose write ignores the
54
+ * fingerprint it was given lets every replica of a deployment record the
55
+ * same change.
56
+ */
57
+ appliedSettings?: AppliedSettingsPort;
40
58
  }
41
59
  /** Fixture writers — implemented per adapter against its own schema. */
42
60
  interface ContractSeed {
@@ -63,6 +81,34 @@ interface ContractSeed {
63
81
  }): Promise<{
64
82
  subscriptionId: string;
65
83
  }>;
84
+ /**
85
+ * A published BundleVersion to book against.
86
+ *
87
+ * A fixture writer rather than a call into `bundleRepository`: the catalog
88
+ * repository is a subject of the suite, not a tool for setting up someone
89
+ * else's scenario, and a booking scenario that failed because the catalog
90
+ * did would say the wrong thing.
91
+ *
92
+ * Optional because an adapter may not carry the catalog tables at all —
93
+ * `adapter-drizzle` does not. A required writer nobody can implement is a
94
+ * contract that lies about what conformance means; the booking scenarios
95
+ * gate on this and report the gap as a skip instead.
96
+ */
97
+ createBundleVersion?(input: {
98
+ bundleKey: string;
99
+ features: string[];
100
+ }): Promise<{
101
+ bundleVersionId: string;
102
+ }>;
103
+ /**
104
+ * Clears a booking's `canceledAt` while leaving `canceledEffectiveAt`.
105
+ *
106
+ * A shape no repository method produces, and one the nullable columns
107
+ * nonetheless permit — so the adapters have to agree on how to read it.
108
+ * Optional: a harness that cannot reach its store directly says so and the
109
+ * scenario skips, rather than the scenario inventing a way in.
110
+ */
111
+ clearBookingRequestDate?(subscriptionBundleId: string): Promise<void>;
66
112
  createPromoCode(input: {
67
113
  code: string;
68
114
  maxRedemptions: number | null;
@@ -82,8 +128,6 @@ interface PersistenceContractHarness {
82
128
  interface PersistenceAdapterContractOptions {
83
129
  /** Display name in the test output, e.g. `'adapter-prisma @ postgres16'`. */
84
130
  name: string;
85
- /** Project identity used by catalog lifecycle scenarios. */
86
- projectKey: string;
87
131
  /** Builds the harness once for the whole suite. */
88
132
  create(): Promise<PersistenceContractHarness>;
89
133
  }
@@ -94,7 +138,6 @@ interface PersistenceAdapterContractOptions {
94
138
  * ```ts
95
139
  * persistenceAdapterContract({
96
140
  * name: 'adapter-prisma @ postgres',
97
- * projectKey: 'my-app',
98
141
  * create: () => createPrismaHarness(),
99
142
  * });
100
143
  * ```