platform-types 1.10.704 → 1.10.706
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/cjs/subscription.js +3 -2
- package/dist/subscription.d.ts +144 -12
- package/dist/subscription.js +3 -2
- package/package.json +1 -1
package/dist/cjs/subscription.js
CHANGED
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
* (see `PlanCatalogue.trial`). A trial with no payment method drops to
|
|
14
14
|
* `basico` (`active`, free-tier limits, no lock-out) on the first nightly
|
|
15
15
|
* sweep after that date, unless a courtesy gift covers today. A Stripe
|
|
16
|
-
* checkout
|
|
17
|
-
*
|
|
16
|
+
* checkout grants no trial of its own: it carries over what is left of the
|
|
17
|
+
* row's `trialEndsAt` (as `subscription_data.trial_end`) when that is at
|
|
18
|
+
* least 48 h + 5 min away, and bills from checkout otherwise. Courtesy
|
|
18
19
|
* gifts (formerly the Founders cohort) are now a one-off ops action via
|
|
19
20
|
* `gift-subscription` that sets `freeUntil` on the SUBSCRIPTION row.
|
|
20
21
|
* - `freeUntil` lives on every Subscription independent of status. It is the
|
package/dist/subscription.d.ts
CHANGED
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
* (see `PlanCatalogue.trial`). A trial with no payment method drops to
|
|
13
13
|
* `basico` (`active`, free-tier limits, no lock-out) on the first nightly
|
|
14
14
|
* sweep after that date, unless a courtesy gift covers today. A Stripe
|
|
15
|
-
* checkout
|
|
16
|
-
*
|
|
15
|
+
* checkout grants no trial of its own: it carries over what is left of the
|
|
16
|
+
* row's `trialEndsAt` (as `subscription_data.trial_end`) when that is at
|
|
17
|
+
* least 48 h + 5 min away, and bills from checkout otherwise. Courtesy
|
|
17
18
|
* gifts (formerly the Founders cohort) are now a one-off ops action via
|
|
18
19
|
* `gift-subscription` that sets `freeUntil` on the SUBSCRIPTION row.
|
|
19
20
|
* - `freeUntil` lives on every Subscription independent of status. It is the
|
|
@@ -38,7 +39,9 @@ declare global {
|
|
|
38
39
|
* `trialTier` platform global with `trialEndsAt` set `trialDays` days out
|
|
39
40
|
* (`PlanCatalogue.trial`) — once that date passes with no payment method the
|
|
40
41
|
* nightly sweep drops the row to `basico`/`active` (unless a courtesy gift
|
|
41
|
-
* covers today)
|
|
42
|
+
* covers today). A Stripe checkout carries over the remaining
|
|
43
|
+
* `trialEndsAt` when it is at least 48 h + 5 min away, else no trial —
|
|
44
|
+
* never a fresh fixed period.
|
|
42
45
|
* - `active` — paid subscription, period current.
|
|
43
46
|
* - `past_due` — payment failed, in the 7-day grace window.
|
|
44
47
|
* - `readonly` — grace elapsed, writes blocked, tenant can still read.
|
|
@@ -223,17 +226,22 @@ declare global {
|
|
|
223
226
|
/**
|
|
224
227
|
* How a billing cycle of a plan can be bought:
|
|
225
228
|
*
|
|
226
|
-
* - `self` — self-serve checkout: the cycle has a charged price
|
|
227
|
-
* plan has a `currency
|
|
229
|
+
* - `self` — self-serve checkout: the cycle has a charged price, the
|
|
230
|
+
* plan has a `currency`, and the plan is active.
|
|
228
231
|
* - `sales` — the plan charges some cycle, but not this one self-serve
|
|
229
|
-
* (no price on it,
|
|
232
|
+
* (no price on it, no `currency`, or `isActive: false`); route
|
|
233
|
+
* to "Contactar ventas". On `GET /subscription/plans` the
|
|
234
|
+
* caller's OWN hidden tier reads `self` instead, as checkout
|
|
235
|
+
* lets that store renew it.
|
|
230
236
|
* - `none` — neither cycle is charged (the free tier); nothing to buy.
|
|
231
237
|
*/
|
|
232
238
|
type PlanCheckoutMode = 'self' | 'sales' | 'none';
|
|
233
239
|
/**
|
|
234
240
|
* A sellable plan in the catalog, exactly as `GET /subscription/plans` and
|
|
235
241
|
* `GET /public/plans` emit it — both build it with the same catalogue
|
|
236
|
-
* builder, so the two endpoints return identical plans
|
|
242
|
+
* builder, so the two endpoints return identical plans — except the
|
|
243
|
+
* caller's own hidden tier's `checkout` on `GET /subscription/plans` (see
|
|
244
|
+
* {@link PlanCheckoutMode}). The template fields
|
|
237
245
|
* (copy, prices, flags) live in DynamoDB (`PLAN#{tier}` / `SK: PLAN`),
|
|
238
246
|
* administered via `POST /platform/billing/plans` +
|
|
239
247
|
* `PATCH /platform/billing/plans/{tier}`; `features` are code, rendered at
|
|
@@ -271,7 +279,9 @@ declare global {
|
|
|
271
279
|
/**
|
|
272
280
|
* Whether the plan is shown on the pricing page and accepting new
|
|
273
281
|
* subscribers. Pre-launch / sales-led tiers set this `false` without
|
|
274
|
-
* deleting the row.
|
|
282
|
+
* deleting the row. `POST /subscription/checkout` refuses a `false`
|
|
283
|
+
* tier with 400 `PLAN_NOT_PURCHASABLE` unless the store's subscription
|
|
284
|
+
* is already on it — existing subscribers on it may renew.
|
|
275
285
|
*/
|
|
276
286
|
isActive: boolean;
|
|
277
287
|
/**
|
|
@@ -716,9 +726,10 @@ declare global {
|
|
|
716
726
|
}
|
|
717
727
|
/**
|
|
718
728
|
* One tier's `SK: PLAN` template row, as assessed by
|
|
719
|
-
* `report-plan-catalog-drift` (`POST /platform/operations`). Plan
|
|
720
|
-
* are code (`planFeatureMatrix.ts`) and cannot drift; the template
|
|
721
|
-
*
|
|
729
|
+
* `report-plan-catalog-drift` (`POST /platform/operations`). Plan feature
|
|
730
|
+
* DEFAULTS are code (`planFeatureMatrix.ts`) and cannot drift; the template
|
|
731
|
+
* row — its live `grants` overlay included — is the only catalogue state a
|
|
732
|
+
* seeder/admin write can still leave stale.
|
|
722
733
|
*/
|
|
723
734
|
interface TierCatalogDrift {
|
|
724
735
|
tier: PlanTier;
|
|
@@ -732,6 +743,19 @@ declare global {
|
|
|
732
743
|
* place to echo a catalogue's payment-provider IDs.
|
|
733
744
|
*/
|
|
734
745
|
missingProviderIds: string[];
|
|
746
|
+
/**
|
|
747
|
+
* Keys in the template row's `grants` overlay that the api does not
|
|
748
|
+
* declare (retired or misspelt), sorted. Inert — every reader ignores them
|
|
749
|
+
* and the code default applies — but stored, so they are drift: a `null`
|
|
750
|
+
* for that key on `PATCH /platform/billing/plans/grants` removes them.
|
|
751
|
+
*/
|
|
752
|
+
undeclaredGrantKeys: string[];
|
|
753
|
+
/**
|
|
754
|
+
* Declared keys whose overlay value has the wrong shape for their type
|
|
755
|
+
* (a `limit` on a boolean key, a fraction, `-2`), sorted. Ignored on read
|
|
756
|
+
* exactly like an undeclared key, and reported for the same reason.
|
|
757
|
+
*/
|
|
758
|
+
malformedGrantKeys: string[];
|
|
735
759
|
}
|
|
736
760
|
/** One store holding at least one `OVERRIDE#` row under a key the api no longer declares. */
|
|
737
761
|
interface OrphanOverrideStore {
|
|
@@ -778,7 +802,9 @@ declare global {
|
|
|
778
802
|
interface PlanCatalogDriftReport {
|
|
779
803
|
/**
|
|
780
804
|
* True when ANY tier lacks a template row, a paid one is missing a provider
|
|
781
|
-
* identifier,
|
|
805
|
+
* identifier, a tier's `grants` overlay holds an undeclared key
|
|
806
|
+
* (`undeclaredGrantKeys`) or a wrong-shape value (`malformedGrantKeys`), or
|
|
807
|
+
* any store holds an override under an undeclared key.
|
|
782
808
|
*
|
|
783
809
|
* ⚠️ An UNBUILT roster (`orphanOverrides.rosterBuiltAt === null`) does not
|
|
784
810
|
* flip this. A stage whose scan has never completed would otherwise answer
|
|
@@ -794,6 +820,112 @@ declare global {
|
|
|
794
820
|
tiers: TierCatalogDrift[];
|
|
795
821
|
orphanOverrides: OrphanOverrideDrift;
|
|
796
822
|
}
|
|
823
|
+
/**
|
|
824
|
+
* One feature's grant on one tier, as `PATCH /platform/billing/plans/grants`
|
|
825
|
+
* takes and reports it: `{ enabled }` for a boolean key, `{ limit }` for a
|
|
826
|
+
* numeric or metered one (`-1` = unlimited).
|
|
827
|
+
*/
|
|
828
|
+
type PlanGrantValue = {
|
|
829
|
+
enabled: boolean;
|
|
830
|
+
} | {
|
|
831
|
+
limit: number;
|
|
832
|
+
};
|
|
833
|
+
/**
|
|
834
|
+
* Body of `PATCH /platform/billing/plans/grants` (MANAGER). One request sets
|
|
835
|
+
* one or more keys on any tiers, atomically: `grants[key][tier]` is the new
|
|
836
|
+
* grant, or `null` to drop that tier's overlay entry (the code default
|
|
837
|
+
* applies again). A value equal to the code default is stored as no entry,
|
|
838
|
+
* so the overlay stays sparse. The final ladder of every changed key must
|
|
839
|
+
* rise with `displayOrder` (`FEATURE_LADDER_NON_MONOTONIC` otherwise).
|
|
840
|
+
*/
|
|
841
|
+
interface PlanGrantsWriteRequest {
|
|
842
|
+
/**
|
|
843
|
+
* Keyed by feature key. A `string` key rather than `FeatureKey` because a
|
|
844
|
+
* `null` may name an undeclared key, to clear an inert overlay entry; a
|
|
845
|
+
* non-null value for one is refused (`PLAN_GRANT_UNKNOWN_KEY`).
|
|
846
|
+
*/
|
|
847
|
+
grants: Record<string, Partial<Record<PlanTier, PlanGrantValue | null>>>;
|
|
848
|
+
/** Screened operator reason (10-500 characters, no personal data); lands in each tier's audit entry. */
|
|
849
|
+
reason: string;
|
|
850
|
+
/**
|
|
851
|
+
* Required on a live write: the comma-joined sorted keys the request
|
|
852
|
+
* changes — the string a dry run of the same body returns. It names the
|
|
853
|
+
* keys, not the tiers or values, so it proves the caller meant those keys;
|
|
854
|
+
* the dry run is where the tiers and the impact are reviewed.
|
|
855
|
+
*/
|
|
856
|
+
confirm?: string;
|
|
857
|
+
/** `true` writes nothing and returns the impact plus the `confirm` string. */
|
|
858
|
+
dryRun?: boolean;
|
|
859
|
+
}
|
|
860
|
+
/** One key's effective grant on one tier, before and after the write. */
|
|
861
|
+
interface PlanGrantChange {
|
|
862
|
+
key: string;
|
|
863
|
+
/** `null` for an undeclared key — it has no effective grant on either side. */
|
|
864
|
+
before: PlanGrantValue | null;
|
|
865
|
+
after: PlanGrantValue | null;
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Stores on a tier that a reduction would bite, for one key: they lose a
|
|
869
|
+
* boolean feature, or their current usage exceeds a lowered limit. Measured
|
|
870
|
+
* per store with its own overrides applied, so a store whose override keeps
|
|
871
|
+
* the old grant is not listed. A `readonly` / `canceled` store is never
|
|
872
|
+
* examined — its plan already lapsed, so the reduction takes nothing more.
|
|
873
|
+
*/
|
|
874
|
+
interface PlanGrantImpact {
|
|
875
|
+
key: string;
|
|
876
|
+
storeIds: string[];
|
|
877
|
+
/**
|
|
878
|
+
* `false` for a lowered limit with no usage counter to compare against
|
|
879
|
+
* (`priceListsMax`): `storeIds` is then
|
|
880
|
+
* empty because nothing was measured, never because nothing is over.
|
|
881
|
+
*/
|
|
882
|
+
measured: boolean;
|
|
883
|
+
}
|
|
884
|
+
/** One affected tier in a `PATCH /platform/billing/plans/grants` result. */
|
|
885
|
+
interface PlanGrantsTierResult {
|
|
886
|
+
tier: PlanTier;
|
|
887
|
+
changes: PlanGrantChange[];
|
|
888
|
+
/**
|
|
889
|
+
* Stores on this tier, any status: those whose SUBSCRIPTION row is on it
|
|
890
|
+
* (`planTier-status`) plus, on `profesional` — the tier a store with no
|
|
891
|
+
* SUBSCRIPTION row resolves to — every store with no row. A lower bound
|
|
892
|
+
* when `truncated`.
|
|
893
|
+
*/
|
|
894
|
+
subscribedStores: number;
|
|
895
|
+
/** Dry run only: per reduced key, the stores it bites. Empty when nothing on this tier is reduced. */
|
|
896
|
+
impact?: PlanGrantImpact[];
|
|
897
|
+
/**
|
|
898
|
+
* Dry run: `impact` is a lower bound — more live stores than the walk
|
|
899
|
+
* examines (100), the request's time budget ran out, one store could not
|
|
900
|
+
* be read, or the tier's store list itself is short. Live write (present
|
|
901
|
+
* only when `true`): the follow-up did not reach every store — the budget
|
|
902
|
+
* ran out, a frame or grace reconcile failed, or the store list is short;
|
|
903
|
+
* a `PLAN_GRANTS_FANOUT_INCOMPLETE` error row carries the counts. On a
|
|
904
|
+
* `storefront` / `customDomain` change, every listed store it did not
|
|
905
|
+
* settle has a due-now grace entry the hourly storefront grace sweep
|
|
906
|
+
* reconciles (unless the row says some were not scheduled).
|
|
907
|
+
*/
|
|
908
|
+
truncated?: boolean;
|
|
909
|
+
/** Live write only: how many stores the `subscription` socket frame was sent to. */
|
|
910
|
+
notifiedStores?: number;
|
|
911
|
+
/**
|
|
912
|
+
* Live write only, and only when the tier's `storefront` or `customDomain`
|
|
913
|
+
* changed: how many stores' shop grace a reconcile settled — written
|
|
914
|
+
* (a lost grant starts the 14-day grace; a regained one clears it) or
|
|
915
|
+
* already in line. A failed reconcile, a store gone, or a store the budget
|
|
916
|
+
* did not reach is not counted.
|
|
917
|
+
*/
|
|
918
|
+
reconciledStores?: number;
|
|
919
|
+
}
|
|
920
|
+
/** `data` of `PATCH /platform/billing/plans/grants`. */
|
|
921
|
+
interface PlanGrantsWriteResult {
|
|
922
|
+
dryRun: boolean;
|
|
923
|
+
/** `false` on a dry run and on an identical replay (no change, no write, no audit). */
|
|
924
|
+
written: boolean;
|
|
925
|
+
/** The comma-joined sorted changed keys — what a live run must send as `confirm`. Empty when nothing changes. */
|
|
926
|
+
confirm: string;
|
|
927
|
+
tiers: PlanGrantsTierResult[];
|
|
928
|
+
}
|
|
797
929
|
}
|
|
798
930
|
export type BillingProviderName = SubscriptionProvider;
|
|
799
931
|
export type InvoiceSummary = globalThis.InvoiceSummary;
|
package/dist/subscription.js
CHANGED
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
* (see `PlanCatalogue.trial`). A trial with no payment method drops to
|
|
13
13
|
* `basico` (`active`, free-tier limits, no lock-out) on the first nightly
|
|
14
14
|
* sweep after that date, unless a courtesy gift covers today. A Stripe
|
|
15
|
-
* checkout
|
|
16
|
-
*
|
|
15
|
+
* checkout grants no trial of its own: it carries over what is left of the
|
|
16
|
+
* row's `trialEndsAt` (as `subscription_data.trial_end`) when that is at
|
|
17
|
+
* least 48 h + 5 min away, and bills from checkout otherwise. Courtesy
|
|
17
18
|
* gifts (formerly the Founders cohort) are now a one-off ops action via
|
|
18
19
|
* `gift-subscription` that sets `freeUntil` on the SUBSCRIPTION row.
|
|
19
20
|
* - `freeUntil` lives on every Subscription independent of status. It is the
|