@cosmicdrift/kumiko-bundled-features 0.337.1 → 0.339.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/dist/agent-tools/tool-catalog.js +37 -17
  2. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +3 -2
  3. package/dist/auth-email-password/handlers/invite-accept.write.js +3 -4
  4. package/dist/auth-email-password/handlers/invite-info.query.js +4 -1
  5. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +3 -4
  6. package/dist/auth-email-password/handlers/signup-confirm.write.js +2 -1
  7. package/dist/auth-email-password/handlers/signup-request.write.js +2 -2
  8. package/dist/auth-email-password/web/auth-gate.d.ts +12 -2
  9. package/dist/auth-email-password/web/auth-gate.js +25 -1
  10. package/dist/auth-email-password/web/auth-redirect.d.ts +5 -0
  11. package/dist/auth-email-password/web/auth-redirect.js +58 -0
  12. package/dist/auth-email-password/web/client-plugin.d.ts +8 -1
  13. package/dist/auth-email-password/web/client-plugin.js +2 -0
  14. package/dist/auth-email-password/web/index.d.ts +2 -1
  15. package/dist/auth-email-password/web/index.js +1 -0
  16. package/dist/auth-email-password/web/session.d.ts +3 -1
  17. package/dist/auth-email-password/web/session.js +8 -2
  18. package/dist/auth-mfa/feature.js +1 -1
  19. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +1 -1
  20. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +2 -1
  21. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  22. package/dist/auth-mfa/mfa-code-verifier.js +1 -1
  23. package/dist/auth-mfa/mfa-status-checker.js +1 -1
  24. package/dist/billing-foundation/aggregate-id.d.ts +2 -0
  25. package/dist/billing-foundation/aggregate-id.js +8 -0
  26. package/dist/billing-foundation/checkout-core.d.ts +3 -0
  27. package/dist/billing-foundation/checkout-core.js +3 -0
  28. package/dist/billing-foundation/constants.d.ts +38 -0
  29. package/dist/billing-foundation/constants.js +43 -0
  30. package/dist/billing-foundation/consumer-protection/confirmation-mail.d.ts +21 -0
  31. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +125 -0
  32. package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +32 -0
  33. package/dist/billing-foundation/consumer-protection/consent-gate.js +96 -0
  34. package/dist/billing-foundation/consumer-protection/consent-locale.d.ts +5 -0
  35. package/dist/billing-foundation/consumer-protection/consent-locale.js +17 -0
  36. package/dist/billing-foundation/consumer-protection/consent-text.d.ts +11 -0
  37. package/dist/billing-foundation/consumer-protection/consent-text.js +28 -0
  38. package/dist/billing-foundation/consumer-protection/issue-confirmation.d.ts +15 -0
  39. package/dist/billing-foundation/consumer-protection/issue-confirmation.js +149 -0
  40. package/dist/billing-foundation/consumer-protection/register-consent.d.ts +3 -0
  41. package/dist/billing-foundation/consumer-protection/register-consent.js +63 -0
  42. package/dist/billing-foundation/consumer-protection/register-termination.d.ts +3 -0
  43. package/dist/billing-foundation/consumer-protection/register-termination.js +40 -0
  44. package/dist/billing-foundation/consumer-protection/termination-mail.d.ts +45 -0
  45. package/dist/billing-foundation/consumer-protection/termination-mail.js +76 -0
  46. package/dist/billing-foundation/consumer-protection/termination-notify.d.ts +18 -0
  47. package/dist/billing-foundation/consumer-protection/termination-notify.js +21 -0
  48. package/dist/billing-foundation/consumer-protection/termination-pages.d.ts +8 -0
  49. package/dist/billing-foundation/consumer-protection/termination-pages.js +268 -0
  50. package/dist/billing-foundation/consumer-protection/termination-record.d.ts +73 -0
  51. package/dist/billing-foundation/consumer-protection/termination-record.js +230 -0
  52. package/dist/billing-foundation/consumer-protection/termination-request.d.ts +45 -0
  53. package/dist/billing-foundation/consumer-protection/termination-request.js +231 -0
  54. package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +62 -0
  55. package/dist/billing-foundation/consumer-protection/termination-texts.js +168 -0
  56. package/dist/billing-foundation/events.d.ts +105 -2
  57. package/dist/billing-foundation/events.js +88 -2
  58. package/dist/billing-foundation/feature.js +6 -2
  59. package/dist/billing-foundation/handlers/billing-plans.query.js +19 -1
  60. package/dist/billing-foundation/handlers/create-checkout-session.write.js +33 -2
  61. package/dist/billing-foundation/handlers/process-event.write.d.ts +2 -2
  62. package/dist/billing-foundation/handlers/process-event.write.js +43 -15
  63. package/dist/billing-foundation/handlers/process-payment-event.write.d.ts +2 -1
  64. package/dist/billing-foundation/handlers/process-payment-event.write.js +6 -2
  65. package/dist/billing-foundation/handlers/start-plan-checkout.write.js +17 -1
  66. package/dist/billing-foundation/handlers/sync-subscription.write.js +0 -1
  67. package/dist/billing-foundation/i18n.js +61 -0
  68. package/dist/billing-foundation/index.d.ts +3 -2
  69. package/dist/billing-foundation/index.js +2 -1
  70. package/dist/billing-foundation/tenant-destroy-hook.js +4 -4
  71. package/dist/billing-foundation/types.d.ts +54 -9
  72. package/dist/billing-foundation/validate-options.js +51 -10
  73. package/dist/billing-foundation/web/billing-plans-panel.js +40 -3
  74. package/dist/billing-foundation/web/cancel-contract-dialog.d.ts +7 -0
  75. package/dist/billing-foundation/web/cancel-contract-dialog.js +57 -0
  76. package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +28 -0
  77. package/dist/billing-foundation/web/checkout-consent-dialog.js +38 -0
  78. package/dist/billing-foundation/webhook-handler.js +5 -2
  79. package/dist/cap-counter/with-cap-enforcement.js +7 -3
  80. package/dist/cap-overview/access.d.ts +2 -1
  81. package/dist/cap-overview/access.js +26 -5
  82. package/dist/cap-overview/feature.d.ts +4 -0
  83. package/dist/cap-overview/feature.js +8 -6
  84. package/dist/cap-overview/handlers/caps-usage.query.d.ts +1 -1
  85. package/dist/cap-overview/handlers/caps-usage.query.js +6 -4
  86. package/dist/cap-overview/handlers/tenant-caps-list.query.js +12 -7
  87. package/dist/cap-overview/index.d.ts +2 -2
  88. package/dist/cap-overview/index.js +2 -2
  89. package/dist/cap-overview/screens.d.ts +1 -1
  90. package/dist/cap-overview/screens.js +17 -16
  91. package/dist/channel-discord/discord-channel.d.ts +6 -0
  92. package/dist/channel-discord/discord-channel.js +19 -0
  93. package/dist/channel-discord/feature.d.ts +3 -0
  94. package/dist/channel-discord/feature.js +30 -0
  95. package/dist/channel-discord/index.d.ts +2 -0
  96. package/dist/channel-discord/index.js +2 -0
  97. package/dist/channel-slack/feature.d.ts +3 -0
  98. package/dist/channel-slack/feature.js +30 -0
  99. package/dist/channel-slack/index.d.ts +2 -0
  100. package/dist/channel-slack/index.js +2 -0
  101. package/dist/channel-slack/slack-channel.d.ts +5 -0
  102. package/dist/channel-slack/slack-channel.js +16 -0
  103. package/dist/channel-teams/feature.d.ts +3 -0
  104. package/dist/channel-teams/feature.js +34 -0
  105. package/dist/channel-teams/index.d.ts +2 -0
  106. package/dist/channel-teams/index.js +2 -0
  107. package/dist/channel-teams/teams-channel.d.ts +5 -0
  108. package/dist/channel-teams/teams-channel.js +38 -0
  109. package/dist/channel-telegram/feature.d.ts +3 -0
  110. package/dist/channel-telegram/feature.js +28 -0
  111. package/dist/channel-telegram/index.d.ts +2 -0
  112. package/dist/channel-telegram/index.js +2 -0
  113. package/dist/channel-telegram/telegram-channel.d.ts +8 -0
  114. package/dist/channel-telegram/telegram-channel.js +54 -0
  115. package/dist/config/handlers/set.write.js +18 -2
  116. package/dist/crypto-shredding/feature.js +3 -2
  117. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +1 -1
  118. package/dist/crypto-shredding/handlers/forget-subject.write.js +30 -19
  119. package/dist/custom-fields/feature.js +9 -6
  120. package/dist/custom-fields/handlers/clear-custom-field.write.js +2 -1
  121. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -1
  122. package/dist/custom-fields/handlers/set-custom-field.write.js +2 -1
  123. package/dist/custom-fields/wire-user-data-rights.js +1 -1
  124. package/dist/data-retention/feature.js +1 -1
  125. package/dist/delivery/channel-context.d.ts +2 -1
  126. package/dist/delivery/channel-context.js +2 -2
  127. package/dist/delivery/chat-webhook-channel.d.ts +19 -0
  128. package/dist/delivery/chat-webhook-channel.js +48 -0
  129. package/dist/delivery/chat-webhook-sender.d.ts +21 -0
  130. package/dist/delivery/chat-webhook-sender.js +102 -0
  131. package/dist/delivery/delivery-service.js +12 -7
  132. package/dist/delivery/index.d.ts +2 -0
  133. package/dist/delivery/index.js +2 -0
  134. package/dist/delivery/jobs.js +1 -1
  135. package/dist/delivery/testing.d.ts +2 -0
  136. package/dist/delivery/types.d.ts +3 -1
  137. package/dist/delivery/types.js +1 -2
  138. package/dist/document-ingest-foundation/feature.js +3 -2
  139. package/dist/file-derivatives/handlers/public-variant-by-file-ref.query.js +1 -1
  140. package/dist/files-tenant-data/index.js +1 -1
  141. package/dist/form-draft/feature.js +1 -1
  142. package/dist/form-draft/handlers/discard.write.js +2 -1
  143. package/dist/form-draft/handlers/save.write.js +2 -1
  144. package/dist/inbound-mail-foundation/connect-routes.d.ts +7 -0
  145. package/dist/inbound-mail-foundation/connect-routes.js +13 -8
  146. package/dist/inbound-mail-foundation/feature.js +1 -1
  147. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +2 -1
  148. package/dist/inbound-mail-foundation/index.d.ts +1 -0
  149. package/dist/inbound-mail-foundation/index.js +1 -0
  150. package/dist/inbound-mail-foundation/oauth-access-token.d.ts +28 -0
  151. package/dist/inbound-mail-foundation/oauth-access-token.js +131 -0
  152. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +1 -1
  153. package/dist/inbound-mail-foundation/types.d.ts +18 -1
  154. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +5 -0
  155. package/dist/inbound-mail-foundation/watch-supervisor.js +42 -14
  156. package/dist/managed-pages/handlers/set.write.js +2 -1
  157. package/dist/notes-history/executor.d.ts +2 -0
  158. package/dist/notes-history/executor.js +9 -1
  159. package/dist/notes-history/feature.d.ts +2 -3
  160. package/dist/notes-history/feature.js +2 -1
  161. package/dist/notes-history/handlers/add-note.write.d.ts +2 -1
  162. package/dist/notes-history/handlers/add-note.write.js +21 -4
  163. package/dist/notes-history-user-data/hooks.js +26 -8
  164. package/dist/renderer-simple/feature.d.ts +8 -2
  165. package/dist/renderer-simple/feature.js +8 -5
  166. package/dist/renderer-simple/index.d.ts +2 -2
  167. package/dist/renderer-simple/index.js +1 -1
  168. package/dist/renderer-simple/simple-renderer.d.ts +15 -0
  169. package/dist/renderer-simple/simple-renderer.js +74 -27
  170. package/dist/secrets/feature.js +1 -1
  171. package/dist/sessions/feature.js +1 -1
  172. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -1
  173. package/dist/subscription-mollie/plugin-methods.js +1 -0
  174. package/dist/subscription-mollie/verify-webhook.js +5 -3
  175. package/dist/subscription-stripe/plugin-methods.d.ts +3 -1
  176. package/dist/subscription-stripe/plugin-methods.js +78 -13
  177. package/dist/subscription-stripe/verify-webhook.js +7 -3
  178. package/dist/tags/executor.d.ts +2 -0
  179. package/dist/tags/executor.js +9 -1
  180. package/dist/tags/feature.d.ts +4 -3
  181. package/dist/tags/feature.js +4 -2
  182. package/dist/tags/handlers/assign-tag.write.d.ts +2 -1
  183. package/dist/tags/handlers/assign-tag.write.js +4 -4
  184. package/dist/tags/handlers/remove-tag.write.d.ts +2 -1
  185. package/dist/tags/handlers/remove-tag.write.js +3 -3
  186. package/dist/tenant-handover/handlers/claim.write.js +2 -2
  187. package/dist/tenant-lifecycle/feature.js +1 -1
  188. package/dist/tenant-lifecycle/handlers/cancel-destruction.write.js +4 -1
  189. package/dist/tenant-lifecycle/handlers/request-destruction.write.js +2 -1
  190. package/dist/tier-engine/feature.js +1 -1
  191. package/dist/tier-engine/handlers/get-tenant-tier.query.js +2 -1
  192. package/dist/tier-engine/handlers/set-tenant-tier.write.js +2 -1
  193. package/dist/user/handlers/detail.query.js +1 -0
  194. package/dist/user/handlers/list.query.js +1 -0
  195. package/dist/user-data-rights/feature.js +2 -2
  196. package/dist/user-data-rights/handlers/cancel-deletion.write.js +2 -1
  197. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +1 -1
  198. package/dist/user-data-rights/handlers/download-attempt-list.query.js +1 -0
  199. package/dist/user-data-rights/handlers/download-by-job.query.js +2 -1
  200. package/dist/user-data-rights/handlers/download-by-token.query.js +2 -1
  201. package/dist/user-data-rights/handlers/export-status.query.js +2 -1
  202. package/dist/user-data-rights/handlers/lift-restriction.write.js +3 -4
  203. package/dist/user-data-rights/handlers/my-audit-log.query.js +2 -1
  204. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +2 -1
  205. package/dist/user-data-rights/handlers/request-deletion.write.js +1 -1
  206. package/dist/user-data-rights/handlers/request-export.write.js +2 -1
  207. package/dist/user-data-rights/handlers/restrict-account.write.js +2 -2
  208. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +2 -1
  209. package/dist/user-data-rights/lib/update-user-lifecycle.js +1 -1
  210. package/dist/user-data-rights/run-forget-cleanup.js +30 -15
  211. package/dist/workflow-runner/event-subscriber.js +6 -2
  212. package/dist/workflow-runner/event-trigger.js +5 -0
  213. package/dist/workflow-runner/handlers/resume-run.write.js +147 -59
  214. package/dist/workflow-runner/pending-projection.js +1 -0
  215. package/dist/workflow-runner/runner.d.ts +7 -1
  216. package/dist/workflow-runner/runner.js +1 -1
  217. package/dist/workflow-runner/tables.js +8 -1
  218. package/package.json +41 -9
  219. package/src/agent-tools/changes.json +14 -0
  220. package/src/auth-email-password/changes.json +7 -0
  221. package/src/billing-foundation/changes.json +83 -0
  222. package/src/cap-counter/changes.json +7 -0
  223. package/src/cap-overview/changes.json +14 -0
  224. package/src/config/changes.json +7 -0
  225. package/src/crypto-shredding/changes.json +13 -0
  226. package/src/custom-fields/changes.json +7 -0
  227. package/src/delivery/changes.json +14 -0
  228. package/src/inbound-mail-foundation/changes.json +7 -0
  229. package/src/notes-history/changes.json +7 -0
  230. package/src/renderer-simple/changes.json +9 -1
  231. package/src/subscription-mollie/changes.json +13 -0
  232. package/src/subscription-stripe/changes.json +13 -0
  233. package/src/tags/changes.json +7 -0
  234. package/src/user-data-rights/changes.json +6 -0
  235. package/src/workflow-runner/changes.json +7 -0
