@saasicat/core 1.0.0-rc.23 → 1.0.0-rc.25
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/README.md +1 -1
- package/dist/.build-stamp +1 -1
- package/dist/index.cjs +1589 -367
- package/dist/index.d.cts +2866 -254
- package/dist/index.d.ts +2866 -254
- package/dist/index.js +1522 -366
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -24,11 +24,17 @@ interface DateAtOrAfter {
|
|
|
24
24
|
interface DateAfter {
|
|
25
25
|
gt: Date;
|
|
26
26
|
}
|
|
27
|
-
/** `OR` block of the validity window; exactly one
|
|
27
|
+
/** `OR` block of the validity window; exactly one field per variant. */
|
|
28
28
|
type ValidityWindowClause = {
|
|
29
29
|
validFrom: DateAtOrBefore | null;
|
|
30
30
|
} | {
|
|
31
31
|
validUntil: DateAtOrAfter | null;
|
|
32
|
+
} | {
|
|
33
|
+
supersededAt: null;
|
|
34
|
+
} | {
|
|
35
|
+
validUntil: {
|
|
36
|
+
not: null;
|
|
37
|
+
};
|
|
32
38
|
};
|
|
33
39
|
/** Optional `OR` block for models with `endsAt` (precise admin termination). */
|
|
34
40
|
type EndsAtClause = {
|
|
@@ -60,6 +66,7 @@ interface ActivePlanVersionWhereWithEndsAt {
|
|
|
60
66
|
* `publishedAt IS NOT NULL`
|
|
61
67
|
* `(validFrom IS NULL OR validFrom <= asOf)`
|
|
62
68
|
* `(validUntil IS NULL OR validUntil >= startOfUtcDay(asOf))` // day-inclusive
|
|
69
|
+
* `(supersededAt IS NULL OR validUntil IS NOT NULL)` // superseded: only with a last day
|
|
63
70
|
* with `withEndsAt`: additionally `(endsAt IS NULL OR endsAt > asOf)`. // precise
|
|
64
71
|
*
|
|
65
72
|
* `planId` stays with the caller (repo-specific type). Matching Prisma
|
|
@@ -79,6 +86,22 @@ declare function buildActivePlanVersionWhere(asOf: Date, options: {
|
|
|
79
86
|
type ActiveVersionWhere = ActivePlanVersionWhere;
|
|
80
87
|
/** Model-neutral counterpart that additionally checks an `endsAt` timestamp. */
|
|
81
88
|
type ActiveVersionWhereWithEndsAt = ActivePlanVersionWhereWithEndsAt;
|
|
89
|
+
/** The dates of a version that decide whether it takes bookings, as a row carries them. */
|
|
90
|
+
interface VersionWindow {
|
|
91
|
+
validFrom?: string | Date | null;
|
|
92
|
+
validUntil?: string | Date | null;
|
|
93
|
+
endsAt?: string | Date | null;
|
|
94
|
+
supersededAt?: string | Date | null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Whether a version that is published takes bookings at `asOf` — the same
|
|
98
|
+
* window {@link buildActivePlanVersionWhere} asks the database for, for a row
|
|
99
|
+
* already read: `validFrom` at or before `asOf`, `validUntil` not before the
|
|
100
|
+
* day of `asOf`, `endsAt` after `asOf`, and a superseded version only within
|
|
101
|
+
* a last day it carries. A date that is absent does not close the window.
|
|
102
|
+
* Whether the row is published is the caller's to know.
|
|
103
|
+
*/
|
|
104
|
+
declare function isVersionActiveAt(version: VersionWindow, asOf: Date): boolean;
|
|
82
105
|
/**
|
|
83
106
|
* Model-neutral alias for {@link buildActivePlanVersionWhere}. The original
|
|
84
107
|
* export remains available for backwards compatibility.
|
|
@@ -770,9 +793,18 @@ interface SelfServiceBlockedPlans {
|
|
|
770
793
|
* passed it in code" attached. The file is read at boot, so an edit lands on
|
|
771
794
|
* the next restart.
|
|
772
795
|
*/
|
|
796
|
+
/**
|
|
797
|
+
* Whether the operator may retire a plan version for the subscriptions already
|
|
798
|
+
* on it. It reaches contracts customers have made, so it rests on a clause in
|
|
799
|
+
* the operator's terms; `termsConfirmed` states that they carry it.
|
|
800
|
+
*/
|
|
801
|
+
interface OrderlyRetirementSettings {
|
|
802
|
+
termsConfirmed: boolean;
|
|
803
|
+
}
|
|
773
804
|
interface PlanCatalogTenantBilling {
|
|
774
805
|
cancellationNoticeDays: CancellationNoticePeriods;
|
|
775
806
|
selfServiceBlockedPlans: SelfServiceBlockedPlans;
|
|
807
|
+
orderlyRetirement: OrderlyRetirementSettings;
|
|
776
808
|
}
|
|
777
809
|
/**
|
|
778
810
|
* Who is told when the settings in the file change between two starts.
|
|
@@ -846,6 +878,13 @@ interface PlanCatalogPayments {
|
|
|
846
878
|
/** Every account taking new payment methods or holding a reference in use. */
|
|
847
879
|
accounts: Record<string, PlanCatalogPaymentAccount>;
|
|
848
880
|
}
|
|
881
|
+
/** `config/saas.yaml#tax`: the adapter an installation names, and what the operator declares to it. */
|
|
882
|
+
interface PlanCatalogTax {
|
|
883
|
+
/** The adapter's package name, such as `@saasicat/tax-de`. */
|
|
884
|
+
adapter: string;
|
|
885
|
+
/** The options the adapter's factory builds it with; the factory checks them. */
|
|
886
|
+
options?: Record<string, unknown>;
|
|
887
|
+
}
|
|
849
888
|
/**
|
|
850
889
|
* The part of `config/saas.yaml` that is configuration rather than catalogue.
|
|
851
890
|
*
|
|
@@ -858,8 +897,15 @@ interface PlanCatalogSettings {
|
|
|
858
897
|
app: PlanCatalogApp;
|
|
859
898
|
/** ISO-4217 currency code. */
|
|
860
899
|
currency: string;
|
|
861
|
-
/**
|
|
862
|
-
|
|
900
|
+
/**
|
|
901
|
+
* VAT rate in percent. Every installation names it unless `tax` names a
|
|
902
|
+
* tax adapter, which is then the one source of every rate.
|
|
903
|
+
*/
|
|
904
|
+
vatRate?: number;
|
|
905
|
+
/** The tax adapter that decides each charge's treatment, and its options. */
|
|
906
|
+
tax?: PlanCatalogTax;
|
|
907
|
+
/** The installation's time zone, an IANA name; required with `tax` (`SC-PRIC-045`). */
|
|
908
|
+
timeZone?: string;
|
|
863
909
|
/** Commercial settings for the tenant self-service routes. */
|
|
864
910
|
tenantBilling: PlanCatalogTenantBilling;
|
|
865
911
|
/** App-wide marketing configuration. Optional. */
|
|
@@ -975,6 +1021,574 @@ interface PromoCodeValidationLog {
|
|
|
975
1021
|
createdAt: string;
|
|
976
1022
|
}
|
|
977
1023
|
|
|
1024
|
+
/**
|
|
1025
|
+
* A tenant's own limits beside its plan — a negotiated contract, a pilot.
|
|
1026
|
+
* `quotas[key]` replaces the plan's value for that quota, `-1` meaning
|
|
1027
|
+
* unlimited; `features` adds to the plan's. Stored as JSON in
|
|
1028
|
+
* `subscriptions.customLimits`.
|
|
1029
|
+
*/
|
|
1030
|
+
interface CustomLimits {
|
|
1031
|
+
quotas?: Record<QuotaKey, number>;
|
|
1032
|
+
features?: FeatureKey[];
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* The keys a stored `customLimits` value is read by. The normative admin API
|
|
1036
|
+
* schema (`CustomLimits` in `@saasicat/spec`) is held to the same list.
|
|
1037
|
+
*/
|
|
1038
|
+
declare const CUSTOM_LIMITS_KEYS: readonly ["quotas", "features"];
|
|
1039
|
+
/** What a stored `customLimits` value gave, and what in it went unread. */
|
|
1040
|
+
interface ReadCustomLimits {
|
|
1041
|
+
limits: CustomLimits | null;
|
|
1042
|
+
/**
|
|
1043
|
+
* The parts of the stored value the platform does not read — a key it does
|
|
1044
|
+
* not know, or a `quotas`/`features` of the wrong kind. Empty when every
|
|
1045
|
+
* part was read.
|
|
1046
|
+
*/
|
|
1047
|
+
unread: string[];
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Reads a stored `customLimits` value the way the platform applies it.
|
|
1051
|
+
*
|
|
1052
|
+
* A shape the platform does not read is reported rather than refused: the
|
|
1053
|
+
* tenant keeps its plan's limits and goes on working, as a limit nothing can
|
|
1054
|
+
* count does not block anybody (`SC-ENTL-010`), and the caller says out loud
|
|
1055
|
+
* which limits were not applied. Each quota value goes through
|
|
1056
|
+
* `readQuotaValue`, the one reading of a quota in JSON.
|
|
1057
|
+
*/
|
|
1058
|
+
declare function readCustomLimits(value: unknown): ReadCustomLimits;
|
|
1059
|
+
/**
|
|
1060
|
+
* Reads stored limits for an adapter, and reports what went unread once per
|
|
1061
|
+
* subscription — every entitlement read passes through here, so reporting on
|
|
1062
|
+
* each would bury the one line an operator needs under thousands.
|
|
1063
|
+
*/
|
|
1064
|
+
declare function customLimitsReader(report: (line: string) => void): (subscriptionId: string, stored: unknown) => CustomLimits | null;
|
|
1065
|
+
|
|
1066
|
+
/** Alias for historical compatibility — equivalent to VersionChangeDirection. */
|
|
1067
|
+
type ChangeDirection = VersionChangeDirection;
|
|
1068
|
+
interface DiffResult {
|
|
1069
|
+
nonRegressive: boolean;
|
|
1070
|
+
changes: VersionChange[];
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* `Decimal | string | number` — the three forms in which prices appear
|
|
1074
|
+
* in the platform. `Decimal` is the Prisma class (with
|
|
1075
|
+
* `.toNumber()`), which is not imported directly in order to keep the
|
|
1076
|
+
* platform Prisma-free — a structural view suffices.
|
|
1077
|
+
*/
|
|
1078
|
+
type DecimalLike = number | string | {
|
|
1079
|
+
toNumber(): number;
|
|
1080
|
+
};
|
|
1081
|
+
interface PlanVersionFields {
|
|
1082
|
+
features: FeatureKey[];
|
|
1083
|
+
/**
|
|
1084
|
+
* Quotas of the version. -1 = unlimited; missing key = 0.
|
|
1085
|
+
*
|
|
1086
|
+
* Every key either side carries is compared. Which keys exist is the
|
|
1087
|
+
* installation's decision — they come from `@DefinesQuota` — so a fixed
|
|
1088
|
+
* set here would have compared the three the platform happened to know by
|
|
1089
|
+
* name and let every other one be lowered without the confirmation
|
|
1090
|
+
* publishing a regression asks for.
|
|
1091
|
+
*/
|
|
1092
|
+
quotas: Record<QuotaKey, number>;
|
|
1093
|
+
monthlyNet: DecimalLike;
|
|
1094
|
+
yearlyNet: DecimalLike;
|
|
1095
|
+
}
|
|
1096
|
+
interface BundleVersionFields {
|
|
1097
|
+
features: FeatureKey[];
|
|
1098
|
+
/** Quota contributions of the bundle. -1 = unlimited; missing key = 0. */
|
|
1099
|
+
quotas: Record<QuotaKey, number>;
|
|
1100
|
+
/** Default pricing; null = only override pricing possible. */
|
|
1101
|
+
monthlyNet: DecimalLike | null;
|
|
1102
|
+
yearlyNet: DecimalLike | null;
|
|
1103
|
+
}
|
|
1104
|
+
declare function classifyPlanDiff(oldV: PlanVersionFields, newV: PlanVersionFields): DiffResult;
|
|
1105
|
+
/**
|
|
1106
|
+
* Classification of a BundleVersion diff for contract protection.
|
|
1107
|
+
*
|
|
1108
|
+
* Quotas are compared exactly as they are for a plan.
|
|
1109
|
+
*
|
|
1110
|
+
* Pricing can be `null` (the bundle only has override pricing); a switch
|
|
1111
|
+
* from value ↔ null is classified as REGRESSION (value dropped) or IMPROVEMENT
|
|
1112
|
+
* (value added, lowerIsBetter inverted). Both null
|
|
1113
|
+
* stay NEUTRAL.
|
|
1114
|
+
*/
|
|
1115
|
+
declare function classifyBundleVersionDiff(oldV: BundleVersionFields, newV: BundleVersionFields): DiffResult;
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* - `improvement` — nothing dearer in any rhythm, no feature missing, no quota
|
|
1119
|
+
* lower. Taken at once and free, the term kept.
|
|
1120
|
+
* - `more-for-more` — nothing missing or lower, but dearer in at least one
|
|
1121
|
+
* rhythm. Taken like an upgrade: at once, the difference prorated. The rule
|
|
1122
|
+
* reads every rhythm, so in the subscriber's own the difference can be zero
|
|
1123
|
+
* or below — monthly 49 to 45 with yearly 490 to 500 is more for more for a
|
|
1124
|
+
* monthly subscriber too.
|
|
1125
|
+
* - `takes-something-away` — a feature missing or a quota lower, whatever the
|
|
1126
|
+
* price. Taken like a downgrade: at the end of the running term, and only
|
|
1127
|
+
* when the subscriber asks for it.
|
|
1128
|
+
* - `same` — the two agree on everything compared: there is nothing to offer.
|
|
1129
|
+
*/
|
|
1130
|
+
type VersionOfferClass = 'improvement' | 'more-for-more' | 'takes-something-away' | 'same';
|
|
1131
|
+
/**
|
|
1132
|
+
* A version as the comparison reads it. A price may be absent: that is a
|
|
1133
|
+
* rhythm the version is not sold in, and a rhythm that stops being sold counts
|
|
1134
|
+
* against the candidate like a price that went up.
|
|
1135
|
+
*/
|
|
1136
|
+
type VersionOfferFields = BundleVersionFields;
|
|
1137
|
+
interface VersionOffer {
|
|
1138
|
+
readonly class: VersionOfferClass;
|
|
1139
|
+
/** Every difference, bound to candidate, as the catalogue's diff states it. */
|
|
1140
|
+
readonly changes: readonly VersionChange[];
|
|
1141
|
+
}
|
|
1142
|
+
/** One version as a subscriber compares it. A price of null is a rhythm it is not sold in. */
|
|
1143
|
+
interface VersionOfferSide {
|
|
1144
|
+
readonly planVersionId: string;
|
|
1145
|
+
readonly version: number;
|
|
1146
|
+
readonly features: readonly string[];
|
|
1147
|
+
readonly quotas: Readonly<Record<string, number>>;
|
|
1148
|
+
readonly monthlyNet: number | null;
|
|
1149
|
+
readonly yearlyNet: number | null;
|
|
1150
|
+
/** The last day it is sold on, where a successor closes its window — ISO, the whole day included. */
|
|
1151
|
+
readonly validUntil: string | null;
|
|
1152
|
+
/** When an operator ended it, where one did — ISO; from then it is not sold. */
|
|
1153
|
+
readonly endsAt: string | null;
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* A newer version of the subscriber's plan, offered: the version bound and the
|
|
1157
|
+
* one offered side by side, what kind of offer it is, and when a switch taken
|
|
1158
|
+
* now would take effect — at once, or, for one that takes something away, at
|
|
1159
|
+
* the end of the running term. `GET billing/version-offer` answers with it.
|
|
1160
|
+
*/
|
|
1161
|
+
interface VersionOfferView {
|
|
1162
|
+
readonly plan: string;
|
|
1163
|
+
readonly bound: VersionOfferSide;
|
|
1164
|
+
readonly offered: VersionOfferSide;
|
|
1165
|
+
readonly class: Exclude<VersionOfferClass, 'same'>;
|
|
1166
|
+
readonly changes: readonly VersionChange[];
|
|
1167
|
+
/** ISO instant. */
|
|
1168
|
+
readonly takesEffectAt: string;
|
|
1169
|
+
}
|
|
1170
|
+
/**
|
|
1171
|
+
* What taking an offer did: the version left and the one taken, and whether it
|
|
1172
|
+
* applied at once or waits for `takesEffectAt`. `POST billing/version-offer/accept`
|
|
1173
|
+
* answers with it.
|
|
1174
|
+
*/
|
|
1175
|
+
interface VersionSwitchResult {
|
|
1176
|
+
readonly class: Exclude<VersionOfferClass, 'same'>;
|
|
1177
|
+
readonly fromPlanVersionId: string;
|
|
1178
|
+
readonly planVersionId: string;
|
|
1179
|
+
readonly immediate: boolean;
|
|
1180
|
+
/** ISO instant. */
|
|
1181
|
+
readonly takesEffectAt: string;
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Classifies `candidate` against `bound`. The comparison is the catalogue's
|
|
1185
|
+
* own diff — prices with a rhythm that may be absent, as a bundle version's
|
|
1186
|
+
* are — so an offer and a published version describe their changes alike.
|
|
1187
|
+
*/
|
|
1188
|
+
declare function classifyVersionOffer(bound: VersionOfferFields, candidate: VersionOfferFields): VersionOffer;
|
|
1189
|
+
|
|
1190
|
+
/** A version, as an announcement names it. */
|
|
1191
|
+
interface RetiredVersionRef {
|
|
1192
|
+
readonly planVersionId: string;
|
|
1193
|
+
readonly planKey: string;
|
|
1194
|
+
readonly version: number;
|
|
1195
|
+
}
|
|
1196
|
+
/** An announcement as it is kept: one per retirement, whoever it reaches. */
|
|
1197
|
+
interface VersionRetirementRecord {
|
|
1198
|
+
readonly id: string;
|
|
1199
|
+
/** The version retired. */
|
|
1200
|
+
readonly retired: RetiredVersionRef;
|
|
1201
|
+
/** The version its subscriptions continue on, named by the operator. */
|
|
1202
|
+
readonly replacement: RetiredVersionRef;
|
|
1203
|
+
readonly announcedAt: Date;
|
|
1204
|
+
/** Who announced it — an actor tag, as the audit log writes it. */
|
|
1205
|
+
readonly announcedBy: string;
|
|
1206
|
+
}
|
|
1207
|
+
type NewVersionRetirement = Omit<VersionRetirementRecord, 'id'>;
|
|
1208
|
+
/**
|
|
1209
|
+
* The manifest capability that announces retiring a version. The platform sets
|
|
1210
|
+
* it where it serves the routes, and the admin UI offers the action only where
|
|
1211
|
+
* it is set. Whether the operator's terms allow it is a blocker the preview
|
|
1212
|
+
* reports, so an operator who has not confirmed them learns what is missing.
|
|
1213
|
+
*/
|
|
1214
|
+
declare const VERSION_RETIREMENT_CAPABILITY = "planVersions.retire";
|
|
1215
|
+
/**
|
|
1216
|
+
* One of the two versions of a retirement, as the subscriber compares them:
|
|
1217
|
+
* price in each rhythm, quotas and features, with the plan it belongs to — the
|
|
1218
|
+
* replacement may be a version of another plan.
|
|
1219
|
+
*/
|
|
1220
|
+
interface RetirementSide extends VersionOfferSide {
|
|
1221
|
+
readonly planKey: string;
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* A plan version a subscription is on is being retired, and the subscription
|
|
1225
|
+
* continues on the named replacement from its effective date. Sent once per
|
|
1226
|
+
* subscription and retirement, when the retirement is announced, and kept as
|
|
1227
|
+
* it was sent: the record shows what the subscriber was told, prices included.
|
|
1228
|
+
*/
|
|
1229
|
+
interface VersionRetiredNotice {
|
|
1230
|
+
readonly kind: 'version-retired';
|
|
1231
|
+
readonly tenantId: string;
|
|
1232
|
+
readonly subscriptionId: string;
|
|
1233
|
+
readonly retirementId: string;
|
|
1234
|
+
readonly retired: RetirementSide;
|
|
1235
|
+
readonly replacement: RetirementSide;
|
|
1236
|
+
/** Every difference, retired to replacement, as the catalogue's diff states it. */
|
|
1237
|
+
readonly changes: readonly VersionChange[];
|
|
1238
|
+
/**
|
|
1239
|
+
* The rhythm the subscription is billed in when the retirement takes
|
|
1240
|
+
* effect — a change of rhythm scheduled by then included — which says
|
|
1241
|
+
* which of the two prices applies.
|
|
1242
|
+
*/
|
|
1243
|
+
readonly billingCycle: string;
|
|
1244
|
+
/** ISO 8601. */
|
|
1245
|
+
readonly effectiveAt: string;
|
|
1246
|
+
/** ISO date (`YYYY-MM-DD`), UTC. */
|
|
1247
|
+
readonly lastDayToCancel: string;
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* The one reminder of a retirement, where staying put costs the subscription
|
|
1251
|
+
* something (`SC-SUB-034`): sent 14 days before the retirement takes effect,
|
|
1252
|
+
* once per subscription and retired version. It says again what the
|
|
1253
|
+
* retirement notice said, and what a switch taken now would cost. Its
|
|
1254
|
+
* `billingCycle` is still the rhythm billed at the date, read again from the
|
|
1255
|
+
* subscription as it stands when the reminder is sent: a change of rhythm
|
|
1256
|
+
* scheduled since the announcement is in it.
|
|
1257
|
+
*/
|
|
1258
|
+
interface VersionRetirementReminder extends Omit<VersionRetiredNotice, 'kind'> {
|
|
1259
|
+
readonly kind: 'version-retirement-reminder';
|
|
1260
|
+
/**
|
|
1261
|
+
* What switching to the replacement now costs in the subscription's rhythm
|
|
1262
|
+
* (`SC-SUB-032`), or null where it cannot switch now: in a trial, with a
|
|
1263
|
+
* change scheduled, or where either plan is held for a special contract.
|
|
1264
|
+
*/
|
|
1265
|
+
readonly switchTerms: RetirementSwitchTerms | null;
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Why a retirement does not reach a subscription on the version:
|
|
1269
|
+
*
|
|
1270
|
+
* - `ended` — the subscription is over.
|
|
1271
|
+
* - `cancelled-before` — its cancellation lands by the effective date.
|
|
1272
|
+
* - `changes-before` — a scheduled change moves it to another plan, or to
|
|
1273
|
+
* another version of this one, by then.
|
|
1274
|
+
* - `no-term` — it carries no date a term can be counted from.
|
|
1275
|
+
* - `already-told` — an earlier announcement of this version reached it, and
|
|
1276
|
+
* stands.
|
|
1277
|
+
*/
|
|
1278
|
+
type RetirementSkipReason = 'ended' | 'cancelled-before' | 'changes-before' | 'no-term' | 'already-told';
|
|
1279
|
+
/** A refusal as the preview reports it and the announcement throws it. */
|
|
1280
|
+
interface RetirementBlocker {
|
|
1281
|
+
readonly code: string;
|
|
1282
|
+
readonly message: string;
|
|
1283
|
+
readonly params: Record<string, string | number>;
|
|
1284
|
+
}
|
|
1285
|
+
/** A subscription a retirement reaches, with what it means there. */
|
|
1286
|
+
interface RetirementReachedRow {
|
|
1287
|
+
readonly tenantId: string;
|
|
1288
|
+
readonly subscriptionId: string;
|
|
1289
|
+
readonly status: string;
|
|
1290
|
+
/** The rhythm it is billed in when the retirement takes effect. */
|
|
1291
|
+
readonly billingCycle: string;
|
|
1292
|
+
/** ISO 8601. */
|
|
1293
|
+
readonly effectiveAt: string;
|
|
1294
|
+
/** ISO date, UTC. */
|
|
1295
|
+
readonly lastDayToCancel: string;
|
|
1296
|
+
/** Reached by another retirement within the last twelve months: the announcement waits. */
|
|
1297
|
+
readonly reachedRecently: boolean;
|
|
1298
|
+
}
|
|
1299
|
+
/** A subscription on the version a retirement does not reach, and why. */
|
|
1300
|
+
interface RetirementSkippedRow {
|
|
1301
|
+
readonly tenantId: string;
|
|
1302
|
+
readonly subscriptionId: string;
|
|
1303
|
+
readonly reason: RetirementSkipReason;
|
|
1304
|
+
}
|
|
1305
|
+
/** What announcing a retirement now would do. */
|
|
1306
|
+
interface RetirementPreview {
|
|
1307
|
+
readonly retired: RetirementSide;
|
|
1308
|
+
readonly replacement: RetirementSide;
|
|
1309
|
+
/** Every difference, retired to replacement, as the subscribers will be told it. */
|
|
1310
|
+
readonly changes: readonly VersionChange[];
|
|
1311
|
+
/** ISO 8601: the moment it is computed for. */
|
|
1312
|
+
readonly asOf: string;
|
|
1313
|
+
readonly reached: readonly RetirementReachedRow[];
|
|
1314
|
+
readonly skipped: readonly RetirementSkippedRow[];
|
|
1315
|
+
/** Empty where it may be announced as it stands. */
|
|
1316
|
+
readonly blockers: readonly RetirementBlocker[];
|
|
1317
|
+
}
|
|
1318
|
+
/** What an announcement did. */
|
|
1319
|
+
interface RetirementAnnounced {
|
|
1320
|
+
readonly retirement: VersionRetirementRecord;
|
|
1321
|
+
/** Notices sent now; the rest are sent by the next run. */
|
|
1322
|
+
readonly told: number;
|
|
1323
|
+
readonly failed: number;
|
|
1324
|
+
}
|
|
1325
|
+
/**
|
|
1326
|
+
* Why a notice not told yet waits — for a subscription a plan version's
|
|
1327
|
+
* retirement reached, or a booking an add-on version's did. The run that sends
|
|
1328
|
+
* the notices asks the same questions in the same order.
|
|
1329
|
+
*/
|
|
1330
|
+
interface NotToldReasons {
|
|
1331
|
+
/**
|
|
1332
|
+
* What the notice announces would not fit at its date: the replacement's
|
|
1333
|
+
* plan could not carry the add-ons held then, or the replacement add-on
|
|
1334
|
+
* could not run beside a plan the booking meets. It waits until it would.
|
|
1335
|
+
*/
|
|
1336
|
+
readonly doesNotFit: number;
|
|
1337
|
+
/** Told of another retirement within the last twelve months: it waits until those are over. */
|
|
1338
|
+
readonly twelveMonths: number;
|
|
1339
|
+
/**
|
|
1340
|
+
* No longer reached: something of the subscriber's own — a change taking
|
|
1341
|
+
* it off the version, a cancellation landing first — came before the date.
|
|
1342
|
+
* It will not be sent.
|
|
1343
|
+
*/
|
|
1344
|
+
readonly noLongerReached: number;
|
|
1345
|
+
/** Nothing holds it back: it has reached nobody yet, and the next run tries again. */
|
|
1346
|
+
readonly nobodyYet: number;
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* How far a retirement has come, counted over the subscriptions — or, for an
|
|
1350
|
+
* add-on version, the bookings — it reached (`SC-SUB-033`, `SC-BUN-053`).
|
|
1351
|
+
*/
|
|
1352
|
+
interface RetirementProgress {
|
|
1353
|
+
/** Off the retired version: moved at their date, switched early, or changed on their own. */
|
|
1354
|
+
readonly moved: number;
|
|
1355
|
+
/** Still on the retired version, before their date. */
|
|
1356
|
+
readonly waiting: number;
|
|
1357
|
+
/** Still on the retired version after their date: the run has not moved them yet, or cannot. */
|
|
1358
|
+
readonly overdue: number;
|
|
1359
|
+
/**
|
|
1360
|
+
* Still on the retired version, and ended by their date: there is nothing
|
|
1361
|
+
* to move. A booking that ended after its date, before a move came, counts
|
|
1362
|
+
* here too: nothing moves a booking that has ended.
|
|
1363
|
+
*/
|
|
1364
|
+
readonly ended: number;
|
|
1365
|
+
/**
|
|
1366
|
+
* Still on the retired version, and not told yet: their notice has reached
|
|
1367
|
+
* nobody, so their date is not set and nothing moves them (`SC-SUB-038`).
|
|
1368
|
+
*/
|
|
1369
|
+
readonly notTold: number;
|
|
1370
|
+
/**
|
|
1371
|
+
* Why those counted `notTold` are not told yet, each counted once. Absent
|
|
1372
|
+
* from a server that does not count them.
|
|
1373
|
+
*/
|
|
1374
|
+
readonly notToldReasons?: NotToldReasons;
|
|
1375
|
+
/**
|
|
1376
|
+
* Reminded 14 days before their date (`SC-SUB-034`) — counted beside the
|
|
1377
|
+
* four above, not instead of one: a subscription reminded moves later.
|
|
1378
|
+
*/
|
|
1379
|
+
readonly reminded: number;
|
|
1380
|
+
}
|
|
1381
|
+
/** An announcement as the administration lists it, with how far it has come. */
|
|
1382
|
+
interface VersionRetirementView extends VersionRetirementRecord {
|
|
1383
|
+
readonly progress: RetirementProgress;
|
|
1384
|
+
}
|
|
1385
|
+
/** What one run of the moves at the date did. */
|
|
1386
|
+
interface RetirementMoveRun {
|
|
1387
|
+
/**
|
|
1388
|
+
* Subscriptions, or bookings, moved onto their replacement, with the
|
|
1389
|
+
* contract the move writes.
|
|
1390
|
+
*/
|
|
1391
|
+
readonly moved: number;
|
|
1392
|
+
/** Moves that could not be made, and are tried again by the next run. */
|
|
1393
|
+
readonly failed: number;
|
|
1394
|
+
}
|
|
1395
|
+
/** What switching to the replacement before the date did (`SC-SUB-032`). */
|
|
1396
|
+
interface RetirementSwitchResult {
|
|
1397
|
+
readonly fromPlanVersionId: string;
|
|
1398
|
+
readonly planVersionId: string;
|
|
1399
|
+
/** ISO date of the last day the price is held, or null where none is. */
|
|
1400
|
+
readonly heldUntilDay: string | null;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
/** What the switch costs, per period of the subscriber's rhythm. */
|
|
1404
|
+
interface RetirementSwitchTerms {
|
|
1405
|
+
/** The replacement's net price. */
|
|
1406
|
+
readonly priceNet: number;
|
|
1407
|
+
/**
|
|
1408
|
+
* Where the replacement costs more: the price the subscriber goes on paying,
|
|
1409
|
+
* the difference that is held, and the last day it is held — the day before
|
|
1410
|
+
* the date they were told. Null where it costs the same or less: its price
|
|
1411
|
+
* then applies from the subscriber's next period.
|
|
1412
|
+
*/
|
|
1413
|
+
readonly held: {
|
|
1414
|
+
readonly priceNet: number;
|
|
1415
|
+
readonly amountNet: number;
|
|
1416
|
+
readonly lastDay: string;
|
|
1417
|
+
} | null;
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* A side of a retirement as its prices are compared: what it costs in each
|
|
1421
|
+
* rhythm, for a plan version or for an add-on version beside a plan.
|
|
1422
|
+
*/
|
|
1423
|
+
type RetirementPricedSide = Pick<RetirementSide, 'monthlyNet' | 'yearlyNet'>;
|
|
1424
|
+
/**
|
|
1425
|
+
* What switching to the replacement now costs in `billingCycle`, or null where
|
|
1426
|
+
* the replacement has no price in it. A plan version's retirement and an add-on
|
|
1427
|
+
* version's are priced alike: each side by what it costs in each rhythm.
|
|
1428
|
+
*/
|
|
1429
|
+
declare function retirementSwitchTerms(notice: {
|
|
1430
|
+
readonly retired: RetirementPricedSide;
|
|
1431
|
+
readonly replacement: RetirementPricedSide;
|
|
1432
|
+
readonly lastDayToCancel: string;
|
|
1433
|
+
}, billingCycle: string): RetirementSwitchTerms | null;
|
|
1434
|
+
|
|
1435
|
+
/** An add-on version, as an announcement names it. */
|
|
1436
|
+
interface RetiredBundleVersionRef {
|
|
1437
|
+
readonly bundleVersionId: string;
|
|
1438
|
+
readonly bundleKey: string;
|
|
1439
|
+
readonly version: number;
|
|
1440
|
+
}
|
|
1441
|
+
/** An add-on retirement as it is kept: one per announcement, whichever bookings it reaches. */
|
|
1442
|
+
interface BundleVersionRetirementRecord {
|
|
1443
|
+
readonly id: string;
|
|
1444
|
+
/** The version retired. */
|
|
1445
|
+
readonly retired: RetiredBundleVersionRef;
|
|
1446
|
+
/** The version of the same add-on its bookings continue on, named by the operator. */
|
|
1447
|
+
readonly replacement: RetiredBundleVersionRef;
|
|
1448
|
+
readonly announcedAt: Date;
|
|
1449
|
+
/** Who announced it — an actor tag, as the audit log writes it. */
|
|
1450
|
+
readonly announcedBy: string;
|
|
1451
|
+
}
|
|
1452
|
+
type NewBundleVersionRetirement = Omit<BundleVersionRetirementRecord, 'id'>;
|
|
1453
|
+
/**
|
|
1454
|
+
* The manifest capability that announces retiring an add-on version. The
|
|
1455
|
+
* platform sets it where it serves the routes, and the admin UI offers the
|
|
1456
|
+
* action only where it is set.
|
|
1457
|
+
*/
|
|
1458
|
+
declare const BUNDLE_VERSION_RETIREMENT_CAPABILITY = "bundleVersions.retire";
|
|
1459
|
+
/**
|
|
1460
|
+
* An add-on version as the subscriber compares it with another — the one
|
|
1461
|
+
* retired and its replacement, or the one booked and the one offered: what it
|
|
1462
|
+
* grants, and its price beside the subscription's plan in each rhythm —
|
|
1463
|
+
* `pricingOverrides` included — or null where it has none there.
|
|
1464
|
+
*/
|
|
1465
|
+
interface BundleVersionSide {
|
|
1466
|
+
readonly bundleVersionId: string;
|
|
1467
|
+
readonly bundleKey: string;
|
|
1468
|
+
readonly label: string;
|
|
1469
|
+
readonly version: number;
|
|
1470
|
+
readonly features: readonly string[];
|
|
1471
|
+
readonly quotas: Readonly<Record<string, number>>;
|
|
1472
|
+
readonly monthlyNet: number | null;
|
|
1473
|
+
readonly yearlyNet: number | null;
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* An add-on version a booking is on is being retired, and the booking
|
|
1477
|
+
* continues on the named replacement from its effective date. Sent once per
|
|
1478
|
+
* booking and retirement, and kept as it was sent: the record shows what the
|
|
1479
|
+
* subscriber was told, prices included.
|
|
1480
|
+
*/
|
|
1481
|
+
interface BundleVersionRetiredNotice {
|
|
1482
|
+
readonly kind: 'bundle-version-retired';
|
|
1483
|
+
readonly tenantId: string;
|
|
1484
|
+
readonly subscriptionId: string;
|
|
1485
|
+
readonly subscriptionBundleId: string;
|
|
1486
|
+
readonly retirementId: string;
|
|
1487
|
+
/** The plan the add-on runs beside at the date, which both sides are priced for. */
|
|
1488
|
+
readonly planKey: string;
|
|
1489
|
+
readonly retired: BundleVersionSide;
|
|
1490
|
+
readonly replacement: BundleVersionSide;
|
|
1491
|
+
/** Every difference, retired to replacement, at the prices for `planKey`. */
|
|
1492
|
+
readonly changes: readonly VersionChange[];
|
|
1493
|
+
/** The rhythm the booking is billed in, which says which of the two prices applies. */
|
|
1494
|
+
readonly billingCycle: string;
|
|
1495
|
+
/** ISO 8601. */
|
|
1496
|
+
readonly effectiveAt: string;
|
|
1497
|
+
/** ISO date (`YYYY-MM-DD`), UTC: the last day it may be cancelled without its minimum term. */
|
|
1498
|
+
readonly lastDayToCancel: string;
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Why an add-on retirement does not reach a booking of the version:
|
|
1502
|
+
*
|
|
1503
|
+
* - `ended` — the subscription is over, or the booking's cancellation has
|
|
1504
|
+
* already landed.
|
|
1505
|
+
* - `cancelled-before` — the booking's cancellation lands by the effective date.
|
|
1506
|
+
* - `changes-before` — the booking's switch to a newer version, taken for the
|
|
1507
|
+
* end of its term, lands by the effective date.
|
|
1508
|
+
* - `no-term` — it carries no period an end can be counted from.
|
|
1509
|
+
* - `already-told` — an earlier announcement of this version reached it, and
|
|
1510
|
+
* stands.
|
|
1511
|
+
*/
|
|
1512
|
+
type BundleRetirementSkipReason = 'ended' | 'cancelled-before' | 'changes-before' | 'no-term' | 'already-told';
|
|
1513
|
+
/**
|
|
1514
|
+
* What switching a booking to its retirement's replacement now would cost
|
|
1515
|
+
* (`SC-BUN-054`), in the rhythm the booking is billed in now — its own, or
|
|
1516
|
+
* else its plan's — which need not be the one its notice was told in.
|
|
1517
|
+
*/
|
|
1518
|
+
interface BundleRetirementSwitchTerms extends RetirementSwitchTerms {
|
|
1519
|
+
readonly billingCycle: string;
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* The one reminder of an add-on retirement (`SC-BUN-056`): sent once, 14 days
|
|
1523
|
+
* before the booking's date, where staying put costs it something. It says
|
|
1524
|
+
* again what the booking was told, with both versions priced for the plan the
|
|
1525
|
+
* add-on runs beside at the date as the catalogue prices them when it is sent,
|
|
1526
|
+
* in the rhythm the booking is billed in then.
|
|
1527
|
+
*/
|
|
1528
|
+
interface BundleVersionRetirementReminder extends Omit<BundleVersionRetiredNotice, 'kind'> {
|
|
1529
|
+
readonly kind: 'bundle-version-retirement-reminder';
|
|
1530
|
+
/** What switching to the replacement now costs (`SC-BUN-054`), or null where the booking cannot. */
|
|
1531
|
+
readonly switchTerms: BundleRetirementSwitchTerms | null;
|
|
1532
|
+
}
|
|
1533
|
+
/** What switching a booking to its retirement's replacement before the date did. */
|
|
1534
|
+
interface BundleRetirementSwitchResult {
|
|
1535
|
+
readonly subscriptionBundleId: string;
|
|
1536
|
+
readonly fromBundleVersionId: string;
|
|
1537
|
+
readonly bundleVersionId: string;
|
|
1538
|
+
/** ISO date of the last day the price is held, or null where none is. */
|
|
1539
|
+
readonly heldUntilDay: string | null;
|
|
1540
|
+
}
|
|
1541
|
+
/** A booking an add-on retirement reaches, with what it means there. */
|
|
1542
|
+
interface BundleRetirementReachedRow {
|
|
1543
|
+
readonly tenantId: string;
|
|
1544
|
+
readonly subscriptionId: string;
|
|
1545
|
+
readonly subscriptionBundleId: string;
|
|
1546
|
+
/** The plan the add-on runs beside when the retirement takes effect. */
|
|
1547
|
+
readonly planKey: string;
|
|
1548
|
+
/** The rhythm the plan is billed in then. */
|
|
1549
|
+
readonly planCycle: string;
|
|
1550
|
+
/** The rhythm the booking is billed in. */
|
|
1551
|
+
readonly billingCycle: string;
|
|
1552
|
+
/** ISO 8601. */
|
|
1553
|
+
readonly effectiveAt: string;
|
|
1554
|
+
/** ISO date, UTC. */
|
|
1555
|
+
readonly lastDayToCancel: string;
|
|
1556
|
+
/** Its subscription was reached by a retirement within the last twelve months: the announcement waits. */
|
|
1557
|
+
readonly reachedRecently: boolean;
|
|
1558
|
+
}
|
|
1559
|
+
/** A booking of the version an add-on retirement does not reach, and why. */
|
|
1560
|
+
interface BundleRetirementSkippedRow {
|
|
1561
|
+
readonly tenantId: string;
|
|
1562
|
+
readonly subscriptionId: string;
|
|
1563
|
+
readonly subscriptionBundleId: string;
|
|
1564
|
+
readonly reason: BundleRetirementSkipReason;
|
|
1565
|
+
}
|
|
1566
|
+
/** What announcing an add-on retirement now would do. */
|
|
1567
|
+
interface BundleRetirementPreview {
|
|
1568
|
+
/** The two versions at their own prices, before any plan's override. */
|
|
1569
|
+
readonly retired: BundleVersionSide;
|
|
1570
|
+
readonly replacement: BundleVersionSide;
|
|
1571
|
+
/** Every difference at those prices; each booking is told the one at its plan's. */
|
|
1572
|
+
readonly changes: readonly VersionChange[];
|
|
1573
|
+
/** ISO 8601: the moment it is computed for. */
|
|
1574
|
+
readonly asOf: string;
|
|
1575
|
+
readonly reached: readonly BundleRetirementReachedRow[];
|
|
1576
|
+
readonly skipped: readonly BundleRetirementSkippedRow[];
|
|
1577
|
+
/** Empty where it may be announced as it stands. */
|
|
1578
|
+
readonly blockers: readonly RetirementBlocker[];
|
|
1579
|
+
}
|
|
1580
|
+
/** What an add-on announcement did. */
|
|
1581
|
+
interface BundleRetirementAnnounced {
|
|
1582
|
+
readonly retirement: BundleVersionRetirementRecord;
|
|
1583
|
+
/** Notices sent now; the rest are sent by the next run. */
|
|
1584
|
+
readonly told: number;
|
|
1585
|
+
readonly failed: number;
|
|
1586
|
+
}
|
|
1587
|
+
/** An add-on announcement as the administration lists it, with how far it has come. */
|
|
1588
|
+
interface BundleVersionRetirementView extends BundleVersionRetirementRecord {
|
|
1589
|
+
readonly progress: RetirementProgress;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
978
1592
|
type SubscriptionStatus = 'TRIAL' | 'ACTIVE' | 'PAST_DUE' | 'CANCELED' | 'PENDING_SALES';
|
|
979
1593
|
interface Subscription {
|
|
980
1594
|
id: string;
|
|
@@ -984,8 +1598,8 @@ interface Subscription {
|
|
|
984
1598
|
planVersionId: string;
|
|
985
1599
|
billingCycle: BillingCycle;
|
|
986
1600
|
status: SubscriptionStatus;
|
|
987
|
-
/** Override per
|
|
988
|
-
customLimits?:
|
|
1601
|
+
/** Override per tenant; unset fields fall back to the PlanVersion. */
|
|
1602
|
+
customLimits?: CustomLimits | null;
|
|
989
1603
|
/** ENTERPRISE special contract. */
|
|
990
1604
|
customMonthlyNet?: number | null;
|
|
991
1605
|
isPilot: boolean;
|
|
@@ -996,15 +1610,7 @@ interface Subscription {
|
|
|
996
1610
|
canceledAt: string | null;
|
|
997
1611
|
currentPeriodStart: string | null;
|
|
998
1612
|
currentPeriodEnd: string | null;
|
|
999
|
-
/** Plan
|
|
1000
|
-
pendingPlanVersionId: string | null;
|
|
1001
|
-
pendingPlanVersionEffectiveAt: string | null;
|
|
1002
|
-
pendingPlanVersionAccepted: boolean;
|
|
1003
|
-
pendingPlanVersionAcceptedAt: string | null;
|
|
1004
|
-
pendingPlanVersionAcceptedByUserId: string | null;
|
|
1005
|
-
pendingPlanVersionNotifiedAt: string | null;
|
|
1006
|
-
pendingPlanVersionReminderSentAt: string | null;
|
|
1007
|
-
/** Plan change at period end (orthogonal to pendingPlanVersionId). */
|
|
1613
|
+
/** Plan change at period end. */
|
|
1008
1614
|
pendingPlanId: PlanId | null;
|
|
1009
1615
|
pendingBillingCycle: BillingCycle | null;
|
|
1010
1616
|
pendingEffectiveAt: string | null;
|
|
@@ -1067,7 +1673,7 @@ interface VersionedEntityBase {
|
|
|
1067
1673
|
* has become part of the contract. Optional for backwards-compat reasons;
|
|
1068
1674
|
* the helper defensively interprets `undefined` as `>0` (= frozen). How the
|
|
1069
1675
|
* adapter counts depends on the version type: PlanVersion via
|
|
1070
|
-
* `Subscription.planVersionId` (+ `
|
|
1676
|
+
* `Subscription.planVersionId` (+ `pendingChangeVersionId`), BundleVersion
|
|
1071
1677
|
* via the respective app-specific Subscription→Bundle binding.
|
|
1072
1678
|
*/
|
|
1073
1679
|
subscriptionCount?: number;
|
|
@@ -1079,9 +1685,11 @@ interface VersionedEntityBase {
|
|
|
1079
1685
|
* their own minimum term + their own cancellation (user requirement from
|
|
1080
1686
|
* P11.7.3).
|
|
1081
1687
|
*
|
|
1082
|
-
* - `bundleVersionId` binds the booking to an *exact* BundleVersion
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1688
|
+
* - `bundleVersionId` binds the booking to an *exact* BundleVersion. A newer
|
|
1689
|
+
* version of the add-on does not change it by being published: an add-on
|
|
1690
|
+
* retirement moves the booking onto its replacement at its date
|
|
1691
|
+
* (`SC-BUN-049`), and the subscriber moves it by taking a newer version
|
|
1692
|
+
* offered (`SC-BUN-058`).
|
|
1085
1693
|
* - `startedAt` is the contract start of this booking.
|
|
1086
1694
|
* - `minimumTermEndsAt` = end of the minimum term; `null` = no minimum term
|
|
1087
1695
|
* (platform default = no commitment, set service-side).
|
|
@@ -1113,6 +1721,15 @@ interface SubscriptionBundleRecord {
|
|
|
1113
1721
|
billingCycle: BillingCycle | null;
|
|
1114
1722
|
currentPeriodStart: Date | null;
|
|
1115
1723
|
currentPeriodEnd: Date | null;
|
|
1724
|
+
/**
|
|
1725
|
+
* A switch to another version of the add-on, taken for the end of the
|
|
1726
|
+
* booking's running term because it takes something away (`SC-BUN-058`):
|
|
1727
|
+
* the version the booking continues on, and from when. Both null where
|
|
1728
|
+
* none is scheduled. The run that makes the switch at that moment clears
|
|
1729
|
+
* them; until then the booking stays on `bundleVersionId`.
|
|
1730
|
+
*/
|
|
1731
|
+
pendingBundleVersionId: string | null;
|
|
1732
|
+
pendingVersionEffectiveAt: Date | null;
|
|
1116
1733
|
createdAt: Date;
|
|
1117
1734
|
updatedAt: Date;
|
|
1118
1735
|
}
|
|
@@ -1136,6 +1753,18 @@ interface SubscriptionBundleView extends SubscriptionBundleRecord {
|
|
|
1136
1753
|
* defect: a field called `monthlyNet` on a yearly booking cannot be right.
|
|
1137
1754
|
*/
|
|
1138
1755
|
priceNet: number | null;
|
|
1756
|
+
/**
|
|
1757
|
+
* The number of the version a switch scheduled for the end of the booking's
|
|
1758
|
+
* term moves it to (`pendingBundleVersionId`); null where none is
|
|
1759
|
+
* scheduled.
|
|
1760
|
+
*/
|
|
1761
|
+
pendingVersion?: number | null;
|
|
1762
|
+
/**
|
|
1763
|
+
* The retirement of the add-on version this booking is on, as the
|
|
1764
|
+
* subscriber was told it (`SC-BUN-046`); absent or null where none was
|
|
1765
|
+
* told, or once the booking is on another version.
|
|
1766
|
+
*/
|
|
1767
|
+
retirement?: BundleVersionRetiredNotice | null;
|
|
1139
1768
|
}
|
|
1140
1769
|
interface CreateSubscriptionBundleData {
|
|
1141
1770
|
subscriptionId: string;
|
|
@@ -1627,7 +2256,13 @@ interface AuditQuery {
|
|
|
1627
2256
|
entity?: string;
|
|
1628
2257
|
entityId?: string;
|
|
1629
2258
|
action?: string;
|
|
1630
|
-
/**
|
|
2259
|
+
/**
|
|
2260
|
+
* A tag, matched exactly, or a pattern with `*` at its start, its end or
|
|
2261
|
+
* both, matched without regard to case: `cli:*` is every entry from the
|
|
2262
|
+
* command line, `*:ops@example.com:*` every entry of one person, whatever
|
|
2263
|
+
* they acted through. Everything between the stars is literal. A tag reads
|
|
2264
|
+
* `<source>:<email>:<context>`.
|
|
2265
|
+
*/
|
|
1631
2266
|
actorTag?: string;
|
|
1632
2267
|
from?: string;
|
|
1633
2268
|
to?: string;
|
|
@@ -1780,6 +2415,23 @@ interface PromotionOnPrice {
|
|
|
1780
2415
|
*/
|
|
1781
2416
|
declare function promotionOnPrice(promotions: PromotionRow[], targetKey: string, locale: string, cycle: 'monthly' | 'yearly', basePrice: number | null, today?: Date, targetType?: PromotionTargetType): PromotionOnPrice | null;
|
|
1782
2417
|
|
|
2418
|
+
/** An amount as written, to the cent. */
|
|
2419
|
+
declare function roundToCents(amount: number): number;
|
|
2420
|
+
/** The terms added as written, exactly, and rounded once to the cent. */
|
|
2421
|
+
declare function sumToCents(...terms: number[]): number;
|
|
2422
|
+
/** The amount in whole cents, rounded once. */
|
|
2423
|
+
declare function toCents(amount: number): number;
|
|
2424
|
+
/** `percent` % of `amount`, to the cent — the discount a percentage takes off. */
|
|
2425
|
+
declare function percentOf(amount: number, percent: number): number;
|
|
2426
|
+
/** `amount × part / whole`, to the cent — a share of a period, say. */
|
|
2427
|
+
declare function prorate(amount: number, part: number, whole: number): number;
|
|
2428
|
+
/** Gross from net at a tax rate in per cent: net × (100 + rate) / 100. */
|
|
2429
|
+
declare function grossFromNet(net: number, vatRate: number): number;
|
|
2430
|
+
/** Net from gross at a tax rate in per cent: gross × 100 / (100 + rate). */
|
|
2431
|
+
declare function netFromGross(gross: number, vatRate: number): number;
|
|
2432
|
+
/** The tax a gross amount includes at a rate in per cent: gross × rate / (100 + rate). */
|
|
2433
|
+
declare function computeIncludedVat(gross: number, vatRate: number): number;
|
|
2434
|
+
|
|
1783
2435
|
type CheckoutOfferLineItemKind = 'plan' | 'bundle' | 'discount';
|
|
1784
2436
|
/** Frozen billable line item in the offer. */
|
|
1785
2437
|
interface CheckoutOfferLineItem {
|
|
@@ -2087,6 +2739,12 @@ interface PublicMarketingCatalogResponse {
|
|
|
2087
2739
|
currency: string;
|
|
2088
2740
|
/** VAT rate in percent — for the CheckoutOffer price breakdown. */
|
|
2089
2741
|
vatRate: number;
|
|
2742
|
+
/**
|
|
2743
|
+
* The country the rate applies to: the issuer's, where a tax adapter
|
|
2744
|
+
* decides and a subscriber elsewhere may be charged another — the page says
|
|
2745
|
+
* so (`SC-PRIC-037`). `null` where the one rate of the file applies to all.
|
|
2746
|
+
*/
|
|
2747
|
+
vatRateShownFor: string | null;
|
|
2090
2748
|
/** What a new payment method is taken with here, if one is taken. */
|
|
2091
2749
|
newPaymentMethods: PublicNewPaymentMethods;
|
|
2092
2750
|
/** Visible, marketed plans — sorted by `priority` DESC. */
|
|
@@ -2252,57 +2910,6 @@ declare function readQuotaValue(value: unknown): number | null;
|
|
|
2252
2910
|
*/
|
|
2253
2911
|
declare function readQuotaRecord(value: unknown): Record<string, number>;
|
|
2254
2912
|
|
|
2255
|
-
/** Alias for historical compatibility — equivalent to VersionChangeDirection. */
|
|
2256
|
-
type ChangeDirection = VersionChangeDirection;
|
|
2257
|
-
interface DiffResult {
|
|
2258
|
-
nonRegressive: boolean;
|
|
2259
|
-
changes: VersionChange[];
|
|
2260
|
-
}
|
|
2261
|
-
/**
|
|
2262
|
-
* `Decimal | string | number` — the three forms in which prices appear
|
|
2263
|
-
* in the platform. `Decimal` is the Prisma class (with
|
|
2264
|
-
* `.toNumber()`), which is not imported directly in order to keep the
|
|
2265
|
-
* platform Prisma-free — a structural view suffices.
|
|
2266
|
-
*/
|
|
2267
|
-
type DecimalLike = number | string | {
|
|
2268
|
-
toNumber(): number;
|
|
2269
|
-
};
|
|
2270
|
-
interface PlanVersionFields {
|
|
2271
|
-
features: FeatureKey[];
|
|
2272
|
-
/**
|
|
2273
|
-
* Quotas of the version. -1 = unlimited; missing key = 0.
|
|
2274
|
-
*
|
|
2275
|
-
* Every key either side carries is compared. Which keys exist is the
|
|
2276
|
-
* installation's decision — they come from `@DefinesQuota` — so a fixed
|
|
2277
|
-
* set here would have compared the three the platform happened to know by
|
|
2278
|
-
* name and let every other one be lowered without the confirmation
|
|
2279
|
-
* publishing a regression asks for.
|
|
2280
|
-
*/
|
|
2281
|
-
quotas: Record<QuotaKey, number>;
|
|
2282
|
-
monthlyNet: DecimalLike;
|
|
2283
|
-
yearlyNet: DecimalLike;
|
|
2284
|
-
}
|
|
2285
|
-
interface BundleVersionFields {
|
|
2286
|
-
features: FeatureKey[];
|
|
2287
|
-
/** Quota contributions of the bundle. -1 = unlimited; missing key = 0. */
|
|
2288
|
-
quotas: Record<QuotaKey, number>;
|
|
2289
|
-
/** Default pricing; null = only override pricing possible. */
|
|
2290
|
-
monthlyNet: DecimalLike | null;
|
|
2291
|
-
yearlyNet: DecimalLike | null;
|
|
2292
|
-
}
|
|
2293
|
-
declare function classifyPlanDiff(oldV: PlanVersionFields, newV: PlanVersionFields): DiffResult;
|
|
2294
|
-
/**
|
|
2295
|
-
* Classification of a BundleVersion diff for contract protection.
|
|
2296
|
-
*
|
|
2297
|
-
* Quotas are compared exactly as they are for a plan.
|
|
2298
|
-
*
|
|
2299
|
-
* Pricing can be `null` (the bundle only has override pricing); a switch
|
|
2300
|
-
* from value ↔ null is classified as REGRESSION (value dropped) or IMPROVEMENT
|
|
2301
|
-
* (value added, lowerIsBetter inverted). Both null
|
|
2302
|
-
* stay NEUTRAL.
|
|
2303
|
-
*/
|
|
2304
|
-
declare function classifyBundleVersionDiff(oldV: BundleVersionFields, newV: BundleVersionFields): DiffResult;
|
|
2305
|
-
|
|
2306
2913
|
interface PromoPreviewRequest {
|
|
2307
2914
|
/** Promo code (case-insensitive, normalized to uppercase in the service). */
|
|
2308
2915
|
code: string;
|
|
@@ -2578,6 +3185,264 @@ interface MaintenanceUnlockView {
|
|
|
2578
3185
|
wasLocked: boolean;
|
|
2579
3186
|
}
|
|
2580
3187
|
|
|
3188
|
+
/**
|
|
3189
|
+
* A newer version of a booked add-on, offered beside the booking: the version
|
|
3190
|
+
* booked and the one on sale side by side, what kind of offer it is, and when
|
|
3191
|
+
* a switch taken now would take effect — at once, or, for one that takes
|
|
3192
|
+
* something away, at the end of the booking's running term. The list of the
|
|
3193
|
+
* tenant's bookings carries it on each booking, as `offer`.
|
|
3194
|
+
*/
|
|
3195
|
+
interface BundleVersionOfferView {
|
|
3196
|
+
readonly subscriptionBundleId: string;
|
|
3197
|
+
/** The plan both versions are priced beside: the one the subscription is on. */
|
|
3198
|
+
readonly planKey: string;
|
|
3199
|
+
/** The rhythm the booking is billed in, which the kind of offer is judged in. */
|
|
3200
|
+
readonly billingCycle: BillingCycle;
|
|
3201
|
+
readonly bound: BundleVersionSide;
|
|
3202
|
+
readonly offered: BundleVersionSide;
|
|
3203
|
+
readonly class: Exclude<VersionOfferClass, 'same'>;
|
|
3204
|
+
/** Every difference, bound to offered, with the price in the booking's rhythm alone. */
|
|
3205
|
+
readonly changes: readonly VersionChange[];
|
|
3206
|
+
/** ISO instant. */
|
|
3207
|
+
readonly takesEffectAt: string;
|
|
3208
|
+
}
|
|
3209
|
+
/**
|
|
3210
|
+
* What taking an add-on offer did: the booking, the version left and the one
|
|
3211
|
+
* taken, and whether it applied at once or waits for `takesEffectAt`.
|
|
3212
|
+
*/
|
|
3213
|
+
interface BundleVersionSwitchResult {
|
|
3214
|
+
readonly class: Exclude<VersionOfferClass, 'same'>;
|
|
3215
|
+
readonly subscriptionBundleId: string;
|
|
3216
|
+
readonly fromBundleVersionId: string;
|
|
3217
|
+
readonly bundleVersionId: string;
|
|
3218
|
+
readonly immediate: boolean;
|
|
3219
|
+
/** ISO instant. */
|
|
3220
|
+
readonly takesEffectAt: string;
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
/** What a notice is about. */
|
|
3224
|
+
type SubscriptionNoticeKind = 'version-offered' | 'version-retired' | 'version-retirement-reminder' | 'bundle-version-retired' | 'bundle-version-retirement-reminder' | 'bundle-version-offered';
|
|
3225
|
+
/** Which notice: there is one per subscription, kind and subject. */
|
|
3226
|
+
interface SubscriptionNoticeKey {
|
|
3227
|
+
readonly tenantId: string;
|
|
3228
|
+
readonly subscriptionId: string;
|
|
3229
|
+
readonly kind: SubscriptionNoticeKind;
|
|
3230
|
+
/**
|
|
3231
|
+
* What it is about. For `version-offered`, the id of the version offered;
|
|
3232
|
+
* for `version-retired`, the id of the version retired — so a subscription
|
|
3233
|
+
* is told of a version's retirement once, whichever announcement it came
|
|
3234
|
+
* with. The announcement is in the notice as `retirementId`. For
|
|
3235
|
+
* `version-retirement-reminder`, the id of the version retired as well: a
|
|
3236
|
+
* subscription is reminded of a version's retirement once. For
|
|
3237
|
+
* `bundle-version-retired`, the id of the add-on version retired: a
|
|
3238
|
+
* subscription holds one booking of an add-on, so that booking is told of
|
|
3239
|
+
* the retirement once. For `bundle-version-retirement-reminder`, the id of
|
|
3240
|
+
* the add-on version retired as well: that booking is reminded of it once.
|
|
3241
|
+
* For `bundle-version-offered`, the id of the add-on version offered: that
|
|
3242
|
+
* booking is told of the version once.
|
|
3243
|
+
*/
|
|
3244
|
+
readonly subject: string;
|
|
3245
|
+
}
|
|
3246
|
+
/** Who a notice went to and how, in the application's own terms. */
|
|
3247
|
+
interface SubscriptionNoticeDelivery {
|
|
3248
|
+
/** The addresses, or user ids, it was sent to. Empty where nobody could be told. */
|
|
3249
|
+
readonly recipients: readonly string[];
|
|
3250
|
+
/** The way it went — `email`, `in-app`, whatever the application calls it. */
|
|
3251
|
+
readonly channel: string;
|
|
3252
|
+
}
|
|
3253
|
+
/** A notice as it is kept. */
|
|
3254
|
+
interface SubscriptionNoticeRecord extends SubscriptionNoticeKey {
|
|
3255
|
+
readonly id: string;
|
|
3256
|
+
/** The notice as it was last handed to the application: a `SubscriptionNotice`. */
|
|
3257
|
+
readonly content: unknown;
|
|
3258
|
+
readonly createdAt: Date;
|
|
3259
|
+
/**
|
|
3260
|
+
* When a run took it on to deliver it. Null where no run holds it — before
|
|
3261
|
+
* the first attempt, and again after an attempt that failed.
|
|
3262
|
+
*/
|
|
3263
|
+
readonly claimedAt: Date | null;
|
|
3264
|
+
/** When the application confirmed it sent it; null until then. */
|
|
3265
|
+
readonly deliveredAt: Date | null;
|
|
3266
|
+
/** Who it went to and how; set together with `deliveredAt`. */
|
|
3267
|
+
readonly delivery: SubscriptionNoticeDelivery | null;
|
|
3268
|
+
}
|
|
3269
|
+
/**
|
|
3270
|
+
* A newer version of the subscription's plan is now offered to it. Sent once
|
|
3271
|
+
* per version, when the offer appears beside the plan — the notice and the
|
|
3272
|
+
* offer say the same thing.
|
|
3273
|
+
*/
|
|
3274
|
+
interface VersionOfferedNotice {
|
|
3275
|
+
readonly kind: 'version-offered';
|
|
3276
|
+
readonly tenantId: string;
|
|
3277
|
+
readonly subscriptionId: string;
|
|
3278
|
+
/** The offer as `GET billing/version-offer` answers it at the moment the notice is due. */
|
|
3279
|
+
readonly offer: VersionOfferView;
|
|
3280
|
+
}
|
|
3281
|
+
/**
|
|
3282
|
+
* A newer version of an add-on a booking is on is now offered to it. Sent once
|
|
3283
|
+
* per booking and version, when the offer appears beside the add-on — the
|
|
3284
|
+
* notice and the offer say the same thing.
|
|
3285
|
+
*/
|
|
3286
|
+
interface BundleVersionOfferedNotice {
|
|
3287
|
+
readonly kind: 'bundle-version-offered';
|
|
3288
|
+
readonly tenantId: string;
|
|
3289
|
+
readonly subscriptionId: string;
|
|
3290
|
+
readonly subscriptionBundleId: string;
|
|
3291
|
+
/** The offer as the list of the tenant's bookings shows it at the moment the notice is due. */
|
|
3292
|
+
readonly offer: BundleVersionOfferView;
|
|
3293
|
+
}
|
|
3294
|
+
/** A notice handed to the application to send. */
|
|
3295
|
+
type SubscriptionNotice = VersionOfferedNotice | VersionRetiredNotice | VersionRetirementReminder | BundleVersionRetiredNotice | BundleVersionRetirementReminder | BundleVersionOfferedNotice;
|
|
3296
|
+
|
|
3297
|
+
/**
|
|
3298
|
+
* A `subscription_notices` row as either adapter reads it back. The two JSON
|
|
3299
|
+
* columns are `unknown`: the database holds whatever was written to them.
|
|
3300
|
+
*/
|
|
3301
|
+
interface CanonicalSubscriptionNoticeRow {
|
|
3302
|
+
id: string;
|
|
3303
|
+
tenantId: string;
|
|
3304
|
+
subscriptionId: string;
|
|
3305
|
+
kind: string;
|
|
3306
|
+
subject: string;
|
|
3307
|
+
content: unknown;
|
|
3308
|
+
createdAt: Date;
|
|
3309
|
+
claimedAt: Date | null;
|
|
3310
|
+
deliveredAt: Date | null;
|
|
3311
|
+
recipients: unknown;
|
|
3312
|
+
channel: string | null;
|
|
3313
|
+
}
|
|
3314
|
+
/**
|
|
3315
|
+
* Reads a row back as a record, naming each column rather than spreading the
|
|
3316
|
+
* row. The kind and the delivery are checked rather than cast: the record is
|
|
3317
|
+
* what a subscriber is later shown they were told, and a value nobody can read
|
|
3318
|
+
* must stop at the read and name its row.
|
|
3319
|
+
*/
|
|
3320
|
+
declare function toSubscriptionNoticeRecord(row: CanonicalSubscriptionNoticeRow): SubscriptionNoticeRecord;
|
|
3321
|
+
|
|
3322
|
+
/** The dates of a version that decide its state, as a row carries them. */
|
|
3323
|
+
interface VersionSaleDates extends VersionWindow {
|
|
3324
|
+
readonly publishedAt?: string | Date | null;
|
|
3325
|
+
}
|
|
3326
|
+
/**
|
|
3327
|
+
* Where a version stands. A day is an ISO date (`YYYY-MM-DD`, UTC):
|
|
3328
|
+
* - `scheduled` — published and not on sale yet; `from` is its first day.
|
|
3329
|
+
* - `on-sale` — on sale now; `until` is its last day, where one is known.
|
|
3330
|
+
* - `off-sale` — no longer on sale; `since` is its first day off sale, where
|
|
3331
|
+
* one is known — a version superseded without a last day has none.
|
|
3332
|
+
*/
|
|
3333
|
+
type VersionSale = {
|
|
3334
|
+
readonly kind: 'draft';
|
|
3335
|
+
} | {
|
|
3336
|
+
readonly kind: 'scheduled';
|
|
3337
|
+
readonly from: string;
|
|
3338
|
+
} | {
|
|
3339
|
+
readonly kind: 'on-sale';
|
|
3340
|
+
readonly until: string | null;
|
|
3341
|
+
} | {
|
|
3342
|
+
readonly kind: 'off-sale';
|
|
3343
|
+
readonly since: string | null;
|
|
3344
|
+
};
|
|
3345
|
+
type VersionSaleKind = VersionSale['kind'];
|
|
3346
|
+
/** The state of `version` at `now`. */
|
|
3347
|
+
declare function versionSale(version: VersionSaleDates, now: Date): VersionSale;
|
|
3348
|
+
/**
|
|
3349
|
+
* The version on sale at `now` among one plan's or add-on's versions, in the
|
|
3350
|
+
* order the platform picks it: the latest `validFrom`, a version without one
|
|
3351
|
+
* last, then the highest number.
|
|
3352
|
+
*/
|
|
3353
|
+
declare function versionOnSale<V extends VersionSaleDates & {
|
|
3354
|
+
readonly version?: number;
|
|
3355
|
+
}>(versions: readonly V[], now: Date): V | null;
|
|
3356
|
+
/**
|
|
3357
|
+
* What a listing shows for a plan or add-on: the version on sale, otherwise
|
|
3358
|
+
* the next one scheduled. A draft is not shown by this.
|
|
3359
|
+
*/
|
|
3360
|
+
declare function versionOnSaleOrNext<V extends VersionSaleDates & {
|
|
3361
|
+
readonly version?: number;
|
|
3362
|
+
}>(versions: readonly V[], now: Date): V | null;
|
|
3363
|
+
|
|
3364
|
+
/** A `version_retirements` row as either adapter reads it back. */
|
|
3365
|
+
interface CanonicalVersionRetirementRow {
|
|
3366
|
+
id: string;
|
|
3367
|
+
retiredPlanVersionId: string;
|
|
3368
|
+
retiredPlanKey: string;
|
|
3369
|
+
retiredVersion: number;
|
|
3370
|
+
replacementPlanVersionId: string;
|
|
3371
|
+
replacementPlanKey: string;
|
|
3372
|
+
replacementVersion: number;
|
|
3373
|
+
announcedAt: Date;
|
|
3374
|
+
announcedBy: string;
|
|
3375
|
+
}
|
|
3376
|
+
/** Reads a row back as a record, naming each column rather than spreading the row. */
|
|
3377
|
+
declare function toVersionRetirementRecord(row: CanonicalVersionRetirementRow): VersionRetirementRecord;
|
|
3378
|
+
|
|
3379
|
+
/** A `bundle_version_retirements` row as either adapter reads it back. */
|
|
3380
|
+
interface CanonicalBundleVersionRetirementRow {
|
|
3381
|
+
id: string;
|
|
3382
|
+
retiredBundleVersionId: string;
|
|
3383
|
+
retiredBundleKey: string;
|
|
3384
|
+
retiredVersion: number;
|
|
3385
|
+
replacementBundleVersionId: string;
|
|
3386
|
+
replacementBundleKey: string;
|
|
3387
|
+
replacementVersion: number;
|
|
3388
|
+
announcedAt: Date;
|
|
3389
|
+
announcedBy: string;
|
|
3390
|
+
}
|
|
3391
|
+
/** Reads a row back as a record, naming each column rather than spreading the row. */
|
|
3392
|
+
declare function toBundleVersionRetirementRecord(row: CanonicalBundleVersionRetirementRow): BundleVersionRetirementRecord;
|
|
3393
|
+
|
|
3394
|
+
/** A scheduled change as a subscription row holds it. */
|
|
3395
|
+
interface ScheduledChangeColumns {
|
|
3396
|
+
readonly pendingPlan: string | null;
|
|
3397
|
+
readonly pendingBillingCycle: string | null;
|
|
3398
|
+
readonly pendingEffectiveAt: Date | null;
|
|
3399
|
+
readonly pendingChangeVersionId: string | null;
|
|
3400
|
+
}
|
|
3401
|
+
/** No change scheduled: what a plan change writes where it does not keep one. */
|
|
3402
|
+
declare const NO_SCHEDULED_CHANGE: ScheduledChangeColumns;
|
|
3403
|
+
/**
|
|
3404
|
+
* The scheduled-change columns a plan change writes onto `current`: all
|
|
3405
|
+
* cleared, unless the write keeps the change. A kept change is left as it is,
|
|
3406
|
+
* with one exception: a change that only moves the rhythm on the plan being
|
|
3407
|
+
* left — the plan it was scheduled on, no version named — follows the
|
|
3408
|
+
* subscription to its new plan. Recorded as it was, it would take the
|
|
3409
|
+
* subscription back to the plan it left when it comes due.
|
|
3410
|
+
*/
|
|
3411
|
+
declare function scheduledChangeAfterWrite(current: {
|
|
3412
|
+
readonly plan: string;
|
|
3413
|
+
} & ScheduledChangeColumns, input: {
|
|
3414
|
+
readonly planId: string;
|
|
3415
|
+
readonly keepsPendingChange?: boolean;
|
|
3416
|
+
}): Partial<ScheduledChangeColumns>;
|
|
3417
|
+
|
|
3418
|
+
/** How many days before a retirement takes effect its reminder is due. */
|
|
3419
|
+
declare const RETIREMENT_REMINDER_LEAD_DAYS = 14;
|
|
3420
|
+
/**
|
|
3421
|
+
* When the reminder of a retirement is due: 14 days before it takes effect, at
|
|
3422
|
+
* the same time of day. UTC has no change of clocks, so that is the effective
|
|
3423
|
+
* day less 14 calendar days.
|
|
3424
|
+
*/
|
|
3425
|
+
declare function retirementReminderDueAt(notice: Pick<VersionRetiredNotice, 'effectiveAt'>): Date;
|
|
3426
|
+
/**
|
|
3427
|
+
* Whether the reminder is due at `now`: from its day until the retirement
|
|
3428
|
+
* takes effect. A run that did not happen on the day is caught up by the next
|
|
3429
|
+
* one before the date; after it there is nothing left to remind of.
|
|
3430
|
+
*/
|
|
3431
|
+
declare function retirementReminderIsDue(notice: Pick<VersionRetiredNotice, 'effectiveAt'>, now: Date): boolean;
|
|
3432
|
+
/**
|
|
3433
|
+
* Whether staying put costs the subscription something when the retirement
|
|
3434
|
+
* takes effect (D9): the replacement takes a feature or a quota away, or is
|
|
3435
|
+
* dearer in `billingCycle`, the rhythm it is billed in then — or not sold in
|
|
3436
|
+
* it. A price that rises only in another rhythm costs it nothing. A plan
|
|
3437
|
+
* version's retirement and an add-on version's are judged alike.
|
|
3438
|
+
*/
|
|
3439
|
+
declare function retirementCostsTheSubscription(notice: {
|
|
3440
|
+
readonly retired: RetirementPricedSide;
|
|
3441
|
+
readonly replacement: RetirementPricedSide;
|
|
3442
|
+
readonly changes: readonly VersionChange[];
|
|
3443
|
+
readonly lastDayToCancel: string;
|
|
3444
|
+
}, billingCycle: string): boolean;
|
|
3445
|
+
|
|
2581
3446
|
/** A `maintenance_windows` row as either adapter reads it back. */
|
|
2582
3447
|
type CanonicalMaintenanceWindowRow = MaintenanceWindowRecord;
|
|
2583
3448
|
/**
|
|
@@ -2726,11 +3591,8 @@ interface PlanVersionRow extends VersionedEntityBase {
|
|
|
2726
3591
|
* `endsAt` is user-initiated: `POST /admin/catalog/plan-versions/:id/terminate`
|
|
2727
3592
|
* sets the field. When `endsAt < NOW()` the version is no longer live for
|
|
2728
3593
|
* new bookings — existing subscriptions (P1) stay bound.
|
|
2729
|
-
*
|
|
2730
|
-
* Optional, because consumer backends add the column additively — if it
|
|
2731
|
-
* is missing, there is no end date.
|
|
2732
3594
|
*/
|
|
2733
|
-
endsAt
|
|
3595
|
+
endsAt: string | null;
|
|
2734
3596
|
/** @deprecated Read from `quotas['users']` once available. */
|
|
2735
3597
|
maxUsers?: number;
|
|
2736
3598
|
/** @deprecated Legacy field; read from `quotas['vehicles']`. */
|
|
@@ -2795,12 +3657,12 @@ interface PlanCatalogReadSnapshot {
|
|
|
2795
3657
|
/** Plan stems (deletedAt IS NULL). */
|
|
2796
3658
|
plans: PlanRow[];
|
|
2797
3659
|
/**
|
|
2798
|
-
*
|
|
2799
|
-
*
|
|
2800
|
-
*
|
|
2801
|
-
*
|
|
3660
|
+
* Per `planId` (= planKey) the version on sale at the moment the snapshot
|
|
3661
|
+
* was asked for — the rule of `PlanRepository.findActivePlanVersion`, so
|
|
3662
|
+
* the catalogue names the version a booking made at that moment binds.
|
|
3663
|
+
* A plan with nothing on sale is taken over without pricing or quotas.
|
|
2802
3664
|
*/
|
|
2803
|
-
|
|
3665
|
+
versionsOnSale: PlanVersionRow[];
|
|
2804
3666
|
/** Feature catalog entries (deletedAt IS NULL). */
|
|
2805
3667
|
featureEntries: FeatureCatalogEntryRow[];
|
|
2806
3668
|
}
|
|
@@ -2809,7 +3671,8 @@ interface PlanCatalogReadSnapshot {
|
|
|
2809
3671
|
* implement it against their Prisma tables.
|
|
2810
3672
|
*/
|
|
2811
3673
|
interface PlanCatalogReadSink {
|
|
2812
|
-
|
|
3674
|
+
/** The catalogue as it stands at `asOf`. */
|
|
3675
|
+
loadSnapshot(asOf: Date): Promise<PlanCatalogReadSnapshot>;
|
|
2813
3676
|
}
|
|
2814
3677
|
|
|
2815
3678
|
/**
|
|
@@ -3068,13 +3931,34 @@ interface EmailPort {
|
|
|
3068
3931
|
}
|
|
3069
3932
|
/** Adapter for MFA secret persistence. */
|
|
3070
3933
|
interface MfaPort {
|
|
3071
|
-
/**
|
|
3934
|
+
/**
|
|
3935
|
+
* Returns the stored secret or null. What is stored is the value the
|
|
3936
|
+
* platform handed to `setSecret`: sealed by the installation's
|
|
3937
|
+
* `SecretSealer`, and opened by the platform, not here.
|
|
3938
|
+
*/
|
|
3072
3939
|
getSecret(userId: string): Promise<string | null>;
|
|
3073
|
-
/** Persists or deletes (null) the
|
|
3940
|
+
/** Persists or deletes (null) the sealed secret, as it is given. */
|
|
3074
3941
|
setSecret(userId: string, secret: string | null): Promise<void>;
|
|
3075
3942
|
/** The platform calls this during the mfa-setup command. */
|
|
3076
3943
|
isEnabled(userId: string): Promise<boolean>;
|
|
3077
3944
|
}
|
|
3945
|
+
/**
|
|
3946
|
+
* Seals a secret before it is stored and opens it after it is read.
|
|
3947
|
+
*
|
|
3948
|
+
* The TOTP secret of a SuperAdmin is the second factor of the accounts that can
|
|
3949
|
+
* change every tenant's plan, codes and contracts. Stored as it is, whoever
|
|
3950
|
+
* holds a dump, a backup or a replica holds it too, and the second factor adds
|
|
3951
|
+
* nothing against them. The key stays with the installation — in its
|
|
3952
|
+
* configuration, not in the database the sealed value lives in.
|
|
3953
|
+
*
|
|
3954
|
+
* `open` refuses what it did not seal: a value from another key, a format it
|
|
3955
|
+
* does not know, a secret stored before sealing. The platform then treats the
|
|
3956
|
+
* code as wrong and the administrator enrols again.
|
|
3957
|
+
*/
|
|
3958
|
+
interface SecretSealer {
|
|
3959
|
+
seal(plain: string): Promise<string>;
|
|
3960
|
+
open(sealed: string): Promise<string>;
|
|
3961
|
+
}
|
|
3078
3962
|
/**
|
|
3079
3963
|
* Opaque transaction context. The consumer determines the concrete type
|
|
3080
3964
|
* (e.g. `Prisma.TransactionClient`). Platform code only passes it
|
|
@@ -3205,8 +4089,18 @@ interface PromoCodeRedemptionListItem extends PromoCodeRedemptionRecord {
|
|
|
3205
4089
|
*/
|
|
3206
4090
|
interface PromoCodeRepository {
|
|
3207
4091
|
findById(id: string): Promise<PromoCodeRecord | null>;
|
|
4092
|
+
/**
|
|
4093
|
+
* The code with this name, deleted ones included: a deleted code keeps its
|
|
4094
|
+
* name (`SC-PROMO-028`), so the platform's duplicate check has to see it.
|
|
4095
|
+
* Every caller that redeems or previews checks `deletedAt` itself.
|
|
4096
|
+
*/
|
|
3208
4097
|
findByCode(code: string, tx?: TransactionContext): Promise<PromoCodeRecord | null>;
|
|
3209
4098
|
findMany(filter: PromoCodeFilter): Promise<PromoCodeRecord[]>;
|
|
4099
|
+
/**
|
|
4100
|
+
* Refuses a name that is taken — by a live or a deleted code — with
|
|
4101
|
+
* `promoCodeTaken`: two creates can pass the platform's duplicate check
|
|
4102
|
+
* together, and the second one's answer is the refusal, not a driver error.
|
|
4103
|
+
*/
|
|
3210
4104
|
create(data: CreatePromoCodeData): Promise<PromoCodeRecord>;
|
|
3211
4105
|
update(id: string, data: UpdatePromoCodeData): Promise<PromoCodeRecord>;
|
|
3212
4106
|
softDelete(id: string): Promise<void>;
|
|
@@ -3228,7 +4122,8 @@ interface PromoCodeRepository {
|
|
|
3228
4122
|
releaseSlot(id: string, tx?: TransactionContext): Promise<void>;
|
|
3229
4123
|
/**
|
|
3230
4124
|
* Bulk-expire cron: sets all codes with `validUntil < now` and status
|
|
3231
|
-
* ACTIVE/PAUSED to EXPIRED
|
|
4125
|
+
* ACTIVE/PAUSED to EXPIRED, leaving deleted codes as they were — a write
|
|
4126
|
+
* to a row the operator removed. Returns: number of updated rows.
|
|
3232
4127
|
*/
|
|
3233
4128
|
expireDueCodes(now: Date): Promise<number>;
|
|
3234
4129
|
}
|
|
@@ -3328,7 +4223,14 @@ interface PromoCodeHoldRepository {
|
|
|
3328
4223
|
interface PromoCodeRedemptionRepository {
|
|
3329
4224
|
findBySubscription(subscriptionId: string, tx?: TransactionContext): Promise<PromoCodeRedemptionRecord | null>;
|
|
3330
4225
|
create(data: Omit<PromoCodeRedemptionRecord, 'id' | 'redeemedAt' | 'status' | 'reversedAt'>, tx?: TransactionContext): Promise<PromoCodeRedemptionRecord>;
|
|
3331
|
-
|
|
4226
|
+
/**
|
|
4227
|
+
* Marks the redemption reversed while it is not reversed yet, in one
|
|
4228
|
+
* conditional statement, and answers with it; `null` where it already was.
|
|
4229
|
+
* Two reversals of one redemption at the same moment then find one winner,
|
|
4230
|
+
* and only the winner gives the slot back — without the claim both would,
|
|
4231
|
+
* and a limited code would gain a slot it never issued.
|
|
4232
|
+
*/
|
|
4233
|
+
setReversed(id: string, tx?: TransactionContext): Promise<PromoCodeRedemptionRecord | null>;
|
|
3332
4234
|
countByPromoCode(promoCodeId: string, status?: PromoCodeRedemptionStatus): Promise<number>;
|
|
3333
4235
|
listByPromoCode(promoCodeId: string): Promise<PromoCodeRedemptionListItem[]>;
|
|
3334
4236
|
expireDueRedemptions(now: Date): Promise<number>;
|
|
@@ -3373,48 +4275,208 @@ interface PromoRevenueDeductionAggregator {
|
|
|
3373
4275
|
sumGrossForPromoCode(promoCodeId: string): Promise<string>;
|
|
3374
4276
|
}
|
|
3375
4277
|
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
/**
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
* `findActiveByTenantId` the same way, and a status added here must not reach
|
|
3386
|
-
* only whichever of them somebody remembered.
|
|
3387
|
-
*/
|
|
4278
|
+
/** The adapter that gave an answer, recorded beside the answer. */
|
|
4279
|
+
interface TaxAdapterIdentity {
|
|
4280
|
+
/** The adapter's package name, such as `@saasicat/tax-de`. */
|
|
4281
|
+
name: string;
|
|
4282
|
+
/** The adapter's version as published, such as `1.0.0`. */
|
|
4283
|
+
version: string;
|
|
4284
|
+
}
|
|
4285
|
+
/** The kinds of tax treatment every adapter shares, in the order they are named. */
|
|
4286
|
+
declare const TAX_TREATMENT_KINDS: readonly ["standard", "reduced", "exempt", "reverse-charge", "not-taxable", "small-business"];
|
|
3388
4287
|
/**
|
|
3389
|
-
*
|
|
4288
|
+
* What a tax treatment is, in the words every adapter shares.
|
|
3390
4289
|
*
|
|
3391
|
-
*
|
|
3392
|
-
*
|
|
3393
|
-
*
|
|
3394
|
-
*
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
4290
|
+
* - `standard` and `reduced`: the issuer's country taxes the charge at a rate.
|
|
4291
|
+
* - `exempt`: the charge is exempt in the issuer's country.
|
|
4292
|
+
* - `reverse-charge`: the subscriber, a business in another country, owes the
|
|
4293
|
+
* tax instead of the issuer.
|
|
4294
|
+
* - `not-taxable`: the charge is not taxable in the issuer's country at all,
|
|
4295
|
+
* such as a service to a business outside the European Union.
|
|
4296
|
+
* - `small-business`: the issuer charges no tax under a small business scheme.
|
|
4297
|
+
*/
|
|
4298
|
+
type TaxTreatmentKind = (typeof TAX_TREATMENT_KINDS)[number];
|
|
4299
|
+
/** The treatment an adapter decided, as a contract and an invoice record it. */
|
|
4300
|
+
interface TaxTreatment {
|
|
4301
|
+
kind: TaxTreatmentKind;
|
|
4302
|
+
/** The rate in percent, such as `19`; `0` for every kind that charges no tax. */
|
|
4303
|
+
rate: number;
|
|
4304
|
+
/**
|
|
4305
|
+
* The sentence the document has to carry for this treatment, such as the
|
|
4306
|
+
* reference to the reverse charge; `null` where the law asks for none.
|
|
4307
|
+
*/
|
|
4308
|
+
note: string | null;
|
|
4309
|
+
/** Who decided it. */
|
|
4310
|
+
adapter: TaxAdapterIdentity;
|
|
4311
|
+
}
|
|
4312
|
+
/**
|
|
4313
|
+
* Where a subscriber stands for tax purposes, as its record stands: what an
|
|
4314
|
+
* adapter decides a treatment from.
|
|
4315
|
+
*/
|
|
4316
|
+
interface SubscriberTaxOrigin {
|
|
4317
|
+
/** The country of the billing address, ISO 3166-1 alpha-2; `null` while unknown. */
|
|
4318
|
+
country: string | null;
|
|
3408
4319
|
/**
|
|
3409
|
-
*
|
|
3410
|
-
*
|
|
3411
|
-
*
|
|
3412
|
-
* contract, and are refused where they do not add up.
|
|
4320
|
+
* Whether the subscriber is a business, as sign-up or the operator recorded
|
|
4321
|
+
* it; `null` while nobody has said. Never derived from a tax identifier: a
|
|
4322
|
+
* business outside the European Union may have none.
|
|
3413
4323
|
*/
|
|
3414
|
-
|
|
3415
|
-
/**
|
|
3416
|
-
|
|
3417
|
-
|
|
4324
|
+
business: boolean | null;
|
|
4325
|
+
/** The VAT identification number as entered, validated or not. */
|
|
4326
|
+
vatId: string | null;
|
|
4327
|
+
/**
|
|
4328
|
+
* The same number, only when its latest completed check found it valid;
|
|
4329
|
+
* otherwise `null`. An adapter decides as though a subscriber whose number
|
|
4330
|
+
* is not validated had none (`SC-PRIC-040`).
|
|
4331
|
+
*/
|
|
4332
|
+
validatedVatId: string | null;
|
|
4333
|
+
}
|
|
4334
|
+
/** The issuer as an adapter needs it: the operator, as `config/saas.yaml` names it. */
|
|
4335
|
+
interface TaxIssuer {
|
|
4336
|
+
/** ISO 3166-1 alpha-2; `null` where the configuration names none. */
|
|
4337
|
+
country: string | null;
|
|
4338
|
+
vatId: string | null;
|
|
4339
|
+
}
|
|
4340
|
+
/** What an adapter decides a treatment for. */
|
|
4341
|
+
interface TaxDecisionRequest {
|
|
4342
|
+
issuer: TaxIssuer;
|
|
4343
|
+
origin: SubscriberTaxOrigin;
|
|
4344
|
+
/**
|
|
4345
|
+
* The period the charge covers, as a charge records it: from `from` up to
|
|
4346
|
+
* `until`, which is the first moment after it. A rate that changed in
|
|
4347
|
+
* between is the adapter's to see.
|
|
4348
|
+
*/
|
|
4349
|
+
period: {
|
|
4350
|
+
from: Date;
|
|
4351
|
+
until: Date;
|
|
4352
|
+
};
|
|
4353
|
+
/**
|
|
4354
|
+
* The installation's time zone, an IANA name such as `Europe/Berlin`: the
|
|
4355
|
+
* calendar in which the days of the period count (`SC-PRIC-045`).
|
|
4356
|
+
*/
|
|
4357
|
+
timeZone: string;
|
|
4358
|
+
}
|
|
4359
|
+
/**
|
|
4360
|
+
* An adapter's answer: a treatment, or a sentence saying the case is not
|
|
4361
|
+
* supported. An unsupported case is refused before a contract exists rather
|
|
4362
|
+
* than invoiced with a guessed tax (`SC-PRIC-039`).
|
|
4363
|
+
*/
|
|
4364
|
+
type TaxDecision = {
|
|
4365
|
+
supported: true;
|
|
4366
|
+
treatment: TaxTreatment;
|
|
4367
|
+
} | {
|
|
4368
|
+
supported: false;
|
|
4369
|
+
reason: string;
|
|
4370
|
+
};
|
|
4371
|
+
/**
|
|
4372
|
+
* A completed check of a VAT identification number, with its date and what
|
|
4373
|
+
* the service returned (`SC-PRIC-040`). Every check is recorded for the
|
|
4374
|
+
* subscriber and never rewritten: a reverse charge rests on the confirmation
|
|
4375
|
+
* that held when the invoice was issued, and neither a later check nor a
|
|
4376
|
+
* corrected number may take it away.
|
|
4377
|
+
*/
|
|
4378
|
+
interface VatIdCheck {
|
|
4379
|
+
/** The number checked, exactly as it was stored when the check ran. */
|
|
4380
|
+
vatId: string;
|
|
4381
|
+
/**
|
|
4382
|
+
* When the service's answer was received, by the platform's clock, to the
|
|
4383
|
+
* millisecond. `keepsVatIdCheck` makes the check with the latest one count,
|
|
4384
|
+
* so a date of day precision — such as the request date VIES returns —
|
|
4385
|
+
* would make two checks of one day tie, and a date in the future would hold
|
|
4386
|
+
* back every check after it. Such a date belongs in `confirmation`.
|
|
4387
|
+
*/
|
|
4388
|
+
checkedAt: Date;
|
|
4389
|
+
/** Whether the service confirmed the number as valid. */
|
|
4390
|
+
valid: boolean;
|
|
4391
|
+
/** The service that answered, such as `VIES`. */
|
|
4392
|
+
service: string;
|
|
4393
|
+
/**
|
|
4394
|
+
* What the service returned as its confirmation — a request identifier, the
|
|
4395
|
+
* name and address it holds for the number — as text, as the service sent it.
|
|
4396
|
+
*/
|
|
4397
|
+
confirmation: Record<string, string>;
|
|
4398
|
+
}
|
|
4399
|
+
/**
|
|
4400
|
+
* How a check ended. A check that could not complete, such as while the
|
|
4401
|
+
* service is unavailable, is not a result: it leaves the number unvalidated
|
|
4402
|
+
* and is never read as valid.
|
|
4403
|
+
*/
|
|
4404
|
+
type VatIdCheckOutcome = {
|
|
4405
|
+
completed: true;
|
|
4406
|
+
check: VatIdCheck;
|
|
4407
|
+
} | {
|
|
4408
|
+
completed: false;
|
|
4409
|
+
reason: string;
|
|
4410
|
+
};
|
|
4411
|
+
/**
|
|
4412
|
+
* How an application binds a tax adapter, the way it binds a payment gateway:
|
|
4413
|
+
* the adapter's name, which `config/saas.yaml#tax.adapter` names, and how to
|
|
4414
|
+
* build it from the options the file gives it. The options come from the file,
|
|
4415
|
+
* so the factory checks them and throws for one the adapter cannot take.
|
|
4416
|
+
*/
|
|
4417
|
+
interface TaxAdapterFactory {
|
|
4418
|
+
/** The adapter's package name, such as `@saasicat/tax-de`. */
|
|
4419
|
+
readonly adapterName: string;
|
|
4420
|
+
create(options: Readonly<Record<string, unknown>>): TaxAdapter;
|
|
4421
|
+
}
|
|
4422
|
+
/**
|
|
4423
|
+
* The tax adapter of an installation: a package for the country of its issuer,
|
|
4424
|
+
* named in `config/saas.yaml`. An adapter is a template, not tax advice; its
|
|
4425
|
+
* documentation says what it decides and on which basis.
|
|
4426
|
+
*/
|
|
4427
|
+
interface TaxAdapter extends TaxAdapterIdentity {
|
|
4428
|
+
/** The treatment of a charge, or why the case is not supported. Decides only; writes nothing. */
|
|
4429
|
+
decide(request: TaxDecisionRequest): TaxDecision;
|
|
4430
|
+
/**
|
|
4431
|
+
* Checks a VAT identification number with the service the adapter names.
|
|
4432
|
+
* Resolves to an outcome whatever the service does: an error, a timeout and
|
|
4433
|
+
* an answer the adapter cannot read are each a check that did not complete.
|
|
4434
|
+
*/
|
|
4435
|
+
checkVatId(vatId: string, issuer: TaxIssuer): Promise<VatIdCheckOutcome>;
|
|
4436
|
+
}
|
|
4437
|
+
|
|
4438
|
+
type ContractLineItemKind = 'plan' | 'bundle' | 'discount';
|
|
4439
|
+
type SubscriptionContractStatus = 'active' | 'scheduled' | 'terminated' | 'superseded';
|
|
4440
|
+
/**
|
|
4441
|
+
* The statuses a contract is looked up under when asking "what is this tenant
|
|
4442
|
+
* on right now" — `scheduled` included, because a contract that starts today
|
|
4443
|
+
* and has not been switched to `active` yet is still the one in force at its
|
|
4444
|
+
* own `effectiveFrom`.
|
|
4445
|
+
*
|
|
4446
|
+
* One list rather than one per adapter: the two adapters have to answer
|
|
4447
|
+
* `findActiveByTenantId` the same way, and a status added here must not reach
|
|
4448
|
+
* only whichever of them somebody remembered.
|
|
4449
|
+
*/
|
|
4450
|
+
/**
|
|
4451
|
+
* How many bundle versions one price lookup may name.
|
|
4452
|
+
*
|
|
4453
|
+
* One number rather than two: the server validates against it and the client
|
|
4454
|
+
* batches to stay inside it, and a client that learned the cap by receiving a
|
|
4455
|
+
* 400 would fail silently — the lookup answers with an empty map, and every
|
|
4456
|
+
* card falls back to a catalogue price the tenant may not be charged.
|
|
4457
|
+
*/
|
|
4458
|
+
declare const BUNDLE_PRICE_LOOKUP_LIMIT = 200;
|
|
4459
|
+
declare const ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES: readonly SubscriptionContractStatus[];
|
|
4460
|
+
interface ContractLineItemRecord {
|
|
4461
|
+
id: string;
|
|
4462
|
+
contractId: string;
|
|
4463
|
+
kind: ContractLineItemKind;
|
|
4464
|
+
sourceKey: string;
|
|
4465
|
+
sourceVersionId: string | null;
|
|
4466
|
+
titleSnapshot: string;
|
|
4467
|
+
descriptionSnapshot: string | null;
|
|
4468
|
+
quantity: number;
|
|
4469
|
+
unit: string | null;
|
|
4470
|
+
/**
|
|
4471
|
+
* What the line costs over one of its billing periods, `quantity` already
|
|
4472
|
+
* in it — not a unit price. A contract's totals take its lines as they
|
|
4473
|
+
* stand, each counted as often as it falls due in one period of the
|
|
4474
|
+
* contract, and are refused where they do not add up.
|
|
4475
|
+
*/
|
|
4476
|
+
priceNet: number;
|
|
4477
|
+
/** `priceNet` with the line's share of the tax its rhythm owes. */
|
|
4478
|
+
priceGross: number;
|
|
4479
|
+
billingCycle: 'monthly' | 'yearly';
|
|
3418
4480
|
/**
|
|
3419
4481
|
* ISO 4217, as the line was booked in.
|
|
3420
4482
|
*
|
|
@@ -3488,6 +4550,14 @@ interface SubscriptionContractRecord extends SubscriptionContractParties {
|
|
|
3488
4550
|
* never presented as what was agreed.
|
|
3489
4551
|
*/
|
|
3490
4552
|
partiesMigrated: boolean;
|
|
4553
|
+
/**
|
|
4554
|
+
* The tax treatment the installation's tax adapter decided when the
|
|
4555
|
+
* contract was concluded, with the adapter's name and version
|
|
4556
|
+
* (`SC-PRIC-038`). `null` for a contract concluded without an adapter,
|
|
4557
|
+
* before one existed, or by a path that does not ask one yet; each invoice
|
|
4558
|
+
* then takes the adapter's answer when it is issued.
|
|
4559
|
+
*/
|
|
4560
|
+
taxTreatment: TaxTreatment | null;
|
|
3491
4561
|
status: SubscriptionContractStatus;
|
|
3492
4562
|
effectiveFrom: Date;
|
|
3493
4563
|
effectiveUntil: Date | null;
|
|
@@ -3534,8 +4604,19 @@ interface NewSubscriptionContractData extends CreateSubscriptionContractData {
|
|
|
3534
4604
|
* means `false`.
|
|
3535
4605
|
*/
|
|
3536
4606
|
partiesMigrated?: boolean;
|
|
4607
|
+
/**
|
|
4608
|
+
* The treatment the platform had the tax adapter decide, recorded as it
|
|
4609
|
+
* was answered and never rewritten. Absent means `null`.
|
|
4610
|
+
*/
|
|
4611
|
+
taxTreatment?: TaxTreatment | null;
|
|
3537
4612
|
}
|
|
3538
4613
|
interface TerminateSubscriptionContractData {
|
|
4614
|
+
/**
|
|
4615
|
+
* The tenant the caller read the contract under. The write matches it as
|
|
4616
|
+
* well as the id, so an id that reaches the call by mistake cannot end
|
|
4617
|
+
* another tenant's contract, whether or not a row policy would stop it.
|
|
4618
|
+
*/
|
|
4619
|
+
tenantId: string;
|
|
3539
4620
|
effectiveUntil: Date;
|
|
3540
4621
|
/**
|
|
3541
4622
|
* The terminal status, or `null` to end the contract by date alone.
|
|
@@ -3557,6 +4638,12 @@ interface TerminateSubscriptionContractData {
|
|
|
3557
4638
|
* it is still as the caller read it.
|
|
3558
4639
|
*/
|
|
3559
4640
|
interface SupersedeSubscriptionContractData {
|
|
4641
|
+
/**
|
|
4642
|
+
* The tenant the caller read the contract under. The write matches it as
|
|
4643
|
+
* well as the id, so an id that reaches the call by mistake cannot end
|
|
4644
|
+
* another tenant's contract, whether or not a row policy would stop it.
|
|
4645
|
+
*/
|
|
4646
|
+
tenantId: string;
|
|
3560
4647
|
/** When the successor takes over; written as the contract's `effectiveUntil`. */
|
|
3561
4648
|
at: Date;
|
|
3562
4649
|
/**
|
|
@@ -3630,16 +4717,115 @@ interface SubscriberContact extends PartyAddress {
|
|
|
3630
4717
|
/** Where invoices will be sent. */
|
|
3631
4718
|
invoiceEmail: string | null;
|
|
3632
4719
|
}
|
|
4720
|
+
/**
|
|
4721
|
+
* Whether the subscriber is a business: part of its tax origin beside the
|
|
4722
|
+
* country and the VAT identification number (ADR 0013).
|
|
4723
|
+
*/
|
|
4724
|
+
interface SubscriberTaxStatus {
|
|
4725
|
+
/**
|
|
4726
|
+
* As sign-up or the operator recorded it; `null` while nobody has said.
|
|
4727
|
+
* Never derived from a tax identifier: a business outside the European
|
|
4728
|
+
* Union may have none, and is still a business.
|
|
4729
|
+
*/
|
|
4730
|
+
business: boolean | null;
|
|
4731
|
+
}
|
|
4732
|
+
/**
|
|
4733
|
+
* The address an invoice names. Sign-up asks for every one of them, and once
|
|
4734
|
+
* given they can be changed but not cleared: without them nothing can be
|
|
4735
|
+
* invoiced (`SC-PRIC-032`).
|
|
4736
|
+
*/
|
|
4737
|
+
declare const SUBSCRIBER_INVOICE_ADDRESS_FIELDS: readonly ["addressLine1", "postalCode", "city", "country"];
|
|
4738
|
+
type SubscriberInvoiceAddressField = (typeof SUBSCRIBER_INVOICE_ADDRESS_FIELDS)[number];
|
|
4739
|
+
/**
|
|
4740
|
+
* Whether a subscriber can be given its next contract where a tax adapter
|
|
4741
|
+
* decides (`SC-PRIC-032`, `SC-PRIC-039`): which fields of the address an
|
|
4742
|
+
* invoice names are empty, and the adapter's sentence where it supports no
|
|
4743
|
+
* treatment for the subscriber as it stands. Computed when it is read, from the
|
|
4744
|
+
* record and the adapter as they are then.
|
|
4745
|
+
*/
|
|
4746
|
+
interface SubscriberReadiness {
|
|
4747
|
+
ready: boolean;
|
|
4748
|
+
missing: SubscriberInvoiceAddressField[];
|
|
4749
|
+
/** The adapter's sentence, or `null` where it treats the subscriber. */
|
|
4750
|
+
taxRefusal: string | null;
|
|
4751
|
+
}
|
|
4752
|
+
/**
|
|
4753
|
+
* A tenant's subscriber as the operator sees it beside the tenant: who the
|
|
4754
|
+
* contracts are concluded with, what a tax adapter decides from, and — where
|
|
4755
|
+
* one decides — what holds its next contract back (`SC-PRIC-070`).
|
|
4756
|
+
*/
|
|
4757
|
+
interface AdminTenantSubscriber {
|
|
4758
|
+
subscriber: {
|
|
4759
|
+
id: string;
|
|
4760
|
+
customerNumber: string;
|
|
4761
|
+
legalName: string;
|
|
4762
|
+
addressLine1: string | null;
|
|
4763
|
+
addressLine2: string | null;
|
|
4764
|
+
postalCode: string | null;
|
|
4765
|
+
city: string | null;
|
|
4766
|
+
country: string | null;
|
|
4767
|
+
business: boolean | null;
|
|
4768
|
+
vatId: string | null;
|
|
4769
|
+
/** Whether the check that counts for the VAT id found it valid. */
|
|
4770
|
+
vatIdValidated: boolean;
|
|
4771
|
+
taxNumber: string | null;
|
|
4772
|
+
/** Created from the application's own tenant record, not from what a customer entered. */
|
|
4773
|
+
migrated: boolean;
|
|
4774
|
+
} | null;
|
|
4775
|
+
/** `null` where no tax adapter decides, or the tenant has no subscriber. */
|
|
4776
|
+
readiness: SubscriberReadiness | null;
|
|
4777
|
+
}
|
|
4778
|
+
/**
|
|
4779
|
+
* The manifest capability that announces the operator's view of a tenant's
|
|
4780
|
+
* subscriber. The platform sets it where it serves the view.
|
|
4781
|
+
*/
|
|
4782
|
+
declare const SUBSCRIBER_STANDING_CAPABILITY = "subscribers.read";
|
|
4783
|
+
/**
|
|
4784
|
+
* The manifest capability that says a tax adapter decides, so a subscriber can
|
|
4785
|
+
* be held back from its next contract: the operator's lists ask which only
|
|
4786
|
+
* where it is set, and are spared the question everywhere else.
|
|
4787
|
+
*/
|
|
4788
|
+
declare const SUBSCRIBER_ATTENTION_CAPABILITY = "subscribers.attention";
|
|
4789
|
+
/**
|
|
4790
|
+
* How many tenants one question about attention may name: a page of a list,
|
|
4791
|
+
* not the whole of it. A list longer than this asks in pages.
|
|
4792
|
+
*/
|
|
4793
|
+
declare const SUBSCRIBER_ATTENTION_PAGE_SIZE = 200;
|
|
4794
|
+
/**
|
|
4795
|
+
* The manifest capability that announces the operator's corrections of a
|
|
4796
|
+
* subscriber — its legal identity, its business status, a check of its VAT
|
|
4797
|
+
* identification number — beside the subscriber's view.
|
|
4798
|
+
*/
|
|
4799
|
+
declare const SUBSCRIBER_CORRECTION_CAPABILITY = "subscribers.correct";
|
|
4800
|
+
/** A tenant whose subscriber cannot be given its next contract, and why. */
|
|
4801
|
+
interface AdminSubscriberAttention {
|
|
4802
|
+
tenantId: string;
|
|
4803
|
+
readiness: SubscriberReadiness;
|
|
4804
|
+
}
|
|
4805
|
+
/** A live subscriber with the check of its VAT id that counts now. */
|
|
4806
|
+
interface SubscriberWithCurrentCheck {
|
|
4807
|
+
subscriber: SubscriberRecord;
|
|
4808
|
+
currentVatIdCheck: SubscriberVatIdCheckRecord | null;
|
|
4809
|
+
}
|
|
3633
4810
|
/** A subscriber's master data, as it stands. */
|
|
3634
|
-
type SubscriberDetails = LegalIdentity & SubscriberContact;
|
|
4811
|
+
type SubscriberDetails = LegalIdentity & SubscriberContact & SubscriberTaxStatus;
|
|
3635
4812
|
/**
|
|
3636
4813
|
* What a subscriber is created with.
|
|
3637
4814
|
*
|
|
3638
|
-
* Only the legal name is required. The address, the tax identifiers
|
|
3639
|
-
* invoice email stay optional until sign-up asks for
|
|
3640
|
-
* requires them; an absent or blank value is recorded as
|
|
4815
|
+
* Only the legal name is required. The address, the tax identifiers, the
|
|
4816
|
+
* business status and the invoice email stay optional until sign-up asks for
|
|
4817
|
+
* them and invoicing requires them; an absent or blank value is recorded as
|
|
4818
|
+
* unknown.
|
|
3641
4819
|
*/
|
|
3642
|
-
type NewSubscriberDetails = Pick<SubscriberDetails, 'legalName'> & Partial<Omit<SubscriberDetails, 'legalName'
|
|
4820
|
+
type NewSubscriberDetails = Pick<SubscriberDetails, 'legalName'> & Partial<Omit<SubscriberDetails, 'legalName'>> & {
|
|
4821
|
+
/**
|
|
4822
|
+
* A check of `vatId` made before the subscriber existed — in a
|
|
4823
|
+
* sign-up's step 4, or by `SubscriberService.assessNewSubscriber` —
|
|
4824
|
+
* recorded with it when it is created, so its first contract is
|
|
4825
|
+
* decided from it. A check of another number is refused.
|
|
4826
|
+
*/
|
|
4827
|
+
vatIdCheck?: VatIdCheck | null;
|
|
4828
|
+
};
|
|
3643
4829
|
interface SubscriberRecord extends SubscriberDetails {
|
|
3644
4830
|
id: string;
|
|
3645
4831
|
/**
|
|
@@ -3693,13 +4879,15 @@ interface SubscriberIdentityDelta {
|
|
|
3693
4879
|
previous: SubscriberIdentityValues;
|
|
3694
4880
|
corrected: SubscriberIdentityValues;
|
|
3695
4881
|
}
|
|
3696
|
-
/**
|
|
4882
|
+
/**
|
|
4883
|
+
* What a repository writes for a correction the service has accepted. The
|
|
4884
|
+
* repository dates it, while it holds the subscriber's row lock.
|
|
4885
|
+
*/
|
|
3697
4886
|
interface SubscriberCorrectionData {
|
|
3698
4887
|
/** The new values; a field equal to what is stored is not recorded. */
|
|
3699
4888
|
corrected: SubscriberIdentityValues;
|
|
3700
4889
|
reason: string;
|
|
3701
4890
|
correctedBy: string;
|
|
3702
|
-
correctedAt: Date;
|
|
3703
4891
|
}
|
|
3704
4892
|
/** One correction of a subscriber's legal identity, as it was recorded. */
|
|
3705
4893
|
interface SubscriberCorrectionRecord {
|
|
@@ -3711,6 +4899,12 @@ interface SubscriberCorrectionRecord {
|
|
|
3711
4899
|
corrected: SubscriberIdentityValues;
|
|
3712
4900
|
reason: string;
|
|
3713
4901
|
correctedBy: string;
|
|
4902
|
+
/**
|
|
4903
|
+
* When the write that made it held the subscriber's row lock, by the
|
|
4904
|
+
* platform's clock. The list is in the order the database numbered the
|
|
4905
|
+
* writes; on one clock these dates follow that order, while two instances
|
|
4906
|
+
* whose clocks differ may date neighbouring corrections out of it.
|
|
4907
|
+
*/
|
|
3714
4908
|
correctedAt: Date;
|
|
3715
4909
|
}
|
|
3716
4910
|
/** The outcome of writing a correction: nothing is recorded when no value moved. */
|
|
@@ -3718,11 +4912,147 @@ interface SubscriberCorrectionResult {
|
|
|
3718
4912
|
subscriber: SubscriberRecord;
|
|
3719
4913
|
correction: SubscriberCorrectionRecord | null;
|
|
3720
4914
|
}
|
|
4915
|
+
/**
|
|
4916
|
+
* The details a subscriber's tax origin consists of, and whose change is
|
|
4917
|
+
* recorded with its date — in the order they are named and shown.
|
|
4918
|
+
*/
|
|
4919
|
+
declare const SUBSCRIBER_TAX_ORIGIN_FIELDS: readonly ["country", "business", "vatId"];
|
|
4920
|
+
type SubscriberTaxOriginField = (typeof SUBSCRIBER_TAX_ORIGIN_FIELDS)[number];
|
|
4921
|
+
/** Tax origin values by field, holding only the fields a change moved. */
|
|
4922
|
+
type SubscriberTaxOriginValues = Partial<Pick<SubscriberDetails, SubscriberTaxOriginField>>;
|
|
4923
|
+
/**
|
|
4924
|
+
* One change of a subscriber's tax origin, as it was recorded: written in the
|
|
4925
|
+
* same transaction as the change, whichever way it arrived — a contact change
|
|
4926
|
+
* of the country, a correction of the VAT identification number, a change of
|
|
4927
|
+
* the business status — and never rewritten. A change applies from the
|
|
4928
|
+
* subscriber's next invoice (`SC-PRIC-043`).
|
|
4929
|
+
*/
|
|
4930
|
+
interface SubscriberTaxOriginChangeRecord {
|
|
4931
|
+
id: string;
|
|
4932
|
+
subscriberId: string;
|
|
4933
|
+
/** The values the change replaced. */
|
|
4934
|
+
previous: SubscriberTaxOriginValues;
|
|
4935
|
+
/** The values it wrote. */
|
|
4936
|
+
changed: SubscriberTaxOriginValues;
|
|
4937
|
+
/** Who changed it, as an actor tag the audit log would write. */
|
|
4938
|
+
changedBy: string;
|
|
4939
|
+
/**
|
|
4940
|
+
* When the write that made it held the subscriber's row lock, by the
|
|
4941
|
+
* platform's clock. The list is in the order the database numbered the
|
|
4942
|
+
* writes; on one clock these dates follow that order, while two instances
|
|
4943
|
+
* whose clocks differ may date neighbouring changes out of it.
|
|
4944
|
+
*/
|
|
4945
|
+
changedAt: Date;
|
|
4946
|
+
/**
|
|
4947
|
+
* Why it was changed: the reason of the correction or of the change of
|
|
4948
|
+
* business status that made it; `null` for a change of the country, which
|
|
4949
|
+
* comes with the contact details and states none.
|
|
4950
|
+
*/
|
|
4951
|
+
reason: string | null;
|
|
4952
|
+
}
|
|
4953
|
+
/** What a repository writes for a change of the business status the service has accepted. */
|
|
4954
|
+
interface SubscriberBusinessStatusData {
|
|
4955
|
+
business: boolean | null;
|
|
4956
|
+
/** Who changes it, as an actor tag the audit log would write. */
|
|
4957
|
+
changedBy: string;
|
|
4958
|
+
/** Why, in the operator's words: whether it is a business decides the tax treatment. */
|
|
4959
|
+
reason: string;
|
|
4960
|
+
}
|
|
4961
|
+
/** The outcome of writing a business status: nothing is recorded when it does not move. */
|
|
4962
|
+
interface SubscriberBusinessStatusResult {
|
|
4963
|
+
subscriber: SubscriberRecord;
|
|
4964
|
+
change: SubscriberTaxOriginChangeRecord | null;
|
|
4965
|
+
}
|
|
4966
|
+
/**
|
|
4967
|
+
* One completed check of a subscriber's VAT identification number, as it was
|
|
4968
|
+
* recorded: never rewritten, whether it counts now or not.
|
|
4969
|
+
*/
|
|
4970
|
+
interface SubscriberVatIdCheckRecord extends VatIdCheck {
|
|
4971
|
+
id: string;
|
|
4972
|
+
subscriberId: string;
|
|
4973
|
+
/** When the check was recorded, by the platform's clock. */
|
|
4974
|
+
recordedAt: Date;
|
|
4975
|
+
}
|
|
4976
|
+
/** The outcome of recording a check: the check as recorded, and the one that counts now. */
|
|
4977
|
+
interface RecordedVatIdCheck {
|
|
4978
|
+
recorded: SubscriberVatIdCheckRecord;
|
|
4979
|
+
/**
|
|
4980
|
+
* The check that counts for the subscriber's number from now on: the one
|
|
4981
|
+
* just recorded, one recorded earlier that completed later, or none — a
|
|
4982
|
+
* check of a number the subscriber no longer has counts for nothing.
|
|
4983
|
+
*/
|
|
4984
|
+
current: SubscriberVatIdCheckRecord | null;
|
|
4985
|
+
}
|
|
4986
|
+
/**
|
|
4987
|
+
* What became of a check of a subscriber's VAT identification number: the
|
|
4988
|
+
* check as it was recorded, and whether it counts for the number held — or why
|
|
4989
|
+
* it did not complete, in which case nothing was recorded and the number stays
|
|
4990
|
+
* as validated as it was (`SC-PRIC-040`).
|
|
4991
|
+
*/
|
|
4992
|
+
type SubscriberVatIdCheckResult = {
|
|
4993
|
+
completed: true;
|
|
4994
|
+
check: SubscriberVatIdCheckRecord;
|
|
4995
|
+
counts: boolean;
|
|
4996
|
+
} | {
|
|
4997
|
+
completed: false;
|
|
4998
|
+
reason: string;
|
|
4999
|
+
};
|
|
5000
|
+
/** A check of a subscriber's VAT identification number, as the operator is shown it. */
|
|
5001
|
+
type AdminVatIdCheckOutcome = {
|
|
5002
|
+
completed: true;
|
|
5003
|
+
valid: boolean;
|
|
5004
|
+
/** When the service answered, as an ISO string. */
|
|
5005
|
+
checkedAt: string;
|
|
5006
|
+
service: string;
|
|
5007
|
+
/** Whether it is the check that counts for the number held now. */
|
|
5008
|
+
counts: boolean;
|
|
5009
|
+
} | {
|
|
5010
|
+
completed: false;
|
|
5011
|
+
reason: string;
|
|
5012
|
+
};
|
|
5013
|
+
/**
|
|
5014
|
+
* The answer to an operator's correction or check: the subscriber as it now
|
|
5015
|
+
* stands, and the check a VAT identification number got, where one was made.
|
|
5016
|
+
*/
|
|
5017
|
+
interface AdminSubscriberCorrected {
|
|
5018
|
+
subscriber: AdminTenantSubscriber;
|
|
5019
|
+
vatIdCheck: AdminVatIdCheckOutcome | null;
|
|
5020
|
+
}
|
|
5021
|
+
/**
|
|
5022
|
+
* One entry of a subscriber's history as the operator reads it, the latest
|
|
5023
|
+
* first: a correction of its legal identity, a change of its country or
|
|
5024
|
+
* business status, or a check of its VAT identification number. Dates are ISO
|
|
5025
|
+
* strings.
|
|
5026
|
+
*/
|
|
5027
|
+
type AdminSubscriberHistoryEntry = {
|
|
5028
|
+
kind: 'identity-corrected';
|
|
5029
|
+
at: string;
|
|
5030
|
+
by: string;
|
|
5031
|
+
previous: SubscriberIdentityValues;
|
|
5032
|
+
corrected: SubscriberIdentityValues;
|
|
5033
|
+
reason: string;
|
|
5034
|
+
} | {
|
|
5035
|
+
kind: 'tax-origin-changed';
|
|
5036
|
+
at: string;
|
|
5037
|
+
by: string;
|
|
5038
|
+
previous: SubscriberTaxOriginValues;
|
|
5039
|
+
changed: SubscriberTaxOriginValues;
|
|
5040
|
+
/** `null` for a change of the country with the contact details. */
|
|
5041
|
+
reason: string | null;
|
|
5042
|
+
} | {
|
|
5043
|
+
kind: 'vat-id-checked';
|
|
5044
|
+
at: string;
|
|
5045
|
+
vatId: string;
|
|
5046
|
+
valid: boolean;
|
|
5047
|
+
service: string;
|
|
5048
|
+
/** Whether it is the check that counts for the number held now. */
|
|
5049
|
+
counts: boolean;
|
|
5050
|
+
};
|
|
3721
5051
|
|
|
3722
5052
|
/**
|
|
3723
|
-
* What made the charge arise. activation: the first period of a subscription. renewal: a later period. planChange: what an immediate plan change adds. bundleBooking: the first, short period of an add-on. credit: a decision that reduces what is owed. correction: a counter-entry reversing an earlier charge, which is how the append-only journal answers a mistake.
|
|
5053
|
+
* What made the charge arise. activation: the first period of a subscription. renewal: a later period. planChange: what an immediate plan change adds. bundleBooking: the first, short period of an add-on. bundleChange: what an add-on's switch to a dearer version adds for the rest of its period. credit: a decision that reduces what is owed. correction: a counter-entry reversing an earlier charge, which is how the append-only journal answers a mistake.
|
|
3724
5054
|
*/
|
|
3725
|
-
type SubscriberChargeOrigin = 'activation' | 'renewal' | 'planChange' | 'bundleBooking' | 'credit' | 'correction';
|
|
5055
|
+
type SubscriberChargeOrigin = 'activation' | 'renewal' | 'planChange' | 'bundleBooking' | 'bundleChange' | 'credit' | 'correction';
|
|
3726
5056
|
/**
|
|
3727
5057
|
* Which kind of contract line the charge realises.
|
|
3728
5058
|
*/
|
|
@@ -3854,10 +5184,7 @@ interface SubscriptionRecord {
|
|
|
3854
5184
|
trialEntitlementPlan?: string | null;
|
|
3855
5185
|
pendingPlan?: string | null;
|
|
3856
5186
|
pendingEffectiveAt?: Date | null;
|
|
3857
|
-
customLimits?:
|
|
3858
|
-
quotas?: Record<string, number>;
|
|
3859
|
-
features?: string[];
|
|
3860
|
-
} | null;
|
|
5187
|
+
customLimits?: CustomLimits | null;
|
|
3861
5188
|
planVersionId: string;
|
|
3862
5189
|
planVersion: PlanVersionRecord;
|
|
3863
5190
|
/**
|
|
@@ -3901,7 +5228,8 @@ interface SubscriptionRepository {
|
|
|
3901
5228
|
findByTenantIdLocked(tenantId: string, tx: TransactionContext): Promise<SubscriptionRecord | null>;
|
|
3902
5229
|
/**
|
|
3903
5230
|
* Counts subscriptions that bind a specific PlanVersion — both
|
|
3904
|
-
* via the active `planVersionId` and via the scheduled
|
|
5231
|
+
* via the active `planVersionId` and via the version a scheduled change will
|
|
5232
|
+
* bind (`pendingChangeVersionId`).
|
|
3905
5233
|
* Needed by the `PlanVersionsService` for the editability decision:
|
|
3906
5234
|
* a published-but-future PlanVersion stays correctable only as long
|
|
3907
5235
|
* as no booking references it.
|
|
@@ -3911,6 +5239,14 @@ interface SubscriptionRepository {
|
|
|
3911
5239
|
* frozen (fail-closed). Implementation hint: count in a single
|
|
3912
5240
|
* COUNT(*) over the subscription table with an OR over the two
|
|
3913
5241
|
* FK columns — not in two separate queries, to avoid race conditions.
|
|
5242
|
+
*
|
|
5243
|
+
* Counts across every tenant. The platform calls it inside
|
|
5244
|
+
* `RlsBypassPort`; an implementation on a tenant-scoped client has to see
|
|
5245
|
+
* every tenant's rows there. Whether the frame lifts the policy for this
|
|
5246
|
+
* query is up to the application's bypass and the database layer behind it
|
|
5247
|
+
* — one that lifts only reads such as `find*` leaves a `count` filtered, and
|
|
5248
|
+
* then the implementation lifts the policy itself. A subscriber hidden from
|
|
5249
|
+
* the count counts as nobody, which opens the version for editing.
|
|
3914
5250
|
*/
|
|
3915
5251
|
countByPlanVersionId?(planVersionId: string): Promise<number>;
|
|
3916
5252
|
/**
|
|
@@ -3930,6 +5266,9 @@ interface SubscriptionRepository {
|
|
|
3930
5266
|
*
|
|
3931
5267
|
* Optional — if not implemented, the service defensively treats the
|
|
3932
5268
|
* version as frozen (fail-closed).
|
|
5269
|
+
*
|
|
5270
|
+
* Counts across every tenant, inside `RlsBypassPort`, and has to see every
|
|
5271
|
+
* tenant's rows there, as `countByPlanVersionId` does.
|
|
3933
5272
|
*/
|
|
3934
5273
|
countByBundleVersionId?(bundleVersionId: string): Promise<number>;
|
|
3935
5274
|
/**
|
|
@@ -3940,8 +5279,9 @@ interface SubscriptionRepository {
|
|
|
3940
5279
|
* (subscriptions on superseded versions are included).
|
|
3941
5280
|
*
|
|
3942
5281
|
* Returns a map `planKey → count`; plans without an active subscription
|
|
3943
|
-
* are missing (UI defaults to 0). Platform-wide count across all tenants
|
|
3944
|
-
*
|
|
5282
|
+
* are missing (UI defaults to 0). Platform-wide count across all tenants:
|
|
5283
|
+
* the platform calls it inside `RlsBypassPort`, and an implementation has to
|
|
5284
|
+
* see every tenant's rows there, as for `countByPlanVersionId`.
|
|
3945
5285
|
*
|
|
3946
5286
|
* Optional — if not implemented, the tenant column stays 0.
|
|
3947
5287
|
*/
|
|
@@ -3988,6 +5328,59 @@ interface SubscriptionBundleRepository {
|
|
|
3988
5328
|
* implementations to avoid drift.
|
|
3989
5329
|
*/
|
|
3990
5330
|
countActiveByBundleVersionId(bundleVersionId: string, asOf?: Date): Promise<number>;
|
|
5331
|
+
/**
|
|
5332
|
+
* Every booking of the add-on version `bundleVersionId`, in every tenant,
|
|
5333
|
+
* whatever its state. The platform reads it to find the bookings an add-on
|
|
5334
|
+
* retirement reaches, inside the RLS bypass, and decides itself which of
|
|
5335
|
+
* them are still running.
|
|
5336
|
+
*
|
|
5337
|
+
* Optional, so a repository written before it keeps working; retiring an
|
|
5338
|
+
* add-on version over one without it is refused at start-up.
|
|
5339
|
+
*/
|
|
5340
|
+
listOfVersion?(bundleVersionId: string): Promise<SubscriptionBundleRecord[]>;
|
|
5341
|
+
/**
|
|
5342
|
+
* Moves the booking `subscriptionBundleId` from the add-on version `from`
|
|
5343
|
+
* onto `to` and answers it as it now stands, or null where it is not on
|
|
5344
|
+
* `from` any more, or gone. Nothing else changes: its period, its terms,
|
|
5345
|
+
* its rhythm and its cancellation stay as they are. Conditional on `from`,
|
|
5346
|
+
* so a move and the put-back of a move that could not write its contract
|
|
5347
|
+
* never write over each other, nor two runs over one booking.
|
|
5348
|
+
*
|
|
5349
|
+
* An add-on retirement moves a booking at its date, and a subscriber by
|
|
5350
|
+
* taking a newer version offered (`SC-BUN-058`). Optional, so a repository
|
|
5351
|
+
* written before it keeps working; retiring an add-on version over one
|
|
5352
|
+
* without it is refused at start-up, and no newer version is offered.
|
|
5353
|
+
*/
|
|
5354
|
+
moveToVersion?(subscriptionBundleId: string, from: string, to: string): Promise<SubscriptionBundleRecord | null>;
|
|
5355
|
+
/**
|
|
5356
|
+
* Schedules the booking `subscriptionBundleId` to continue on the add-on
|
|
5357
|
+
* version `to` from `effectiveAt` — `pendingBundleVersionId` and
|
|
5358
|
+
* `pendingVersionEffectiveAt` — and answers it as it now stands, or null
|
|
5359
|
+
* where it is not on `from` any more, already has a switch scheduled, or is
|
|
5360
|
+
* gone. Nothing else changes, its version included: the switch is made at
|
|
5361
|
+
* that moment by the run (`listScheduledVersionsDue`).
|
|
5362
|
+
*
|
|
5363
|
+
* Optional, and so are the two methods after it: without all three, a
|
|
5364
|
+
* newer version that takes something away is not offered.
|
|
5365
|
+
*/
|
|
5366
|
+
scheduleVersion?(subscriptionBundleId: string, switchTo: {
|
|
5367
|
+
from: string;
|
|
5368
|
+
to: string;
|
|
5369
|
+
effectiveAt: Date;
|
|
5370
|
+
}): Promise<SubscriptionBundleRecord | null>;
|
|
5371
|
+
/**
|
|
5372
|
+
* Clears the switch scheduled for the booking `subscriptionBundleId`, and
|
|
5373
|
+
* answers it as it now stands; null where no switch to `to` is scheduled
|
|
5374
|
+
* any more, or it is gone. Its version stays as it is.
|
|
5375
|
+
*/
|
|
5376
|
+
unscheduleVersion?(subscriptionBundleId: string, to: string): Promise<SubscriptionBundleRecord | null>;
|
|
5377
|
+
/**
|
|
5378
|
+
* Every booking, in every tenant and whatever its state, with a switch
|
|
5379
|
+
* scheduled to take effect at or before `asOf` — oldest first. The
|
|
5380
|
+
* platform reads it inside the RLS bypass and decides itself which of
|
|
5381
|
+
* them still move.
|
|
5382
|
+
*/
|
|
5383
|
+
listScheduledVersionsDue?(asOf: Date): Promise<SubscriptionBundleRecord[]>;
|
|
3991
5384
|
}
|
|
3992
5385
|
/**
|
|
3993
5386
|
* Append-only repository for V3 SubscriptionContracts. Contracts are the
|
|
@@ -4055,8 +5448,8 @@ interface SubscriptionContractRepository {
|
|
|
4055
5448
|
*
|
|
4056
5449
|
* Platform-wide: unlike every other read here it is anchored by no tenant,
|
|
4057
5450
|
* no contract and no offer, and a start makes it before anything is served.
|
|
4058
|
-
* An implementation on a tenant-scoped client
|
|
4059
|
-
* `countActiveByPlanKey`
|
|
5451
|
+
* An implementation on a tenant-scoped client counts inside the bypass
|
|
5452
|
+
* frame, as `countActiveByPlanKey` does — the platform wraps the call in
|
|
4060
5453
|
* `RlsBypassPort`, and one that answers with the caller's tenant scope
|
|
4061
5454
|
* instead returns nothing at a boot, where there is no tenant. The
|
|
4062
5455
|
* persistence contract runs with no policy forced, so it cannot catch that
|
|
@@ -4090,19 +5483,66 @@ interface SubscriberRepository {
|
|
|
4090
5483
|
findById(subscriberId: string, tx?: TransactionContext): Promise<SubscriberRecord | null>;
|
|
4091
5484
|
/** The subscriber live for this tenant, or `null` when it has none. */
|
|
4092
5485
|
findByTenantId(tenantId: string, tx?: TransactionContext): Promise<SubscriberRecord | null>;
|
|
4093
|
-
/**
|
|
4094
|
-
|
|
5486
|
+
/**
|
|
5487
|
+
* Writes the members given and keeps the rest; `null` when no such
|
|
5488
|
+
* subscriber exists. Read and written under the lock a correction takes. A
|
|
5489
|
+
* change of the country is a change of the tax origin and is recorded as
|
|
5490
|
+
* one in the same step, by `changedBy` and dated while the lock is held.
|
|
5491
|
+
*/
|
|
5492
|
+
updateContact(subscriberId: string, change: SubscriberContactChange, changedBy: string, tx?: TransactionContext): Promise<SubscriberRecord | null>;
|
|
4095
5493
|
/**
|
|
4096
5494
|
* Writes a correction of the legal identity and records it, in one step:
|
|
4097
5495
|
* the subscriber is read and changed under a lock, so the values recorded
|
|
4098
5496
|
* as replaced are the ones this write replaced even when two corrections
|
|
4099
|
-
* arrive at once.
|
|
4100
|
-
*
|
|
4101
|
-
*
|
|
5497
|
+
* arrive at once. The correction is dated while the lock is held and
|
|
5498
|
+
* numbered by the database as it is written. A field whose stored value
|
|
5499
|
+
* already equals the corrected one is left out of the record, and when none
|
|
5500
|
+
* differs nothing is written and `correction` is `null`. `null` when no
|
|
5501
|
+
* such subscriber exists.
|
|
5502
|
+
*
|
|
5503
|
+
* A corrected VAT identification number is a change of the tax origin and
|
|
5504
|
+
* is recorded as one too, by the same actor and with the same date.
|
|
5505
|
+
* The check that counted for the number it replaced counts no more — it
|
|
5506
|
+
* would otherwise validate that number again should it come back — and
|
|
5507
|
+
* stays recorded (`listVatIdChecks`); the number written is held from that
|
|
5508
|
+
* date (`vatIdSince`), so no check completed before it counts for it.
|
|
4102
5509
|
*/
|
|
4103
5510
|
correctIdentity(subscriberId: string, data: SubscriberCorrectionData, tx?: TransactionContext): Promise<SubscriberCorrectionResult | null>;
|
|
4104
|
-
/** Every correction of this subscriber, the latest first. */
|
|
5511
|
+
/** Every correction of this subscriber, the latest written first. */
|
|
4105
5512
|
listCorrections(subscriberId: string): Promise<SubscriberCorrectionRecord[]>;
|
|
5513
|
+
/**
|
|
5514
|
+
* Writes whether the subscriber is a business and records the change of
|
|
5515
|
+
* its tax origin, in one step and under the same lock as a correction,
|
|
5516
|
+
* dated while the lock is held. When the stored status already equals the
|
|
5517
|
+
* one given nothing is written and `change` is `null`. `null` when no such
|
|
5518
|
+
* subscriber exists.
|
|
5519
|
+
*/
|
|
5520
|
+
changeBusinessStatus(subscriberId: string, data: SubscriberBusinessStatusData, tx?: TransactionContext): Promise<SubscriberBusinessStatusResult | null>;
|
|
5521
|
+
/**
|
|
5522
|
+
* Records a completed check of the subscriber's VAT identification number.
|
|
5523
|
+
* Every check is recorded and none is rewritten or removed: it is the
|
|
5524
|
+
* evidence a reverse charge rests on. Under the lock a correction takes it
|
|
5525
|
+
* then decides whether the check counts from now on — only for the number
|
|
5526
|
+
* the subscriber holds, completed since it holds it, and never over a check
|
|
5527
|
+
* that completed later (`keepsVatIdCheck` from `@saasicat/core` decides).
|
|
5528
|
+
* `null` when no such subscriber exists.
|
|
5529
|
+
*/
|
|
5530
|
+
recordVatIdCheck(subscriberId: string, check: VatIdCheck, tx?: TransactionContext): Promise<RecordedVatIdCheck | null>;
|
|
5531
|
+
/**
|
|
5532
|
+
* The check that counts for the subscriber's number now, or `null` while
|
|
5533
|
+
* none does: never checked, or corrected since.
|
|
5534
|
+
*/
|
|
5535
|
+
findCurrentVatIdCheck(subscriberId: string, tx?: TransactionContext): Promise<SubscriberVatIdCheckRecord | null>;
|
|
5536
|
+
/** Every check recorded for this subscriber, counting or not, the latest checked first. */
|
|
5537
|
+
listVatIdChecks(subscriberId: string): Promise<SubscriberVatIdCheckRecord[]>;
|
|
5538
|
+
/**
|
|
5539
|
+
* The live subscribers of these tenants, each with the check of its VAT id
|
|
5540
|
+
* that counts now, in at most a few reads — what the operator's lists mark
|
|
5541
|
+
* a subscriber from. A tenant without a live subscriber is left out.
|
|
5542
|
+
*/
|
|
5543
|
+
listForTenants(tenantIds: readonly string[], tx?: TransactionContext): Promise<SubscriberWithCurrentCheck[]>;
|
|
5544
|
+
/** Every recorded change of this subscriber's tax origin, the latest written first. */
|
|
5545
|
+
listTaxOriginChanges(subscriberId: string): Promise<SubscriberTaxOriginChangeRecord[]>;
|
|
4106
5546
|
}
|
|
4107
5547
|
/**
|
|
4108
5548
|
* The subscriber's account: the charges that became due, one per contract line
|
|
@@ -4133,7 +5573,7 @@ interface SubscriberLedgerRepository {
|
|
|
4133
5573
|
*
|
|
4134
5574
|
* The platform controller `GET /billing/usage` maps this form 1:1 into the
|
|
4135
5575
|
* response body. The consumer adapter loads from its own subscription
|
|
4136
|
-
* table (Prisma include planVersion
|
|
5576
|
+
* table (Prisma include planVersion).
|
|
4137
5577
|
*/
|
|
4138
5578
|
interface SubscriptionUsageRecord {
|
|
4139
5579
|
/**
|
|
@@ -4192,6 +5632,17 @@ interface SubscriptionUsageRecord {
|
|
|
4192
5632
|
pendingPlan: string | null;
|
|
4193
5633
|
pendingBillingCycle: string | null;
|
|
4194
5634
|
pendingEffectiveAt: Date | null;
|
|
5635
|
+
/**
|
|
5636
|
+
* The version a scheduled change binds when it lands, where it names one —
|
|
5637
|
+
* a newer version taken for the end of the term, or the version a change
|
|
5638
|
+
* to another plan was quoted at. Read where it matters whether the
|
|
5639
|
+
* subscription stays on its version: a change on the same plan in the same
|
|
5640
|
+
* rhythm is otherwise indistinguishable from staying put.
|
|
5641
|
+
*
|
|
5642
|
+
* Optional, because an adapter written before it does not pass it through;
|
|
5643
|
+
* both shipped adapters do.
|
|
5644
|
+
*/
|
|
5645
|
+
pendingChangeVersionId?: string | null;
|
|
4195
5646
|
planVersion: {
|
|
4196
5647
|
id: string;
|
|
4197
5648
|
planId: string;
|
|
@@ -4200,18 +5651,6 @@ interface SubscriptionUsageRecord {
|
|
|
4200
5651
|
supersededAt: Date | null;
|
|
4201
5652
|
changeNote: string | null;
|
|
4202
5653
|
};
|
|
4203
|
-
pendingPlanVersion: {
|
|
4204
|
-
id: string;
|
|
4205
|
-
planId: string;
|
|
4206
|
-
version: number;
|
|
4207
|
-
nonRegressive: boolean;
|
|
4208
|
-
changeNote: string | null;
|
|
4209
|
-
/** Catalog diff form from version-publish; free-form JSON structure. */
|
|
4210
|
-
publishedChanges: unknown;
|
|
4211
|
-
} | null;
|
|
4212
|
-
pendingPlanVersionEffectiveAt: Date | null;
|
|
4213
|
-
pendingPlanVersionAccepted: boolean;
|
|
4214
|
-
pendingPlanVersionAcceptedAt: Date | null;
|
|
4215
5654
|
/**
|
|
4216
5655
|
* P11.4: frozen package snapshot from the
|
|
4217
5656
|
* `CheckoutOffer` that was activated during onboarding. Read-only —
|
|
@@ -4232,8 +5671,44 @@ interface SubscriptionUsageRecord {
|
|
|
4232
5671
|
* Read adapter for the UI/display form of a subscription. Used by
|
|
4233
5672
|
* `TenantBillingController.getUsage`.
|
|
4234
5673
|
*/
|
|
5674
|
+
/** A subscription read across tenants, with the tenant it belongs to. */
|
|
5675
|
+
interface TenantSubscriptionUsage {
|
|
5676
|
+
readonly tenantId: string;
|
|
5677
|
+
readonly subscription: SubscriptionUsageRecord & {
|
|
5678
|
+
readonly id: string;
|
|
5679
|
+
};
|
|
5680
|
+
}
|
|
4235
5681
|
interface SubscriptionUsagePort {
|
|
4236
5682
|
findForTenant(tenantId: string): Promise<SubscriptionUsageRecord | null>;
|
|
5683
|
+
/**
|
|
5684
|
+
* Every subscription of `planKey`, in every tenant, bound to a version of
|
|
5685
|
+
* that plan numbered below `version`. The platform reads it to find the
|
|
5686
|
+
* subscriptions a newer version is offered to, inside the RLS bypass.
|
|
5687
|
+
*
|
|
5688
|
+
* Optional, so a port written before it keeps working; an application that
|
|
5689
|
+
* turns version notices on over a port without it is refused at start-up.
|
|
5690
|
+
*/
|
|
5691
|
+
listBoundToEarlierVersions?(planKey: string, version: number): Promise<TenantSubscriptionUsage[]>;
|
|
5692
|
+
/**
|
|
5693
|
+
* Every subscription, in every tenant, bound to the plan version
|
|
5694
|
+
* `planVersionId`, whatever its status. The platform reads it to find the
|
|
5695
|
+
* subscriptions a retirement reaches, inside the RLS bypass, and decides
|
|
5696
|
+
* itself which of them are still running.
|
|
5697
|
+
*
|
|
5698
|
+
* Optional, so a port written before it keeps working; a retirement over a
|
|
5699
|
+
* port without it is refused at start-up.
|
|
5700
|
+
*/
|
|
5701
|
+
listBoundToVersion?(planVersionId: string): Promise<TenantSubscriptionUsage[]>;
|
|
5702
|
+
/**
|
|
5703
|
+
* The subscriptions `subscriptionIds`, in whichever tenant, each with the
|
|
5704
|
+
* tenant it belongs to; an id that names none is left out. The platform
|
|
5705
|
+
* reads it inside the RLS bypass to find the subscription of each booking
|
|
5706
|
+
* an add-on retirement reaches.
|
|
5707
|
+
*
|
|
5708
|
+
* Optional, so a port written before it keeps working; retiring an add-on
|
|
5709
|
+
* version over a port without it is refused at start-up.
|
|
5710
|
+
*/
|
|
5711
|
+
listByIds?(subscriptionIds: readonly string[]): Promise<TenantSubscriptionUsage[]>;
|
|
4237
5712
|
}
|
|
4238
5713
|
/**
|
|
4239
5714
|
* Returns the current usage for all quotaKeys of a tenant declared via
|
|
@@ -4279,14 +5754,98 @@ interface ImmediatePlanChangeInput {
|
|
|
4279
5754
|
* no cancellation, and loses against one that has acquired one.
|
|
4280
5755
|
*/
|
|
4281
5756
|
expectedCanceledAt: Date | null;
|
|
5757
|
+
/**
|
|
5758
|
+
* Whether a change that leaves the plan as it is keeps the plan version
|
|
5759
|
+
* the subscription is bound to.
|
|
5760
|
+
*
|
|
5761
|
+
* A scheduled change that only moves the rhythm passes `true`: the
|
|
5762
|
+
* subscriber agreed to the version they are on, and moving them to a newer
|
|
5763
|
+
* one is theirs to decide, by taking it when it is offered. A sale passes
|
|
5764
|
+
* `false` — a change of plan, or onboarding, where the customer chose at
|
|
5765
|
+
* the version in effect — and the write binds the version of `planId` in effect at
|
|
5766
|
+
* `periodStart`. Where `planId` is another plan than the one bound, the
|
|
5767
|
+
* version in effect is bound either way, and so it is where the
|
|
5768
|
+
* subscription is bound to no version at all: it has none to keep.
|
|
5769
|
+
*/
|
|
5770
|
+
keepsBoundVersion: boolean;
|
|
5771
|
+
/**
|
|
5772
|
+
* The version of `planId` the change was quoted at: a scheduled change to
|
|
5773
|
+
* another plan passes the version its preview showed when it was
|
|
5774
|
+
* scheduled, recorded as `pendingChangeVersionId`. The write binds it
|
|
5775
|
+
* rather than the version in effect, so a version published in between
|
|
5776
|
+
* does not reach the customer by a change they already agreed to. `null`
|
|
5777
|
+
* binds the version in effect — a sale, onboarding, and a change quoted
|
|
5778
|
+
* where no repository reads versions. A version kept by
|
|
5779
|
+
* `keepsBoundVersion` wins over it.
|
|
5780
|
+
*/
|
|
5781
|
+
quotedPlanVersionId: string | null;
|
|
5782
|
+
/**
|
|
5783
|
+
* `true`: bind `quotedPlanVersionId` or nothing. Where that version no
|
|
5784
|
+
* longer takes bookings by `periodStart` (or now), the write claims nothing
|
|
5785
|
+
* and answers `claimed: false`, rather than binding the version in effect.
|
|
5786
|
+
* A switch to a version offered passes it: the subscriber agreed to that
|
|
5787
|
+
* version, and what the switch answers and records names it. Left out, a
|
|
5788
|
+
* version that stopped taking bookings gives way to the one in effect.
|
|
5789
|
+
*/
|
|
5790
|
+
quotedVersionOnly?: boolean;
|
|
5791
|
+
/**
|
|
5792
|
+
* The version the caller read the subscription bound to, where its
|
|
5793
|
+
* decision rests on it: the write claims the row only while that binding
|
|
5794
|
+
* still holds. A switch to a version offered passes it — it writes back the
|
|
5795
|
+
* plan it read, and a change made in between would otherwise be undone.
|
|
5796
|
+
* `null` claims a row bound to no version. Left out, the binding is not
|
|
5797
|
+
* claimed — and a write that binds no version (`bindsPlanVersion: false`)
|
|
5798
|
+
* has none to claim.
|
|
5799
|
+
*/
|
|
5800
|
+
expectedPlanVersionId?: string | null;
|
|
5801
|
+
/**
|
|
5802
|
+
* `true`: the change the subscription has scheduled survives the write. A
|
|
5803
|
+
* retirement's move passes it — the change is the subscriber's own, and the
|
|
5804
|
+
* move is not. One that only moves the rhythm on the plan being left follows
|
|
5805
|
+
* the subscription to `planId` (`scheduledChangeAfterWrite`). The write then
|
|
5806
|
+
* claims the row only while the scheduled change is still the one it read.
|
|
5807
|
+
* Left out, the write clears it: a change the subscriber makes replaces the
|
|
5808
|
+
* one they scheduled before.
|
|
5809
|
+
*/
|
|
5810
|
+
keepsPendingChange?: boolean;
|
|
5811
|
+
/**
|
|
5812
|
+
* `true`: the write puts back a binding the subscription held a moment
|
|
5813
|
+
* before, so `quotedPlanVersionId` counts whether or not it still takes
|
|
5814
|
+
* bookings — it has to be a version of `planId`, nothing more. A
|
|
5815
|
+
* retirement's move or switch passes it to bind the subscription back to
|
|
5816
|
+
* the version retired, where the contract that has to come with the move
|
|
5817
|
+
* could not be written: that version is off sale, often by its own end, and
|
|
5818
|
+
* undoing a move is not a booking (`SC-PLAN-016` asks only of one). Left
|
|
5819
|
+
* out, a version that no longer takes bookings is not bound.
|
|
5820
|
+
*/
|
|
5821
|
+
restoresQuotedVersion?: boolean;
|
|
4282
5822
|
}
|
|
4283
5823
|
/** Input for `schedulePlanChange` (change at period end). */
|
|
4284
5824
|
interface ScheduledPlanChangeInput {
|
|
4285
5825
|
pendingPlan: string;
|
|
4286
5826
|
pendingBillingCycle: string;
|
|
4287
5827
|
pendingEffectiveAt: Date;
|
|
5828
|
+
/**
|
|
5829
|
+
* The version of `pendingPlan` the preview quoted, where the change does
|
|
5830
|
+
* not keep the version bound — a change to another plan, or one on a
|
|
5831
|
+
* subscription bound to none; stored as `pendingChangeVersionId` and bound
|
|
5832
|
+
* when the change comes due. `null` where the plan stays on a bound
|
|
5833
|
+
* version — the version bound then is kept, whatever it is by that day — or
|
|
5834
|
+
* where no repository reads versions.
|
|
5835
|
+
*/
|
|
5836
|
+
pendingChangeVersionId: string | null;
|
|
4288
5837
|
/** See `ImmediatePlanChangeInput.expectedCanceledAt`. */
|
|
4289
5838
|
expectedCanceledAt: Date | null;
|
|
5839
|
+
/** See `ImmediatePlanChangeInput.expectedPlanVersionId`. */
|
|
5840
|
+
expectedPlanVersionId?: string | null;
|
|
5841
|
+
/**
|
|
5842
|
+
* The change the caller read as scheduled, where its decision rests on it —
|
|
5843
|
+
* `null` for nothing scheduled. The write claims the row only while that
|
|
5844
|
+
* still holds. A switch to a version offered passes `null`: an offer is
|
|
5845
|
+
* made only while nothing is scheduled, and a change scheduled in between
|
|
5846
|
+
* would otherwise be written over. Left out, it is not claimed.
|
|
5847
|
+
*/
|
|
5848
|
+
expectedPendingPlan?: string | null;
|
|
4290
5849
|
}
|
|
4291
5850
|
/**
|
|
4292
5851
|
* Input for `applyOnboardingSelection`. Plan-change fields that the
|
|
@@ -4381,24 +5940,17 @@ interface TenantSubscriptionWritePort {
|
|
|
4381
5940
|
changePlanImmediate(tenantId: string, input: ImmediatePlanChangeInput): Promise<{
|
|
4382
5941
|
plan: string;
|
|
4383
5942
|
billingCycle: string;
|
|
4384
|
-
/**
|
|
5943
|
+
/**
|
|
5944
|
+
* False when what the caller claimed moved since it read it — the
|
|
5945
|
+
* cancellation, and the binding where it passed one — or when the
|
|
5946
|
+
* version it required no longer takes bookings.
|
|
5947
|
+
*/
|
|
4385
5948
|
claimed: boolean;
|
|
4386
5949
|
}>;
|
|
4387
5950
|
/** Change at period end: set pending fields. */
|
|
4388
5951
|
schedulePlanChange(tenantId: string, input: ScheduledPlanChangeInput): Promise<{
|
|
4389
5952
|
claimed: boolean;
|
|
4390
5953
|
}>;
|
|
4391
|
-
/**
|
|
4392
|
-
* Marks the pending PlanVersion as accepted. Idempotent — a duplicate
|
|
4393
|
-
* accept is a no-op. Returns `alreadyAccepted: true` if the status was
|
|
4394
|
-
* already set.
|
|
4395
|
-
*/
|
|
4396
|
-
acceptPendingPlanVersion(tenantId: string, userId: string, now: Date): Promise<{
|
|
4397
|
-
accepted: boolean;
|
|
4398
|
-
acceptedAt: Date | null;
|
|
4399
|
-
effectiveAt: Date | null;
|
|
4400
|
-
alreadyAccepted: boolean;
|
|
4401
|
-
}>;
|
|
4402
5954
|
/**
|
|
4403
5955
|
* Record a cancellation. The dates are decided above this port.
|
|
4404
5956
|
*
|
|
@@ -4440,30 +5992,22 @@ interface TenantSubscriptionWritePort {
|
|
|
4440
5992
|
/** Read adapter for PlanVersions. */
|
|
4441
5993
|
interface PlanVersionRepository {
|
|
4442
5994
|
/**
|
|
4443
|
-
*
|
|
4444
|
-
*
|
|
4445
|
-
* transaction.
|
|
4446
|
-
*
|
|
4447
|
-
* Note: ignores `validFrom`/`validUntil`. For time-aware
|
|
4448
|
-
* resolution (onboarding, plan fallback for TRIAL) use `findActive`.
|
|
4449
|
-
*
|
|
4450
|
-
* A plan key no plan has finds `null`, not an error.
|
|
4451
|
-
*/
|
|
4452
|
-
findLatestLive(planId: string, tx?: TransactionContext): Promise<PlanVersionRecord | null>;
|
|
4453
|
-
/**
|
|
4454
|
-
* PlanVersion of a plan active at `asOf`:
|
|
5995
|
+
* The version of a plan on sale at `asOf` — what a booking made then
|
|
5996
|
+
* binds — by the same rule as `PlanRepository.findActivePlanVersion`:
|
|
4455
5997
|
* `publishedAt IS NOT NULL`
|
|
4456
5998
|
* `(validFrom IS NULL OR validFrom <= asOf)`
|
|
4457
5999
|
* `(validUntil IS NULL OR validUntil >= startOfUtcDay(asOf))`
|
|
6000
|
+
* `(endsAt IS NULL OR endsAt > asOf)`
|
|
4458
6001
|
*
|
|
4459
6002
|
* `validUntil` is day-inclusive. If multiple versions match, adapters
|
|
4460
|
-
* return the highest `validFrom`,
|
|
4461
|
-
*
|
|
4462
|
-
*
|
|
6003
|
+
* return the highest `validFrom`, ordering null start dates last, then the
|
|
6004
|
+
* highest version. Adapters build the WHERE with
|
|
6005
|
+
* `buildActivePlanVersionWhere(asOf, { withEndsAt: true })`. Optionally
|
|
6006
|
+
* within a transaction.
|
|
4463
6007
|
*
|
|
4464
6008
|
* A plan key no plan has finds `null`, not an error.
|
|
4465
6009
|
*/
|
|
4466
|
-
findActive
|
|
6010
|
+
findActive(planId: string, asOf?: Date, tx?: TransactionContext): Promise<PlanVersionRecord | null>;
|
|
4467
6011
|
}
|
|
4468
6012
|
|
|
4469
6013
|
/** Aggregate snapshot of subscriptions, orchestrated by `AdminStatsService`. */
|
|
@@ -4482,6 +6026,11 @@ interface SubscriptionStatsSnapshot {
|
|
|
4482
6026
|
/**
|
|
4483
6027
|
* Stats adapter for subscriptions. Consumers implement this based on their
|
|
4484
6028
|
* Prisma `subscription.groupBy(...)` / `count(...)` calls.
|
|
6029
|
+
*
|
|
6030
|
+
* The figures span every tenant: the platform reads them, together with the
|
|
6031
|
+
* promo code and audit figures, inside `RlsBypassPort`, and an implementation
|
|
6032
|
+
* has to see every tenant's rows there — as for
|
|
6033
|
+
* `SubscriptionRepository.countByPlanVersionId`.
|
|
4485
6034
|
*/
|
|
4486
6035
|
interface SubscriptionStatsPort {
|
|
4487
6036
|
getStats(): Promise<SubscriptionStatsSnapshot>;
|
|
@@ -4528,6 +6077,19 @@ interface AdminActor {
|
|
|
4528
6077
|
source: 'web' | 'cli';
|
|
4529
6078
|
context: string;
|
|
4530
6079
|
}
|
|
6080
|
+
/**
|
|
6081
|
+
* A platform job acting on its own schedule — no person behind it, so no user:
|
|
6082
|
+
* the canonical `audit_logs.userId` is nullable for exactly this. `context`
|
|
6083
|
+
* names the job, and the actor tag reads `job:platform:<job>`.
|
|
6084
|
+
*/
|
|
6085
|
+
interface PlatformJobActor {
|
|
6086
|
+
userId: null;
|
|
6087
|
+
email: 'platform';
|
|
6088
|
+
source: 'job';
|
|
6089
|
+
context: string;
|
|
6090
|
+
}
|
|
6091
|
+
/** Whoever an audit entry names: a person, from the web or the CLI, or a platform job. */
|
|
6092
|
+
type AuditActor = AdminActor | PlatformJobActor;
|
|
4531
6093
|
/**
|
|
4532
6094
|
* Audit adapter: platform services write to the audit log through this
|
|
4533
6095
|
* interface. The consumer implementation persists the records (e.g.
|
|
@@ -4539,7 +6101,7 @@ interface AdminActor {
|
|
|
4539
6101
|
*/
|
|
4540
6102
|
interface AuditPort {
|
|
4541
6103
|
write(input: {
|
|
4542
|
-
actor:
|
|
6104
|
+
actor: AuditActor;
|
|
4543
6105
|
entity: string;
|
|
4544
6106
|
entityId: string;
|
|
4545
6107
|
action: string;
|
|
@@ -4620,7 +6182,9 @@ interface AdminUserListRow {
|
|
|
4620
6182
|
}
|
|
4621
6183
|
interface AdminSubscriptionListRow {
|
|
4622
6184
|
id: string;
|
|
6185
|
+
/** The tenant by its id too: what the operator's lists ask a subscriber's standing by. */
|
|
4623
6186
|
tenant: {
|
|
6187
|
+
id: string;
|
|
4624
6188
|
slug: string;
|
|
4625
6189
|
name: string;
|
|
4626
6190
|
};
|
|
@@ -4682,6 +6246,14 @@ interface ManifestAccessPort {
|
|
|
4682
6246
|
* good at boot as it is in a request.
|
|
4683
6247
|
*/
|
|
4684
6248
|
interface RlsBypassPort {
|
|
6249
|
+
/**
|
|
6250
|
+
* Runs `fn` with the policy lifted. Where the installation keeps more than
|
|
6251
|
+
* the flag in the frame — the user, the tenant, an audit actor — the bypass
|
|
6252
|
+
* frame carries it over rather than replacing it: an operator's route runs
|
|
6253
|
+
* inside it, and what the request's own frame held is still read there.
|
|
6254
|
+
* `store.run({ ...store.getStore(), bypassRls: true }, fn)` rather than
|
|
6255
|
+
* `store.run({ bypassRls: true }, fn)`.
|
|
6256
|
+
*/
|
|
4685
6257
|
runWithBypass<T>(fn: () => Promise<T>): Promise<T>;
|
|
4686
6258
|
}
|
|
4687
6259
|
|
|
@@ -4742,37 +6314,41 @@ interface PlanRepository {
|
|
|
4742
6314
|
findVersionById?(versionId: string): Promise<PlanVersionRow | null>;
|
|
4743
6315
|
findCurrentDraft?(planKey: string): Promise<PlanVersionRow | null>;
|
|
4744
6316
|
/**
|
|
4745
|
-
*
|
|
6317
|
+
* The newest published version of a plan:
|
|
4746
6318
|
* `publishedAt IS NOT NULL AND supersededAt IS NULL`.
|
|
4747
6319
|
*
|
|
4748
|
-
*
|
|
4749
|
-
*
|
|
4750
|
-
*
|
|
4751
|
-
*
|
|
4752
|
-
* the version *active at a point in time*.
|
|
6320
|
+
* The version a publish chains to, not the version on sale: a successor
|
|
6321
|
+
* published today with a start next month is the newest at once, and its
|
|
6322
|
+
* predecessor goes on selling until then. What is on sale — for a booking,
|
|
6323
|
+
* a price, a catalogue, an offer — is `findActivePlanVersion`.
|
|
4753
6324
|
*/
|
|
4754
6325
|
findLatestLivePlanVersion?(planKey: string, tx?: TransactionContext): Promise<PlanVersionRow | null>;
|
|
4755
6326
|
/**
|
|
4756
|
-
*
|
|
6327
|
+
* The version of a plan on sale at `asOf` — the one a booking made then
|
|
6328
|
+
* binds:
|
|
4757
6329
|
* `publishedAt IS NOT NULL`
|
|
4758
6330
|
* `(validFrom IS NULL OR validFrom <= asOf)`
|
|
4759
6331
|
* `(validUntil IS NULL OR validUntil >= startOfUtcDay(asOf))` — day-inclusive
|
|
6332
|
+
* `(endsAt IS NULL OR endsAt > asOf)`
|
|
4760
6333
|
*
|
|
4761
|
-
* `validFrom IS NULL` is treated like "valid since forever" so that
|
|
4762
|
-
* without a start date
|
|
4763
|
-
*
|
|
4764
|
-
*
|
|
4765
|
-
* Adapters build the WHERE via
|
|
6334
|
+
* `validFrom IS NULL` is treated like "valid since forever" so that a
|
|
6335
|
+
* version published without a start date does not fall out of the
|
|
6336
|
+
* catalogue. `validUntil` is day-inclusive (calendar day): the version is
|
|
6337
|
+
* valid until the end of its validUntil day, not just until midnight.
|
|
6338
|
+
* Adapters build the WHERE via
|
|
6339
|
+
* `buildActivePlanVersionWhere(asOf, { withEndsAt: true })`.
|
|
4766
6340
|
*
|
|
4767
6341
|
* If multiple match: the one with the highest `validFrom` (= the
|
|
4768
|
-
* "last active"). Adapters must request
|
|
4769
|
-
* null start date remains a genuine fallback.
|
|
4770
|
-
* time.
|
|
6342
|
+
* "last active"), then the highest version. Adapters must request
|
|
6343
|
+
* `NULLS LAST` explicitly so a null start date remains a genuine fallback.
|
|
6344
|
+
* Default `asOf` is the call time.
|
|
4771
6345
|
*
|
|
4772
|
-
*
|
|
4773
|
-
*
|
|
4774
|
-
*
|
|
4775
|
-
*
|
|
6346
|
+
* Every read of what is on sale goes through this — the catalogue, the
|
|
6347
|
+
* plan-change preview, checkout, the public marketing catalogue, every
|
|
6348
|
+
* booking and the offer to existing subscriptions — so all of them name
|
|
6349
|
+
* the same version at the same moment. Existing subscriptions stay on
|
|
6350
|
+
* their bound `planVersionId`. A repository that reads versions and
|
|
6351
|
+
* leaves this out is refused at start-up.
|
|
4776
6352
|
*/
|
|
4777
6353
|
findActivePlanVersion?(planKey: string, asOf?: Date, tx?: TransactionContext): Promise<PlanVersionRow | null>;
|
|
4778
6354
|
/**
|
|
@@ -4870,27 +6446,30 @@ interface BundleRepository {
|
|
|
4870
6446
|
findVersionById(versionId: string, tx?: TransactionContext): Promise<BundleVersionRow | null>;
|
|
4871
6447
|
findCurrentDraft(bundleId: string): Promise<BundleVersionRow | null>;
|
|
4872
6448
|
/**
|
|
4873
|
-
*
|
|
6449
|
+
* The newest published BundleVersion of a bundle:
|
|
4874
6450
|
* `publishedAt IS NOT NULL AND supersededAt IS NULL`.
|
|
4875
6451
|
*
|
|
4876
|
-
*
|
|
4877
|
-
*
|
|
6452
|
+
* The version a publish chains to, not the version on sale: a successor
|
|
6453
|
+
* published today with a start next month is the newest at once, and its
|
|
6454
|
+
* predecessor goes on selling until then. What is on sale — for a booking,
|
|
6455
|
+
* a catalogue, an upsell — is `findActiveBundleVersion`.
|
|
4878
6456
|
*/
|
|
4879
6457
|
findLatestLive(bundleId: string, tx?: TransactionContext): Promise<BundleVersionRow | null>;
|
|
4880
6458
|
/**
|
|
4881
|
-
* BundleVersion
|
|
6459
|
+
* The BundleVersion on sale at `asOf` — the one a booking made then may
|
|
6460
|
+
* take:
|
|
4882
6461
|
* `publishedAt IS NOT NULL`
|
|
4883
6462
|
* `(validFrom IS NULL OR validFrom <= asOf)`
|
|
4884
6463
|
* `(validUntil IS NULL OR validUntil >= startOfUtcDay(asOf))`
|
|
6464
|
+
* `(supersededAt IS NULL OR validUntil IS NOT NULL)`
|
|
4885
6465
|
*
|
|
4886
|
-
* Both boundaries are inclusive
|
|
4887
|
-
*
|
|
4888
|
-
*
|
|
4889
|
-
*
|
|
4890
|
-
*
|
|
4891
|
-
* can omit the capability and consumers can fall back explicitly.
|
|
6466
|
+
* Both boundaries are inclusive, and a superseded version sells only
|
|
6467
|
+
* within a last day it carries — the rule of `buildActiveVersionWhere`.
|
|
6468
|
+
* If multiple versions match, adapters return the highest `validFrom`,
|
|
6469
|
+
* then the highest `version`; a null `validFrom` sorts last. Default
|
|
6470
|
+
* `asOf` is the call time.
|
|
4892
6471
|
*/
|
|
4893
|
-
findActiveBundleVersion
|
|
6472
|
+
findActiveBundleVersion(bundleId: string, asOf?: Date, tx?: TransactionContext): Promise<BundleVersionRow | null>;
|
|
4894
6473
|
/**
|
|
4895
6474
|
* Creates a new draft version (`publishedAt = null`). Throws if
|
|
4896
6475
|
* a draft already exists (partial unique index violation).
|
|
@@ -5413,15 +6992,116 @@ interface MaintenanceWindowPort {
|
|
|
5413
6992
|
update(id: string, stage: MaintenanceWindowStage, changes: MaintenanceWindowChanges): Promise<MaintenanceWindowRecord | null>;
|
|
5414
6993
|
}
|
|
5415
6994
|
/**
|
|
5416
|
-
* Hears when a window is announced, moved or cancelled, so the application can
|
|
5417
|
-
* write to its users. Optional: without it tenants learn of a window from the
|
|
5418
|
-
* banner alone.
|
|
5419
|
-
*
|
|
5420
|
-
* Called after the change is recorded, and never waited on by the operator: a
|
|
5421
|
-
* notification that fails is logged, and the window stands as recorded.
|
|
6995
|
+
* Hears when a window is announced, moved or cancelled, so the application can
|
|
6996
|
+
* write to its users. Optional: without it tenants learn of a window from the
|
|
6997
|
+
* banner alone.
|
|
6998
|
+
*
|
|
6999
|
+
* Called after the change is recorded, and never waited on by the operator: a
|
|
7000
|
+
* notification that fails is logged, and the window stands as recorded.
|
|
7001
|
+
*/
|
|
7002
|
+
interface MaintenanceNotificationPort {
|
|
7003
|
+
windowChanged(event: MaintenanceWindowEvent): Promise<void>;
|
|
7004
|
+
}
|
|
7005
|
+
|
|
7006
|
+
/** A notice to record before anybody is told: its key and what it says. */
|
|
7007
|
+
interface NoticeToRecord extends SubscriptionNoticeKey {
|
|
7008
|
+
readonly content: unknown;
|
|
7009
|
+
}
|
|
7010
|
+
/**
|
|
7011
|
+
* Keeps the record of every notice sent to a subscriber: one per subscription,
|
|
7012
|
+
* kind and subject, with when and to whom it went.
|
|
7013
|
+
*
|
|
7014
|
+
* Delivery takes three writes so that a notice is sent once even where several
|
|
7015
|
+
* instances run the same job: a run claims the notice, the application sends
|
|
7016
|
+
* it, and the run confirms it — or releases it where the sending failed, for the
|
|
7017
|
+
* next run to try again. Each write is conditional on what the caller read; an
|
|
7018
|
+
* adapter translates and does not decide.
|
|
7019
|
+
*/
|
|
7020
|
+
interface SubscriptionNoticeRepository {
|
|
7021
|
+
/**
|
|
7022
|
+
* Records the notice named by `key` where it is not recorded yet, and
|
|
7023
|
+
* claims it for this run: where it is not delivered and no run holds it,
|
|
7024
|
+
* or the run that holds it took it on before `staleBefore`. A claim stores
|
|
7025
|
+
* `content` as what the notice says. Returns the notice as claimed, or null
|
|
7026
|
+
* where it is delivered or another run holds a fresh claim — of two
|
|
7027
|
+
* concurrent calls exactly one claims it.
|
|
7028
|
+
*/
|
|
7029
|
+
claim(key: SubscriptionNoticeKey, content: unknown, now: Date, staleBefore: Date): Promise<SubscriptionNoticeRecord | null>;
|
|
7030
|
+
/**
|
|
7031
|
+
* Records the notice `id` as delivered, provided it is still held by the
|
|
7032
|
+
* claim taken at `claimedAt` and not delivered. Returns false where it is
|
|
7033
|
+
* not: the claim went stale and another run took the notice on.
|
|
7034
|
+
*/
|
|
7035
|
+
confirm(id: string, claimedAt: Date, delivery: SubscriptionNoticeDelivery, now: Date): Promise<boolean>;
|
|
7036
|
+
/**
|
|
7037
|
+
* Lets go of the claim taken at `claimedAt`, so the next run tries again.
|
|
7038
|
+
* Does nothing where the notice is delivered or held by another claim.
|
|
7039
|
+
*/
|
|
7040
|
+
release(id: string, claimedAt: Date): Promise<void>;
|
|
7041
|
+
/** The subscriptions a notice of `kind` about `subject` has been delivered to. */
|
|
7042
|
+
listDeliveredSubscriptionIds(kind: SubscriptionNoticeKind, subject: string): Promise<string[]>;
|
|
7043
|
+
/** Every notice of one subscription, the most recently recorded first. */
|
|
7044
|
+
listForSubscription(subscriptionId: string): Promise<SubscriptionNoticeRecord[]>;
|
|
7045
|
+
/**
|
|
7046
|
+
* Records each notice where it is not recorded yet, unclaimed and not
|
|
7047
|
+
* delivered — in the caller's transaction where one is given, so a notice
|
|
7048
|
+
* exists exactly when what it tells of does. A notice already recorded
|
|
7049
|
+
* under the same key is left as it is and not counted: the answer is how
|
|
7050
|
+
* many were recorded now, so a caller can tell that another got there
|
|
7051
|
+
* first — under a transaction running beside it as well.
|
|
7052
|
+
*/
|
|
7053
|
+
record(notices: readonly NoticeToRecord[], now: Date, tx?: TransactionContext): Promise<number>;
|
|
7054
|
+
/** Every notice of `kind` recorded at or after `since`, the most recent first. */
|
|
7055
|
+
listOfKindSince(kind: SubscriptionNoticeKind, since: Date): Promise<SubscriptionNoticeRecord[]>;
|
|
7056
|
+
/**
|
|
7057
|
+
* The notices of `kind` that are not delivered and that no run holds — never
|
|
7058
|
+
* claimed, released, or claimed before `staleBefore` — the oldest first.
|
|
7059
|
+
*/
|
|
7060
|
+
listUndelivered(kind: SubscriptionNoticeKind, staleBefore: Date): Promise<SubscriptionNoticeRecord[]>;
|
|
7061
|
+
}
|
|
7062
|
+
/**
|
|
7063
|
+
* Sends a notice to the administrators of the tenant it is for, in the
|
|
7064
|
+
* application's words and through its channels. The platform decides when a
|
|
7065
|
+
* notice is due; who the administrators are, what the message says and how it
|
|
7066
|
+
* travels are the application's.
|
|
7067
|
+
*
|
|
7068
|
+
* Resolve with who it went to and how — the platform keeps that as the record.
|
|
7069
|
+
* Throw where it could not be sent and should be tried again: the claim is
|
|
7070
|
+
* released and the next run sends it. Resolving with no recipients records that
|
|
7071
|
+
* nobody could be told, and the notice is not tried again — except a
|
|
7072
|
+
* retirement's notice (`version-retired`, `bundle-version-retired`), which
|
|
7073
|
+
* nobody was told of: it is tried again by every run until somebody is, and its
|
|
7074
|
+
* date counts from then.
|
|
7075
|
+
*/
|
|
7076
|
+
interface SubscriptionNoticePort {
|
|
7077
|
+
deliver(notice: SubscriptionNotice): Promise<SubscriptionNoticeDelivery>;
|
|
7078
|
+
}
|
|
7079
|
+
|
|
7080
|
+
/**
|
|
7081
|
+
* Keeps every add-on retirement announcement: which version, which
|
|
7082
|
+
* replacement, when and by whom. What it means for each booking it reaches is
|
|
7083
|
+
* kept beside it as a notice of kind `bundle-version-retired`, written in the
|
|
7084
|
+
* same transaction.
|
|
7085
|
+
*/
|
|
7086
|
+
interface BundleVersionRetirementRepository {
|
|
7087
|
+
/** Records an announcement, in the caller's transaction where one is given. */
|
|
7088
|
+
create(data: NewBundleVersionRetirement, tx?: TransactionContext): Promise<BundleVersionRetirementRecord>;
|
|
7089
|
+
/** Every announcement, the most recent first. */
|
|
7090
|
+
list(): Promise<BundleVersionRetirementRecord[]>;
|
|
7091
|
+
findById(id: string): Promise<BundleVersionRetirementRecord | null>;
|
|
7092
|
+
}
|
|
7093
|
+
|
|
7094
|
+
/**
|
|
7095
|
+
* Keeps every retirement announcement: which version, which replacement, when
|
|
7096
|
+
* and by whom. What it means for each subscription it reaches is kept beside it
|
|
7097
|
+
* as a notice of kind `version-retired`, written in the same transaction.
|
|
5422
7098
|
*/
|
|
5423
|
-
interface
|
|
5424
|
-
|
|
7099
|
+
interface VersionRetirementRepository {
|
|
7100
|
+
/** Records an announcement, in the caller's transaction where one is given. */
|
|
7101
|
+
create(data: NewVersionRetirement, tx?: TransactionContext): Promise<VersionRetirementRecord>;
|
|
7102
|
+
/** Every announcement, the most recent first. */
|
|
7103
|
+
list(): Promise<VersionRetirementRecord[]>;
|
|
7104
|
+
findById(id: string): Promise<VersionRetirementRecord | null>;
|
|
5425
7105
|
}
|
|
5426
7106
|
|
|
5427
7107
|
/** Class reference usable as a DI token (e.g. the consumer's `PrismaService`). */
|
|
@@ -5461,9 +7141,11 @@ interface PersistenceCapabilities {
|
|
|
5461
7141
|
*/
|
|
5462
7142
|
pessimisticLocking: boolean;
|
|
5463
7143
|
/**
|
|
5464
|
-
* The adapter stack integrates with Postgres row-level security
|
|
5465
|
-
* `RlsBypassPort` frame
|
|
5466
|
-
*
|
|
7144
|
+
* The adapter stack integrates with Postgres row-level security: the
|
|
7145
|
+
* `RlsBypassPort` frame lifts the installation's policies for what the
|
|
7146
|
+
* platform does across tenants, reads and writes alike. Informational —
|
|
7147
|
+
* nothing in the platform reads it, and the policies themselves remain
|
|
7148
|
+
* the installation's.
|
|
5467
7149
|
*/
|
|
5468
7150
|
rowLevelSecurity: boolean;
|
|
5469
7151
|
/** Advisory-lock support (`pg_advisory_*`). No platform path requires it today. */
|
|
@@ -5471,7 +7153,12 @@ interface PersistenceCapabilities {
|
|
|
5471
7153
|
}
|
|
5472
7154
|
/** Always-required slice: admin surface + transactions. */
|
|
5473
7155
|
interface SaaSiCatPersistenceCore {
|
|
5474
|
-
|
|
7156
|
+
/**
|
|
7157
|
+
* Absent where the schema leaves the SuperAdmin MFA table out
|
|
7158
|
+
* (`notAdopted: ['SuperAdminMfa']`); the application then passes its own
|
|
7159
|
+
* `MfaPort` in `adapters`, and a start without one is refused.
|
|
7160
|
+
*/
|
|
7161
|
+
mfa?: PersistenceProvider<MfaPort>;
|
|
5475
7162
|
audit: PersistenceProvider<AuditPort>;
|
|
5476
7163
|
rlsBypass: PersistenceProvider<RlsBypassPort>;
|
|
5477
7164
|
transactionRunner: PersistenceProvider<TransactionRunner>;
|
|
@@ -5529,6 +7216,24 @@ interface SaaSiCatPersistenceTenantBilling {
|
|
|
5529
7216
|
subscriptionUsagePort: PersistenceProvider<SubscriptionUsagePort>;
|
|
5530
7217
|
subscriptionWritePort: PersistenceProvider<TenantSubscriptionWritePort>;
|
|
5531
7218
|
usageSnapshotPort?: PersistenceProvider<UsageSnapshotPort>;
|
|
7219
|
+
/**
|
|
7220
|
+
* The record of what each subscriber was told (`tenantBilling.versionNotices`).
|
|
7221
|
+
* Optional so an adapter written before it keeps working; an installation
|
|
7222
|
+
* that turns notices on without one is refused at start-up.
|
|
7223
|
+
*/
|
|
7224
|
+
subscriptionNotices?: PersistenceProvider<SubscriptionNoticeRepository>;
|
|
7225
|
+
/**
|
|
7226
|
+
* The record of every retirement announcement. Optional so an adapter
|
|
7227
|
+
* written before it keeps working; an installation that lets an operator
|
|
7228
|
+
* retire versions without one is refused at start-up.
|
|
7229
|
+
*/
|
|
7230
|
+
versionRetirements?: PersistenceProvider<VersionRetirementRepository>;
|
|
7231
|
+
/**
|
|
7232
|
+
* The record of every add-on retirement announcement. Optional so an
|
|
7233
|
+
* adapter written before it keeps working; without it, retiring an add-on
|
|
7234
|
+
* version is off, and retiring a plan version is not affected.
|
|
7235
|
+
*/
|
|
7236
|
+
bundleVersionRetirements?: PersistenceProvider<BundleVersionRetirementRepository>;
|
|
5532
7237
|
}
|
|
5533
7238
|
/**
|
|
5534
7239
|
* The record of payment gateway callbacks and the payment methods they confirm
|
|
@@ -5643,10 +7348,41 @@ declare const CATALOG_ERROR_CODES: {
|
|
|
5643
7348
|
readonly PLAN_TERMINATE_INVALID_DATE: "PLAN_TERMINATE_INVALID_DATE";
|
|
5644
7349
|
readonly PLAN_TERMINATE_DATE_NOT_FUTURE: "PLAN_TERMINATE_DATE_NOT_FUTURE";
|
|
5645
7350
|
readonly PLAN_TERMINATE_NOT_IMPLEMENTED: "PLAN_TERMINATE_NOT_IMPLEMENTED";
|
|
7351
|
+
/**
|
|
7352
|
+
* Subscriptions told of a retirement still move onto this version, and
|
|
7353
|
+
* nothing moves onto a version that has ended. Carries the version, its
|
|
7354
|
+
* plan key and the first day it may end: the day after the last move.
|
|
7355
|
+
*/
|
|
7356
|
+
readonly PLAN_TERMINATE_BEFORE_RETIREMENT_MOVES: "PLAN_TERMINATE_BEFORE_RETIREMENT_MOVES";
|
|
7357
|
+
/**
|
|
7358
|
+
* Subscriptions told of a retirement are past their date and still to be
|
|
7359
|
+
* moved onto this version — a move the platform could not make yet — so it
|
|
7360
|
+
* cannot end until they have moved. Carries how many, the version and its
|
|
7361
|
+
* plan key.
|
|
7362
|
+
*/
|
|
7363
|
+
readonly PLAN_TERMINATE_WHILE_MOVES_OVERDUE: "PLAN_TERMINATE_WHILE_MOVES_OVERDUE";
|
|
7364
|
+
/**
|
|
7365
|
+
* Subscriptions on a retired version have not yet been told of their move
|
|
7366
|
+
* onto this version — their notice has reached nobody, so their date is not
|
|
7367
|
+
* set — and it cannot end until they have been. Carries how many, the
|
|
7368
|
+
* version and its plan key.
|
|
7369
|
+
*/
|
|
7370
|
+
readonly PLAN_TERMINATE_WHILE_NOTICES_UNDELIVERED: "PLAN_TERMINATE_WHILE_NOTICES_UNDELIVERED";
|
|
5646
7371
|
readonly BUNDLE_VERSION_ALREADY_PUBLISHED: "BUNDLE_VERSION_ALREADY_PUBLISHED";
|
|
5647
7372
|
readonly BUNDLE_VERSION_NOT_EDITABLE: "BUNDLE_VERSION_NOT_EDITABLE";
|
|
5648
7373
|
readonly BUNDLE_VERSION_NOT_PUBLISHED: "BUNDLE_VERSION_NOT_PUBLISHED";
|
|
5649
7374
|
readonly BUNDLE_VERSION_SUPERSEDED: "BUNDLE_VERSION_SUPERSEDED";
|
|
7375
|
+
/**
|
|
7376
|
+
* The bundle version is published, and its window has not opened: it goes
|
|
7377
|
+
* on sale on `validFrom`, and until then its predecessor is the one sold.
|
|
7378
|
+
*/
|
|
7379
|
+
readonly BUNDLE_VERSION_NOT_YET_ON_SALE: "BUNDLE_VERSION_NOT_YET_ON_SALE";
|
|
7380
|
+
/**
|
|
7381
|
+
* The add-on itself has been deleted from the catalogue. Deleting it leaves
|
|
7382
|
+
* its versions' dates as they were, so the version asked for can still be
|
|
7383
|
+
* inside its window; it is not on offer all the same.
|
|
7384
|
+
*/
|
|
7385
|
+
readonly BUNDLE_DELETED: "BUNDLE_DELETED";
|
|
5650
7386
|
readonly BUNDLE_VERSION_REGRESSION: "BUNDLE_VERSION_REGRESSION";
|
|
5651
7387
|
readonly BUNDLE_VERSION_ZERO_PRICE: "BUNDLE_VERSION_ZERO_PRICE";
|
|
5652
7388
|
readonly BUNDLE_VERSION_NO_PRICE: "BUNDLE_VERSION_NO_PRICE";
|
|
@@ -5664,6 +7400,13 @@ declare const CATALOG_ERROR_CODES: {
|
|
|
5664
7400
|
readonly PLAN_NOT_FOUND: "PLAN_NOT_FOUND";
|
|
5665
7401
|
readonly PLAN_VERSION_NOT_FOUND: "PLAN_VERSION_NOT_FOUND";
|
|
5666
7402
|
readonly BUNDLE_NOT_FOUND: "BUNDLE_NOT_FOUND";
|
|
7403
|
+
/**
|
|
7404
|
+
* Bookings told that their add-on version is being retired have still to
|
|
7405
|
+
* move onto a version of this add-on — waiting for their notice, for their
|
|
7406
|
+
* date, or past it — and a deleted add-on is booked by nothing, the move
|
|
7407
|
+
* included. Carries how many, and the add-on's key.
|
|
7408
|
+
*/
|
|
7409
|
+
readonly BUNDLE_DELETE_WHILE_RETIREMENT_MOVES_PENDING: "BUNDLE_DELETE_WHILE_RETIREMENT_MOVES_PENDING";
|
|
5667
7410
|
readonly BUNDLE_VERSION_NOT_FOUND: "BUNDLE_VERSION_NOT_FOUND";
|
|
5668
7411
|
readonly FEATURE_NOT_FOUND: "FEATURE_NOT_FOUND";
|
|
5669
7412
|
readonly QUOTA_NOT_FOUND: "QUOTA_NOT_FOUND";
|
|
@@ -5703,6 +7446,22 @@ declare const BILLING_ERROR_CODES: {
|
|
|
5703
7446
|
readonly BUNDLE_NOT_SELF_SERVICE: "BUNDLE_NOT_SELF_SERVICE";
|
|
5704
7447
|
readonly BUNDLE_CYCLE_EXCEEDS_PLAN: "BUNDLE_CYCLE_EXCEEDS_PLAN";
|
|
5705
7448
|
readonly BUNDLE_NOT_PRICED_FOR_THIS_PLAN: "BUNDLE_NOT_PRICED_FOR_THIS_PLAN";
|
|
7449
|
+
/**
|
|
7450
|
+
* The bundle cannot run on a plan the subscription is already set to move
|
|
7451
|
+
* to — by a scheduled change, or by a retirement it has been told of — and
|
|
7452
|
+
* the booking would still be running then: that plan does not book it, or
|
|
7453
|
+
* has no price for it. Carries that plan's key, the rhythm it is billed in
|
|
7454
|
+
* there, and the day the move takes effect from, which can lie in the past
|
|
7455
|
+
* while the move has not run yet.
|
|
7456
|
+
*/
|
|
7457
|
+
readonly BUNDLE_CANNOT_RUN_ON_UPCOMING_PLAN: "BUNDLE_CANNOT_RUN_ON_UPCOMING_PLAN";
|
|
7458
|
+
/**
|
|
7459
|
+
* As `BUNDLE_CANNOT_RUN_ON_UPCOMING_PLAN`, where only the rhythm stands in
|
|
7460
|
+
* the way: a yearly bundle, and the subscription billed monthly from the
|
|
7461
|
+
* day of the move — a switch of rhythm on the plan it keeps, for one, where
|
|
7462
|
+
* naming the plan would point at the one it is already on. Same values.
|
|
7463
|
+
*/
|
|
7464
|
+
readonly BUNDLE_CANNOT_RUN_ON_UPCOMING_CYCLE: "BUNDLE_CANNOT_RUN_ON_UPCOMING_CYCLE";
|
|
5706
7465
|
readonly SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED: "SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED";
|
|
5707
7466
|
readonly SUBSCRIPTION_BUNDLE_NOT_CANCELLED: "SUBSCRIPTION_BUNDLE_NOT_CANCELLED";
|
|
5708
7467
|
readonly SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE: "SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE";
|
|
@@ -5721,6 +7480,12 @@ declare const BILLING_ERROR_CODES: {
|
|
|
5721
7480
|
* in it: a plan without a yearly price is a monthly plan.
|
|
5722
7481
|
*/
|
|
5723
7482
|
readonly PLAN_NOT_SOLD_IN_CYCLE: "PLAN_NOT_SOLD_IN_CYCLE";
|
|
7483
|
+
/**
|
|
7484
|
+
* The subscription is bound to a plan version the plan repository does not
|
|
7485
|
+
* find, or finds as a version of another plan. What the subscription pays
|
|
7486
|
+
* cannot be read, so no change is quoted until the binding is repaired.
|
|
7487
|
+
*/
|
|
7488
|
+
readonly BOUND_PLAN_VERSION_UNREADABLE: "BOUND_PLAN_VERSION_UNREADABLE";
|
|
5724
7489
|
/** Plan change refused. Carries `blockers[]` with their own codes. */
|
|
5725
7490
|
readonly PLAN_CHANGE_BLOCKED: "PLAN_CHANGE_BLOCKED";
|
|
5726
7491
|
/**
|
|
@@ -5743,6 +7508,175 @@ declare const BILLING_ERROR_CODES: {
|
|
|
5743
7508
|
* Carries the recomputed dates, so the page can re-ask instead of guessing.
|
|
5744
7509
|
*/
|
|
5745
7510
|
readonly CANCELLATION_TERMS_CHANGED: "CANCELLATION_TERMS_CHANGED";
|
|
7511
|
+
/**
|
|
7512
|
+
* The version the caller asked to switch to is no longer the one offered —
|
|
7513
|
+
* another is on sale, the subscription moved, or there is no offer. Nothing
|
|
7514
|
+
* was switched. Carries the current `offer`, or `null`, so the page can show
|
|
7515
|
+
* it instead of guessing.
|
|
7516
|
+
*/
|
|
7517
|
+
readonly VERSION_OFFER_CHANGED: "VERSION_OFFER_CHANGED";
|
|
7518
|
+
/**
|
|
7519
|
+
* The version a change to another plan named is not the one on sale when
|
|
7520
|
+
* the change was submitted: its preview was shown at another moment.
|
|
7521
|
+
* Nothing was changed. Carries the current `preview`, so the page shows
|
|
7522
|
+
* what the change binds now instead of what it would have.
|
|
7523
|
+
*/
|
|
7524
|
+
readonly PLAN_CHANGE_QUOTE_CHANGED: "PLAN_CHANGE_QUOTE_CHANGED";
|
|
7525
|
+
/**
|
|
7526
|
+
* A change to another plan named no version, where its preview names one:
|
|
7527
|
+
* nothing says which price and terms the customer was shown, so nothing
|
|
7528
|
+
* is changed.
|
|
7529
|
+
*/
|
|
7530
|
+
readonly PLAN_CHANGE_VERSION_NOT_NAMED: "PLAN_CHANGE_VERSION_NOT_NAMED";
|
|
7531
|
+
/**
|
|
7532
|
+
* A version that takes something away takes effect when the term ends, and
|
|
7533
|
+
* the subscription's cancellation lands no later: the switch would never
|
|
7534
|
+
* happen, so it is refused rather than recorded. Carries both dates.
|
|
7535
|
+
*/
|
|
7536
|
+
readonly VERSION_SWITCH_AFTER_CANCELLATION: "VERSION_SWITCH_AFTER_CANCELLATION";
|
|
7537
|
+
/**
|
|
7538
|
+
* A version that takes something away takes effect when the term ends, and
|
|
7539
|
+
* it stops being sold before then — by its window or because an operator
|
|
7540
|
+
* ended it — so it could not be bound when the change comes due. Refused
|
|
7541
|
+
* rather than recorded; carries the dates.
|
|
7542
|
+
*/
|
|
7543
|
+
readonly VERSION_ENDS_BEFORE_SWITCH: "VERSION_ENDS_BEFORE_SWITCH";
|
|
7544
|
+
/**
|
|
7545
|
+
* The operator's terms are not confirmed to carry the clause a retirement
|
|
7546
|
+
* rests on (`tenantBilling.orderlyRetirement.termsConfirmed` in
|
|
7547
|
+
* `config/saas.yaml`), so none is accepted.
|
|
7548
|
+
*/
|
|
7549
|
+
readonly RETIREMENT_TERMS_NOT_CONFIRMED: "RETIREMENT_TERMS_NOT_CONFIRMED";
|
|
7550
|
+
/**
|
|
7551
|
+
* The version is still on sale: a subscription booked after the
|
|
7552
|
+
* announcement would be on it without having been told. Carries the plan
|
|
7553
|
+
* key and the version.
|
|
7554
|
+
*/
|
|
7555
|
+
readonly RETIREMENT_VERSION_ON_SALE: "RETIREMENT_VERSION_ON_SALE";
|
|
7556
|
+
/** The replacement is not on sale, so nobody can continue on it. Carries plan key and version. */
|
|
7557
|
+
readonly RETIREMENT_REPLACEMENT_NOT_ON_SALE: "RETIREMENT_REPLACEMENT_NOT_ON_SALE";
|
|
7558
|
+
/**
|
|
7559
|
+
* The replacement has no price in the rhythm some of the subscriptions it
|
|
7560
|
+
* reaches are billed in, so they cannot continue on it. Carries how many,
|
|
7561
|
+
* and the replacement's plan key and version.
|
|
7562
|
+
*/
|
|
7563
|
+
readonly RETIREMENT_REPLACEMENT_NOT_SOLD_IN_RHYTHM: "RETIREMENT_REPLACEMENT_NOT_SOLD_IN_RHYTHM";
|
|
7564
|
+
/**
|
|
7565
|
+
* Some of the subscriptions the retirement reaches hold an add-on that
|
|
7566
|
+
* cannot run on the replacement's plan, so they cannot continue on it.
|
|
7567
|
+
* Carries how many, and the replacement's plan key and version.
|
|
7568
|
+
*/
|
|
7569
|
+
readonly RETIREMENT_REPLACEMENT_CANNOT_CARRY_BUNDLES: "RETIREMENT_REPLACEMENT_CANNOT_CARRY_BUNDLES";
|
|
7570
|
+
/** The replacement named is the version being retired. */
|
|
7571
|
+
readonly RETIREMENT_REPLACEMENT_IS_RETIRED: "RETIREMENT_REPLACEMENT_IS_RETIRED";
|
|
7572
|
+
/** No running subscription is on the version: there is nobody to tell. Carries plan key and version. */
|
|
7573
|
+
readonly RETIREMENT_NOTHING_AFFECTED: "RETIREMENT_NOTHING_AFFECTED";
|
|
7574
|
+
/**
|
|
7575
|
+
* Some of the subscriptions it reaches were reached by a retirement within
|
|
7576
|
+
* the last twelve months, and a subscription is reached at most once in that
|
|
7577
|
+
* time. Carries how many and which.
|
|
7578
|
+
*/
|
|
7579
|
+
readonly RETIREMENT_WITHIN_TWELVE_MONTHS: "RETIREMENT_WITHIN_TWELVE_MONTHS";
|
|
7580
|
+
/**
|
|
7581
|
+
* The subscriptions the retirement reaches, or their dates, changed since
|
|
7582
|
+
* the preview the operator confirmed. Carries the preview as it stands.
|
|
7583
|
+
*/
|
|
7584
|
+
readonly RETIREMENT_PREVIEW_CHANGED: "RETIREMENT_PREVIEW_CHANGED";
|
|
7585
|
+
/** No retirement of the subscription's version waits for its date: there is nothing to switch to. */
|
|
7586
|
+
readonly RETIREMENT_SWITCH_NOT_PENDING: "RETIREMENT_SWITCH_NOT_PENDING";
|
|
7587
|
+
/** The switch opens once the trial has converted: a trial has no contract to hold the price on. */
|
|
7588
|
+
readonly RETIREMENT_SWITCH_IN_TRIAL: "RETIREMENT_SWITCH_IN_TRIAL";
|
|
7589
|
+
/**
|
|
7590
|
+
* An add-on running today cannot run beside the replacement's plan, which
|
|
7591
|
+
* the switch would move the subscription onto today. Carries the add-on,
|
|
7592
|
+
* the plan and the earliest day the booking can end. Its own code rather
|
|
7593
|
+
* than a plan change's: the switch has no other plan to choose and no day
|
|
7594
|
+
* to pick, so the way past it is the add-on ending.
|
|
7595
|
+
*/
|
|
7596
|
+
readonly RETIREMENT_SWITCH_BUNDLE_CANNOT_FOLLOW: "RETIREMENT_SWITCH_BUNDLE_CANNOT_FOLLOW";
|
|
7597
|
+
/**
|
|
7598
|
+
* As `RETIREMENT_SWITCH_BUNDLE_CANNOT_FOLLOW`, where only the version the
|
|
7599
|
+
* add-on continues on from a retirement's date cannot run beside the
|
|
7600
|
+
* replacement's plan. The version it is on can, so cancelling it — it then
|
|
7601
|
+
* ends before that date — lets the switch through. Given while that date
|
|
7602
|
+
* is ahead and the add-on is not cancelled yet; otherwise the earlier code
|
|
7603
|
+
* names the day it can end. Carries the add-on, that version, its date and
|
|
7604
|
+
* the plan.
|
|
7605
|
+
*/
|
|
7606
|
+
readonly RETIREMENT_SWITCH_BUNDLE_REPLACEMENT_CANNOT_FOLLOW: "RETIREMENT_SWITCH_BUNDLE_REPLACEMENT_CANNOT_FOLLOW";
|
|
7607
|
+
/**
|
|
7608
|
+
* The subscription takes no switch now: a change is scheduled, it has
|
|
7609
|
+
* ended, or its plan is held for a special contract.
|
|
7610
|
+
*/
|
|
7611
|
+
readonly RETIREMENT_SWITCH_NOT_OPEN: "RETIREMENT_SWITCH_NOT_OPEN";
|
|
7612
|
+
/**
|
|
7613
|
+
* The version named is not the replacement the retirement names. Carries
|
|
7614
|
+
* the retirement as it now stands.
|
|
7615
|
+
*/
|
|
7616
|
+
readonly RETIREMENT_SWITCH_CHANGED: "RETIREMENT_SWITCH_CHANGED";
|
|
7617
|
+
/**
|
|
7618
|
+
* The add-on version is still on sale: a booking made after the
|
|
7619
|
+
* announcement would be on it without having been told. Carries the
|
|
7620
|
+
* add-on key and the version.
|
|
7621
|
+
*/
|
|
7622
|
+
readonly BUNDLE_RETIREMENT_VERSION_ON_SALE: "BUNDLE_RETIREMENT_VERSION_ON_SALE";
|
|
7623
|
+
/** The replacement is not on sale, so no booking can continue on it. Carries add-on key and version. */
|
|
7624
|
+
readonly BUNDLE_RETIREMENT_REPLACEMENT_NOT_ON_SALE: "BUNDLE_RETIREMENT_REPLACEMENT_NOT_ON_SALE";
|
|
7625
|
+
/**
|
|
7626
|
+
* The replacement is a version of another add-on. A booking continues on
|
|
7627
|
+
* a version of its own add-on, so it stays the same booking with its term.
|
|
7628
|
+
* Carries both add-on keys.
|
|
7629
|
+
*/
|
|
7630
|
+
readonly BUNDLE_RETIREMENT_REPLACEMENT_OF_ANOTHER_BUNDLE: "BUNDLE_RETIREMENT_REPLACEMENT_OF_ANOTHER_BUNDLE";
|
|
7631
|
+
/**
|
|
7632
|
+
* Some of the bookings it reaches run, at their date, beside a plan the
|
|
7633
|
+
* replacement cannot run beside: not allowed there, without a price there
|
|
7634
|
+
* in the booking's rhythm, or in a longer rhythm than the plan's. Carries
|
|
7635
|
+
* how many, and the replacement's add-on key and version.
|
|
7636
|
+
*/
|
|
7637
|
+
readonly BUNDLE_RETIREMENT_REPLACEMENT_CANNOT_RUN: "BUNDLE_RETIREMENT_REPLACEMENT_CANNOT_RUN";
|
|
7638
|
+
/** No running booking is on the version: there is nobody to tell. Carries add-on key and version. */
|
|
7639
|
+
readonly BUNDLE_RETIREMENT_NOTHING_AFFECTED: "BUNDLE_RETIREMENT_NOTHING_AFFECTED";
|
|
7640
|
+
/**
|
|
7641
|
+
* The booking is on an add-on version being retired, and was cancelled to
|
|
7642
|
+
* end before it would move, so it was never told and nothing moves it.
|
|
7643
|
+
* Reinstated, it would run on past the date on a version nobody sells;
|
|
7644
|
+
* booking the replacement once it has ended is the way. Carries the add-on
|
|
7645
|
+
* key, the version, the replacement's version and the day it can be booked
|
|
7646
|
+
* from.
|
|
7647
|
+
*/
|
|
7648
|
+
readonly BUNDLE_RETIREMENT_REINSTATE_REFUSED: "BUNDLE_RETIREMENT_REINSTATE_REFUSED";
|
|
7649
|
+
/**
|
|
7650
|
+
* As `BUNDLE_RETIREMENT_REINSTATE_REFUSED`, where the replacement cannot
|
|
7651
|
+
* run beside the plan the subscription is on when the booking ends, or
|
|
7652
|
+
* beside one it is already set to move to after that, in any rhythm it
|
|
7653
|
+
* could be booked in, so there is no version of the add-on to book.
|
|
7654
|
+
* Carries the add-on key, the version and the replacement's version.
|
|
7655
|
+
*/
|
|
7656
|
+
readonly BUNDLE_RETIREMENT_REINSTATE_REPLACEMENT_CANNOT_RUN: "BUNDLE_RETIREMENT_REINSTATE_REPLACEMENT_CANNOT_RUN";
|
|
7657
|
+
/**
|
|
7658
|
+
* As `BUNDLE_RETIREMENT_REINSTATE_REFUSED`, where the subscription ends by
|
|
7659
|
+
* the day the replacement could be booked from, so there is no day to
|
|
7660
|
+
* name. Carries the add-on key, the version and the replacement's version.
|
|
7661
|
+
*/
|
|
7662
|
+
readonly BUNDLE_RETIREMENT_REINSTATE_SUBSCRIPTION_ENDS: "BUNDLE_RETIREMENT_REINSTATE_SUBSCRIPTION_ENDS";
|
|
7663
|
+
/**
|
|
7664
|
+
* The plan the add-on runs beside, or the rhythm it is billed in, changes
|
|
7665
|
+
* before the date the booking was told — by a change scheduled, or by a
|
|
7666
|
+
* retirement told that moves the subscription to another plan — so the
|
|
7667
|
+
* price a switch now would hold is not the one the booking pays until
|
|
7668
|
+
* then. Switching once the plan has changed, or waiting for the
|
|
7669
|
+
* date, is the way. Carries the add-on and the date.
|
|
7670
|
+
*/
|
|
7671
|
+
readonly BUNDLE_RETIREMENT_SWITCH_PLAN_CHANGES: "BUNDLE_RETIREMENT_SWITCH_PLAN_CHANGES";
|
|
7672
|
+
/**
|
|
7673
|
+
* The add-on version the caller asked to switch a booking to is no longer
|
|
7674
|
+
* the one offered beside it — another is on sale, the booking moved, or
|
|
7675
|
+
* there is no offer. Nothing was switched. Carries the version named
|
|
7676
|
+
* (`bundleVersionId`) and the current `offer`, or `null`, so the page can
|
|
7677
|
+
* show it instead of guessing.
|
|
7678
|
+
*/
|
|
7679
|
+
readonly BUNDLE_VERSION_OFFER_CHANGED: "BUNDLE_VERSION_OFFER_CHANGED";
|
|
5746
7680
|
/** The subscription has ended; its plan can no longer be changed. */
|
|
5747
7681
|
readonly SUBSCRIPTION_ENDED: "SUBSCRIPTION_ENDED";
|
|
5748
7682
|
/** An active special contract blocks self-service plan changes. */
|
|
@@ -5760,14 +7694,33 @@ declare const BILLING_ERROR_CODES: {
|
|
|
5760
7694
|
readonly CANCELLATION_LOCKS_THE_CYCLE: "CANCELLATION_LOCKS_THE_CYCLE";
|
|
5761
7695
|
/**
|
|
5762
7696
|
* A bundle the tenant already holds runs past the cycle they are moving to.
|
|
7697
|
+
* Carries the bundle, the earliest day the booking can end, and the two
|
|
7698
|
+
* rhythms.
|
|
5763
7699
|
*
|
|
5764
7700
|
* Its own code rather than `BUNDLE_CYCLE_EXCEEDS_PLAN`, which states the
|
|
5765
7701
|
* same rule about a booking that has not been made yet. The two need
|
|
5766
7702
|
* different sentences: this one can name the day the obstacle lifts and
|
|
5767
|
-
* tell the reader to
|
|
5768
|
-
*
|
|
7703
|
+
* tell the reader how to get past it, and that advice is wrong for someone
|
|
7704
|
+
* who is only about to book. One template cannot serve both.
|
|
5769
7705
|
*/
|
|
5770
7706
|
readonly BUNDLE_BOOKING_OUTLASTS_TARGET_CYCLE: "BUNDLE_BOOKING_OUTLASTS_TARGET_CYCLE";
|
|
7707
|
+
/**
|
|
7708
|
+
* A bundle the tenant already holds cannot run on the plan they are moving
|
|
7709
|
+
* to: that plan may not book it, or it has no price there in the rhythm
|
|
7710
|
+
* the booking is billed in. Carries the bundle, the plan and the earliest
|
|
7711
|
+
* day the booking can end.
|
|
7712
|
+
*/
|
|
7713
|
+
readonly BUNDLE_BOOKING_DOES_NOT_FIT_TARGET_PLAN: "BUNDLE_BOOKING_DOES_NOT_FIT_TARGET_PLAN";
|
|
7714
|
+
/**
|
|
7715
|
+
* A bundle the tenant already holds can run on the plan they are moving
|
|
7716
|
+
* to, but the version it continues on from a retirement's date cannot.
|
|
7717
|
+
* Cancelling it lets the change through at once: the booking then ends
|
|
7718
|
+
* before that date and never reaches the version. Given while that date is
|
|
7719
|
+
* ahead and the booking is not cancelled yet; otherwise
|
|
7720
|
+
* `BUNDLE_BOOKING_DOES_NOT_FIT_TARGET_PLAN` names the day it can end.
|
|
7721
|
+
* Carries the bundle, that version, its date and the plan.
|
|
7722
|
+
*/
|
|
7723
|
+
readonly BUNDLE_REPLACEMENT_DOES_NOT_FIT_TARGET_PLAN: "BUNDLE_REPLACEMENT_DOES_NOT_FIT_TARGET_PLAN";
|
|
5771
7724
|
/**
|
|
5772
7725
|
* Features of the previewed bundle are already covered by the plan or by
|
|
5773
7726
|
* another booked bundle. A warning rather than a blocker: paying twice is
|
|
@@ -5789,7 +7742,6 @@ declare const BILLING_ERROR_CODES: {
|
|
|
5789
7742
|
* tenant reads and therefore needs a shipped text for.
|
|
5790
7743
|
*/
|
|
5791
7744
|
readonly BUNDLE_FEATURE_DEPENDENCY_UNSATISFIED: "BUNDLE_FEATURE_DEPENDENCY_UNSATISFIED";
|
|
5792
|
-
readonly NO_PENDING_PLAN_VERSION: "NO_PENDING_PLAN_VERSION";
|
|
5793
7745
|
readonly ONBOARDING_CREATE_FAILED: "ONBOARDING_CREATE_FAILED";
|
|
5794
7746
|
readonly BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS: "BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS";
|
|
5795
7747
|
/**
|
|
@@ -5838,6 +7790,21 @@ declare const CONTRACT_ERROR_CODES: {
|
|
|
5838
7790
|
* describes. Nothing was written; load the offer and conclude it again.
|
|
5839
7791
|
*/
|
|
5840
7792
|
readonly CHECKOUT_OFFER_CHANGED: "CHECKOUT_OFFER_CHANGED";
|
|
7793
|
+
/**
|
|
7794
|
+
* An offer concludes a tenant's first contract, and this tenant has a
|
|
7795
|
+
* contract in force at the moment the offer's would take effect, or one
|
|
7796
|
+
* beginning after it. Concluded, the two would run side by side. Nothing
|
|
7797
|
+
* was written; a running subscription changes through its plan and its
|
|
7798
|
+
* add-ons. Carries the offer and the contract that runs.
|
|
7799
|
+
*/
|
|
7800
|
+
readonly CHECKOUT_OFFER_CONTRACT_IN_FORCE: "CHECKOUT_OFFER_CONTRACT_IN_FORCE";
|
|
7801
|
+
/**
|
|
7802
|
+
* The offer names a version of an add-on the tenant has booked in another
|
|
7803
|
+
* version. Concluded, the contract would name a version the booking is not
|
|
7804
|
+
* on. Nothing was written; a booking changes its version through the offer
|
|
7805
|
+
* beside it. Carries the offer, the add-on, the booking and both versions.
|
|
7806
|
+
*/
|
|
7807
|
+
readonly CHECKOUT_OFFER_ADD_ON_BOOKED_IN_ANOTHER_VERSION: "CHECKOUT_OFFER_ADD_ON_BOOKED_IN_ANOTHER_VERSION";
|
|
5841
7808
|
readonly SUBSCRIPTION_CONTRACT_NOT_FOUND: "SUBSCRIPTION_CONTRACT_NOT_FOUND";
|
|
5842
7809
|
readonly NO_ACTIVE_SUBSCRIPTION_CONTRACT: "NO_ACTIVE_SUBSCRIPTION_CONTRACT";
|
|
5843
7810
|
readonly SUBSCRIPTION_CONTRACT_ALREADY_CLOSED: "SUBSCRIPTION_CONTRACT_ALREADY_CLOSED";
|
|
@@ -5849,6 +7816,11 @@ declare const CONTRACT_ERROR_CODES: {
|
|
|
5849
7816
|
* would take effect. Nothing was written.
|
|
5850
7817
|
*/
|
|
5851
7818
|
readonly SUBSCRIPTION_CONTRACT_CHANGED: "SUBSCRIPTION_CONTRACT_CHANGED";
|
|
7819
|
+
/**
|
|
7820
|
+
* A contract states a tax rate — `field` names where — other than the one
|
|
7821
|
+
* the installation's tax adapter decides for its subscriber.
|
|
7822
|
+
*/
|
|
7823
|
+
readonly SUBSCRIPTION_CONTRACT_TAX_RATE_NOT_DECIDED: "SUBSCRIPTION_CONTRACT_TAX_RATE_NOT_DECIDED";
|
|
5852
7824
|
};
|
|
5853
7825
|
type ContractErrorCode = (typeof CONTRACT_ERROR_CODES)[keyof typeof CONTRACT_ERROR_CODES];
|
|
5854
7826
|
/** The parties contracts are concluded with (`SubscriberService`), and their absence. */
|
|
@@ -5875,6 +7847,29 @@ declare const SUBSCRIBER_ERROR_CODES: {
|
|
|
5875
7847
|
readonly SUBSCRIBER_CORRECTION_CHANGES_NOTHING: "SUBSCRIBER_CORRECTION_CHANGES_NOTHING";
|
|
5876
7848
|
/** The operator declared another legal entity: that is a transfer, not an edit. */
|
|
5877
7849
|
readonly SUBSCRIBER_TAKEOVER_IS_A_TRANSFER: "SUBSCRIBER_TAKEOVER_IS_A_TRANSFER";
|
|
7850
|
+
/**
|
|
7851
|
+
* A contact change named whether the subscriber is a business. That is part
|
|
7852
|
+
* of its tax origin and changes as a recorded change naming who made it.
|
|
7853
|
+
*/
|
|
7854
|
+
readonly SUBSCRIBER_BUSINESS_STATUS_NOT_A_CONTACT: "SUBSCRIBER_BUSINESS_STATUS_NOT_A_CONTACT";
|
|
7855
|
+
/** A change of the subscriber's contact details or business status did not say who makes it. */
|
|
7856
|
+
readonly SUBSCRIBER_CHANGE_ACTOR_REQUIRED: "SUBSCRIBER_CHANGE_ACTOR_REQUIRED";
|
|
7857
|
+
/**
|
|
7858
|
+
* Where a tax adapter decides, a contract names its subscriber only once
|
|
7859
|
+
* the address an invoice names is complete (`SC-PRIC-032`): a party copied
|
|
7860
|
+
* onto a contract incomplete cannot be completed afterwards. Carries
|
|
7861
|
+
* `missing`, the empty fields, for a screen to name by their labels; the
|
|
7862
|
+
* shipped sentence names all four rather than the keys.
|
|
7863
|
+
*/
|
|
7864
|
+
readonly SUBSCRIBER_IDENTITY_INCOMPLETE: "SUBSCRIBER_IDENTITY_INCOMPLETE";
|
|
7865
|
+
/**
|
|
7866
|
+
* A change of whether the subscriber is a business states no reason. It
|
|
7867
|
+
* decides the tax treatment of the next invoice, so the change log keeps
|
|
7868
|
+
* why it moved (`SC-PRIC-043`).
|
|
7869
|
+
*/
|
|
7870
|
+
readonly SUBSCRIBER_BUSINESS_STATUS_REASON_REQUIRED: "SUBSCRIBER_BUSINESS_STATUS_REASON_REQUIRED";
|
|
7871
|
+
/** A check of the subscriber's VAT identification number was asked for, and it holds none. */
|
|
7872
|
+
readonly SUBSCRIBER_VAT_ID_MISSING: "SUBSCRIBER_VAT_ID_MISSING";
|
|
5878
7873
|
};
|
|
5879
7874
|
type SubscriberErrorCode = (typeof SUBSCRIBER_ERROR_CODES)[keyof typeof SUBSCRIBER_ERROR_CODES];
|
|
5880
7875
|
/** Self-service registration funnel (`PendingRegistration`). */
|
|
@@ -5992,6 +7987,31 @@ declare const MAINTENANCE_ERROR_CODES: {
|
|
|
5992
7987
|
readonly MAINTENANCE_MESSAGE_TOO_LONG: "MAINTENANCE_MESSAGE_TOO_LONG";
|
|
5993
7988
|
};
|
|
5994
7989
|
type MaintenanceErrorCode = (typeof MAINTENANCE_ERROR_CODES)[keyof typeof MAINTENANCE_ERROR_CODES];
|
|
7990
|
+
/** Codes of the installation's tax adapter (ADR 0013). */
|
|
7991
|
+
declare const TAX_ERROR_CODES: {
|
|
7992
|
+
/**
|
|
7993
|
+
* The tax adapter answers that it does not support the subscriber's case;
|
|
7994
|
+
* `adapter` names it and `reason` is its sentence. Nothing is concluded with
|
|
7995
|
+
* a guessed tax (`SC-PRIC-039`).
|
|
7996
|
+
*/
|
|
7997
|
+
readonly TAX_TREATMENT_NOT_SUPPORTED: "TAX_TREATMENT_NOT_SUPPORTED";
|
|
7998
|
+
/**
|
|
7999
|
+
* The tax adapter needs the VAT identification number checked to treat the
|
|
8000
|
+
* case, and the check did not complete — the service is unavailable, timed
|
|
8001
|
+
* out, or answered in a way the adapter cannot read (`503`). Nothing is
|
|
8002
|
+
* decided in the subscriber's favour on a number not checked
|
|
8003
|
+
* (`SC-PRIC-040`): try again later. `adapter` names the adapter and
|
|
8004
|
+
* `reason` says why.
|
|
8005
|
+
*/
|
|
8006
|
+
readonly TAX_VAT_ID_CHECK_NOT_COMPLETED: "TAX_VAT_ID_CHECK_NOT_COMPLETED";
|
|
8007
|
+
/**
|
|
8008
|
+
* A VAT identification number was to be checked, and `config/saas.yaml`
|
|
8009
|
+
* names no tax adapter, which is what names the service to check with
|
|
8010
|
+
* (`409`).
|
|
8011
|
+
*/
|
|
8012
|
+
readonly TAX_VAT_ID_CHECK_NOT_AVAILABLE: "TAX_VAT_ID_CHECK_NOT_AVAILABLE";
|
|
8013
|
+
};
|
|
8014
|
+
type TaxErrorCode = (typeof TAX_ERROR_CODES)[keyof typeof TAX_ERROR_CODES];
|
|
5995
8015
|
/**
|
|
5996
8016
|
* Every exception code the platform emits, in one object.
|
|
5997
8017
|
*
|
|
@@ -6000,6 +8020,27 @@ type MaintenanceErrorCode = (typeof MAINTENANCE_ERROR_CODES)[keyof typeof MAINTE
|
|
|
6000
8020
|
* removing one may not.
|
|
6001
8021
|
*/
|
|
6002
8022
|
declare const PLATFORM_ERROR_CODES: {
|
|
8023
|
+
/**
|
|
8024
|
+
* The tax adapter answers that it does not support the subscriber's case;
|
|
8025
|
+
* `adapter` names it and `reason` is its sentence. Nothing is concluded with
|
|
8026
|
+
* a guessed tax (`SC-PRIC-039`).
|
|
8027
|
+
*/
|
|
8028
|
+
readonly TAX_TREATMENT_NOT_SUPPORTED: "TAX_TREATMENT_NOT_SUPPORTED";
|
|
8029
|
+
/**
|
|
8030
|
+
* The tax adapter needs the VAT identification number checked to treat the
|
|
8031
|
+
* case, and the check did not complete — the service is unavailable, timed
|
|
8032
|
+
* out, or answered in a way the adapter cannot read (`503`). Nothing is
|
|
8033
|
+
* decided in the subscriber's favour on a number not checked
|
|
8034
|
+
* (`SC-PRIC-040`): try again later. `adapter` names the adapter and
|
|
8035
|
+
* `reason` says why.
|
|
8036
|
+
*/
|
|
8037
|
+
readonly TAX_VAT_ID_CHECK_NOT_COMPLETED: "TAX_VAT_ID_CHECK_NOT_COMPLETED";
|
|
8038
|
+
/**
|
|
8039
|
+
* A VAT identification number was to be checked, and `config/saas.yaml`
|
|
8040
|
+
* names no tax adapter, which is what names the service to check with
|
|
8041
|
+
* (`409`).
|
|
8042
|
+
*/
|
|
8043
|
+
readonly TAX_VAT_ID_CHECK_NOT_AVAILABLE: "TAX_VAT_ID_CHECK_NOT_AVAILABLE";
|
|
6003
8044
|
/** The application is locked for maintenance; the body carries the window. */
|
|
6004
8045
|
readonly MAINTENANCE: "MAINTENANCE";
|
|
6005
8046
|
/** A window is already open: move or cancel it before announcing another. */
|
|
@@ -6076,6 +8117,29 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6076
8117
|
readonly SUBSCRIBER_CORRECTION_CHANGES_NOTHING: "SUBSCRIBER_CORRECTION_CHANGES_NOTHING";
|
|
6077
8118
|
/** The operator declared another legal entity: that is a transfer, not an edit. */
|
|
6078
8119
|
readonly SUBSCRIBER_TAKEOVER_IS_A_TRANSFER: "SUBSCRIBER_TAKEOVER_IS_A_TRANSFER";
|
|
8120
|
+
/**
|
|
8121
|
+
* A contact change named whether the subscriber is a business. That is part
|
|
8122
|
+
* of its tax origin and changes as a recorded change naming who made it.
|
|
8123
|
+
*/
|
|
8124
|
+
readonly SUBSCRIBER_BUSINESS_STATUS_NOT_A_CONTACT: "SUBSCRIBER_BUSINESS_STATUS_NOT_A_CONTACT";
|
|
8125
|
+
/** A change of the subscriber's contact details or business status did not say who makes it. */
|
|
8126
|
+
readonly SUBSCRIBER_CHANGE_ACTOR_REQUIRED: "SUBSCRIBER_CHANGE_ACTOR_REQUIRED";
|
|
8127
|
+
/**
|
|
8128
|
+
* Where a tax adapter decides, a contract names its subscriber only once
|
|
8129
|
+
* the address an invoice names is complete (`SC-PRIC-032`): a party copied
|
|
8130
|
+
* onto a contract incomplete cannot be completed afterwards. Carries
|
|
8131
|
+
* `missing`, the empty fields, for a screen to name by their labels; the
|
|
8132
|
+
* shipped sentence names all four rather than the keys.
|
|
8133
|
+
*/
|
|
8134
|
+
readonly SUBSCRIBER_IDENTITY_INCOMPLETE: "SUBSCRIBER_IDENTITY_INCOMPLETE";
|
|
8135
|
+
/**
|
|
8136
|
+
* A change of whether the subscriber is a business states no reason. It
|
|
8137
|
+
* decides the tax treatment of the next invoice, so the change log keeps
|
|
8138
|
+
* why it moved (`SC-PRIC-043`).
|
|
8139
|
+
*/
|
|
8140
|
+
readonly SUBSCRIBER_BUSINESS_STATUS_REASON_REQUIRED: "SUBSCRIBER_BUSINESS_STATUS_REASON_REQUIRED";
|
|
8141
|
+
/** A check of the subscriber's VAT identification number was asked for, and it holds none. */
|
|
8142
|
+
readonly SUBSCRIBER_VAT_ID_MISSING: "SUBSCRIBER_VAT_ID_MISSING";
|
|
6079
8143
|
readonly CHECKOUT_OFFER_LINE_ITEMS_REQUIRED: "CHECKOUT_OFFER_LINE_ITEMS_REQUIRED";
|
|
6080
8144
|
readonly CHECKOUT_OFFER_PLAN_LINE_ITEM_REQUIRED: "CHECKOUT_OFFER_PLAN_LINE_ITEM_REQUIRED";
|
|
6081
8145
|
readonly CHECKOUT_OFFER_BUNDLE_LINE_ITEMS_REQUIRED: "CHECKOUT_OFFER_BUNDLE_LINE_ITEMS_REQUIRED";
|
|
@@ -6110,6 +8174,21 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6110
8174
|
* describes. Nothing was written; load the offer and conclude it again.
|
|
6111
8175
|
*/
|
|
6112
8176
|
readonly CHECKOUT_OFFER_CHANGED: "CHECKOUT_OFFER_CHANGED";
|
|
8177
|
+
/**
|
|
8178
|
+
* An offer concludes a tenant's first contract, and this tenant has a
|
|
8179
|
+
* contract in force at the moment the offer's would take effect, or one
|
|
8180
|
+
* beginning after it. Concluded, the two would run side by side. Nothing
|
|
8181
|
+
* was written; a running subscription changes through its plan and its
|
|
8182
|
+
* add-ons. Carries the offer and the contract that runs.
|
|
8183
|
+
*/
|
|
8184
|
+
readonly CHECKOUT_OFFER_CONTRACT_IN_FORCE: "CHECKOUT_OFFER_CONTRACT_IN_FORCE";
|
|
8185
|
+
/**
|
|
8186
|
+
* The offer names a version of an add-on the tenant has booked in another
|
|
8187
|
+
* version. Concluded, the contract would name a version the booking is not
|
|
8188
|
+
* on. Nothing was written; a booking changes its version through the offer
|
|
8189
|
+
* beside it. Carries the offer, the add-on, the booking and both versions.
|
|
8190
|
+
*/
|
|
8191
|
+
readonly CHECKOUT_OFFER_ADD_ON_BOOKED_IN_ANOTHER_VERSION: "CHECKOUT_OFFER_ADD_ON_BOOKED_IN_ANOTHER_VERSION";
|
|
6113
8192
|
readonly SUBSCRIPTION_CONTRACT_NOT_FOUND: "SUBSCRIPTION_CONTRACT_NOT_FOUND";
|
|
6114
8193
|
readonly NO_ACTIVE_SUBSCRIPTION_CONTRACT: "NO_ACTIVE_SUBSCRIPTION_CONTRACT";
|
|
6115
8194
|
readonly SUBSCRIPTION_CONTRACT_ALREADY_CLOSED: "SUBSCRIPTION_CONTRACT_ALREADY_CLOSED";
|
|
@@ -6121,6 +8200,11 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6121
8200
|
* would take effect. Nothing was written.
|
|
6122
8201
|
*/
|
|
6123
8202
|
readonly SUBSCRIPTION_CONTRACT_CHANGED: "SUBSCRIPTION_CONTRACT_CHANGED";
|
|
8203
|
+
/**
|
|
8204
|
+
* A contract states a tax rate — `field` names where — other than the one
|
|
8205
|
+
* the installation's tax adapter decides for its subscriber.
|
|
8206
|
+
*/
|
|
8207
|
+
readonly SUBSCRIPTION_CONTRACT_TAX_RATE_NOT_DECIDED: "SUBSCRIPTION_CONTRACT_TAX_RATE_NOT_DECIDED";
|
|
6124
8208
|
/**
|
|
6125
8209
|
* Feature not covered by the plan. Defined in `upsell.types.ts` because the
|
|
6126
8210
|
* upsell body type is built around it; re-exported here so an exhaustive
|
|
@@ -6132,6 +8216,22 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6132
8216
|
readonly BUNDLE_NOT_SELF_SERVICE: "BUNDLE_NOT_SELF_SERVICE";
|
|
6133
8217
|
readonly BUNDLE_CYCLE_EXCEEDS_PLAN: "BUNDLE_CYCLE_EXCEEDS_PLAN";
|
|
6134
8218
|
readonly BUNDLE_NOT_PRICED_FOR_THIS_PLAN: "BUNDLE_NOT_PRICED_FOR_THIS_PLAN";
|
|
8219
|
+
/**
|
|
8220
|
+
* The bundle cannot run on a plan the subscription is already set to move
|
|
8221
|
+
* to — by a scheduled change, or by a retirement it has been told of — and
|
|
8222
|
+
* the booking would still be running then: that plan does not book it, or
|
|
8223
|
+
* has no price for it. Carries that plan's key, the rhythm it is billed in
|
|
8224
|
+
* there, and the day the move takes effect from, which can lie in the past
|
|
8225
|
+
* while the move has not run yet.
|
|
8226
|
+
*/
|
|
8227
|
+
readonly BUNDLE_CANNOT_RUN_ON_UPCOMING_PLAN: "BUNDLE_CANNOT_RUN_ON_UPCOMING_PLAN";
|
|
8228
|
+
/**
|
|
8229
|
+
* As `BUNDLE_CANNOT_RUN_ON_UPCOMING_PLAN`, where only the rhythm stands in
|
|
8230
|
+
* the way: a yearly bundle, and the subscription billed monthly from the
|
|
8231
|
+
* day of the move — a switch of rhythm on the plan it keeps, for one, where
|
|
8232
|
+
* naming the plan would point at the one it is already on. Same values.
|
|
8233
|
+
*/
|
|
8234
|
+
readonly BUNDLE_CANNOT_RUN_ON_UPCOMING_CYCLE: "BUNDLE_CANNOT_RUN_ON_UPCOMING_CYCLE";
|
|
6135
8235
|
readonly SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED: "SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED";
|
|
6136
8236
|
readonly SUBSCRIPTION_BUNDLE_NOT_CANCELLED: "SUBSCRIPTION_BUNDLE_NOT_CANCELLED";
|
|
6137
8237
|
readonly SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE: "SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE";
|
|
@@ -6150,6 +8250,12 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6150
8250
|
* in it: a plan without a yearly price is a monthly plan.
|
|
6151
8251
|
*/
|
|
6152
8252
|
readonly PLAN_NOT_SOLD_IN_CYCLE: "PLAN_NOT_SOLD_IN_CYCLE";
|
|
8253
|
+
/**
|
|
8254
|
+
* The subscription is bound to a plan version the plan repository does not
|
|
8255
|
+
* find, or finds as a version of another plan. What the subscription pays
|
|
8256
|
+
* cannot be read, so no change is quoted until the binding is repaired.
|
|
8257
|
+
*/
|
|
8258
|
+
readonly BOUND_PLAN_VERSION_UNREADABLE: "BOUND_PLAN_VERSION_UNREADABLE";
|
|
6153
8259
|
/** Plan change refused. Carries `blockers[]` with their own codes. */
|
|
6154
8260
|
readonly PLAN_CHANGE_BLOCKED: "PLAN_CHANGE_BLOCKED";
|
|
6155
8261
|
/**
|
|
@@ -6172,6 +8278,175 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6172
8278
|
* Carries the recomputed dates, so the page can re-ask instead of guessing.
|
|
6173
8279
|
*/
|
|
6174
8280
|
readonly CANCELLATION_TERMS_CHANGED: "CANCELLATION_TERMS_CHANGED";
|
|
8281
|
+
/**
|
|
8282
|
+
* The version the caller asked to switch to is no longer the one offered —
|
|
8283
|
+
* another is on sale, the subscription moved, or there is no offer. Nothing
|
|
8284
|
+
* was switched. Carries the current `offer`, or `null`, so the page can show
|
|
8285
|
+
* it instead of guessing.
|
|
8286
|
+
*/
|
|
8287
|
+
readonly VERSION_OFFER_CHANGED: "VERSION_OFFER_CHANGED";
|
|
8288
|
+
/**
|
|
8289
|
+
* The version a change to another plan named is not the one on sale when
|
|
8290
|
+
* the change was submitted: its preview was shown at another moment.
|
|
8291
|
+
* Nothing was changed. Carries the current `preview`, so the page shows
|
|
8292
|
+
* what the change binds now instead of what it would have.
|
|
8293
|
+
*/
|
|
8294
|
+
readonly PLAN_CHANGE_QUOTE_CHANGED: "PLAN_CHANGE_QUOTE_CHANGED";
|
|
8295
|
+
/**
|
|
8296
|
+
* A change to another plan named no version, where its preview names one:
|
|
8297
|
+
* nothing says which price and terms the customer was shown, so nothing
|
|
8298
|
+
* is changed.
|
|
8299
|
+
*/
|
|
8300
|
+
readonly PLAN_CHANGE_VERSION_NOT_NAMED: "PLAN_CHANGE_VERSION_NOT_NAMED";
|
|
8301
|
+
/**
|
|
8302
|
+
* A version that takes something away takes effect when the term ends, and
|
|
8303
|
+
* the subscription's cancellation lands no later: the switch would never
|
|
8304
|
+
* happen, so it is refused rather than recorded. Carries both dates.
|
|
8305
|
+
*/
|
|
8306
|
+
readonly VERSION_SWITCH_AFTER_CANCELLATION: "VERSION_SWITCH_AFTER_CANCELLATION";
|
|
8307
|
+
/**
|
|
8308
|
+
* A version that takes something away takes effect when the term ends, and
|
|
8309
|
+
* it stops being sold before then — by its window or because an operator
|
|
8310
|
+
* ended it — so it could not be bound when the change comes due. Refused
|
|
8311
|
+
* rather than recorded; carries the dates.
|
|
8312
|
+
*/
|
|
8313
|
+
readonly VERSION_ENDS_BEFORE_SWITCH: "VERSION_ENDS_BEFORE_SWITCH";
|
|
8314
|
+
/**
|
|
8315
|
+
* The operator's terms are not confirmed to carry the clause a retirement
|
|
8316
|
+
* rests on (`tenantBilling.orderlyRetirement.termsConfirmed` in
|
|
8317
|
+
* `config/saas.yaml`), so none is accepted.
|
|
8318
|
+
*/
|
|
8319
|
+
readonly RETIREMENT_TERMS_NOT_CONFIRMED: "RETIREMENT_TERMS_NOT_CONFIRMED";
|
|
8320
|
+
/**
|
|
8321
|
+
* The version is still on sale: a subscription booked after the
|
|
8322
|
+
* announcement would be on it without having been told. Carries the plan
|
|
8323
|
+
* key and the version.
|
|
8324
|
+
*/
|
|
8325
|
+
readonly RETIREMENT_VERSION_ON_SALE: "RETIREMENT_VERSION_ON_SALE";
|
|
8326
|
+
/** The replacement is not on sale, so nobody can continue on it. Carries plan key and version. */
|
|
8327
|
+
readonly RETIREMENT_REPLACEMENT_NOT_ON_SALE: "RETIREMENT_REPLACEMENT_NOT_ON_SALE";
|
|
8328
|
+
/**
|
|
8329
|
+
* The replacement has no price in the rhythm some of the subscriptions it
|
|
8330
|
+
* reaches are billed in, so they cannot continue on it. Carries how many,
|
|
8331
|
+
* and the replacement's plan key and version.
|
|
8332
|
+
*/
|
|
8333
|
+
readonly RETIREMENT_REPLACEMENT_NOT_SOLD_IN_RHYTHM: "RETIREMENT_REPLACEMENT_NOT_SOLD_IN_RHYTHM";
|
|
8334
|
+
/**
|
|
8335
|
+
* Some of the subscriptions the retirement reaches hold an add-on that
|
|
8336
|
+
* cannot run on the replacement's plan, so they cannot continue on it.
|
|
8337
|
+
* Carries how many, and the replacement's plan key and version.
|
|
8338
|
+
*/
|
|
8339
|
+
readonly RETIREMENT_REPLACEMENT_CANNOT_CARRY_BUNDLES: "RETIREMENT_REPLACEMENT_CANNOT_CARRY_BUNDLES";
|
|
8340
|
+
/** The replacement named is the version being retired. */
|
|
8341
|
+
readonly RETIREMENT_REPLACEMENT_IS_RETIRED: "RETIREMENT_REPLACEMENT_IS_RETIRED";
|
|
8342
|
+
/** No running subscription is on the version: there is nobody to tell. Carries plan key and version. */
|
|
8343
|
+
readonly RETIREMENT_NOTHING_AFFECTED: "RETIREMENT_NOTHING_AFFECTED";
|
|
8344
|
+
/**
|
|
8345
|
+
* Some of the subscriptions it reaches were reached by a retirement within
|
|
8346
|
+
* the last twelve months, and a subscription is reached at most once in that
|
|
8347
|
+
* time. Carries how many and which.
|
|
8348
|
+
*/
|
|
8349
|
+
readonly RETIREMENT_WITHIN_TWELVE_MONTHS: "RETIREMENT_WITHIN_TWELVE_MONTHS";
|
|
8350
|
+
/**
|
|
8351
|
+
* The subscriptions the retirement reaches, or their dates, changed since
|
|
8352
|
+
* the preview the operator confirmed. Carries the preview as it stands.
|
|
8353
|
+
*/
|
|
8354
|
+
readonly RETIREMENT_PREVIEW_CHANGED: "RETIREMENT_PREVIEW_CHANGED";
|
|
8355
|
+
/** No retirement of the subscription's version waits for its date: there is nothing to switch to. */
|
|
8356
|
+
readonly RETIREMENT_SWITCH_NOT_PENDING: "RETIREMENT_SWITCH_NOT_PENDING";
|
|
8357
|
+
/** The switch opens once the trial has converted: a trial has no contract to hold the price on. */
|
|
8358
|
+
readonly RETIREMENT_SWITCH_IN_TRIAL: "RETIREMENT_SWITCH_IN_TRIAL";
|
|
8359
|
+
/**
|
|
8360
|
+
* An add-on running today cannot run beside the replacement's plan, which
|
|
8361
|
+
* the switch would move the subscription onto today. Carries the add-on,
|
|
8362
|
+
* the plan and the earliest day the booking can end. Its own code rather
|
|
8363
|
+
* than a plan change's: the switch has no other plan to choose and no day
|
|
8364
|
+
* to pick, so the way past it is the add-on ending.
|
|
8365
|
+
*/
|
|
8366
|
+
readonly RETIREMENT_SWITCH_BUNDLE_CANNOT_FOLLOW: "RETIREMENT_SWITCH_BUNDLE_CANNOT_FOLLOW";
|
|
8367
|
+
/**
|
|
8368
|
+
* As `RETIREMENT_SWITCH_BUNDLE_CANNOT_FOLLOW`, where only the version the
|
|
8369
|
+
* add-on continues on from a retirement's date cannot run beside the
|
|
8370
|
+
* replacement's plan. The version it is on can, so cancelling it — it then
|
|
8371
|
+
* ends before that date — lets the switch through. Given while that date
|
|
8372
|
+
* is ahead and the add-on is not cancelled yet; otherwise the earlier code
|
|
8373
|
+
* names the day it can end. Carries the add-on, that version, its date and
|
|
8374
|
+
* the plan.
|
|
8375
|
+
*/
|
|
8376
|
+
readonly RETIREMENT_SWITCH_BUNDLE_REPLACEMENT_CANNOT_FOLLOW: "RETIREMENT_SWITCH_BUNDLE_REPLACEMENT_CANNOT_FOLLOW";
|
|
8377
|
+
/**
|
|
8378
|
+
* The subscription takes no switch now: a change is scheduled, it has
|
|
8379
|
+
* ended, or its plan is held for a special contract.
|
|
8380
|
+
*/
|
|
8381
|
+
readonly RETIREMENT_SWITCH_NOT_OPEN: "RETIREMENT_SWITCH_NOT_OPEN";
|
|
8382
|
+
/**
|
|
8383
|
+
* The version named is not the replacement the retirement names. Carries
|
|
8384
|
+
* the retirement as it now stands.
|
|
8385
|
+
*/
|
|
8386
|
+
readonly RETIREMENT_SWITCH_CHANGED: "RETIREMENT_SWITCH_CHANGED";
|
|
8387
|
+
/**
|
|
8388
|
+
* The add-on version is still on sale: a booking made after the
|
|
8389
|
+
* announcement would be on it without having been told. Carries the
|
|
8390
|
+
* add-on key and the version.
|
|
8391
|
+
*/
|
|
8392
|
+
readonly BUNDLE_RETIREMENT_VERSION_ON_SALE: "BUNDLE_RETIREMENT_VERSION_ON_SALE";
|
|
8393
|
+
/** The replacement is not on sale, so no booking can continue on it. Carries add-on key and version. */
|
|
8394
|
+
readonly BUNDLE_RETIREMENT_REPLACEMENT_NOT_ON_SALE: "BUNDLE_RETIREMENT_REPLACEMENT_NOT_ON_SALE";
|
|
8395
|
+
/**
|
|
8396
|
+
* The replacement is a version of another add-on. A booking continues on
|
|
8397
|
+
* a version of its own add-on, so it stays the same booking with its term.
|
|
8398
|
+
* Carries both add-on keys.
|
|
8399
|
+
*/
|
|
8400
|
+
readonly BUNDLE_RETIREMENT_REPLACEMENT_OF_ANOTHER_BUNDLE: "BUNDLE_RETIREMENT_REPLACEMENT_OF_ANOTHER_BUNDLE";
|
|
8401
|
+
/**
|
|
8402
|
+
* Some of the bookings it reaches run, at their date, beside a plan the
|
|
8403
|
+
* replacement cannot run beside: not allowed there, without a price there
|
|
8404
|
+
* in the booking's rhythm, or in a longer rhythm than the plan's. Carries
|
|
8405
|
+
* how many, and the replacement's add-on key and version.
|
|
8406
|
+
*/
|
|
8407
|
+
readonly BUNDLE_RETIREMENT_REPLACEMENT_CANNOT_RUN: "BUNDLE_RETIREMENT_REPLACEMENT_CANNOT_RUN";
|
|
8408
|
+
/** No running booking is on the version: there is nobody to tell. Carries add-on key and version. */
|
|
8409
|
+
readonly BUNDLE_RETIREMENT_NOTHING_AFFECTED: "BUNDLE_RETIREMENT_NOTHING_AFFECTED";
|
|
8410
|
+
/**
|
|
8411
|
+
* The booking is on an add-on version being retired, and was cancelled to
|
|
8412
|
+
* end before it would move, so it was never told and nothing moves it.
|
|
8413
|
+
* Reinstated, it would run on past the date on a version nobody sells;
|
|
8414
|
+
* booking the replacement once it has ended is the way. Carries the add-on
|
|
8415
|
+
* key, the version, the replacement's version and the day it can be booked
|
|
8416
|
+
* from.
|
|
8417
|
+
*/
|
|
8418
|
+
readonly BUNDLE_RETIREMENT_REINSTATE_REFUSED: "BUNDLE_RETIREMENT_REINSTATE_REFUSED";
|
|
8419
|
+
/**
|
|
8420
|
+
* As `BUNDLE_RETIREMENT_REINSTATE_REFUSED`, where the replacement cannot
|
|
8421
|
+
* run beside the plan the subscription is on when the booking ends, or
|
|
8422
|
+
* beside one it is already set to move to after that, in any rhythm it
|
|
8423
|
+
* could be booked in, so there is no version of the add-on to book.
|
|
8424
|
+
* Carries the add-on key, the version and the replacement's version.
|
|
8425
|
+
*/
|
|
8426
|
+
readonly BUNDLE_RETIREMENT_REINSTATE_REPLACEMENT_CANNOT_RUN: "BUNDLE_RETIREMENT_REINSTATE_REPLACEMENT_CANNOT_RUN";
|
|
8427
|
+
/**
|
|
8428
|
+
* As `BUNDLE_RETIREMENT_REINSTATE_REFUSED`, where the subscription ends by
|
|
8429
|
+
* the day the replacement could be booked from, so there is no day to
|
|
8430
|
+
* name. Carries the add-on key, the version and the replacement's version.
|
|
8431
|
+
*/
|
|
8432
|
+
readonly BUNDLE_RETIREMENT_REINSTATE_SUBSCRIPTION_ENDS: "BUNDLE_RETIREMENT_REINSTATE_SUBSCRIPTION_ENDS";
|
|
8433
|
+
/**
|
|
8434
|
+
* The plan the add-on runs beside, or the rhythm it is billed in, changes
|
|
8435
|
+
* before the date the booking was told — by a change scheduled, or by a
|
|
8436
|
+
* retirement told that moves the subscription to another plan — so the
|
|
8437
|
+
* price a switch now would hold is not the one the booking pays until
|
|
8438
|
+
* then. Switching once the plan has changed, or waiting for the
|
|
8439
|
+
* date, is the way. Carries the add-on and the date.
|
|
8440
|
+
*/
|
|
8441
|
+
readonly BUNDLE_RETIREMENT_SWITCH_PLAN_CHANGES: "BUNDLE_RETIREMENT_SWITCH_PLAN_CHANGES";
|
|
8442
|
+
/**
|
|
8443
|
+
* The add-on version the caller asked to switch a booking to is no longer
|
|
8444
|
+
* the one offered beside it — another is on sale, the booking moved, or
|
|
8445
|
+
* there is no offer. Nothing was switched. Carries the version named
|
|
8446
|
+
* (`bundleVersionId`) and the current `offer`, or `null`, so the page can
|
|
8447
|
+
* show it instead of guessing.
|
|
8448
|
+
*/
|
|
8449
|
+
readonly BUNDLE_VERSION_OFFER_CHANGED: "BUNDLE_VERSION_OFFER_CHANGED";
|
|
6175
8450
|
/** The subscription has ended; its plan can no longer be changed. */
|
|
6176
8451
|
readonly SUBSCRIPTION_ENDED: "SUBSCRIPTION_ENDED";
|
|
6177
8452
|
/** An active special contract blocks self-service plan changes. */
|
|
@@ -6189,14 +8464,33 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6189
8464
|
readonly CANCELLATION_LOCKS_THE_CYCLE: "CANCELLATION_LOCKS_THE_CYCLE";
|
|
6190
8465
|
/**
|
|
6191
8466
|
* A bundle the tenant already holds runs past the cycle they are moving to.
|
|
8467
|
+
* Carries the bundle, the earliest day the booking can end, and the two
|
|
8468
|
+
* rhythms.
|
|
6192
8469
|
*
|
|
6193
8470
|
* Its own code rather than `BUNDLE_CYCLE_EXCEEDS_PLAN`, which states the
|
|
6194
8471
|
* same rule about a booking that has not been made yet. The two need
|
|
6195
8472
|
* different sentences: this one can name the day the obstacle lifts and
|
|
6196
|
-
* tell the reader to
|
|
6197
|
-
*
|
|
8473
|
+
* tell the reader how to get past it, and that advice is wrong for someone
|
|
8474
|
+
* who is only about to book. One template cannot serve both.
|
|
6198
8475
|
*/
|
|
6199
8476
|
readonly BUNDLE_BOOKING_OUTLASTS_TARGET_CYCLE: "BUNDLE_BOOKING_OUTLASTS_TARGET_CYCLE";
|
|
8477
|
+
/**
|
|
8478
|
+
* A bundle the tenant already holds cannot run on the plan they are moving
|
|
8479
|
+
* to: that plan may not book it, or it has no price there in the rhythm
|
|
8480
|
+
* the booking is billed in. Carries the bundle, the plan and the earliest
|
|
8481
|
+
* day the booking can end.
|
|
8482
|
+
*/
|
|
8483
|
+
readonly BUNDLE_BOOKING_DOES_NOT_FIT_TARGET_PLAN: "BUNDLE_BOOKING_DOES_NOT_FIT_TARGET_PLAN";
|
|
8484
|
+
/**
|
|
8485
|
+
* A bundle the tenant already holds can run on the plan they are moving
|
|
8486
|
+
* to, but the version it continues on from a retirement's date cannot.
|
|
8487
|
+
* Cancelling it lets the change through at once: the booking then ends
|
|
8488
|
+
* before that date and never reaches the version. Given while that date is
|
|
8489
|
+
* ahead and the booking is not cancelled yet; otherwise
|
|
8490
|
+
* `BUNDLE_BOOKING_DOES_NOT_FIT_TARGET_PLAN` names the day it can end.
|
|
8491
|
+
* Carries the bundle, that version, its date and the plan.
|
|
8492
|
+
*/
|
|
8493
|
+
readonly BUNDLE_REPLACEMENT_DOES_NOT_FIT_TARGET_PLAN: "BUNDLE_REPLACEMENT_DOES_NOT_FIT_TARGET_PLAN";
|
|
6200
8494
|
/**
|
|
6201
8495
|
* Features of the previewed bundle are already covered by the plan or by
|
|
6202
8496
|
* another booked bundle. A warning rather than a blocker: paying twice is
|
|
@@ -6218,7 +8512,6 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6218
8512
|
* tenant reads and therefore needs a shipped text for.
|
|
6219
8513
|
*/
|
|
6220
8514
|
readonly BUNDLE_FEATURE_DEPENDENCY_UNSATISFIED: "BUNDLE_FEATURE_DEPENDENCY_UNSATISFIED";
|
|
6221
|
-
readonly NO_PENDING_PLAN_VERSION: "NO_PENDING_PLAN_VERSION";
|
|
6222
8515
|
readonly ONBOARDING_CREATE_FAILED: "ONBOARDING_CREATE_FAILED";
|
|
6223
8516
|
readonly BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS: "BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS";
|
|
6224
8517
|
/**
|
|
@@ -6250,10 +8543,41 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6250
8543
|
readonly PLAN_TERMINATE_INVALID_DATE: "PLAN_TERMINATE_INVALID_DATE";
|
|
6251
8544
|
readonly PLAN_TERMINATE_DATE_NOT_FUTURE: "PLAN_TERMINATE_DATE_NOT_FUTURE";
|
|
6252
8545
|
readonly PLAN_TERMINATE_NOT_IMPLEMENTED: "PLAN_TERMINATE_NOT_IMPLEMENTED";
|
|
8546
|
+
/**
|
|
8547
|
+
* Subscriptions told of a retirement still move onto this version, and
|
|
8548
|
+
* nothing moves onto a version that has ended. Carries the version, its
|
|
8549
|
+
* plan key and the first day it may end: the day after the last move.
|
|
8550
|
+
*/
|
|
8551
|
+
readonly PLAN_TERMINATE_BEFORE_RETIREMENT_MOVES: "PLAN_TERMINATE_BEFORE_RETIREMENT_MOVES";
|
|
8552
|
+
/**
|
|
8553
|
+
* Subscriptions told of a retirement are past their date and still to be
|
|
8554
|
+
* moved onto this version — a move the platform could not make yet — so it
|
|
8555
|
+
* cannot end until they have moved. Carries how many, the version and its
|
|
8556
|
+
* plan key.
|
|
8557
|
+
*/
|
|
8558
|
+
readonly PLAN_TERMINATE_WHILE_MOVES_OVERDUE: "PLAN_TERMINATE_WHILE_MOVES_OVERDUE";
|
|
8559
|
+
/**
|
|
8560
|
+
* Subscriptions on a retired version have not yet been told of their move
|
|
8561
|
+
* onto this version — their notice has reached nobody, so their date is not
|
|
8562
|
+
* set — and it cannot end until they have been. Carries how many, the
|
|
8563
|
+
* version and its plan key.
|
|
8564
|
+
*/
|
|
8565
|
+
readonly PLAN_TERMINATE_WHILE_NOTICES_UNDELIVERED: "PLAN_TERMINATE_WHILE_NOTICES_UNDELIVERED";
|
|
6253
8566
|
readonly BUNDLE_VERSION_ALREADY_PUBLISHED: "BUNDLE_VERSION_ALREADY_PUBLISHED";
|
|
6254
8567
|
readonly BUNDLE_VERSION_NOT_EDITABLE: "BUNDLE_VERSION_NOT_EDITABLE";
|
|
6255
8568
|
readonly BUNDLE_VERSION_NOT_PUBLISHED: "BUNDLE_VERSION_NOT_PUBLISHED";
|
|
6256
8569
|
readonly BUNDLE_VERSION_SUPERSEDED: "BUNDLE_VERSION_SUPERSEDED";
|
|
8570
|
+
/**
|
|
8571
|
+
* The bundle version is published, and its window has not opened: it goes
|
|
8572
|
+
* on sale on `validFrom`, and until then its predecessor is the one sold.
|
|
8573
|
+
*/
|
|
8574
|
+
readonly BUNDLE_VERSION_NOT_YET_ON_SALE: "BUNDLE_VERSION_NOT_YET_ON_SALE";
|
|
8575
|
+
/**
|
|
8576
|
+
* The add-on itself has been deleted from the catalogue. Deleting it leaves
|
|
8577
|
+
* its versions' dates as they were, so the version asked for can still be
|
|
8578
|
+
* inside its window; it is not on offer all the same.
|
|
8579
|
+
*/
|
|
8580
|
+
readonly BUNDLE_DELETED: "BUNDLE_DELETED";
|
|
6257
8581
|
readonly BUNDLE_VERSION_REGRESSION: "BUNDLE_VERSION_REGRESSION";
|
|
6258
8582
|
readonly BUNDLE_VERSION_ZERO_PRICE: "BUNDLE_VERSION_ZERO_PRICE";
|
|
6259
8583
|
readonly BUNDLE_VERSION_NO_PRICE: "BUNDLE_VERSION_NO_PRICE";
|
|
@@ -6271,6 +8595,13 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6271
8595
|
readonly PLAN_NOT_FOUND: "PLAN_NOT_FOUND";
|
|
6272
8596
|
readonly PLAN_VERSION_NOT_FOUND: "PLAN_VERSION_NOT_FOUND";
|
|
6273
8597
|
readonly BUNDLE_NOT_FOUND: "BUNDLE_NOT_FOUND";
|
|
8598
|
+
/**
|
|
8599
|
+
* Bookings told that their add-on version is being retired have still to
|
|
8600
|
+
* move onto a version of this add-on — waiting for their notice, for their
|
|
8601
|
+
* date, or past it — and a deleted add-on is booked by nothing, the move
|
|
8602
|
+
* included. Carries how many, and the add-on's key.
|
|
8603
|
+
*/
|
|
8604
|
+
readonly BUNDLE_DELETE_WHILE_RETIREMENT_MOVES_PENDING: "BUNDLE_DELETE_WHILE_RETIREMENT_MOVES_PENDING";
|
|
6274
8605
|
readonly BUNDLE_VERSION_NOT_FOUND: "BUNDLE_VERSION_NOT_FOUND";
|
|
6275
8606
|
readonly FEATURE_NOT_FOUND: "FEATURE_NOT_FOUND";
|
|
6276
8607
|
readonly QUOTA_NOT_FOUND: "QUOTA_NOT_FOUND";
|
|
@@ -6343,7 +8674,7 @@ declare const PLATFORM_ERROR_CODES: {
|
|
|
6343
8674
|
/** Email already taken (mapped from `PlatformUserExistsError`). */
|
|
6344
8675
|
readonly EMAIL_EXISTS: "EMAIL_EXISTS";
|
|
6345
8676
|
};
|
|
6346
|
-
type PlatformErrorCode = SetupErrorCode | AuthErrorCode | PromoErrorCode | CatalogErrorCode | BillingErrorCode | ContractErrorCode | SubscriberErrorCode | RegistrationErrorCode | PaymentErrorCode | SettingsErrorCode | MaintenanceErrorCode;
|
|
8677
|
+
type PlatformErrorCode = SetupErrorCode | AuthErrorCode | PromoErrorCode | CatalogErrorCode | BillingErrorCode | ContractErrorCode | SubscriberErrorCode | RegistrationErrorCode | PaymentErrorCode | SettingsErrorCode | MaintenanceErrorCode | TaxErrorCode;
|
|
6347
8678
|
/**
|
|
6348
8679
|
* Shape of a coded error response.
|
|
6349
8680
|
*
|
|
@@ -6381,6 +8712,161 @@ declare class PlatformUserExistsError extends Error {
|
|
|
6381
8712
|
* when thrower and catcher see the class from different module instances.
|
|
6382
8713
|
*/
|
|
6383
8714
|
declare function isPlatformUserExistsError(err: unknown): err is PlatformUserExistsError;
|
|
8715
|
+
/**
|
|
8716
|
+
* What a refused write found instead of the state its caller had read:
|
|
8717
|
+
* `gone` — the row no longer exists; `moved` — it exists, but no longer in the
|
|
8718
|
+
* state the write required, because a concurrent request changed it first.
|
|
8719
|
+
*/
|
|
8720
|
+
type PersistenceRefusalReason = 'gone' | 'moved';
|
|
8721
|
+
/**
|
|
8722
|
+
* A write an adapter refused because the row was no longer what the caller
|
|
8723
|
+
* read, carrying the platform's error code for that case.
|
|
8724
|
+
*
|
|
8725
|
+
* The platform checks these conditions before it writes and answers with the
|
|
8726
|
+
* same code. The adapter's own guard is what holds when two requests pass
|
|
8727
|
+
* that check together — a double click, two operators — and throwing this
|
|
8728
|
+
* rather than a plain `Error` gives the loser of that race the answer the
|
|
8729
|
+
* check would have given, instead of a 500 that reads like a crash in the log.
|
|
8730
|
+
* The adapter says what it found; the platform decides what that is on the
|
|
8731
|
+
* wire.
|
|
8732
|
+
*/
|
|
8733
|
+
declare class PersistenceRefusal extends Error {
|
|
8734
|
+
readonly code: string;
|
|
8735
|
+
readonly reason: PersistenceRefusalReason;
|
|
8736
|
+
readonly params: Readonly<Record<string, unknown>>;
|
|
8737
|
+
constructor(code: string, reason: PersistenceRefusalReason, message: string, params?: Readonly<Record<string, unknown>>);
|
|
8738
|
+
}
|
|
8739
|
+
/** Realm-safe type guard, like `isPlatformUserExistsError`. */
|
|
8740
|
+
declare function isPersistenceRefusal(err: unknown): err is PersistenceRefusal;
|
|
8741
|
+
|
|
8742
|
+
/**
|
|
8743
|
+
* The canonical models a schema may leave out, each with the persistence
|
|
8744
|
+
* bundle members that need it.
|
|
8745
|
+
*
|
|
8746
|
+
* `saasicat schema check` lists every canonical model it does not find as not
|
|
8747
|
+
* adopted. Naming one of these in a bundle's `notAdopted` leaves its members
|
|
8748
|
+
* out of the bundle, so the platform decides at start what it can do without
|
|
8749
|
+
* them — and says so where it cannot — instead of the first request failing
|
|
8750
|
+
* against a table that is not there. Any other model the bundle needs: an
|
|
8751
|
+
* application that leaves it out brings its own adapter for it.
|
|
8752
|
+
*/
|
|
8753
|
+
declare const OPTIONAL_CANONICAL_MODELS: {
|
|
8754
|
+
readonly SuperAdminUser: readonly ["core.superAdminProvisioning"];
|
|
8755
|
+
readonly SuperAdminMfa: readonly ["core.mfa"];
|
|
8756
|
+
readonly AppliedSettings: readonly ["core.appliedSettings"];
|
|
8757
|
+
readonly SettingsChange: readonly ["core.appliedSettings"];
|
|
8758
|
+
readonly MaintenanceWindow: readonly ["core.maintenanceWindows"];
|
|
8759
|
+
readonly SubscriptionNotice: readonly ["tenantBilling.subscriptionNotices"];
|
|
8760
|
+
readonly VersionRetirement: readonly ["tenantBilling.versionRetirements"];
|
|
8761
|
+
readonly BundleVersionRetirement: readonly ["tenantBilling.bundleVersionRetirements"];
|
|
8762
|
+
readonly SubscriberLedgerEntry: readonly ["entitlement.subscriberLedgerRepository"];
|
|
8763
|
+
readonly PromoCodeHold: readonly ["promo.holdRepository"];
|
|
8764
|
+
};
|
|
8765
|
+
type OptionalCanonicalModel = keyof typeof OPTIONAL_CANONICAL_MODELS;
|
|
8766
|
+
/** A bundle member one of the optional models is needed by. */
|
|
8767
|
+
type OptionalBundleMember = (typeof OPTIONAL_CANONICAL_MODELS)[OptionalCanonicalModel][number];
|
|
8768
|
+
/**
|
|
8769
|
+
* The bundle members a `notAdopted` list leaves out.
|
|
8770
|
+
*
|
|
8771
|
+
* A name that is not one of the optional models is refused rather than
|
|
8772
|
+
* ignored: a typo would otherwise leave a member in that fails at its first
|
|
8773
|
+
* request, and a model the bundle cannot run without needs the application's
|
|
8774
|
+
* own adapter, which only the application can supply.
|
|
8775
|
+
*/
|
|
8776
|
+
declare function membersLeftOut(notAdopted?: readonly string[]): ReadonlySet<OptionalBundleMember>;
|
|
8777
|
+
|
|
8778
|
+
/** Admits a piece of work when a place is free; see `concurrencyGate`. */
|
|
8779
|
+
type ConcurrencyGate = <T>(work: () => Promise<T>) => Promise<T>;
|
|
8780
|
+
/**
|
|
8781
|
+
* Admits at most `limit` pieces of work at once and queues the rest in the
|
|
8782
|
+
* order they arrived.
|
|
8783
|
+
*
|
|
8784
|
+
* Meant for transactions. Each holds a pooled connection for its whole life,
|
|
8785
|
+
* and the platform's transactions take row locks and then read further. Run
|
|
8786
|
+
* as many at once as there are requests, and every connection can end up held
|
|
8787
|
+
* by a transaction waiting for a lock — or for a connection a sibling needs —
|
|
8788
|
+
* while the statements that would let them finish wait for the pool: the
|
|
8789
|
+
* service stalls until transactions time out. A limit below the pool size
|
|
8790
|
+
* keeps connections free for the work outside a transaction.
|
|
8791
|
+
*
|
|
8792
|
+
* A place is handed to the next in line when work ends, however it ends, so
|
|
8793
|
+
* the count never rises above the limit and nobody waiting is overtaken.
|
|
8794
|
+
*/
|
|
8795
|
+
declare function concurrencyGate(limit: number): ConcurrencyGate;
|
|
8796
|
+
/**
|
|
8797
|
+
* The one gate of a pool: every caller naming the same `pool` — the client or
|
|
8798
|
+
* database handle the transactions run on — gets the same queue.
|
|
8799
|
+
*
|
|
8800
|
+
* A bound is a property of the pool, not of whoever builds a runner. Where
|
|
8801
|
+
* the client is an injection token, Nest builds a runner once for every module
|
|
8802
|
+
* that asks for one, all on the same client; a gate per runner would admit the
|
|
8803
|
+
* limit once per module, and a gate per configuration object would join two
|
|
8804
|
+
* pools that happen to share one. A second, different limit for a pool already
|
|
8805
|
+
* bounded is refused rather than split.
|
|
8806
|
+
*/
|
|
8807
|
+
declare function concurrencyGateOf(pool: object, limit: number): ConcurrencyGate;
|
|
8808
|
+
|
|
8809
|
+
/** The two versioned catalogue entities, by the name their rows go by. */
|
|
8810
|
+
type CatalogVersionKind = 'PlanVersion' | 'BundleVersion';
|
|
8811
|
+
/** A publish of a version that is not there, refused with the platform's code. */
|
|
8812
|
+
declare function catalogVersionGone(kind: CatalogVersionKind, versionId: string): PersistenceRefusal;
|
|
8813
|
+
/**
|
|
8814
|
+
* A publish or discard of a version somebody published first. A published
|
|
8815
|
+
* version is what tenants may have booked, so it is neither published a second
|
|
8816
|
+
* time — which would rewrite when and by whom — nor discarded.
|
|
8817
|
+
*/
|
|
8818
|
+
declare function catalogVersionAlreadyPublished(kind: CatalogVersionKind, versionId: string): PersistenceRefusal;
|
|
8819
|
+
/**
|
|
8820
|
+
* A draft asked for where the plan or bundle already has one: there is one
|
|
8821
|
+
* draft at a time, so that publishing it is never a choice between two.
|
|
8822
|
+
*/
|
|
8823
|
+
declare function catalogDraftExists(kind: CatalogVersionKind, key: string, draftVersion: number): PersistenceRefusal;
|
|
8824
|
+
|
|
8825
|
+
/** A plan key a plan already carries. */
|
|
8826
|
+
declare function planKeyTaken(planKey: string): PersistenceRefusal;
|
|
8827
|
+
/** A bundle key a bundle already carries. */
|
|
8828
|
+
declare function bundleKeyTaken(bundleKey: string): PersistenceRefusal;
|
|
8829
|
+
/** A marketing projection for a version and locale that already has one. */
|
|
8830
|
+
declare function marketingProjectionTaken(target: {
|
|
8831
|
+
targetType: string;
|
|
8832
|
+
targetVersionId: string;
|
|
8833
|
+
locale: string;
|
|
8834
|
+
}): PersistenceRefusal;
|
|
8835
|
+
|
|
8836
|
+
/**
|
|
8837
|
+
* The decimal a number was written as, for a `numeric` column.
|
|
8838
|
+
*
|
|
8839
|
+
* `toFixed` rounds the binary double rather than the decimal somebody typed:
|
|
8840
|
+
* `(1.005).toFixed(2)` is `'1.00'` and `(2.675).toFixed(2)` is `'2.67'`, while
|
|
8841
|
+
* `(10.005).toFixed(2)` is `'10.01'` — which way a value goes depends on its
|
|
8842
|
+
* binary representation, not on a rule anyone chose. The shortest decimal that
|
|
8843
|
+
* reads back as the same number is what was written; handed to the column, the
|
|
8844
|
+
* database applies its one rounding rule, half away from zero. Where the
|
|
8845
|
+
* platform validates an amount to the column's places at its boundary, nothing
|
|
8846
|
+
* is rounded at all.
|
|
8847
|
+
*/
|
|
8848
|
+
declare function toDecimalString(value: number): string;
|
|
8849
|
+
|
|
8850
|
+
/**
|
|
8851
|
+
* A code whose name is taken — by a live code, or by a deleted one, since a
|
|
8852
|
+
* deleted code keeps its name (`SC-PROMO-028`). The platform checks before it
|
|
8853
|
+
* creates; this is what the unique index answers when two creates race past
|
|
8854
|
+
* that check.
|
|
8855
|
+
*/
|
|
8856
|
+
declare function promoCodeTaken(code: string): PersistenceRefusal;
|
|
8857
|
+
|
|
8858
|
+
/** The tenant has no subscription to write to. */
|
|
8859
|
+
declare function subscriptionGone(tenantId: string): PersistenceRefusal;
|
|
8860
|
+
/** The plan to bind has no version in effect at `asOf`. */
|
|
8861
|
+
declare function noActivePlanVersion(planId: string, asOf: Date): PersistenceRefusal;
|
|
8862
|
+
/** The plan to bind is not in the catalogue, or was retired in the meantime. */
|
|
8863
|
+
declare function planNotInCatalog(planKey: string): PersistenceRefusal;
|
|
8864
|
+
/** The booking to cancel does not exist. */
|
|
8865
|
+
declare function subscriptionBundleGone(subscriptionBundleId: string): PersistenceRefusal;
|
|
8866
|
+
/** The booking to cancel was cancelled first, by another request. */
|
|
8867
|
+
declare function subscriptionBundleAlreadyCancelled(subscriptionBundleId: string): PersistenceRefusal;
|
|
8868
|
+
/** No contract of the tenant named carries the id. */
|
|
8869
|
+
declare function subscriptionContractGone(contractId: string): PersistenceRefusal;
|
|
6384
8870
|
|
|
6385
8871
|
/** Feature key → its `requires` keys (from Discovery/FeatureCatalogEntry). */
|
|
6386
8872
|
type FeatureRequiresIndex = ReadonlyMap<string, readonly string[]>;
|
|
@@ -6577,6 +9063,14 @@ interface PendingRegistration {
|
|
|
6577
9063
|
country: string | null;
|
|
6578
9064
|
vatId: string | null;
|
|
6579
9065
|
taxNumber: string | null;
|
|
9066
|
+
/** Whether the sign-up is a business, as step 4 says; `null` where it did not say. */
|
|
9067
|
+
business: boolean | null;
|
|
9068
|
+
/**
|
|
9069
|
+
* The check of `vatId` step 4 made, outside any transaction, where the tax
|
|
9070
|
+
* adapter needed a validated number to treat the sign-up; `null` where it
|
|
9071
|
+
* needed none. The subscriber takes it over when it is created.
|
|
9072
|
+
*/
|
|
9073
|
+
vatIdCheck: VatIdCheck | null;
|
|
6580
9074
|
/** The gateway's session for the payment method, unique within `checkoutGatewayAccount`. */
|
|
6581
9075
|
checkoutSessionId: string | null;
|
|
6582
9076
|
/** The account in `config/saas.yaml#payments.accounts` the session was opened at. */
|
|
@@ -6621,6 +9115,8 @@ interface PendingRegistrationUpdateInput {
|
|
|
6621
9115
|
country?: string | null;
|
|
6622
9116
|
vatId?: string | null;
|
|
6623
9117
|
taxNumber?: string | null;
|
|
9118
|
+
business?: boolean | null;
|
|
9119
|
+
vatIdCheck?: VatIdCheck | null;
|
|
6624
9120
|
checkoutSessionId?: string | null;
|
|
6625
9121
|
checkoutGatewayAccount?: string | null;
|
|
6626
9122
|
gatewayCustomerRef?: string | null;
|
|
@@ -6875,7 +9371,12 @@ interface ConfiguratorPlanMarketing {
|
|
|
6875
9371
|
*/
|
|
6876
9372
|
interface ConfiguratorMarketingProvider {
|
|
6877
9373
|
listPlanMarketing(): ConfiguratorPlanMarketing[];
|
|
6878
|
-
|
|
9374
|
+
/**
|
|
9375
|
+
* The rate the configurator shows. Required where config/saas.yaml names no
|
|
9376
|
+
* tax adapter; left out where it names one, whose rate for a subscriber in
|
|
9377
|
+
* the issuer's country is shown instead.
|
|
9378
|
+
*/
|
|
9379
|
+
getVatRate?(): number;
|
|
6879
9380
|
getCurrency(): string;
|
|
6880
9381
|
}
|
|
6881
9382
|
/**
|
|
@@ -7056,6 +9557,13 @@ interface RegistrationBillingDetails {
|
|
|
7056
9557
|
country: string;
|
|
7057
9558
|
vatId?: string | null;
|
|
7058
9559
|
taxNumber?: string | null;
|
|
9560
|
+
/**
|
|
9561
|
+
* Whether the sign-up is a business. A tax adapter decides from it — a
|
|
9562
|
+
* business elsewhere in the European Union, for instance, is charged under
|
|
9563
|
+
* the reverse charge — and refuses the step where it needs it and it is
|
|
9564
|
+
* missing.
|
|
9565
|
+
*/
|
|
9566
|
+
business?: boolean | null;
|
|
7059
9567
|
}
|
|
7060
9568
|
interface StartCheckoutInput {
|
|
7061
9569
|
pendingRegistrationId: string;
|
|
@@ -7116,13 +9624,6 @@ interface SetupConfirmMfaResponse {
|
|
|
7116
9624
|
ok: boolean;
|
|
7117
9625
|
}
|
|
7118
9626
|
|
|
7119
|
-
/** What the adapter's schema can actually answer about a version's dates. */
|
|
7120
|
-
interface PlanVersionMappingFields {
|
|
7121
|
-
/** `validFrom`/`validUntil` are maintained; otherwise both read as null. */
|
|
7122
|
-
validityWindows: boolean;
|
|
7123
|
-
/** `endsAt` exists; otherwise the field is left off the record entirely. */
|
|
7124
|
-
endsAt: boolean;
|
|
7125
|
-
}
|
|
7126
9627
|
/** A `plans` row as either adapter reads it back. */
|
|
7127
9628
|
interface CanonicalPlanRow {
|
|
7128
9629
|
id: string;
|
|
@@ -7150,9 +9651,9 @@ interface CanonicalPlanVersionRow {
|
|
|
7150
9651
|
publishedChanges: unknown;
|
|
7151
9652
|
changeNote: string;
|
|
7152
9653
|
nonRegressive: boolean;
|
|
7153
|
-
validFrom
|
|
7154
|
-
validUntil
|
|
7155
|
-
endsAt
|
|
9654
|
+
validFrom: Date | null;
|
|
9655
|
+
validUntil: Date | null;
|
|
9656
|
+
endsAt: Date | null;
|
|
7156
9657
|
createdByUserId: string | null;
|
|
7157
9658
|
publishedByUserId: string | null;
|
|
7158
9659
|
createdAt: Date;
|
|
@@ -7165,7 +9666,7 @@ declare function toPlanRow(row: CanonicalPlanRow): PlanRow;
|
|
|
7165
9666
|
* real foreign key has to resolve it first, and only the adapter knows which
|
|
7166
9667
|
* shape it is looking at.
|
|
7167
9668
|
*/
|
|
7168
|
-
declare function toPlanVersionRow(row: CanonicalPlanVersionRow, planKey: string
|
|
9669
|
+
declare function toPlanVersionRow(row: CanonicalPlanVersionRow, planKey: string): PlanVersionRow;
|
|
7169
9670
|
|
|
7170
9671
|
/**
|
|
7171
9672
|
* The legal identity of the issuer a catalogue names, or none where it names no
|
|
@@ -7319,10 +9820,21 @@ interface CanonicalSubscriberRow {
|
|
|
7319
9820
|
vatId: string | null;
|
|
7320
9821
|
taxNumber: string | null;
|
|
7321
9822
|
invoiceEmail: string | null;
|
|
9823
|
+
business: boolean | null;
|
|
7322
9824
|
migrated: boolean;
|
|
7323
9825
|
createdAt: Date;
|
|
7324
9826
|
updatedAt: Date;
|
|
7325
9827
|
}
|
|
9828
|
+
/** A `subscriber_tax_origin_changes` row as either adapter reads it back. */
|
|
9829
|
+
interface CanonicalSubscriberTaxOriginChangeRow {
|
|
9830
|
+
id: string;
|
|
9831
|
+
subscriberId: string;
|
|
9832
|
+
previous: unknown;
|
|
9833
|
+
changed: unknown;
|
|
9834
|
+
changedBy: string;
|
|
9835
|
+
changedAt: Date;
|
|
9836
|
+
reason: string | null;
|
|
9837
|
+
}
|
|
7326
9838
|
/** A `subscriber_corrections` row as either adapter reads it back. */
|
|
7327
9839
|
interface CanonicalSubscriberCorrectionRow {
|
|
7328
9840
|
id: string;
|
|
@@ -7342,6 +9854,7 @@ declare function formatCustomerNumber(prefix: string, sequence: number): string;
|
|
|
7342
9854
|
/** `tenantId` is the tenant the subscriber's live link names, read beside the row. */
|
|
7343
9855
|
declare function toSubscriberRecord(row: CanonicalSubscriberRow, tenantId: string | null): SubscriberRecord;
|
|
7344
9856
|
declare function toSubscriberCorrectionRecord(row: CanonicalSubscriberCorrectionRow): SubscriberCorrectionRecord;
|
|
9857
|
+
declare function toSubscriberTaxOriginChangeRecord(row: CanonicalSubscriberTaxOriginChangeRow): SubscriberTaxOriginChangeRecord;
|
|
7345
9858
|
/**
|
|
7346
9859
|
* The part of a correction that changes something: every corrected field whose
|
|
7347
9860
|
* stored value differs, with the value it replaces. Both adapters decide this
|
|
@@ -7359,7 +9872,7 @@ declare function contractPartiesOf(subscriber: SubscriberRecord, issuer: PlanCat
|
|
|
7359
9872
|
* verified with as its invoice email, and the billing address and tax
|
|
7360
9873
|
* identifiers step 4 took.
|
|
7361
9874
|
*/
|
|
7362
|
-
declare function subscriberFromRegistration(pending: Pick<PendingRegistration, 'tenantName' | 'email' | 'addressLine1' | 'addressLine2' | 'postalCode' | 'city' | 'country' | 'vatId' | 'taxNumber'>): NewSubscriberDetails;
|
|
9875
|
+
declare function subscriberFromRegistration(pending: Pick<PendingRegistration, 'tenantName' | 'email' | 'addressLine1' | 'addressLine2' | 'postalCode' | 'city' | 'country' | 'vatId' | 'taxNumber' | 'business' | 'vatIdCheck'>): NewSubscriberDetails;
|
|
7363
9876
|
|
|
7364
9877
|
/** The payment method types, in the order a form offers them. */
|
|
7365
9878
|
declare const PAYMENT_METHOD_TYPES: readonly PaymentMethodType[];
|
|
@@ -7436,9 +9949,10 @@ declare function refuseForeignPaymentMethodReference(recorded: Pick<CanonicalSub
|
|
|
7436
9949
|
/**
|
|
7437
9950
|
* A `subscription_bundles` row as either adapter reads it back.
|
|
7438
9951
|
*
|
|
7439
|
-
* The three billing columns
|
|
7440
|
-
* a schema that predates them returns a
|
|
7441
|
-
* reads as null, the same as a booking made
|
|
9952
|
+
* The three billing columns and the two of a scheduled switch are optional
|
|
9953
|
+
* because a Prisma client generated from a schema that predates them returns a
|
|
9954
|
+
* row without them; an absent column reads as null, the same as a booking made
|
|
9955
|
+
* before they existed.
|
|
7442
9956
|
*/
|
|
7443
9957
|
interface CanonicalSubscriptionBundleRow {
|
|
7444
9958
|
id: string;
|
|
@@ -7449,6 +9963,8 @@ interface CanonicalSubscriptionBundleRow {
|
|
|
7449
9963
|
billingCycle?: string | null;
|
|
7450
9964
|
currentPeriodStart?: Date | null;
|
|
7451
9965
|
currentPeriodEnd?: Date | null;
|
|
9966
|
+
pendingBundleVersionId?: string | null;
|
|
9967
|
+
pendingVersionEffectiveAt?: Date | null;
|
|
7452
9968
|
canceledAt: Date | null;
|
|
7453
9969
|
canceledEffectiveAt: Date | null;
|
|
7454
9970
|
createdAt: Date;
|
|
@@ -7472,6 +9988,8 @@ interface CanonicalContractRow {
|
|
|
7472
9988
|
subscriberSnapshot: unknown;
|
|
7473
9989
|
issuerSnapshot: unknown;
|
|
7474
9990
|
partiesMigrated: boolean;
|
|
9991
|
+
/** JSON; see `toTaxTreatment`. */
|
|
9992
|
+
taxTreatment: unknown;
|
|
7475
9993
|
status: string;
|
|
7476
9994
|
effectiveFrom: Date;
|
|
7477
9995
|
effectiveUntil: Date | null;
|
|
@@ -7526,6 +10044,100 @@ interface CanonicalRunningContractRow {
|
|
|
7526
10044
|
/** One running contract, and the legal name on its issuer copy where it has one. */
|
|
7527
10045
|
declare function toRunningContractIssuer(row: CanonicalRunningContractRow): RunningContractIssuer;
|
|
7528
10046
|
|
|
10047
|
+
/**
|
|
10048
|
+
* A VAT identification number in the one form it is stored, compared and
|
|
10049
|
+
* checked in: upper case, without the spaces, dots and hyphens it is often
|
|
10050
|
+
* written with. `atu 123.456-78` is `ATU12345678` — the same number, so
|
|
10051
|
+
* entering it in another spelling moves nothing. `null` where nothing is left.
|
|
10052
|
+
* The platform settles every number it is given with this, and a form that
|
|
10053
|
+
* asks whether a number changed compares with it too.
|
|
10054
|
+
*/
|
|
10055
|
+
declare function canonicalVatId(written: string): string | null;
|
|
10056
|
+
/** A `subscriber_vat_id_checks` row as either adapter reads it back. */
|
|
10057
|
+
interface CanonicalSubscriberVatIdCheckRow {
|
|
10058
|
+
id: string;
|
|
10059
|
+
subscriberId: string;
|
|
10060
|
+
vatId: string;
|
|
10061
|
+
checkedAt: Date;
|
|
10062
|
+
valid: boolean;
|
|
10063
|
+
service: string;
|
|
10064
|
+
confirmation: unknown;
|
|
10065
|
+
recordedAt: Date;
|
|
10066
|
+
}
|
|
10067
|
+
/**
|
|
10068
|
+
* What an adapter decides a subscriber's treatment from: the record as it
|
|
10069
|
+
* stands, and the check that counts for its number now. The number counts as
|
|
10070
|
+
* validated only when that check is of the number the subscriber has and found
|
|
10071
|
+
* it valid.
|
|
10072
|
+
*/
|
|
10073
|
+
declare function taxOriginOf(subscriber: Pick<SubscriberRecord, SubscriberTaxOriginField>, currentCheck: VatIdCheck | null): SubscriberTaxOrigin;
|
|
10074
|
+
/** The subscriber's number, and since when it holds it. */
|
|
10075
|
+
interface HeldVatId {
|
|
10076
|
+
vatId: string | null;
|
|
10077
|
+
/**
|
|
10078
|
+
* When the number was last set by a correction; `null` while it is the one
|
|
10079
|
+
* the subscriber was created with.
|
|
10080
|
+
*/
|
|
10081
|
+
vatIdSince: Date | null;
|
|
10082
|
+
}
|
|
10083
|
+
/**
|
|
10084
|
+
* Whether a check just recorded is the one that counts from now on, given the
|
|
10085
|
+
* subscriber's number and the check that counts now. Only a check of the
|
|
10086
|
+
* number the subscriber holds, completed while it held it, and never over a
|
|
10087
|
+
* check that completed later:
|
|
10088
|
+
*
|
|
10089
|
+
* - A check completed before the number was last set says nothing about it:
|
|
10090
|
+
* the number was away in between, and may have been revoked meanwhile.
|
|
10091
|
+
* - Two checks of one number can run side by side, and the one written last
|
|
10092
|
+
* is not the latest — an older "valid" written after a newer "invalid" would
|
|
10093
|
+
* validate a number the latest check refused. Of two checks with the same
|
|
10094
|
+
* date, the one written last counts.
|
|
10095
|
+
*
|
|
10096
|
+
* `vatIdSince` and `checkedAt` are both the platform's clock; between two
|
|
10097
|
+
* instances, the window this leaves is the difference between their clocks.
|
|
10098
|
+
*/
|
|
10099
|
+
declare function keepsVatIdCheck(held: HeldVatId, counting: VatIdCheck | null, check: VatIdCheck): boolean;
|
|
10100
|
+
/** A recorded check read back; a confirmation of another shape reads as empty. */
|
|
10101
|
+
declare function toSubscriberVatIdCheckRecord(row: CanonicalSubscriberVatIdCheckRow): SubscriberVatIdCheckRecord;
|
|
10102
|
+
/** A treatment as it is stored on a contract. */
|
|
10103
|
+
declare function taxTreatmentToJson(treatment: TaxTreatment): Record<string, unknown>;
|
|
10104
|
+
/** A stored treatment read back, or `null` where none is stored or it has another shape. */
|
|
10105
|
+
declare function toTaxTreatment(value: unknown): TaxTreatment | null;
|
|
10106
|
+
/** What a write moves of a subscriber's tax origin, and what follows from it. */
|
|
10107
|
+
interface TaxOriginWrite {
|
|
10108
|
+
/** The values the write replaces, holding only the fields it moves. */
|
|
10109
|
+
previous: SubscriberTaxOriginValues;
|
|
10110
|
+
/** The values it writes, holding only the fields it moves. */
|
|
10111
|
+
changed: SubscriberTaxOriginValues;
|
|
10112
|
+
/** Whether it moves anything, and so has a change to record. */
|
|
10113
|
+
moved: boolean;
|
|
10114
|
+
/**
|
|
10115
|
+
* Whether it moves the VAT identification number. The check that counted
|
|
10116
|
+
* for the old number then counts no more — it says nothing about the new
|
|
10117
|
+
* one, nor about the old one should it come back later — while the check
|
|
10118
|
+
* itself stays recorded; and the number held is held since this write
|
|
10119
|
+
* (`HeldVatId.vatIdSince`).
|
|
10120
|
+
*/
|
|
10121
|
+
endsCountingVatIdCheck: boolean;
|
|
10122
|
+
}
|
|
10123
|
+
/**
|
|
10124
|
+
* What a write moves of the tax origin: every field named whose stored value
|
|
10125
|
+
* differs, with the value it replaces. Every adapter asks this under the lock
|
|
10126
|
+
* it read `current` with, and applies the answer: a change is recorded only
|
|
10127
|
+
* when it moved something.
|
|
10128
|
+
*/
|
|
10129
|
+
declare function taxOriginWrite(current: Pick<SubscriberRecord, SubscriberTaxOriginField>, next: SubscriberTaxOriginValues): TaxOriginWrite;
|
|
10130
|
+
/** Stored tax origin values read back, holding only the fields that are there. */
|
|
10131
|
+
declare function toTaxOriginValues(value: unknown): SubscriberTaxOriginValues;
|
|
10132
|
+
/**
|
|
10133
|
+
* A check of a VAT identification number as a store gives it back. A sign-up
|
|
10134
|
+
* keeps its check where the application's repository puts it — often a JSON
|
|
10135
|
+
* column, which hands `checkedAt` back as text — so it is read again here,
|
|
10136
|
+
* once. Anything that is not a whole check reads as none: a number never
|
|
10137
|
+
* counts as validated on a record that cannot say so.
|
|
10138
|
+
*/
|
|
10139
|
+
declare function vatIdCheckFromStore(value: unknown): VatIdCheck | null;
|
|
10140
|
+
|
|
7529
10141
|
/** Why a version is editable (for UI badges + audit logs). */
|
|
7530
10142
|
type VersionEditableReason = 'draft' | 'pre-active';
|
|
7531
10143
|
interface VersionEditability {
|
|
@@ -7607,4 +10219,4 @@ declare function resolveErrorMessage(body: ResolvableErrorBody, overrides?: Part
|
|
|
7607
10219
|
|
|
7608
10220
|
declare const ERROR_MESSAGES_DE: Record<PlatformErrorCode, string>;
|
|
7609
10221
|
|
|
7610
|
-
export { ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES, AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminAccountEntry, type AdminAccountHolder, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriberAccount, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminUserListFilter, type AdminUserListRow, type AppliedSettingsPort, type AppliedSettingsRecord, type AppliedSettingsValues, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, BUNDLE_PRICE_LOOKUP_LIMIT, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionRow, CATALOGUE_KEYS, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, type CancelSubscriptionBundleData, type CancelSubscriptionInput, type CancelSubscriptionResult, type CancellationNoticePeriods, type CanonicalContractLineItemRow, type CanonicalContractRow, type CanonicalMaintenanceWindowRow, type CanonicalPlanRow, type CanonicalPlanVersionRow, type CanonicalRunningContractRow, type CanonicalSubscriberChargeRow, type CanonicalSubscriberCorrectionRow, type CanonicalSubscriberPaymentMethodRow, type CanonicalSubscriberRow, type CanonicalSubscriptionBundleRow, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferSelection, type CheckoutOfferSelectionUpdate, type CheckoutOfferStatus, type CleanupResult, type CliUserRow, type ComponentKey, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ConfirmedPaymentMethod, type ContractErrorCode, type ContractIssuerParty, type ContractLineItemKind, type ContractLineItemRecord, type ContractSubscriberParty, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriberData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type EmailPort, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, ForeignPaymentMethodReferenceError, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type IssuerCorrectionFault, type IssuerIdentityChange, type KpiCardDef, type KpiDisplayHint, LEGAL_IDENTITY_FIELDS, type LegalIdentity, type LegalIdentityField, MAINTENANCE_CAPABILITY, MAINTENANCE_ERROR_CODES, MAINTENANCE_MESSAGE_MAX_LENGTH, MAINTENANCE_STATE_MAX_AGE_SECONDS, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type MaintenanceErrorCode, type MaintenanceLockView, type MaintenanceNotificationPort, type MaintenanceOverview, type MaintenanceStatusView, type MaintenanceUnlockView, type MaintenanceWindowChanges, type MaintenanceWindowEvent, type MaintenanceWindowPort, type MaintenanceWindowRecord, type MaintenanceWindowStage, type MaintenanceWindowStatus, type MaintenanceWindowView, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MaskedPaymentMethod, type MfaPort, type NewContractLineItemData, type NewMaintenanceWindow, type NewSettingsChange, type NewSubscriberCharge, type NewSubscriberDetails, type NewSubscriptionContractData, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, PASSWORD_RESET_TTL_MINUTES, PAYMENT_ERROR_CODES, PAYMENT_METHOD_TYPES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PartyAddress, type PasswordHasher, type PasswordResetCliResult, PaymentCallbackRejectedError, type PaymentErrorCode, type PaymentEventClaim, type PaymentEventLog, type PaymentGateway, type PaymentGatewayCallback, type PaymentGatewayEvent, type PaymentMethodHolder, type PaymentMethodSetupSession, type PaymentMethodSetupSubject, type PaymentMethodType, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogIssuer, type PlanCatalogIssuerCorrection, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogNotifications, type PlanCatalogPaymentAccount, type PlanCatalogPayments, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanCatalogSettings, type PlanCatalogSubscribers, type PlanCatalogTenantBilling, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMappingFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeHoldRecord, type PromoCodeHoldRepository, type PromoCodeHoldTaken, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionI18n, type PromotionI18nFields, type PromotionOnPrice, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicNewPaymentMethods, type PublicSignupPlan, type PublishBundleVersionData, type PublishBundleVersionMeta, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, type ReassignTenantAdminCliResult, type RecommendablePlan, type RecordSubscriberPaymentMethodData, type RecordSubscriberPaymentMethodOutcome, type RecordSubscriberPaymentMethodResult, type RedeemPromoInTransactionCallback, type RegistrationActivation, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationBillingDetails, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResolvableErrorBody, type ResumeRegistrationInput, type ResumeRegistrationResult, type ReviewCatalogEntryData, type RlsBypassPort, type RunningContractIssuer, type RunningContractIssuers, SETTINGS_ERROR_CODES, SETUP_ERROR_CODES, SUBSCRIBER_ACCOUNT_CAPABILITY, SUBSCRIBER_ERROR_CODES, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePayments, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledPlanChangeInput, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SelfServiceBlockedPlans, type SetCatalogEntryReviewData, type SettingsChangeFilter, type SettingsChangeRecord, type SettingsDifference, type SettingsErrorCode, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartPaymentMethodSetupInput, type StartRegistrationInput, type StartRegistrationResult, type StoredBundleStem, type StrictModeWarning, type StrictModeWarningCode, type SubscriberCharge, type SubscriberChargeOrigin, type SubscriberChargeRecord, type SubscriberChargeSource, type SubscriberContact, type SubscriberContactChange, type SubscriberCorrectionData, type SubscriberCorrectionRecord, type SubscriberCorrectionResult, type SubscriberDetails, type SubscriberErrorCode, type SubscriberIdentityCorrection, type SubscriberIdentityDelta, type SubscriberIdentityValues, type SubscriberLedgerRepository, type SubscriberPaymentMethodRecord, type SubscriberPaymentMethodReference, type SubscriberPaymentMethodRepository, type SubscriberPaymentMethodSetupData, type SubscriberPaymentMethodSetupMatch, type SubscriberPaymentMethodStatus, type SubscriberRecord, type SubscriberRepository, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractParties, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SupersedeSubscriptionContractData, type SyncDiscoveryResult, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, bundleDraftDefaults, bundleStemDefaults, canonicalJson, classifyBundleVersionDiff, classifyIssuerChange, classifyPlanDiff, collectUnsatisfiedRequires, contractPartiesOf, coverageExcludingSelf, definedFields, diffSettings, formatCustomerNumber, formatErrorMessage, identityCorrectionDelta, isBundleRedundant, isForeignPaymentMethodReferenceError, isMaintenanceAnnouncementLapsed, isMaintenanceOverrun, isPaymentCallbackRejectedError, isPlatformUserExistsError, isVersionEditable, issuerIdentityOf, keepOneRecommended, maintenanceRetryAfterSeconds, maintenanceStatusOf, maintenanceWindowStatusOf, maintenanceWindowViewOf, missingRequiresFor, movedIdentityFields, parseZonedInstant, pickActivePromo, planCatalogSettingsOf, previousUtcDay, promoStatus, promotionOnPrice, readQuotaRecord, readQuotaValue, recordedIssuerIdentity, refuseForeignPaymentMethodReference, resolveBundleAvailability, resolveErrorMessage, sameLegalIdentity, selectChargeableBundles, settingsSubtreeOf, startOfUtcDay, subscriberChargeColumns, subscriberFromRegistration, subscriberPaymentMethodColumns, toBundleStemRow, toContractLineItemRecord, toMaintenanceWindowRecord, toPlanRow, toPlanVersionRow, toRunningContractIssuer, toSubscriberChargeRecord, toSubscriberCorrectionRecord, toSubscriberPaymentMethodRecord, toSubscriberRecord, toSubscriptionBundleRecord, toSubscriptionContractRecord };
|
|
10222
|
+
export { ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES, AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminAccountEntry, type AdminAccountHolder, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriberAccount, type AdminSubscriberAttention, type AdminSubscriberCorrected, type AdminSubscriberHistoryEntry, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminTenantSubscriber, type AdminUserListFilter, type AdminUserListRow, type AdminVatIdCheckOutcome, type AppliedSettingsPort, type AppliedSettingsRecord, type AppliedSettingsValues, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditActor, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, BUNDLE_PRICE_LOOKUP_LIMIT, BUNDLE_VERSION_RETIREMENT_CAPABILITY, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRetirementAnnounced, type BundleRetirementPreview, type BundleRetirementReachedRow, type BundleRetirementSkipReason, type BundleRetirementSkippedRow, type BundleRetirementSwitchResult, type BundleRetirementSwitchTerms, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionOfferView, type BundleVersionOfferedNotice, type BundleVersionRetiredNotice, type BundleVersionRetirementRecord, type BundleVersionRetirementReminder, type BundleVersionRetirementRepository, type BundleVersionRetirementView, type BundleVersionRow, type BundleVersionSide, type BundleVersionSwitchResult, CATALOGUE_KEYS, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, CUSTOM_LIMITS_KEYS, type CancelSubscriptionBundleData, type CancelSubscriptionInput, type CancelSubscriptionResult, type CancellationNoticePeriods, type CanonicalBundleVersionRetirementRow, type CanonicalContractLineItemRow, type CanonicalContractRow, type CanonicalMaintenanceWindowRow, type CanonicalPlanRow, type CanonicalPlanVersionRow, type CanonicalRunningContractRow, type CanonicalSubscriberChargeRow, type CanonicalSubscriberCorrectionRow, type CanonicalSubscriberPaymentMethodRow, type CanonicalSubscriberRow, type CanonicalSubscriberTaxOriginChangeRow, type CanonicalSubscriberVatIdCheckRow, type CanonicalSubscriptionBundleRow, type CanonicalSubscriptionNoticeRow, type CanonicalVersionRetirementRow, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type CatalogVersionKind, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferSelection, type CheckoutOfferSelectionUpdate, type CheckoutOfferStatus, type CleanupResult, type CliUserRow, type ComponentKey, type ConcurrencyGate, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ConfirmedPaymentMethod, type ContractErrorCode, type ContractIssuerParty, type ContractLineItemKind, type ContractLineItemRecord, type ContractSubscriberParty, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriberData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type CustomLimits, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type EmailPort, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, ForeignPaymentMethodReferenceError, type HeldVatId, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type IssuerCorrectionFault, type IssuerIdentityChange, type KpiCardDef, type KpiDisplayHint, LEGAL_IDENTITY_FIELDS, type LegalIdentity, type LegalIdentityField, MAINTENANCE_CAPABILITY, MAINTENANCE_ERROR_CODES, MAINTENANCE_MESSAGE_MAX_LENGTH, MAINTENANCE_STATE_MAX_AGE_SECONDS, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type MaintenanceErrorCode, type MaintenanceLockView, type MaintenanceNotificationPort, type MaintenanceOverview, type MaintenanceStatusView, type MaintenanceUnlockView, type MaintenanceWindowChanges, type MaintenanceWindowEvent, type MaintenanceWindowPort, type MaintenanceWindowRecord, type MaintenanceWindowStage, type MaintenanceWindowStatus, type MaintenanceWindowView, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MaskedPaymentMethod, type MfaPort, NO_SCHEDULED_CHANGE, type NewBundleVersionRetirement, type NewContractLineItemData, type NewMaintenanceWindow, type NewSettingsChange, type NewSubscriberCharge, type NewSubscriberDetails, type NewSubscriptionContractData, type NewVersionRetirement, type NotToldReasons, type NoticeToRecord, OPTIONAL_CANONICAL_MODELS, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, type OptionalBundleMember, type OptionalCanonicalModel, type OrderlyRetirementSettings, PASSWORD_RESET_TTL_MINUTES, PAYMENT_ERROR_CODES, PAYMENT_METHOD_TYPES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PartyAddress, type PasswordHasher, type PasswordResetCliResult, PaymentCallbackRejectedError, type PaymentErrorCode, type PaymentEventClaim, type PaymentEventLog, type PaymentGateway, type PaymentGatewayCallback, type PaymentGatewayEvent, type PaymentMethodHolder, type PaymentMethodSetupSession, type PaymentMethodSetupSubject, type PaymentMethodType, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, PersistenceRefusal, type PersistenceRefusalReason, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogIssuer, type PlanCatalogIssuerCorrection, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogNotifications, type PlanCatalogPaymentAccount, type PlanCatalogPayments, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanCatalogSettings, type PlanCatalogSubscribers, type PlanCatalogTax, type PlanCatalogTenantBilling, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformJobActor, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeHoldRecord, type PromoCodeHoldRepository, type PromoCodeHoldTaken, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionI18n, type PromotionI18nFields, type PromotionOnPrice, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicNewPaymentMethods, type PublicSignupPlan, type PublishBundleVersionData, type PublishBundleVersionMeta, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, RETIREMENT_REMINDER_LEAD_DAYS, type ReadCustomLimits, type ReassignTenantAdminCliResult, type RecommendablePlan, type RecordSubscriberPaymentMethodData, type RecordSubscriberPaymentMethodOutcome, type RecordSubscriberPaymentMethodResult, type RecordedVatIdCheck, type RedeemPromoInTransactionCallback, type RegistrationActivation, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationBillingDetails, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResolvableErrorBody, type ResumeRegistrationInput, type ResumeRegistrationResult, type RetiredBundleVersionRef, type RetiredVersionRef, type RetirementAnnounced, type RetirementBlocker, type RetirementMoveRun, type RetirementPreview, type RetirementPricedSide, type RetirementProgress, type RetirementReachedRow, type RetirementSide, type RetirementSkipReason, type RetirementSkippedRow, type RetirementSwitchResult, type RetirementSwitchTerms, type ReviewCatalogEntryData, type RlsBypassPort, type RunningContractIssuer, type RunningContractIssuers, SETTINGS_ERROR_CODES, SETUP_ERROR_CODES, SUBSCRIBER_ACCOUNT_CAPABILITY, SUBSCRIBER_ATTENTION_CAPABILITY, SUBSCRIBER_ATTENTION_PAGE_SIZE, SUBSCRIBER_CORRECTION_CAPABILITY, SUBSCRIBER_ERROR_CODES, SUBSCRIBER_INVOICE_ADDRESS_FIELDS, SUBSCRIBER_STANDING_CAPABILITY, SUBSCRIBER_TAX_ORIGIN_FIELDS, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePayments, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledChangeColumns, type ScheduledPlanChangeInput, type SecretSealer, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SelfServiceBlockedPlans, type SetCatalogEntryReviewData, type SettingsChangeFilter, type SettingsChangeRecord, type SettingsDifference, type SettingsErrorCode, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartPaymentMethodSetupInput, type StartRegistrationInput, type StartRegistrationResult, type StoredBundleStem, type StrictModeWarning, type StrictModeWarningCode, type SubscriberBusinessStatusData, type SubscriberBusinessStatusResult, type SubscriberCharge, type SubscriberChargeOrigin, type SubscriberChargeRecord, type SubscriberChargeSource, type SubscriberContact, type SubscriberContactChange, type SubscriberCorrectionData, type SubscriberCorrectionRecord, type SubscriberCorrectionResult, type SubscriberDetails, type SubscriberErrorCode, type SubscriberIdentityCorrection, type SubscriberIdentityDelta, type SubscriberIdentityValues, type SubscriberInvoiceAddressField, type SubscriberLedgerRepository, type SubscriberPaymentMethodRecord, type SubscriberPaymentMethodReference, type SubscriberPaymentMethodRepository, type SubscriberPaymentMethodSetupData, type SubscriberPaymentMethodSetupMatch, type SubscriberPaymentMethodStatus, type SubscriberReadiness, type SubscriberRecord, type SubscriberRepository, type SubscriberTaxOrigin, type SubscriberTaxOriginChangeRecord, type SubscriberTaxOriginField, type SubscriberTaxOriginValues, type SubscriberTaxStatus, type SubscriberVatIdCheckRecord, type SubscriberVatIdCheckResult, type SubscriberWithCurrentCheck, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractParties, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionNotice, type SubscriptionNoticeDelivery, type SubscriptionNoticeKey, type SubscriptionNoticeKind, type SubscriptionNoticePort, type SubscriptionNoticeRecord, type SubscriptionNoticeRepository, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SupersedeSubscriptionContractData, type SyncDiscoveryResult, TAX_ERROR_CODES, TAX_TREATMENT_KINDS, type TaxAdapter, type TaxAdapterFactory, type TaxAdapterIdentity, type TaxDecision, type TaxDecisionRequest, type TaxErrorCode, type TaxIssuer, type TaxOriginWrite, type TaxTreatment, type TaxTreatmentKind, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionUsage, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, VERSION_RETIREMENT_CAPABILITY, type VatIdCheck, type VatIdCheckOutcome, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionOffer, type VersionOfferClass, type VersionOfferFields, type VersionOfferSide, type VersionOfferView, type VersionOfferedNotice, type VersionRetiredNotice, type VersionRetirementRecord, type VersionRetirementReminder, type VersionRetirementRepository, type VersionRetirementView, type VersionSale, type VersionSaleDates, type VersionSaleKind, type VersionSwitchResult, type VersionWindow, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, bundleDraftDefaults, bundleKeyTaken, bundleStemDefaults, canonicalJson, canonicalVatId, catalogDraftExists, catalogVersionAlreadyPublished, catalogVersionGone, classifyBundleVersionDiff, classifyIssuerChange, classifyPlanDiff, classifyVersionOffer, collectUnsatisfiedRequires, computeIncludedVat, concurrencyGate, concurrencyGateOf, contractPartiesOf, coverageExcludingSelf, customLimitsReader, definedFields, diffSettings, formatCustomerNumber, formatErrorMessage, grossFromNet, identityCorrectionDelta, isBundleRedundant, isForeignPaymentMethodReferenceError, isMaintenanceAnnouncementLapsed, isMaintenanceOverrun, isPaymentCallbackRejectedError, isPersistenceRefusal, isPlatformUserExistsError, isVersionActiveAt, isVersionEditable, issuerIdentityOf, keepOneRecommended, keepsVatIdCheck, maintenanceRetryAfterSeconds, maintenanceStatusOf, maintenanceWindowStatusOf, maintenanceWindowViewOf, marketingProjectionTaken, membersLeftOut, missingRequiresFor, movedIdentityFields, netFromGross, noActivePlanVersion, parseZonedInstant, percentOf, pickActivePromo, planCatalogSettingsOf, planKeyTaken, planNotInCatalog, previousUtcDay, promoCodeTaken, promoStatus, promotionOnPrice, prorate, readCustomLimits, readQuotaRecord, readQuotaValue, recordedIssuerIdentity, refuseForeignPaymentMethodReference, resolveBundleAvailability, resolveErrorMessage, retirementCostsTheSubscription, retirementReminderDueAt, retirementReminderIsDue, retirementSwitchTerms, roundToCents, sameLegalIdentity, scheduledChangeAfterWrite, selectChargeableBundles, settingsSubtreeOf, startOfUtcDay, subscriberChargeColumns, subscriberFromRegistration, subscriberPaymentMethodColumns, subscriptionBundleAlreadyCancelled, subscriptionBundleGone, subscriptionContractGone, subscriptionGone, sumToCents, taxOriginOf, taxOriginWrite, taxTreatmentToJson, toBundleStemRow, toBundleVersionRetirementRecord, toCents, toContractLineItemRecord, toDecimalString, toMaintenanceWindowRecord, toPlanRow, toPlanVersionRow, toRunningContractIssuer, toSubscriberChargeRecord, toSubscriberCorrectionRecord, toSubscriberPaymentMethodRecord, toSubscriberRecord, toSubscriberTaxOriginChangeRecord, toSubscriberVatIdCheckRecord, toSubscriptionBundleRecord, toSubscriptionContractRecord, toSubscriptionNoticeRecord, toTaxOriginValues, toTaxTreatment, toVersionRetirementRecord, vatIdCheckFromStore, versionOnSale, versionOnSaleOrNext, versionSale };
|