@openlup/platform 0.16.0 → 0.17.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 (296) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +285 -5
  3. package/dist/communications/accountingDocumentDelivery.d.ts +35 -0
  4. package/dist/communications/accountingDocumentDelivery.js +33 -0
  5. package/dist/communications/authEmailError.d.ts +5 -0
  6. package/dist/communications/authEmailError.js +8 -0
  7. package/dist/communications/authEmailPorts.d.ts +2 -0
  8. package/dist/communications/authEmailPorts.js +1 -0
  9. package/dist/communications/authSendEmailHook.d.ts +35 -0
  10. package/dist/communications/authSendEmailHook.js +250 -0
  11. package/dist/communications/capturedTransactionalDelivery.d.ts +13 -0
  12. package/dist/communications/capturedTransactionalDelivery.js +14 -0
  13. package/dist/communications/communicationSync.d.ts +11 -0
  14. package/dist/communications/communicationSync.js +79 -0
  15. package/dist/communications/communicationSyncWorker.d.ts +68 -0
  16. package/dist/communications/communicationSyncWorker.js +218 -0
  17. package/dist/communications/consentPolicy.d.ts +19 -0
  18. package/dist/communications/consentPolicy.js +43 -0
  19. package/dist/communications/consentPurposeRegistry.d.ts +4 -0
  20. package/dist/communications/consentPurposeRegistry.js +24 -0
  21. package/dist/communications/contracts/abandonedCart.d.ts +27 -0
  22. package/dist/communications/contracts/abandonedCart.js +25 -0
  23. package/dist/communications/contracts/authEmail.d.ts +62 -0
  24. package/dist/communications/contracts/authEmail.js +1 -0
  25. package/dist/communications/contracts/backInStock.d.ts +28 -0
  26. package/dist/communications/contracts/backInStock.js +28 -0
  27. package/dist/communications/contracts/blocks.d.ts +24 -0
  28. package/dist/communications/contracts/blocks.js +23 -0
  29. package/dist/communications/contracts/checkoutExpired.d.ts +22 -0
  30. package/dist/communications/contracts/checkoutExpired.js +25 -0
  31. package/dist/communications/contracts/checkoutRecovery.d.ts +26 -0
  32. package/dist/communications/contracts/checkoutRecovery.js +37 -0
  33. package/dist/communications/contracts/commerceEmailContent.d.ts +176 -0
  34. package/dist/communications/contracts/commerceEmailContent.js +1 -0
  35. package/dist/communications/contracts/commerceEngagementEmailContent.d.ts +95 -0
  36. package/dist/communications/contracts/commerceEngagementEmailContent.js +1 -0
  37. package/dist/communications/contracts/consent.d.ts +12 -0
  38. package/dist/communications/contracts/consent.js +1 -0
  39. package/dist/communications/contracts/email.d.ts +182 -0
  40. package/dist/communications/contracts/email.js +1 -0
  41. package/dist/communications/contracts/guideCard.d.ts +3 -0
  42. package/dist/communications/contracts/guideCard.js +26 -0
  43. package/dist/communications/contracts/index.d.ts +51 -0
  44. package/dist/communications/contracts/index.js +42 -0
  45. package/dist/communications/contracts/inquiryContent.d.ts +32 -0
  46. package/dist/communications/contracts/inquiryContent.js +33 -0
  47. package/dist/communications/contracts/invoiceDocumentContent.d.ts +26 -0
  48. package/dist/communications/contracts/invoiceDocumentContent.js +36 -0
  49. package/dist/communications/contracts/marketingAutomation.d.ts +52 -0
  50. package/dist/communications/contracts/marketingAutomation.js +1 -0
  51. package/dist/communications/contracts/newsletter.d.ts +63 -0
  52. package/dist/communications/contracts/newsletter.js +1 -0
  53. package/dist/communications/contracts/newsletterWebhook.d.ts +26 -0
  54. package/dist/communications/contracts/newsletterWebhook.js +1 -0
  55. package/dist/communications/contracts/optOutContent.d.ts +11 -0
  56. package/dist/communications/contracts/optOutContent.js +17 -0
  57. package/dist/communications/contracts/orderCanceled.d.ts +25 -0
  58. package/dist/communications/contracts/orderCanceled.js +27 -0
  59. package/dist/communications/contracts/orderDraft.d.ts +46 -0
  60. package/dist/communications/contracts/orderDraft.js +46 -0
  61. package/dist/communications/contracts/orderPaid.d.ts +53 -0
  62. package/dist/communications/contracts/orderPaid.js +71 -0
  63. package/dist/communications/contracts/orderRefunded.d.ts +24 -0
  64. package/dist/communications/contracts/orderRefunded.js +27 -0
  65. package/dist/communications/contracts/paymentFailed.d.ts +24 -0
  66. package/dist/communications/contracts/paymentFailed.js +24 -0
  67. package/dist/communications/contracts/publicIntake.d.ts +49 -0
  68. package/dist/communications/contracts/publicIntake.js +1 -0
  69. package/dist/communications/contracts/render.d.ts +2 -0
  70. package/dist/communications/contracts/render.js +229 -0
  71. package/dist/communications/contracts/reorderReminder.d.ts +24 -0
  72. package/dist/communications/contracts/reorderReminder.js +24 -0
  73. package/dist/communications/contracts/returnEmails.d.ts +25 -0
  74. package/dist/communications/contracts/returnEmails.js +62 -0
  75. package/dist/communications/contracts/reviewEffects.d.ts +26 -0
  76. package/dist/communications/contracts/reviewEffects.js +25 -0
  77. package/dist/communications/contracts/reviewRequest.d.ts +26 -0
  78. package/dist/communications/contracts/reviewRequest.js +24 -0
  79. package/dist/communications/contracts/roleNotificationContent.d.ts +25 -0
  80. package/dist/communications/contracts/roleNotificationContent.js +46 -0
  81. package/dist/communications/contracts/shipmentDelivered.d.ts +23 -0
  82. package/dist/communications/contracts/shipmentDelivered.js +24 -0
  83. package/dist/communications/contracts/shipmentDispatched.d.ts +27 -0
  84. package/dist/communications/contracts/shipmentDispatched.js +35 -0
  85. package/dist/communications/contracts/shipmentException.d.ts +21 -0
  86. package/dist/communications/contracts/shipmentException.js +26 -0
  87. package/dist/communications/contracts/subscriptionActivationActionRequired.d.ts +17 -0
  88. package/dist/communications/contracts/subscriptionActivationActionRequired.js +22 -0
  89. package/dist/communications/contracts/subscriptionAddressChanged.d.ts +19 -0
  90. package/dist/communications/contracts/subscriptionAddressChanged.js +25 -0
  91. package/dist/communications/contracts/subscriptionCancelled.d.ts +19 -0
  92. package/dist/communications/contracts/subscriptionCancelled.js +25 -0
  93. package/dist/communications/contracts/subscriptionCycleSkipped.d.ts +25 -0
  94. package/dist/communications/contracts/subscriptionCycleSkipped.js +40 -0
  95. package/dist/communications/contracts/subscriptionDeliveryRescheduled.d.ts +25 -0
  96. package/dist/communications/contracts/subscriptionDeliveryRescheduled.js +39 -0
  97. package/dist/communications/contracts/subscriptionEmailContent.d.ts +145 -0
  98. package/dist/communications/contracts/subscriptionEmailContent.js +1 -0
  99. package/dist/communications/contracts/subscriptionPackageChanged.d.ts +20 -0
  100. package/dist/communications/contracts/subscriptionPackageChanged.js +26 -0
  101. package/dist/communications/contracts/subscriptionPauseReminder.d.ts +23 -0
  102. package/dist/communications/contracts/subscriptionPauseReminder.js +29 -0
  103. package/dist/communications/contracts/subscriptionPaused.d.ts +21 -0
  104. package/dist/communications/contracts/subscriptionPaused.js +25 -0
  105. package/dist/communications/contracts/subscriptionPaymentExpired.d.ts +34 -0
  106. package/dist/communications/contracts/subscriptionPaymentExpired.js +37 -0
  107. package/dist/communications/contracts/subscriptionPaymentFailed.d.ts +49 -0
  108. package/dist/communications/contracts/subscriptionPaymentFailed.js +56 -0
  109. package/dist/communications/contracts/subscriptionPaymentRecovered.d.ts +19 -0
  110. package/dist/communications/contracts/subscriptionPaymentRecovered.js +22 -0
  111. package/dist/communications/contracts/subscriptionRenewalAtRisk.d.ts +36 -0
  112. package/dist/communications/contracts/subscriptionRenewalAtRisk.js +36 -0
  113. package/dist/communications/contracts/subscriptionRenewalUpcoming.d.ts +49 -0
  114. package/dist/communications/contracts/subscriptionRenewalUpcoming.js +43 -0
  115. package/dist/communications/contracts/subscriptionResumed.d.ts +23 -0
  116. package/dist/communications/contracts/subscriptionResumed.js +25 -0
  117. package/dist/communications/contracts/subscriptionWelcome.d.ts +44 -0
  118. package/dist/communications/contracts/subscriptionWelcome.js +45 -0
  119. package/dist/communications/contracts/subscriptionWinback.d.ts +21 -0
  120. package/dist/communications/contracts/subscriptionWinback.js +28 -0
  121. package/dist/communications/contracts/transactionalDelivery.d.ts +42 -0
  122. package/dist/communications/contracts/transactionalDelivery.js +1 -0
  123. package/dist/communications/contracts/types.d.ts +46 -0
  124. package/dist/communications/contracts/types.js +1 -0
  125. package/dist/communications/contribution.d.ts +10 -0
  126. package/dist/communications/contribution.js +24 -0
  127. package/dist/communications/deliveryReconciliation.d.ts +64 -0
  128. package/dist/communications/deliveryReconciliation.js +60 -0
  129. package/dist/communications/emailEgress.d.ts +38 -0
  130. package/dist/communications/emailEgress.js +100 -0
  131. package/dist/communications/emailHealthAssessment.d.ts +39 -0
  132. package/dist/communications/emailHealthAssessment.js +59 -0
  133. package/dist/communications/emailHealthMetricsPort.d.ts +17 -0
  134. package/dist/communications/emailHealthMetricsPort.js +1 -0
  135. package/dist/communications/emailNotificationControl.d.ts +27 -0
  136. package/dist/communications/emailNotificationControl.js +10 -0
  137. package/dist/communications/emailObservation.d.ts +28 -0
  138. package/dist/communications/emailObservation.js +23 -0
  139. package/dist/communications/emailTransport.d.ts +82 -0
  140. package/dist/communications/emailTransport.js +95 -0
  141. package/dist/communications/errors.d.ts +15 -0
  142. package/dist/communications/errors.js +30 -0
  143. package/dist/communications/index.d.ts +46 -0
  144. package/dist/communications/index.js +38 -0
  145. package/dist/communications/integrationEventSignature.d.ts +15 -0
  146. package/dist/communications/integrationEventSignature.js +37 -0
  147. package/dist/communications/managedTransactionalDeliveryStore.d.ts +12 -0
  148. package/dist/communications/managedTransactionalDeliveryStore.js +49 -0
  149. package/dist/communications/nativeOperations.d.ts +79 -0
  150. package/dist/communications/nativeOperations.js +3 -0
  151. package/dist/communications/newsletterIntegrationContracts.d.ts +130 -0
  152. package/dist/communications/newsletterIntegrationContracts.js +128 -0
  153. package/dist/communications/newsletterWebhookPort.d.ts +11 -0
  154. package/dist/communications/newsletterWebhookPort.js +84 -0
  155. package/dist/communications/newsletterWebhookProcessing.d.ts +17 -0
  156. package/dist/communications/newsletterWebhookProcessing.js +71 -0
  157. package/dist/communications/originPolicy.d.ts +40 -0
  158. package/dist/communications/originPolicy.js +100 -0
  159. package/dist/communications/postgresCommunicationSync.d.ts +79 -0
  160. package/dist/communications/postgresCommunicationSync.js +111 -0
  161. package/dist/communications/postgresConsentEvaluator.d.ts +19 -0
  162. package/dist/communications/postgresConsentEvaluator.js +43 -0
  163. package/dist/communications/postgresDeliveryReconciliation.d.ts +3 -0
  164. package/dist/communications/postgresDeliveryReconciliation.js +113 -0
  165. package/dist/communications/postgresNativeOperations.d.ts +13 -0
  166. package/dist/communications/postgresNativeOperations.js +63 -0
  167. package/dist/communications/postgresNotificationRecipients.d.ts +37 -0
  168. package/dist/communications/postgresNotificationRecipients.js +60 -0
  169. package/dist/communications/postgresTransactionalDeliveryStore.d.ts +7 -0
  170. package/dist/communications/postgresTransactionalDeliveryStore.js +55 -0
  171. package/dist/communications/preferencesToken.d.ts +10 -0
  172. package/dist/communications/preferencesToken.js +40 -0
  173. package/dist/communications/publicPreferenceToken.d.ts +24 -0
  174. package/dist/communications/publicPreferenceToken.js +53 -0
  175. package/dist/communications/shipmentNotifications.d.ts +34 -0
  176. package/dist/communications/shipmentNotifications.js +61 -0
  177. package/dist/communications/sql.d.ts +26 -0
  178. package/dist/communications/sql.js +7 -0
  179. package/dist/communications/standardWebhooks.d.ts +14 -0
  180. package/dist/communications/standardWebhooks.js +73 -0
  181. package/dist/communications/status.d.ts +11 -0
  182. package/dist/communications/status.js +36 -0
  183. package/dist/communications/transactionalDelivery.d.ts +19 -0
  184. package/dist/communications/transactionalDelivery.js +96 -0
  185. package/dist/communications/transactionalDeliveryIdentifier.d.ts +3 -0
  186. package/dist/communications/transactionalDeliveryIdentifier.js +6 -0
  187. package/dist/communications/unsubscribeToken.d.ts +77 -0
  188. package/dist/communications/unsubscribeToken.js +150 -0
  189. package/dist/communications/validation.d.ts +2 -0
  190. package/dist/communications/validation.js +3 -0
  191. package/dist/http/index.d.ts +1 -0
  192. package/dist/http/index.js +1 -0
  193. package/dist/http/webhookSignature.d.ts +42 -0
  194. package/dist/http/webhookSignature.js +86 -0
  195. package/package.json +12 -2
  196. package/release-gates.json +41 -8
  197. package/sql/20260807190000_comms_outbox_rail.sql +329 -0
  198. package/sql/20260810120001_transactional_delivery_receipts.sql +209 -0
  199. package/sql/20260813120000_communications_control_plane.sql +568 -0
  200. package/sql/20261019200000_communications_native_operations.sql +68 -0
  201. package/src/communications/accountingDocumentDelivery.ts +63 -0
  202. package/src/communications/authEmailError.ts +10 -0
  203. package/src/communications/authEmailPorts.ts +2 -0
  204. package/src/communications/authSendEmailHook.ts +310 -0
  205. package/src/communications/capturedTransactionalDelivery.ts +29 -0
  206. package/src/communications/communicationSync.ts +96 -0
  207. package/src/communications/communicationSyncWorker.ts +302 -0
  208. package/src/communications/consentPolicy.ts +82 -0
  209. package/src/communications/consentPurposeRegistry.ts +31 -0
  210. package/src/communications/contracts/abandonedCart.ts +64 -0
  211. package/src/communications/contracts/authEmail.ts +73 -0
  212. package/src/communications/contracts/backInStock.ts +69 -0
  213. package/src/communications/contracts/blocks.ts +47 -0
  214. package/src/communications/contracts/checkoutExpired.ts +62 -0
  215. package/src/communications/contracts/checkoutRecovery.ts +68 -0
  216. package/src/communications/contracts/commerceEmailContent.ts +189 -0
  217. package/src/communications/contracts/commerceEngagementEmailContent.ts +106 -0
  218. package/src/communications/contracts/consent.ts +13 -0
  219. package/src/communications/contracts/email.ts +210 -0
  220. package/src/communications/contracts/guideCard.ts +34 -0
  221. package/src/communications/contracts/index.ts +51 -0
  222. package/src/communications/contracts/inquiryContent.ts +53 -0
  223. package/src/communications/contracts/invoiceDocumentContent.ts +57 -0
  224. package/src/communications/contracts/marketingAutomation.ts +45 -0
  225. package/src/communications/contracts/newsletter.ts +78 -0
  226. package/src/communications/contracts/newsletterWebhook.ts +23 -0
  227. package/src/communications/contracts/optOutContent.ts +23 -0
  228. package/src/communications/contracts/orderCanceled.ts +64 -0
  229. package/src/communications/contracts/orderDraft.ts +112 -0
  230. package/src/communications/contracts/orderPaid.ts +147 -0
  231. package/src/communications/contracts/orderRefunded.ts +63 -0
  232. package/src/communications/contracts/paymentFailed.ts +59 -0
  233. package/src/communications/contracts/publicIntake.ts +53 -0
  234. package/src/communications/contracts/render.ts +271 -0
  235. package/src/communications/contracts/reorderReminder.ts +59 -0
  236. package/src/communications/contracts/returnEmails.ts +113 -0
  237. package/src/communications/contracts/reviewEffects.ts +60 -0
  238. package/src/communications/contracts/reviewRequest.ts +59 -0
  239. package/src/communications/contracts/roleNotificationContent.ts +65 -0
  240. package/src/communications/contracts/shipmentDelivered.ts +59 -0
  241. package/src/communications/contracts/shipmentDispatched.ts +77 -0
  242. package/src/communications/contracts/shipmentException.ts +62 -0
  243. package/src/communications/contracts/subscriptionActivationActionRequired.ts +37 -0
  244. package/src/communications/contracts/subscriptionAddressChanged.ts +56 -0
  245. package/src/communications/contracts/subscriptionCancelled.ts +57 -0
  246. package/src/communications/contracts/subscriptionCycleSkipped.ts +80 -0
  247. package/src/communications/contracts/subscriptionDeliveryRescheduled.ts +79 -0
  248. package/src/communications/contracts/subscriptionEmailContent.ts +163 -0
  249. package/src/communications/contracts/subscriptionPackageChanged.ts +59 -0
  250. package/src/communications/contracts/subscriptionPauseReminder.ts +63 -0
  251. package/src/communications/contracts/subscriptionPaused.ts +58 -0
  252. package/src/communications/contracts/subscriptionPaymentExpired.ts +83 -0
  253. package/src/communications/contracts/subscriptionPaymentFailed.ts +117 -0
  254. package/src/communications/contracts/subscriptionPaymentRecovered.ts +50 -0
  255. package/src/communications/contracts/subscriptionRenewalAtRisk.ts +85 -0
  256. package/src/communications/contracts/subscriptionRenewalUpcoming.ts +103 -0
  257. package/src/communications/contracts/subscriptionResumed.ts +60 -0
  258. package/src/communications/contracts/subscriptionWelcome.ts +102 -0
  259. package/src/communications/contracts/subscriptionWinback.ts +62 -0
  260. package/src/communications/contracts/transactionalDelivery.ts +43 -0
  261. package/src/communications/contracts/types.ts +58 -0
  262. package/src/communications/contribution.ts +33 -0
  263. package/src/communications/deliveryReconciliation.ts +108 -0
  264. package/src/communications/emailEgress.ts +111 -0
  265. package/src/communications/emailHealthAssessment.ts +106 -0
  266. package/src/communications/emailHealthMetricsPort.ts +17 -0
  267. package/src/communications/emailNotificationControl.ts +28 -0
  268. package/src/communications/emailObservation.ts +43 -0
  269. package/src/communications/emailTransport.ts +167 -0
  270. package/src/communications/errors.ts +34 -0
  271. package/src/communications/index.ts +46 -0
  272. package/src/communications/integrationEventSignature.ts +49 -0
  273. package/src/communications/managedTransactionalDeliveryStore.ts +59 -0
  274. package/src/communications/nativeOperations.ts +40 -0
  275. package/src/communications/newsletterIntegrationContracts.ts +154 -0
  276. package/src/communications/newsletterWebhookPort.ts +104 -0
  277. package/src/communications/newsletterWebhookProcessing.ts +102 -0
  278. package/src/communications/originPolicy.ts +151 -0
  279. package/src/communications/postgresCommunicationSync.ts +127 -0
  280. package/src/communications/postgresConsentEvaluator.ts +49 -0
  281. package/src/communications/postgresDeliveryReconciliation.ts +101 -0
  282. package/src/communications/postgresNativeOperations.ts +55 -0
  283. package/src/communications/postgresNotificationRecipients.ts +57 -0
  284. package/src/communications/postgresTransactionalDeliveryStore.ts +79 -0
  285. package/src/communications/preferencesToken.ts +62 -0
  286. package/src/communications/publicPreferenceToken.ts +68 -0
  287. package/src/communications/shipmentNotifications.ts +78 -0
  288. package/src/communications/sql.ts +7 -0
  289. package/src/communications/standardWebhooks.ts +84 -0
  290. package/src/communications/status.ts +51 -0
  291. package/src/communications/transactionalDelivery.ts +114 -0
  292. package/src/communications/transactionalDeliveryIdentifier.ts +9 -0
  293. package/src/communications/unsubscribeToken.ts +186 -0
  294. package/src/communications/validation.ts +3 -0
  295. package/src/http/index.ts +1 -0
  296. package/src/http/webhookSignature.ts +96 -0