@@ -0,0 +1,231 @@
1
+ // § 312k: the anonymous request handler (public form / API) and the
2
+ // authenticated terminate-contract handler. Both end in the same receipt mail
3
+ // builder and operator notice; the public path never reveals whether the
4
+ // entered email matched a contract.
5
+ import { createSystemUser, declareEscapeHatch, SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
6
+ import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
7
+ import { generateId } from "@cosmicdrift/kumiko-framework/utils";
8
+ import * as z from "zod";
9
+ import { TenantQueries } from "../../tenant/index.js";
10
+ import { UserQueries } from "../../user/index.js";
11
+ import { CONTRACT_TERMINATION_RECEIPT_NOTIFICATION_TYPE, SubscriptionCancelTimings, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, } from "../constants.js";
12
+ import { CONTRACT_TERMINATION_DECLARATION_TYPES, CONTRACT_TERMINATION_KINDS, } from "../events.js";
13
+ import { purchaseRolesOf } from "../plan-catalog.js";
14
+ import { resolveConsentLocale } from "./consent-text.js";
15
+ import { renderTerminationReceipt } from "./termination-mail.js";
16
+ import { notifyOperator, requireNotify } from "./termination-notify.js";
17
+ const TENANT_ADMIN_ROLE = "TenantAdmin";
18
+ const EXTRAORDINARY_REASON_MESSAGE = "reason is required for an extraordinary termination";
19
+ const authUserRowSchema = z.object({
20
+ id: z.string().min(1),
21
+ email: z.string().min(1).optional(),
22
+ isDeleted: z.boolean().optional(),
23
+ });
24
+ const membershipRowsSchema = z.array(z.object({ tenantId: z.string().min(1), roles: z.array(z.string()) }));
25
+ const terminableResultSchema = z.object({ terminable: z.boolean() });
26
+ function hasReasonWhenExtraordinary(value) {
27
+ return value.terminationKind !== "extraordinary" || (value.reason?.trim().length ?? 0) > 0;
28
+ }
29
+ export const requestContractTerminationSchema = z
30
+ .object({
31
+ declarationType: z.enum(CONTRACT_TERMINATION_DECLARATION_TYPES),
32
+ terminationKind: z.enum(CONTRACT_TERMINATION_KINDS),
33
+ reason: z.string().max(2000).optional(),
34
+ name: z.string().min(1).max(200),
35
+ email: z.email(),
36
+ customerReference: z.string().max(200).optional(),
37
+ locale: z.enum(["de", "en"]).optional(),
38
+ })
39
+ .strict()
40
+ .refine(hasReasonWhenExtraordinary, { message: EXTRAORDINARY_REASON_MESSAGE, path: ["reason"] });
41
+ export const terminateContractSchema = z
42
+ .object({
43
+ declarationType: z.enum(CONTRACT_TERMINATION_DECLARATION_TYPES),
44
+ terminationKind: z.enum(CONTRACT_TERMINATION_KINDS),
45
+ reason: z.string().max(2000).optional(),
46
+ })
47
+ .strict()
48
+ .refine(hasReasonWhenExtraordinary, { message: EXTRAORDINARY_REASON_MESSAGE, path: ["reason"] });
49
+ function needsOperatorNotice(declaration) {
50
+ return [
51
+ ...(declaration.declarationType === "withdrawal" ? ["withdrawal"] : []),
52
+ ...(declaration.terminationKind === "extraordinary" ? ["extraordinary"] : []),
53
+ ];
54
+ }
55
+ async function sendTerminationMails(ctx, consumerProtection, plan) {
56
+ await requireNotify(ctx)(CONTRACT_TERMINATION_RECEIPT_NOTIFICATION_TYPE, {
57
+ route: { email: plan.declaration.email },
58
+ data: renderTerminationReceipt({
59
+ locale: plan.locale,
60
+ requestId: plan.requestId,
61
+ receivedAtIso: plan.receivedAtIso,
62
+ declaration: plan.declaration,
63
+ operatorEmail: consumerProtection.operatorEmail,
64
+ }),
65
+ priority: "critical",
66
+ });
67
+ // skip: no operator notice needed for this declaration
68
+ if (plan.reasons.length === 0)
69
+ return;
70
+ await notifyOperator(ctx, consumerProtection, plan);
71
+ }
72
+ // Tenants the entered email can terminate a contract for: tenants where the
73
+ // user is TenantAdmin and the subscription is not terminal. Every identity
74
+ // below comes from the trusted lookups, never from the payload.
75
+ async function findTerminableTenantIds(ctx, requestTenantId, email) {
76
+ declareEscapeHatch({
77
+ reason: "anonymous declarant has no session — finds the contract by email via user:find-for-auth and tenant:memberships as a system user; the calling handler declares its own escapeHatch",
78
+ });
79
+ const user = authUserRowSchema.safeParse(await ctx.queryAs(createSystemUser(requestTenantId), UserQueries.findForAuth, { email }));
80
+ if (!user.success || user.data.isDeleted === true)
81
+ return [];
82
+ const memberships = membershipRowsSchema.safeParse(await ctx.queryAs(createSystemUser(requestTenantId), TenantQueries.memberships, {
83
+ userId: user.data.id,
84
+ }));
85
+ if (!memberships.success)
86
+ return [];
87
+ const adminTenantIds = [
88
+ ...new Set(memberships.data
89
+ .filter((membership) => membership.roles.includes(TENANT_ADMIN_ROLE))
90
+ .map((membership) => membership.tenantId)),
91
+ ];
92
+ const terminable = [];
93
+ for (const tenantId of adminTenantIds) {
94
+ const probe = terminableResultSchema.safeParse(await ctx.queryAs(createSystemUser(tenantId), SubscriptionFoundationQueries.terminableSubscription, {}));
95
+ if (probe.success && probe.data.terminable)
96
+ terminable.push(tenantId);
97
+ }
98
+ return terminable;
99
+ }
100
+ export function createRequestContractTerminationHandler(options, consumerProtection) {
101
+ return {
102
+ name: "request-contract-termination",
103
+ description: "Public § 312k declaration: terminates or withdraws from the contract of the account behind the entered email; the answer and the receipt mail never reveal whether the email matched.",
104
+ schema: requestContractTerminationSchema,
105
+ access: { roles: ["anonymous"] },
106
+ rateLimit: { per: "ip+handler", limit: 5, windowSeconds: 600 },
107
+ ...(consumerProtection.terminationScope === "platform" && { tenantlessAnonymous: true }),
108
+ escapeHatch: {
109
+ reason: "Anonymous declarant has no session — finds the contract by email via ctx.queryAs(system, user:find-for-auth) and tenant:memberships; the tenant written to comes only from those lookups.",
110
+ },
111
+ handler: async (event, ctx) => {
112
+ // @cast-boundary engine-payload — dispatcher-zod-validated payload
113
+ const payload = event.payload;
114
+ const requestId = generateId();
115
+ const receivedAtIso = options.now().toString();
116
+ const { declarationType, terminationKind } = payload;
117
+ const reasons = [];
118
+ const locale = resolveConsentLocale(payload.locale);
119
+ let matchedTenantId;
120
+ const candidates = await findTerminableTenantIds(ctx, event.user.tenantId, payload.email);
121
+ const [onlyCandidate] = candidates;
122
+ if (candidates.length === 1 && onlyCandidate !== undefined) {
123
+ matchedTenantId = onlyCandidate;
124
+ const declared = await ctx.writeAs(createSystemUser(onlyCandidate), SubscriptionFoundationHandlers.declareContractTermination, { requestId, declarationType, terminationKind, receivedAtIso, locale });
125
+ if (!declared.isSuccess)
126
+ reasons.push("recording_failed");
127
+ }
128
+ else {
129
+ reasons.push(candidates.length === 0 ? "unmatched" : "ambiguous");
130
+ const recorded = await ctx.writeAs(createSystemUser(SYSTEM_TENANT_ID), SubscriptionFoundationHandlers.recordUnmatchedContractTermination, {
131
+ requestId,
132
+ declarationType,
133
+ terminationKind,
134
+ receivedAtIso,
135
+ matchResult: candidates.length === 0 ? "none" : "ambiguous",
136
+ });
137
+ if (!recorded.isSuccess)
138
+ reasons.push("recording_failed");
139
+ }
140
+ reasons.push(...needsOperatorNotice(payload));
141
+ await sendTerminationMails(ctx, consumerProtection, {
142
+ locale,
143
+ requestId,
144
+ receivedAtIso,
145
+ channel: "public",
146
+ declaration: {
147
+ declarationType,
148
+ terminationKind,
149
+ name: payload.name,
150
+ email: payload.email,
151
+ ...(payload.customerReference !== undefined && {
152
+ customerReference: payload.customerReference,
153
+ }),
154
+ ...(payload.reason !== undefined && { reason: payload.reason }),
155
+ },
156
+ reasons,
157
+ ...(matchedTenantId !== undefined && { tenantId: matchedTenantId }),
158
+ });
159
+ return {
160
+ isSuccess: true,
161
+ data: { requestId, receivedAtIso },
162
+ };
163
+ },
164
+ };
165
+ }
166
+ export function createTerminateContractHandler(options, consumerProtection) {
167
+ return {
168
+ name: "terminate-contract",
169
+ description: "Terminates the tenant's subscription at the end of the billing period, or withdraws from the contract and cancels it immediately; sends a receipt to the caller's email.",
170
+ schema: terminateContractSchema,
171
+ access: { roles: purchaseRolesOf(options.catalog) },
172
+ escapeHatch: {
173
+ reason: "reads the calling admin's own email via UserQueries.findForAuth as a system user; the receipt goes only to that address",
174
+ },
175
+ handler: async (event, ctx) => {
176
+ // @cast-boundary engine-payload — dispatcher-zod-validated payload
177
+ const payload = event.payload;
178
+ const tenantId = event.user.tenantId;
179
+ const requestId = generateId();
180
+ const { declarationType, terminationKind } = payload;
181
+ const caller = authUserRowSchema.safeParse(await ctx.queryAs(createSystemUser(tenantId), UserQueries.findForAuth, {
182
+ id: event.user.id,
183
+ }));
184
+ if (!caller.success || !caller.data.email || caller.data.isDeleted === true) {
185
+ throw new InternalError({
186
+ message: "billing-foundation:terminate-contract: calling user has no email on record",
187
+ });
188
+ }
189
+ const recorded = await ctx.writeAs(createSystemUser(tenantId), SubscriptionFoundationHandlers.recordContractTermination, {
190
+ requestId,
191
+ declarationType,
192
+ terminationKind,
193
+ channel: "account",
194
+ when: declarationType === "withdrawal"
195
+ ? SubscriptionCancelTimings.immediately
196
+ : SubscriptionCancelTimings.periodEnd,
197
+ });
198
+ if (!recorded.isSuccess)
199
+ return recorded;
200
+ // @cast-boundary engine-payload — our own record handler's return shape
201
+ const data = recorded.data;
202
+ await sendTerminationMails(ctx, consumerProtection, {
203
+ locale: resolveConsentLocale(ctx.locale),
204
+ requestId,
205
+ receivedAtIso: data.receivedAtIso,
206
+ channel: "account",
207
+ declaration: {
208
+ declarationType,
209
+ terminationKind,
210
+ email: caller.data.email,
211
+ ...(payload.reason !== undefined && { reason: payload.reason }),
212
+ },
213
+ reasons: [
214
+ ...(data.noticeReason !== null ? [data.noticeReason] : []),
215
+ ...needsOperatorNotice(payload),
216
+ ],
217
+ tenantId,
218
+ providerCancel: data.providerCancel,
219
+ });
220
+ return {
221
+ isSuccess: true,
222
+ data: {
223
+ requestId,
224
+ receivedAtIso: data.receivedAtIso,
225
+ effectiveAtIso: data.effectiveAtIso,
226
+ providerCancel: data.providerCancel,
227
+ },
228
+ };
229
+ },
230
+ };
231
+ }
@@ -0,0 +1,62 @@
1
+ import type { ContractTerminationDeclarationType, ContractTerminationKind } from "../events.js";
2
+ import type { ConsentLocale } from "./consent-text.js";
3
+ export type TerminationTexts = {
4
+ readonly declarationTypeLabel: Readonly<Record<ContractTerminationDeclarationType, string>>;
5
+ readonly terminationKindLabel: Readonly<Record<ContractTerminationKind, string>>;
6
+ readonly declarationType: string;
7
+ readonly terminationKind: string;
8
+ readonly receivedAt: string;
9
+ readonly requestId: string;
10
+ readonly name: string;
11
+ readonly email: string;
12
+ readonly customerReference: string;
13
+ readonly reasonFieldLabel: string;
14
+ readonly receiptSubject: Readonly<Record<ContractTerminationDeclarationType, string>>;
15
+ readonly receiptIntro: string;
16
+ readonly receiptNextSteps: string;
17
+ readonly receiptRevoke: (operatorEmail: string) => string;
18
+ readonly contact: string;
19
+ readonly operatorSubject: Readonly<Record<ContractTerminationDeclarationType, string>>;
20
+ readonly operatorIntro: string;
21
+ readonly operatorReasons: Readonly<Record<OperatorNoticeReason, string>>;
22
+ readonly noticeReasons: string;
23
+ readonly channel: string;
24
+ readonly channelLabel: Readonly<Record<"public" | "account", string>>;
25
+ readonly tenant: string;
26
+ readonly providerResult: string;
27
+ readonly providerResultLabel: Readonly<Record<"period-end" | "immediately" | "none", string>>;
28
+ readonly page: PageTexts;
29
+ };
30
+ export type PageTexts = {
31
+ readonly title: string;
32
+ readonly lead: string;
33
+ readonly declarationTypeHeading: string;
34
+ readonly kindHeading: string;
35
+ readonly reasonHint: string;
36
+ readonly earliestDate: string;
37
+ readonly nameLabel: string;
38
+ readonly emailLabel: string;
39
+ readonly customerReferenceLabel: string;
40
+ readonly reasonLabel: string;
41
+ readonly reviewButton: string;
42
+ readonly reviewTitle: string;
43
+ readonly reviewLead: string;
44
+ readonly confirmButton: Readonly<Record<ContractTerminationDeclarationType, string>>;
45
+ readonly backButton: string;
46
+ readonly resultTitle: string;
47
+ readonly resultLead: string;
48
+ readonly resultReceivedAt: string;
49
+ readonly resultRequestId: string;
50
+ readonly resultMailNote: string;
51
+ readonly errorsHeading: string;
52
+ readonly errorName: string;
53
+ readonly errorEmail: string;
54
+ readonly errorReason: string;
55
+ readonly errorChoice: string;
56
+ readonly errorGeneric: string;
57
+ readonly rateLimitedTitle: string;
58
+ readonly rateLimitedBody: string;
59
+ };
60
+ export declare const OPERATOR_NOTICE_REASONS: readonly ["unmatched", "ambiguous", "withdrawal", "extraordinary", "provider_cannot_cancel", "provider_error", "no_active_subscription", "recording_failed"];
61
+ export type OperatorNoticeReason = (typeof OPERATOR_NOTICE_REASONS)[number];
62
+ export declare const TERMINATION_TEXTS: Readonly<Record<ConsentLocale, TerminationTexts>>;
@@ -0,0 +1,168 @@
1
+ export const OPERATOR_NOTICE_REASONS = [
2
+ "unmatched",
3
+ "ambiguous",
4
+ "withdrawal",
5
+ "extraordinary",
6
+ "provider_cannot_cancel",
7
+ "provider_error",
8
+ "no_active_subscription",
9
+ "recording_failed",
10
+ ];
11
+ export const TERMINATION_TEXTS = {
12
+ de: {
13
+ declarationTypeLabel: { termination: "Kündigung", withdrawal: "Widerruf" },
14
+ terminationKindLabel: {
15
+ ordinary: "Ordentlich zum nächstmöglichen Zeitpunkt",
16
+ extraordinary: "Außerordentlich (aus wichtigem Grund)",
17
+ },
18
+ declarationType: "Erklärung",
19
+ terminationKind: "Art der Kündigung",
20
+ receivedAt: "Eingegangen am",
21
+ requestId: "Vorgangsnummer",
22
+ name: "Name",
23
+ email: "E-Mail",
24
+ customerReference: "Kundennummer / Referenz",
25
+ reasonFieldLabel: "Begründung",
26
+ receiptSubject: {
27
+ termination: "Eingangsbestätigung deiner Kündigung",
28
+ withdrawal: "Eingangsbestätigung deines Widerrufs",
29
+ },
30
+ receiptIntro: "wir bestätigen den Eingang deiner Erklärung mit folgendem Inhalt. Diese E-Mail ist eine Eingangsbestätigung, keine Bestätigung der Wirksamkeit.",
31
+ receiptNextSteps: "Wir prüfen deine Erklärung und melden uns, sobald sie bearbeitet ist oder wir Rückfragen haben.",
32
+ receiptRevoke: (operatorEmail) => `Hast du diese Erklärung nicht abgegeben oder möchtest du sie zurücknehmen? Schreib uns bitte umgehend an ${operatorEmail}.`,
33
+ contact: "Fragen richtest du bitte an",
34
+ operatorSubject: {
35
+ termination: "Kündigung: Bearbeitung nötig",
36
+ withdrawal: "Widerruf: Bearbeitung nötig",
37
+ },
38
+ operatorIntro: "Es ist eine Erklärung eingegangen, die bearbeitet werden muss.",
39
+ operatorReasons: {
40
+ unmatched: "Kein passender Vertrag zur angegebenen E-Mail gefunden",
41
+ ambiguous: "Die angegebene E-Mail passt zu mehreren Verträgen",
42
+ withdrawal: "Widerruf (nur Erfassung, kein Anbieter-Aufruf über das öffentliche Formular)",
43
+ extraordinary: "Außerordentliche Kündigung, Begründung prüfen",
44
+ provider_cannot_cancel: "Der Zahlungsanbieter unterstützt keine Kündigung per Schnittstelle",
45
+ provider_error: "Die Kündigung beim Zahlungsanbieter ist fehlgeschlagen",
46
+ no_active_subscription: "Keine laufende Subscription beim Anbieter",
47
+ recording_failed: "Die Erklärung konnte nicht gespeichert werden",
48
+ },
49
+ noticeReasons: "Grund der Benachrichtigung",
50
+ channel: "Kanal",
51
+ channelLabel: { public: "Öffentliches Formular", account: "Kundenkonto" },
52
+ tenant: "Mandant",
53
+ providerResult: "Kündigung beim Anbieter",
54
+ providerResultLabel: {
55
+ "period-end": "zum Ende des Abrechnungszeitraums veranlasst",
56
+ immediately: "sofort veranlasst",
57
+ none: "nicht veranlasst",
58
+ },
59
+ page: {
60
+ title: "Vertrag kündigen oder widerrufen",
61
+ lead: "Mit diesem Formular erklärst du die Kündigung oder den Widerruf deines Vertrags. Du brauchst dafür kein Kundenkonto.",
62
+ declarationTypeHeading: "Was möchtest du erklären?",
63
+ kindHeading: "Art der Kündigung",
64
+ reasonHint: "Pflicht bei außerordentlicher Kündigung.",
65
+ earliestDate: "Die Kündigung gilt zum nächstmöglichen Zeitpunkt.",
66
+ nameLabel: "Name",
67
+ emailLabel: "E-Mail-Adresse des Kontos",
68
+ customerReferenceLabel: "Kundennummer (optional)",
69
+ reasonLabel: "Begründung",
70
+ reviewButton: "Weiter zur Prüfung",
71
+ reviewTitle: "Bitte prüfe deine Angaben",
72
+ reviewLead: "Erst mit dem Klick auf den Button unten wird deine Erklärung abgegeben.",
73
+ confirmButton: { termination: "Jetzt kündigen", withdrawal: "Jetzt widerrufen" },
74
+ backButton: "Angaben ändern",
75
+ resultTitle: "Deine Erklärung ist eingegangen",
76
+ resultLead: "Wir haben deine Erklärung erhalten und senden dir eine Eingangsbestätigung.",
77
+ resultReceivedAt: "Eingegangen am",
78
+ resultRequestId: "Vorgangsnummer",
79
+ resultMailNote: "Die Eingangsbestätigung geht an die von dir angegebene E-Mail-Adresse.",
80
+ errorsHeading: "Bitte korrigiere deine Angaben",
81
+ errorName: "Bitte gib deinen Namen an.",
82
+ errorEmail: "Bitte gib eine gültige E-Mail-Adresse an.",
83
+ errorReason: "Bei einer außerordentlichen Kündigung ist eine Begründung nötig.",
84
+ errorChoice: "Bitte wähle eine Erklärung und die Art der Kündigung.",
85
+ errorGeneric: "Deine Erklärung konnte nicht verarbeitet werden. Bitte versuch es erneut.",
86
+ rateLimitedTitle: "Zu viele Anfragen",
87
+ rateLimitedBody: "Von deiner Adresse kamen zu viele Anfragen. Bitte versuch es später erneut.",
88
+ },
89
+ },
90
+ en: {
91
+ declarationTypeLabel: { termination: "Termination", withdrawal: "Withdrawal" },
92
+ terminationKindLabel: {
93
+ ordinary: "Ordinary, at the earliest possible date",
94
+ extraordinary: "Extraordinary (for good cause)",
95
+ },
96
+ declarationType: "Declaration",
97
+ terminationKind: "Kind of termination",
98
+ receivedAt: "Received on",
99
+ requestId: "Reference number",
100
+ name: "Name",
101
+ email: "Email",
102
+ customerReference: "Customer number / reference",
103
+ reasonFieldLabel: "Reason",
104
+ receiptSubject: {
105
+ termination: "Receipt for your termination",
106
+ withdrawal: "Receipt for your withdrawal",
107
+ },
108
+ receiptIntro: "we confirm receipt of your declaration with the following content. This email is a receipt, not a confirmation that the declaration is effective.",
109
+ receiptNextSteps: "We will review your declaration and get back to you once it is processed or if we have questions.",
110
+ receiptRevoke: (operatorEmail) => `If you did not make this declaration or want to take it back, please write to ${operatorEmail} right away.`,
111
+ contact: "Questions go to",
112
+ operatorSubject: {
113
+ termination: "Termination: action needed",
114
+ withdrawal: "Withdrawal: action needed",
115
+ },
116
+ operatorIntro: "A declaration arrived that needs your attention.",
117
+ operatorReasons: {
118
+ unmatched: "No contract matches the entered email",
119
+ ambiguous: "The entered email matches several contracts",
120
+ withdrawal: "Withdrawal (recorded only, no provider call from the public form)",
121
+ extraordinary: "Extraordinary termination, review the reason",
122
+ provider_cannot_cancel: "The payment provider does not support cancelling through its API",
123
+ provider_error: "Cancelling at the payment provider failed",
124
+ no_active_subscription: "No running subscription at the provider",
125
+ recording_failed: "The declaration could not be stored",
126
+ },
127
+ noticeReasons: "Reason for this notice",
128
+ channel: "Channel",
129
+ channelLabel: { public: "Public form", account: "Customer account" },
130
+ tenant: "Tenant",
131
+ providerResult: "Cancellation at the provider",
132
+ providerResultLabel: {
133
+ "period-end": "requested for the end of the billing period",
134
+ immediately: "requested immediately",
135
+ none: "not requested",
136
+ },
137
+ page: {
138
+ title: "Terminate or withdraw from your contract",
139
+ lead: "Use this form to terminate your contract or withdraw from it. You do not need a customer account.",
140
+ declarationTypeHeading: "What do you want to declare?",
141
+ kindHeading: "Kind of termination",
142
+ reasonHint: "Required for an extraordinary termination.",
143
+ earliestDate: "The termination takes effect at the earliest possible date.",
144
+ nameLabel: "Name",
145
+ emailLabel: "Email address of the account",
146
+ customerReferenceLabel: "Customer number (optional)",
147
+ reasonLabel: "Reason",
148
+ reviewButton: "Continue to review",
149
+ reviewTitle: "Please check your details",
150
+ reviewLead: "Your declaration is only submitted when you click the button below.",
151
+ confirmButton: { termination: "Cancel now", withdrawal: "Withdraw now" },
152
+ backButton: "Change details",
153
+ resultTitle: "Your declaration was received",
154
+ resultLead: "We received your declaration and are sending you a receipt.",
155
+ resultReceivedAt: "Received on",
156
+ resultRequestId: "Reference number",
157
+ resultMailNote: "The receipt goes to the email address you entered.",
158
+ errorsHeading: "Please correct your details",
159
+ errorName: "Please enter your name.",
160
+ errorEmail: "Please enter a valid email address.",
161
+ errorReason: "An extraordinary termination needs a reason.",
162
+ errorChoice: "Please choose a declaration and the kind of termination.",
163
+ errorGeneric: "Your declaration could not be processed. Please try again.",
164
+ rateLimitedTitle: "Too many requests",
165
+ rateLimitedBody: "Too many requests came from your address. Please try again later.",
166
+ },
167
+ },
168
+ };
@@ -24,12 +24,12 @@ export declare const subscriptionEventPayloadSchema: z.ZodObject<{
24
24
  tier: z.ZodString;
25
25
  currentPeriodEndIso: z.ZodString;
26
26
  cancelAtIso: z.ZodOptional<z.ZodNullable<z.ZodString>>;
27
+ consentId: z.ZodOptional<z.ZodString>;
27
28
  }, z.core.$strip>;
28
29
  export type SubscriptionEventPayload = z.infer<typeof subscriptionEventPayloadSchema>;
29
30
  export type SubscriptionEventHeaders = {
30
31
  readonly providerEventId: string;
31
32
  readonly providerName: string;
32
- readonly rawPayload: string;
33
33
  };
34
34
  export declare const PAYMENT_AGGREGATE_TYPE: "payment";
35
35
  export declare const PAYMENT_RECEIVED_EVENT_SHORT: "payment-received";
@@ -38,10 +38,113 @@ export declare const paymentEventPayloadSchema: z.ZodObject<{
38
38
  providerName: z.ZodString;
39
39
  providerCustomerId: z.ZodString;
40
40
  priceId: z.ZodString;
41
+ consentId: z.ZodOptional<z.ZodString>;
41
42
  }, z.core.$strip>;
42
43
  export type PaymentEventPayload = z.infer<typeof paymentEventPayloadSchema>;
43
44
  export type PaymentEventHeaders = {
44
45
  readonly providerEventId: string;
45
46
  readonly providerName: string;
46
- readonly rawPayload: string;
47
+ readonly providerCheckoutId?: string;
47
48
  };
49
+ export declare const CHECKOUT_CONSENT_RECORDED_EVENT_SHORT: "checkout-consent-recorded";
50
+ export declare const CHECKOUT_CONSENT_RECORDED_EVENT_QN: "billing-foundation:event:checkout-consent-recorded";
51
+ export declare const checkoutConsentRecordedPayloadSchema: z.ZodObject<{
52
+ consentId: z.ZodString;
53
+ mode: z.ZodEnum<{
54
+ payment: "payment";
55
+ subscription: "subscription";
56
+ }>;
57
+ tier: z.ZodNullable<z.ZodString>;
58
+ priceId: z.ZodString;
59
+ unitAmount: z.ZodNullable<z.ZodNumber>;
60
+ currency: z.ZodNullable<z.ZodString>;
61
+ interval: z.ZodNullable<z.ZodString>;
62
+ intervalCount: z.ZodNullable<z.ZodNumber>;
63
+ consentTextVersion: z.ZodString;
64
+ termsHash: z.ZodString;
65
+ termsTemplateVersion: z.ZodNumber;
66
+ locale: z.ZodString;
67
+ actorUserId: z.ZodString;
68
+ }, z.core.$strip>;
69
+ export type CheckoutConsentRecordedPayload = z.infer<typeof checkoutConsentRecordedPayloadSchema>;
70
+ export declare const CONTRACT_CONFIRMATION_ISSUED_EVENT_SHORT: "contract-confirmation-issued";
71
+ export declare const CONTRACT_CONFIRMATION_ISSUED_EVENT_QN: "billing-foundation:event:contract-confirmation-issued";
72
+ export declare const contractConfirmationIssuedPayloadSchema: z.ZodObject<{
73
+ consentId: z.ZodString;
74
+ issuedAtIso: z.ZodString;
75
+ locale: z.ZodString;
76
+ termsTemplateVersion: z.ZodNumber;
77
+ }, z.core.$strip>;
78
+ export type ContractConfirmationIssuedPayload = z.infer<typeof contractConfirmationIssuedPayloadSchema>;
79
+ export declare const CONTRACT_TERMINATION_DECLARATION_TYPES: readonly ["termination", "withdrawal"];
80
+ export type ContractTerminationDeclarationType = (typeof CONTRACT_TERMINATION_DECLARATION_TYPES)[number];
81
+ export declare const CONTRACT_TERMINATION_KINDS: readonly ["ordinary", "extraordinary"];
82
+ export type ContractTerminationKind = (typeof CONTRACT_TERMINATION_KINDS)[number];
83
+ export declare const CONTRACT_TERMINATION_CHANNELS: readonly ["public", "account"];
84
+ export declare const PROVIDER_CANCEL_OUTCOMES: readonly ["period-end", "immediately", "none"];
85
+ export type ProviderCancelOutcome = (typeof PROVIDER_CANCEL_OUTCOMES)[number];
86
+ export declare const CONTRACT_TERMINATION_REQUESTED_EVENT_SHORT: "contract-termination-requested";
87
+ export declare const CONTRACT_TERMINATION_REQUESTED_EVENT_QN: "billing-foundation:event:contract-termination-requested";
88
+ export declare const contractTerminationRequestedPayloadSchema: z.ZodObject<{
89
+ requestId: z.ZodString;
90
+ declarationType: z.ZodEnum<{
91
+ termination: "termination";
92
+ withdrawal: "withdrawal";
93
+ }>;
94
+ terminationKind: z.ZodEnum<{
95
+ extraordinary: "extraordinary";
96
+ ordinary: "ordinary";
97
+ }>;
98
+ channel: z.ZodEnum<{
99
+ account: "account";
100
+ public: "public";
101
+ }>;
102
+ receivedAtIso: z.ZodString;
103
+ effectiveAtIso: z.ZodNullable<z.ZodString>;
104
+ providerCancel: z.ZodEnum<{
105
+ immediately: "immediately";
106
+ none: "none";
107
+ "period-end": "period-end";
108
+ }>;
109
+ }, z.core.$strip>;
110
+ export type ContractTerminationRequestedPayload = z.infer<typeof contractTerminationRequestedPayloadSchema>;
111
+ export declare const CONTRACT_TERMINATION_DECLARED_EVENT_SHORT: "contract-termination-declared";
112
+ export declare const CONTRACT_TERMINATION_DECLARED_EVENT_QN: "billing-foundation:event:contract-termination-declared";
113
+ export declare const contractTerminationDeclaredPayloadSchema: z.ZodObject<{
114
+ requestId: z.ZodString;
115
+ declarationType: z.ZodEnum<{
116
+ termination: "termination";
117
+ withdrawal: "withdrawal";
118
+ }>;
119
+ terminationKind: z.ZodEnum<{
120
+ extraordinary: "extraordinary";
121
+ ordinary: "ordinary";
122
+ }>;
123
+ receivedAtIso: z.ZodString;
124
+ locale: z.ZodEnum<{
125
+ de: "de";
126
+ en: "en";
127
+ }>;
128
+ }, z.core.$strip>;
129
+ export type ContractTerminationDeclaredPayload = z.infer<typeof contractTerminationDeclaredPayloadSchema>;
130
+ export declare const CONTRACT_TERMINATION_UNMATCHED_AGGREGATE_TYPE: "contract-termination-unmatched";
131
+ export declare const CONTRACT_TERMINATION_UNMATCHED_EVENT_SHORT: "contract-termination-unmatched";
132
+ export declare const CONTRACT_TERMINATION_UNMATCHED_EVENT_QN: "billing-foundation:event:contract-termination-unmatched";
133
+ export declare const contractTerminationUnmatchedPayloadSchema: z.ZodObject<{
134
+ requestId: z.ZodString;
135
+ declarationType: z.ZodEnum<{
136
+ termination: "termination";
137
+ withdrawal: "withdrawal";
138
+ }>;
139
+ terminationKind: z.ZodEnum<{
140
+ extraordinary: "extraordinary";
141
+ ordinary: "ordinary";
142
+ }>;
143
+ channel: z.ZodLiteral<"public">;
144
+ receivedAtIso: z.ZodString;
145
+ matchResult: z.ZodEnum<{
146
+ ambiguous: "ambiguous";
147
+ none: "none";
148
+ }>;
149
+ }, z.core.$strip>;
150
+ export type ContractTerminationUnmatchedPayload = z.infer<typeof contractTerminationUnmatchedPayloadSchema>;