@@ -0,0 +1,209 @@
1
+ -- Public platform transactional-delivery receipt capability.
2
+ --
3
+ -- The forward exposes one neutral durable receipt and three invoker-rights RPCs:
4
+ -- read, record accepted, and record failed. It persists only a command digest,
5
+ -- a neutral delivery reference, a constrained failure code, transition state,
6
+ -- attempt count and timestamps. Delivery content and transport diagnostics stay
7
+ -- outside this compact kernel boundary.
8
+
9
+ CREATE TABLE public.transactional_delivery_receipts (
10
+ idempotency_key text PRIMARY KEY,
11
+ command_fingerprint text NOT NULL,
12
+ state text NOT NULL,
13
+ delivery_reference text,
14
+ error_code text,
15
+ attempt_count integer NOT NULL,
16
+ created_at timestamptz NOT NULL DEFAULT now(),
17
+ updated_at timestamptz NOT NULL DEFAULT now(),
18
+ accepted_at timestamptz,
19
+ failed_at timestamptz,
20
+ CONSTRAINT transactional_delivery_receipts_idempotency_key_nonempty_check
21
+ CHECK (btrim(idempotency_key) <> ''),
22
+ CONSTRAINT transactional_delivery_receipts_idempotency_key_format_check
23
+ CHECK (idempotency_key ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$'),
24
+ CONSTRAINT transactional_delivery_receipts_fingerprint_format_check
25
+ CHECK (command_fingerprint ~ '^[a-f0-9]{64}$'),
26
+ CONSTRAINT transactional_delivery_receipts_state_check
27
+ CHECK (state IN ('accepted', 'failed')),
28
+ CONSTRAINT transactional_delivery_receipts_attempt_count_check
29
+ CHECK (attempt_count >= 1),
30
+ CONSTRAINT transactional_delivery_receipts_evidence_shape_check
31
+ CHECK (
32
+ (state = 'accepted'
33
+ AND delivery_reference IS NOT NULL
34
+ AND error_code IS NULL
35
+ AND accepted_at IS NOT NULL)
36
+ OR
37
+ (state = 'failed'
38
+ AND delivery_reference IS NULL
39
+ AND error_code IS NOT NULL
40
+ AND accepted_at IS NULL
41
+ AND failed_at IS NOT NULL)
42
+ ),
43
+ CONSTRAINT transactional_delivery_receipts_timestamp_order_check
44
+ CHECK (
45
+ updated_at >= created_at
46
+ AND (accepted_at IS NULL OR accepted_at >= created_at)
47
+ AND (failed_at IS NULL OR failed_at >= created_at)
48
+ )
49
+ );
50
+
51
+ CREATE FUNCTION public.transactional_delivery_read_receipt(
52
+ p_idempotency_key text
53
+ )
54
+ RETURNS SETOF public.transactional_delivery_receipts
55
+ LANGUAGE sql
56
+ STABLE
57
+ SET search_path = public, pg_catalog
58
+ AS $$
59
+ SELECT receipt.*
60
+ FROM public.transactional_delivery_receipts AS receipt
61
+ WHERE receipt.idempotency_key = p_idempotency_key;
62
+ $$;
63
+
64
+ CREATE FUNCTION public.transactional_delivery_record_accepted(
65
+ p_idempotency_key text,
66
+ p_command_fingerprint text,
67
+ p_delivery_reference text
68
+ )
69
+ RETURNS public.transactional_delivery_receipts
70
+ LANGUAGE plpgsql
71
+ SET search_path = public, pg_catalog
72
+ AS $$
73
+ DECLARE
74
+ v_receipt public.transactional_delivery_receipts%ROWTYPE;
75
+ BEGIN
76
+ IF p_idempotency_key IS NULL
77
+ OR p_idempotency_key !~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$' THEN
78
+ RAISE EXCEPTION 'transactional_delivery_invalid_idempotency_key' USING ERRCODE = '22023';
79
+ END IF;
80
+ IF p_command_fingerprint IS NULL OR p_command_fingerprint !~ '^[a-f0-9]{64}$' THEN
81
+ RAISE EXCEPTION 'transactional_delivery_invalid_command_fingerprint' USING ERRCODE = '22023';
82
+ END IF;
83
+ IF p_delivery_reference IS NULL
84
+ OR p_delivery_reference !~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$' THEN
85
+ RAISE EXCEPTION 'transactional_delivery_invalid_delivery_reference' USING ERRCODE = '22023';
86
+ END IF;
87
+
88
+ LOOP
89
+ SELECT * INTO v_receipt
90
+ FROM public.transactional_delivery_receipts
91
+ WHERE idempotency_key = p_idempotency_key
92
+ FOR UPDATE;
93
+
94
+ IF FOUND THEN
95
+ IF v_receipt.command_fingerprint <> p_command_fingerprint THEN
96
+ RAISE EXCEPTION 'transactional_delivery_command_fingerprint_conflict' USING ERRCODE = '22023';
97
+ END IF;
98
+ IF v_receipt.state = 'accepted' THEN
99
+ RETURN v_receipt;
100
+ END IF;
101
+
102
+ UPDATE public.transactional_delivery_receipts
103
+ SET state = 'accepted',
104
+ delivery_reference = p_delivery_reference,
105
+ error_code = NULL,
106
+ attempt_count = attempt_count + 1,
107
+ updated_at = now(),
108
+ accepted_at = now()
109
+ WHERE idempotency_key = p_idempotency_key
110
+ RETURNING * INTO v_receipt;
111
+ RETURN v_receipt;
112
+ END IF;
113
+
114
+ INSERT INTO public.transactional_delivery_receipts (
115
+ idempotency_key,
116
+ command_fingerprint,
117
+ state,
118
+ delivery_reference,
119
+ attempt_count,
120
+ accepted_at
121
+ ) VALUES (
122
+ p_idempotency_key,
123
+ p_command_fingerprint,
124
+ 'accepted',
125
+ p_delivery_reference,
126
+ 1,
127
+ now()
128
+ )
129
+ ON CONFLICT (idempotency_key) DO NOTHING
130
+ RETURNING * INTO v_receipt;
131
+
132
+ IF FOUND THEN
133
+ RETURN v_receipt;
134
+ END IF;
135
+ END LOOP;
136
+ END;
137
+ $$;
138
+
139
+ CREATE FUNCTION public.transactional_delivery_record_failed(
140
+ p_idempotency_key text,
141
+ p_command_fingerprint text,
142
+ p_error_code text
143
+ )
144
+ RETURNS public.transactional_delivery_receipts
145
+ LANGUAGE plpgsql
146
+ SET search_path = public, pg_catalog
147
+ AS $$
148
+ DECLARE
149
+ v_receipt public.transactional_delivery_receipts%ROWTYPE;
150
+ BEGIN
151
+ IF p_idempotency_key IS NULL
152
+ OR p_idempotency_key !~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$' THEN
153
+ RAISE EXCEPTION 'transactional_delivery_invalid_idempotency_key' USING ERRCODE = '22023';
154
+ END IF;
155
+ IF p_command_fingerprint IS NULL OR p_command_fingerprint !~ '^[a-f0-9]{64}$' THEN
156
+ RAISE EXCEPTION 'transactional_delivery_invalid_command_fingerprint' USING ERRCODE = '22023';
157
+ END IF;
158
+ IF p_error_code IS NULL OR p_error_code !~ '^[a-z][a-z0-9_.-]{0,127}$' THEN
159
+ RAISE EXCEPTION 'transactional_delivery_invalid_error_code' USING ERRCODE = '22023';
160
+ END IF;
161
+
162
+ LOOP
163
+ SELECT * INTO v_receipt
164
+ FROM public.transactional_delivery_receipts
165
+ WHERE idempotency_key = p_idempotency_key
166
+ FOR UPDATE;
167
+
168
+ IF FOUND THEN
169
+ IF v_receipt.command_fingerprint <> p_command_fingerprint THEN
170
+ RAISE EXCEPTION 'transactional_delivery_command_fingerprint_conflict' USING ERRCODE = '22023';
171
+ END IF;
172
+ IF v_receipt.state = 'accepted' THEN
173
+ RETURN v_receipt;
174
+ END IF;
175
+
176
+ UPDATE public.transactional_delivery_receipts
177
+ SET error_code = p_error_code,
178
+ attempt_count = attempt_count + 1,
179
+ updated_at = now(),
180
+ failed_at = now()
181
+ WHERE idempotency_key = p_idempotency_key
182
+ RETURNING * INTO v_receipt;
183
+ RETURN v_receipt;
184
+ END IF;
185
+
186
+ INSERT INTO public.transactional_delivery_receipts (
187
+ idempotency_key,
188
+ command_fingerprint,
189
+ state,
190
+ error_code,
191
+ attempt_count,
192
+ failed_at
193
+ ) VALUES (
194
+ p_idempotency_key,
195
+ p_command_fingerprint,
196
+ 'failed',
197
+ p_error_code,
198
+ 1,
199
+ now()
200
+ )
201
+ ON CONFLICT (idempotency_key) DO NOTHING
202
+ RETURNING * INTO v_receipt;
203
+
204
+ IF FOUND THEN
205
+ RETURN v_receipt;
206
+ END IF;
207
+ END LOOP;
208
+ END;
209
+ $$;