hazo_notify 3.0.0 → 4.0.2

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 (253) hide show
  1. package/README.md +122 -17
  2. package/config/hazo_notify_config.ini +37 -0
  3. package/dist/components/notification_banner/index.d.ts +27 -0
  4. package/dist/components/notification_banner/index.d.ts.map +1 -0
  5. package/dist/components/notification_banner/index.js +42 -0
  6. package/dist/components/notification_banner/index.js.map +1 -0
  7. package/dist/components/notification_bell/index.d.ts +56 -0
  8. package/dist/components/notification_bell/index.d.ts.map +1 -0
  9. package/dist/components/notification_bell/index.js +73 -0
  10. package/dist/components/notification_bell/index.js.map +1 -0
  11. package/dist/components/template_manager/template_editor.js +3 -3
  12. package/dist/components/template_manager/template_editor.js.map +1 -1
  13. package/dist/components/template_manager/template_manager_admin.d.ts.map +1 -1
  14. package/dist/components/template_manager/template_manager_admin.js +3 -4
  15. package/dist/components/template_manager/template_manager_admin.js.map +1 -1
  16. package/dist/lib/adapters/email/adapter.d.ts +49 -0
  17. package/dist/lib/adapters/email/adapter.d.ts.map +1 -0
  18. package/dist/lib/adapters/email/adapter.js +87 -0
  19. package/dist/lib/adapters/email/adapter.js.map +1 -0
  20. package/dist/lib/adapters/email/config.d.ts +15 -0
  21. package/dist/lib/adapters/email/config.d.ts.map +1 -0
  22. package/dist/lib/{emailer/emailer.js → adapters/email/config.js} +7 -113
  23. package/dist/lib/adapters/email/config.js.map +1 -0
  24. package/dist/lib/adapters/email/envelope.d.ts +29 -0
  25. package/dist/lib/adapters/email/envelope.d.ts.map +1 -0
  26. package/dist/lib/adapters/email/envelope.js +46 -0
  27. package/dist/lib/adapters/email/envelope.js.map +1 -0
  28. package/dist/lib/adapters/email/index.d.ts +12 -0
  29. package/dist/lib/adapters/email/index.d.ts.map +1 -0
  30. package/dist/lib/adapters/email/index.js +11 -0
  31. package/dist/lib/adapters/email/index.js.map +1 -0
  32. package/dist/lib/adapters/email/providers/index.d.ts.map +1 -0
  33. package/dist/lib/adapters/email/providers/index.js.map +1 -0
  34. package/dist/lib/adapters/email/providers/pop3_provider.d.ts.map +1 -0
  35. package/dist/lib/adapters/email/providers/pop3_provider.js.map +1 -0
  36. package/dist/lib/adapters/email/providers/smtp_provider.d.ts.map +1 -0
  37. package/dist/lib/adapters/email/providers/smtp_provider.js.map +1 -0
  38. package/dist/lib/adapters/email/providers/zeptomail_provider.d.ts.map +1 -0
  39. package/dist/lib/adapters/email/providers/zeptomail_provider.js.map +1 -0
  40. package/dist/lib/{emailer/emailer.d.ts → adapters/email/send_email.d.ts} +9 -10
  41. package/dist/lib/adapters/email/send_email.d.ts.map +1 -0
  42. package/dist/lib/adapters/email/send_email.js +122 -0
  43. package/dist/lib/adapters/email/send_email.js.map +1 -0
  44. package/dist/lib/adapters/email/types.d.ts.map +1 -0
  45. package/dist/lib/adapters/email/types.js.map +1 -0
  46. package/dist/lib/adapters/email/utils/constants.d.ts.map +1 -0
  47. package/dist/lib/adapters/email/utils/constants.js.map +1 -0
  48. package/dist/lib/adapters/email/utils/index.d.ts.map +1 -0
  49. package/dist/lib/adapters/email/utils/index.js.map +1 -0
  50. package/dist/lib/adapters/email/utils/logger.d.ts.map +1 -0
  51. package/dist/lib/adapters/email/utils/logger.js.map +1 -0
  52. package/dist/lib/adapters/email/utils/validation.d.ts.map +1 -0
  53. package/dist/lib/adapters/email/utils/validation.js.map +1 -0
  54. package/dist/lib/adapters/telegram/adapter.d.ts +25 -0
  55. package/dist/lib/adapters/telegram/adapter.d.ts.map +1 -0
  56. package/dist/lib/adapters/telegram/adapter.js +75 -0
  57. package/dist/lib/adapters/telegram/adapter.js.map +1 -0
  58. package/dist/lib/adapters/telegram/config.d.ts +22 -0
  59. package/dist/lib/adapters/telegram/config.d.ts.map +1 -0
  60. package/dist/lib/adapters/telegram/config.js +60 -0
  61. package/dist/lib/adapters/telegram/config.js.map +1 -0
  62. package/dist/lib/adapters/telegram/index.d.ts +8 -0
  63. package/dist/lib/adapters/telegram/index.d.ts.map +1 -0
  64. package/dist/lib/adapters/telegram/index.js +5 -0
  65. package/dist/lib/adapters/telegram/index.js.map +1 -0
  66. package/dist/lib/adapters/telegram/splitter.d.ts +7 -0
  67. package/dist/lib/adapters/telegram/splitter.d.ts.map +1 -0
  68. package/dist/lib/adapters/telegram/splitter.js +47 -0
  69. package/dist/lib/adapters/telegram/splitter.js.map +1 -0
  70. package/dist/lib/adapters/telegram/transport.d.ts +31 -0
  71. package/dist/lib/adapters/telegram/transport.d.ts.map +1 -0
  72. package/dist/lib/adapters/telegram/transport.js +112 -0
  73. package/dist/lib/adapters/telegram/transport.js.map +1 -0
  74. package/dist/lib/api/banner.d.ts +41 -0
  75. package/dist/lib/api/banner.d.ts.map +1 -0
  76. package/dist/lib/api/banner.js +53 -0
  77. package/dist/lib/api/banner.js.map +1 -0
  78. package/dist/lib/api/inbox.d.ts +33 -0
  79. package/dist/lib/api/inbox.d.ts.map +1 -0
  80. package/dist/lib/api/inbox.js +52 -0
  81. package/dist/lib/api/inbox.js.map +1 -0
  82. package/dist/lib/channels/index.d.ts +3 -0
  83. package/dist/lib/channels/index.d.ts.map +1 -0
  84. package/dist/lib/channels/index.js +3 -0
  85. package/dist/lib/channels/index.js.map +1 -0
  86. package/dist/lib/channels/registry.d.ts +7 -0
  87. package/dist/lib/channels/registry.d.ts.map +1 -0
  88. package/dist/lib/channels/registry.js +24 -0
  89. package/dist/lib/channels/registry.js.map +1 -0
  90. package/dist/lib/channels/types.d.ts +82 -0
  91. package/dist/lib/channels/types.d.ts.map +1 -0
  92. package/dist/lib/channels/types.js +8 -0
  93. package/dist/lib/channels/types.js.map +1 -0
  94. package/dist/lib/dispatcher/batch-key.d.ts +15 -0
  95. package/dist/lib/dispatcher/batch-key.d.ts.map +1 -0
  96. package/dist/lib/dispatcher/batch-key.js +19 -0
  97. package/dist/lib/dispatcher/batch-key.js.map +1 -0
  98. package/dist/lib/dispatcher/index.d.ts +4 -0
  99. package/dist/lib/dispatcher/index.d.ts.map +1 -0
  100. package/dist/lib/dispatcher/index.js +73 -0
  101. package/dist/lib/dispatcher/index.js.map +1 -0
  102. package/dist/lib/inbox/connection.d.ts +19 -0
  103. package/dist/lib/inbox/connection.d.ts.map +1 -0
  104. package/dist/lib/inbox/connection.js +34 -0
  105. package/dist/lib/inbox/connection.js.map +1 -0
  106. package/dist/lib/inbox/dialects/index.d.ts +10 -0
  107. package/dist/lib/inbox/dialects/index.d.ts.map +1 -0
  108. package/dist/lib/inbox/dialects/index.js +13 -0
  109. package/dist/lib/inbox/dialects/index.js.map +1 -0
  110. package/dist/lib/inbox/dialects/postgres.d.ts +3 -0
  111. package/dist/lib/inbox/dialects/postgres.d.ts.map +1 -0
  112. package/dist/lib/inbox/dialects/postgres.js +110 -0
  113. package/dist/lib/inbox/dialects/postgres.js.map +1 -0
  114. package/dist/lib/inbox/dialects/sqlite.d.ts +3 -0
  115. package/dist/lib/inbox/dialects/sqlite.d.ts.map +1 -0
  116. package/dist/lib/inbox/dialects/sqlite.js +120 -0
  117. package/dist/lib/inbox/dialects/sqlite.js.map +1 -0
  118. package/dist/lib/inbox/dialects/types.d.ts +53 -0
  119. package/dist/lib/inbox/dialects/types.d.ts.map +1 -0
  120. package/dist/lib/inbox/dialects/types.js +2 -0
  121. package/dist/lib/inbox/dialects/types.js.map +1 -0
  122. package/dist/lib/inbox/index.d.ts +9 -0
  123. package/dist/lib/inbox/index.d.ts.map +1 -0
  124. package/dist/lib/inbox/index.js +6 -0
  125. package/dist/lib/inbox/index.js.map +1 -0
  126. package/dist/lib/inbox/storage.d.ts +21 -0
  127. package/dist/lib/inbox/storage.d.ts.map +1 -0
  128. package/dist/lib/inbox/storage.js +94 -0
  129. package/dist/lib/inbox/storage.js.map +1 -0
  130. package/dist/lib/inbox/types.d.ts +57 -0
  131. package/dist/lib/inbox/types.d.ts.map +1 -0
  132. package/dist/lib/inbox/types.js +2 -0
  133. package/dist/lib/inbox/types.js.map +1 -0
  134. package/dist/lib/inbox/worker/cleanup.d.ts +14 -0
  135. package/dist/lib/inbox/worker/cleanup.d.ts.map +1 -0
  136. package/dist/lib/inbox/worker/cleanup.js +37 -0
  137. package/dist/lib/inbox/worker/cleanup.js.map +1 -0
  138. package/dist/lib/inbox/worker/flush.d.ts +31 -0
  139. package/dist/lib/inbox/worker/flush.d.ts.map +1 -0
  140. package/dist/lib/inbox/worker/flush.js +97 -0
  141. package/dist/lib/inbox/worker/flush.js.map +1 -0
  142. package/dist/lib/inbox/worker/render.d.ts +23 -0
  143. package/dist/lib/inbox/worker/render.d.ts.map +1 -0
  144. package/dist/lib/inbox/worker/render.js +42 -0
  145. package/dist/lib/inbox/worker/render.js.map +1 -0
  146. package/dist/lib/inbox/worker/start.d.ts +29 -0
  147. package/dist/lib/inbox/worker/start.d.ts.map +1 -0
  148. package/dist/lib/inbox/worker/start.js +100 -0
  149. package/dist/lib/inbox/worker/start.js.map +1 -0
  150. package/dist/lib/index.d.ts +1 -6
  151. package/dist/lib/index.d.ts.map +1 -1
  152. package/dist/lib/index.js +4 -6
  153. package/dist/lib/index.js.map +1 -1
  154. package/dist/lib/jobs/handler.d.ts +25 -0
  155. package/dist/lib/jobs/handler.d.ts.map +1 -0
  156. package/dist/lib/jobs/handler.js +36 -0
  157. package/dist/lib/jobs/handler.js.map +1 -0
  158. package/dist/lib/jobs/index.d.ts +16 -0
  159. package/dist/lib/jobs/index.d.ts.map +1 -0
  160. package/dist/lib/jobs/index.js +13 -0
  161. package/dist/lib/jobs/index.js.map +1 -0
  162. package/dist/lib/jobs/submit.d.ts +20 -0
  163. package/dist/lib/jobs/submit.d.ts.map +1 -0
  164. package/dist/lib/jobs/submit.js +25 -0
  165. package/dist/lib/jobs/submit.js.map +1 -0
  166. package/dist/lib/jobs/types.d.ts +42 -0
  167. package/dist/lib/jobs/types.d.ts.map +1 -0
  168. package/dist/lib/jobs/types.js +12 -0
  169. package/dist/lib/jobs/types.js.map +1 -0
  170. package/dist/lib/template_manager/db/template_repository.d.ts.map +1 -1
  171. package/dist/lib/template_manager/db/template_repository.js +16 -31
  172. package/dist/lib/template_manager/db/template_repository.js.map +1 -1
  173. package/dist/lib/template_manager/engine/variable_resolver.js +4 -4
  174. package/dist/lib/template_manager/engine/variable_resolver.js.map +1 -1
  175. package/dist/lib/template_manager/handlers/adapters/hazo_auth.d.ts +20 -0
  176. package/dist/lib/template_manager/handlers/adapters/hazo_auth.d.ts.map +1 -0
  177. package/dist/lib/template_manager/handlers/adapters/hazo_auth.js +46 -0
  178. package/dist/lib/template_manager/handlers/adapters/hazo_auth.js.map +1 -0
  179. package/dist/lib/template_manager/handlers/auth.d.ts +47 -0
  180. package/dist/lib/template_manager/handlers/auth.d.ts.map +1 -0
  181. package/dist/lib/template_manager/handlers/auth.js +67 -0
  182. package/dist/lib/template_manager/handlers/auth.js.map +1 -0
  183. package/dist/lib/template_manager/handlers/index.d.ts +67 -0
  184. package/dist/lib/template_manager/handlers/index.d.ts.map +1 -0
  185. package/dist/lib/template_manager/handlers/index.js +282 -0
  186. package/dist/lib/template_manager/handlers/index.js.map +1 -0
  187. package/dist/lib/template_manager/seed/sync.d.ts.map +1 -1
  188. package/dist/lib/template_manager/seed/sync.js +20 -4
  189. package/dist/lib/template_manager/seed/sync.js.map +1 -1
  190. package/dist/lib/template_manager/template_manager.d.ts.map +1 -1
  191. package/dist/lib/template_manager/template_manager.js +67 -26
  192. package/dist/lib/template_manager/template_manager.js.map +1 -1
  193. package/dist/lib/template_manager/types.d.ts +35 -9
  194. package/dist/lib/template_manager/types.d.ts.map +1 -1
  195. package/dist/lib/template_manager/utils/index.d.ts +1 -1
  196. package/dist/lib/template_manager/utils/index.d.ts.map +1 -1
  197. package/dist/lib/template_manager/utils/index.js +1 -1
  198. package/dist/lib/template_manager/utils/index.js.map +1 -1
  199. package/dist/lib/template_manager/utils/validation.d.ts +12 -11
  200. package/dist/lib/template_manager/utils/validation.d.ts.map +1 -1
  201. package/dist/lib/template_manager/utils/validation.js +15 -22
  202. package/dist/lib/template_manager/utils/validation.js.map +1 -1
  203. package/migrations/003_create_notifications_table.sql +48 -0
  204. package/migrations/004_inbox_upsert_rpc.sql +63 -0
  205. package/migrations/005_inbox_v4_refactor.pg.sql +53 -0
  206. package/migrations/005_inbox_v4_refactor.sqlite.sql +30 -0
  207. package/migrations/006_channel_deliveries.pg.sql +61 -0
  208. package/migrations/006_channel_deliveries.sqlite.sql +26 -0
  209. package/migrations/007_templates_bodies_jsonb.pg.sql +17 -0
  210. package/migrations/007_templates_bodies_jsonb.sqlite.sql +18 -0
  211. package/package.json +63 -14
  212. package/dist/lib/emailer/emailer.d.ts.map +0 -1
  213. package/dist/lib/emailer/emailer.js.map +0 -1
  214. package/dist/lib/emailer/index.d.ts +0 -12
  215. package/dist/lib/emailer/index.d.ts.map +0 -1
  216. package/dist/lib/emailer/index.js +0 -13
  217. package/dist/lib/emailer/index.js.map +0 -1
  218. package/dist/lib/emailer/providers/index.d.ts.map +0 -1
  219. package/dist/lib/emailer/providers/index.js.map +0 -1
  220. package/dist/lib/emailer/providers/pop3_provider.d.ts.map +0 -1
  221. package/dist/lib/emailer/providers/pop3_provider.js.map +0 -1
  222. package/dist/lib/emailer/providers/smtp_provider.d.ts.map +0 -1
  223. package/dist/lib/emailer/providers/smtp_provider.js.map +0 -1
  224. package/dist/lib/emailer/providers/zeptomail_provider.d.ts.map +0 -1
  225. package/dist/lib/emailer/providers/zeptomail_provider.js.map +0 -1
  226. package/dist/lib/emailer/types.d.ts.map +0 -1
  227. package/dist/lib/emailer/types.js.map +0 -1
  228. package/dist/lib/emailer/utils/constants.d.ts.map +0 -1
  229. package/dist/lib/emailer/utils/constants.js.map +0 -1
  230. package/dist/lib/emailer/utils/index.d.ts.map +0 -1
  231. package/dist/lib/emailer/utils/index.js.map +0 -1
  232. package/dist/lib/emailer/utils/logger.d.ts.map +0 -1
  233. package/dist/lib/emailer/utils/logger.js.map +0 -1
  234. package/dist/lib/emailer/utils/validation.d.ts.map +0 -1
  235. package/dist/lib/emailer/utils/validation.js.map +0 -1
  236. /package/dist/lib/{emailer → adapters/email}/providers/index.d.ts +0 -0
  237. /package/dist/lib/{emailer → adapters/email}/providers/index.js +0 -0
  238. /package/dist/lib/{emailer → adapters/email}/providers/pop3_provider.d.ts +0 -0
  239. /package/dist/lib/{emailer → adapters/email}/providers/pop3_provider.js +0 -0
  240. /package/dist/lib/{emailer → adapters/email}/providers/smtp_provider.d.ts +0 -0
  241. /package/dist/lib/{emailer → adapters/email}/providers/smtp_provider.js +0 -0
  242. /package/dist/lib/{emailer → adapters/email}/providers/zeptomail_provider.d.ts +0 -0
  243. /package/dist/lib/{emailer → adapters/email}/providers/zeptomail_provider.js +0 -0
  244. /package/dist/lib/{emailer → adapters/email}/types.d.ts +0 -0
  245. /package/dist/lib/{emailer → adapters/email}/types.js +0 -0
  246. /package/dist/lib/{emailer → adapters/email}/utils/constants.d.ts +0 -0
  247. /package/dist/lib/{emailer → adapters/email}/utils/constants.js +0 -0
  248. /package/dist/lib/{emailer → adapters/email}/utils/index.d.ts +0 -0
  249. /package/dist/lib/{emailer → adapters/email}/utils/index.js +0 -0
  250. /package/dist/lib/{emailer → adapters/email}/utils/logger.d.ts +0 -0
  251. /package/dist/lib/{emailer → adapters/email}/utils/logger.js +0 -0
  252. /package/dist/lib/{emailer → adapters/email}/utils/validation.d.ts +0 -0
  253. /package/dist/lib/{emailer → adapters/email}/utils/validation.js +0 -0
@@ -8,7 +8,7 @@
8
8
  * - template_variables retyped to TemplateVariableDefinition[]
9
9
  * - SystemTemplateManifest added (inline content, no file paths)
10
10
  */
11
- import type { Logger } from '../emailer/types.js';
11
+ import type { Logger } from '../adapters/email/types.js';
12
12
  export interface TemplateVariableDefinition {
13
13
  variable_name: string;
14
14
  variable_description: string;
@@ -36,8 +36,25 @@ export interface SystemTemplateManifest {
36
36
  template_name: string;
37
37
  template_label: string;
38
38
  category: string;
39
- html: string;
40
- text: string;
39
+ /**
40
+ * v3-compat field. If `bodies` is not provided, the seeder constructs
41
+ * bodies = { html, text }
42
+ * v4.x consumers should prefer `bodies` directly — `html`/`text` may be
43
+ * removed in v5.
44
+ * @deprecated Use `bodies.html`.
45
+ */
46
+ html?: string;
47
+ /**
48
+ * v3-compat field. See `html`.
49
+ * @deprecated Use `bodies.text`.
50
+ */
51
+ text?: string;
52
+ /**
53
+ * v4.0.0+ canonical. Per-channel body variants keyed by body key
54
+ * (`html`, `text`, `telegram_html`, `markdown`, etc.).
55
+ * If provided, takes precedence over `html` / `text`.
56
+ */
57
+ bodies?: Record<string, string>;
41
58
  variables: TemplateVariableDefinition[];
42
59
  }
43
60
  export interface TemplateCategory {
@@ -60,8 +77,17 @@ export interface EmailTemplate {
60
77
  template_category_id: string;
61
78
  template_variables: TemplateVariableDefinition[];
62
79
  template_name: string;
63
- template_html: string;
64
- template_text: string;
80
+ /**
81
+ * Per-channel body variants. v4.0.0+ canonical storage.
82
+ * Keys are open-ended; adapters declare which keys they consume via
83
+ * ChannelCapabilities.template_body_keys. Examples:
84
+ * { html, text, telegram_html, markdown, ... }
85
+ */
86
+ bodies: Record<string, string>;
87
+ /** @deprecated Removed in v4.0.0. Use bodies.html. */
88
+ template_html?: never;
89
+ /** @deprecated Removed in v4.0.0. Use bodies.text. */
90
+ template_text?: never;
65
91
  is_modified: boolean;
66
92
  created_at: string;
67
93
  changed_at: string | null;
@@ -71,15 +97,15 @@ export interface EmailTemplateInput {
71
97
  template_category_id: string;
72
98
  template_variables?: TemplateVariableDefinition[];
73
99
  template_name: string;
74
- template_html: string;
75
- template_text: string;
100
+ /** Per-channel body variants. See EmailTemplate.bodies. */
101
+ bodies: Record<string, string>;
76
102
  }
77
103
  export interface EmailTemplateUpdate {
78
104
  template_category_id?: string;
79
105
  template_variables?: TemplateVariableDefinition[];
80
106
  template_name?: string;
81
- template_html?: string;
82
- template_text?: string;
107
+ /** Per-channel body variants. See EmailTemplate.bodies. */
108
+ bodies?: Record<string, string>;
83
109
  is_modified?: boolean;
84
110
  }
85
111
  export interface HazoConnectQueryBuilder {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/template_manager/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAMlD,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,0BAA0B,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAMD;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,0BAA0B,EAAE,CAAC;CACzC;AAMD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAMD,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACzC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9D,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;IACvD,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACtD,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvD,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACxE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,KAAK,IAAI,uBAAuB,CAAC;IACjC,iDAAiD;IACjD,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACxD;AAMD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB,CAAC,CAAC,GAAG,OAAO;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,WAAW,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,YAAY,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/template_manager/types.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,5 @@
2
2
  * Utils barrel export for template manager
3
3
  */
4
4
  export { get_system_variables, resolve_system_variables, get_system_variable_definitions, } from './system_variables.js';
5
- export { validate_template_name, validate_category_name, validate_variable_name, validate_template_html_size, validate_template_text_size, extract_variables_from_content, validate_provided_variables, validate_uuid, sanitize_template_name, } from './validation.js';
5
+ export { validate_template_name, validate_category_name, validate_variable_name, validate_template_bodies_size, extract_variables_from_content, validate_provided_variables, validate_uuid, sanitize_template_name, } from './validation.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,aAAa,EACb,sBAAsB,GACvB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,8BAA8B,EAC9B,2BAA2B,EAC3B,aAAa,EACb,sBAAsB,GACvB,MAAM,iBAAiB,CAAC"}
@@ -2,5 +2,5 @@
2
2
  * Utils barrel export for template manager
3
3
  */
4
4
  export { get_system_variables, resolve_system_variables, get_system_variable_definitions, } from './system_variables.js';
5
- export { validate_template_name, validate_category_name, validate_variable_name, validate_template_html_size, validate_template_text_size, extract_variables_from_content, validate_provided_variables, validate_uuid, sanitize_template_name, } from './validation.js';
5
+ export { validate_template_name, validate_category_name, validate_variable_name, validate_template_bodies_size, extract_variables_from_content, validate_provided_variables, validate_uuid, sanitize_template_name, } from './validation.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,aAAa,EACb,sBAAsB,GACvB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,8BAA8B,EAC9B,2BAA2B,EAC3B,aAAa,EACb,sBAAsB,GACvB,MAAM,iBAAiB,CAAC"}
@@ -25,19 +25,20 @@ export declare function validate_category_name(name: string): boolean;
25
25
  */
26
26
  export declare function validate_variable_name(name: string): boolean;
27
27
  /**
28
- * Validate template HTML content size
28
+ * Validate that each value in a `bodies` map fits within the per-body size cap.
29
+ * v4.0.0: replaces the per-column validate_template_html_size / validate_template_text_size.
29
30
  *
30
- * @param html - HTML content to validate
31
- * @returns true if valid, false otherwise
32
- */
33
- export declare function validate_template_html_size(html: string): boolean;
34
- /**
35
- * Validate template text content size
36
- *
37
- * @param text - Text content to validate
38
- * @returns true if valid, false otherwise
31
+ * @param bodies - Record of body key → body content
32
+ * @returns ok: true on success; otherwise the first offending key.
39
33
  */
40
- export declare function validate_template_text_size(text: string): boolean;
34
+ export declare function validate_template_bodies_size(bodies: Record<string, string>): {
35
+ ok: true;
36
+ } | {
37
+ ok: false;
38
+ offending_key: string;
39
+ size: number;
40
+ max: number;
41
+ };
41
42
  /**
42
43
  * Extract variable names from template content
43
44
  *
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiB5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgB5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM5D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOjE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOjE;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAexE;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,gBAAgB,EAAE,MAAM,EACxB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1C,qBAAqB,EAAE,MAAM,EAAE,GAC9B;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAWvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY3D"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiB5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgB5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM5D;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAWhF;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAexE;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,gBAAgB,EAAE,MAAM,EACxB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1C,qBAAqB,EAAE,MAAM,EAAE,GAC9B;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAWvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY3D"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Validates template names, category names, variables, and content
5
5
  */
6
- import { MAX_TEMPLATE_NAME_LENGTH, MAX_CATEGORY_NAME_LENGTH, MAX_TEMPLATE_HTML_SIZE, MAX_TEMPLATE_TEXT_SIZE, VALID_VARIABLE_NAME_PATTERN, VARIABLE_PATTERN, } from '../config/constants.js';
6
+ import { MAX_TEMPLATE_NAME_LENGTH, MAX_CATEGORY_NAME_LENGTH, MAX_TEMPLATE_HTML_SIZE, VALID_VARIABLE_NAME_PATTERN, VARIABLE_PATTERN, } from '../config/constants.js';
7
7
  /**
8
8
  * Validate a template name
9
9
  *
@@ -56,30 +56,23 @@ export function validate_variable_name(name) {
56
56
  return VALID_VARIABLE_NAME_PATTERN.test(name);
57
57
  }
58
58
  /**
59
- * Validate template HTML content size
59
+ * Validate that each value in a `bodies` map fits within the per-body size cap.
60
+ * v4.0.0: replaces the per-column validate_template_html_size / validate_template_text_size.
60
61
  *
61
- * @param html - HTML content to validate
62
- * @returns true if valid, false otherwise
62
+ * @param bodies - Record of body key → body content
63
+ * @returns ok: true on success; otherwise the first offending key.
63
64
  */
64
- export function validate_template_html_size(html) {
65
- if (typeof html !== 'string') {
66
- return false;
67
- }
68
- const byte_size = Buffer.byteLength(html, 'utf8');
69
- return byte_size <= MAX_TEMPLATE_HTML_SIZE;
70
- }
71
- /**
72
- * Validate template text content size
73
- *
74
- * @param text - Text content to validate
75
- * @returns true if valid, false otherwise
76
- */
77
- export function validate_template_text_size(text) {
78
- if (typeof text !== 'string') {
79
- return false;
65
+ export function validate_template_bodies_size(bodies) {
66
+ for (const [key, value] of Object.entries(bodies)) {
67
+ if (typeof value !== 'string') {
68
+ return { ok: false, offending_key: key, size: 0, max: MAX_TEMPLATE_HTML_SIZE };
69
+ }
70
+ const byte_size = Buffer.byteLength(value, 'utf8');
71
+ if (byte_size > MAX_TEMPLATE_HTML_SIZE) {
72
+ return { ok: false, offending_key: key, size: byte_size, max: MAX_TEMPLATE_HTML_SIZE };
73
+ }
80
74
  }
81
- const byte_size = Buffer.byteLength(text, 'utf8');
82
- return byte_size <= MAX_TEMPLATE_TEXT_SIZE;
75
+ return { ok: true };
83
76
  }
84
77
  /**
85
78
  * Extract variable names from template content
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../../src/lib/template_manager/utils/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ -- 003_create_notifications_table.sql
2
+ -- Adds the hazo_notify_inbox table for the dispatcher + flush worker.
3
+ -- Per-recipient inbox with upsert-on-batch_key aggregation.
4
+ -- See spec § 3.1 in the consumer app for full schema rationale.
5
+
6
+ CREATE TABLE IF NOT EXISTS hazo_notify_inbox (
7
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
8
+ scope_id uuid NOT NULL,
9
+ user_id uuid NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
10
+ event_type text NOT NULL,
11
+ subject_id uuid,
12
+ batch_key text NOT NULL,
13
+ in_app_text text NOT NULL,
14
+ deep_link text NOT NULL,
15
+ payload jsonb NOT NULL DEFAULT '{}'::jsonb,
16
+ channels jsonb NOT NULL,
17
+
18
+ aggregate_count integer NOT NULL DEFAULT 1,
19
+ flush_after timestamptz NOT NULL,
20
+ flushed_at timestamptz,
21
+ read_at timestamptz,
22
+
23
+ email_subject text,
24
+ email_body_text text,
25
+ email_body_html text,
26
+ email_template text,
27
+ email_template_vars jsonb,
28
+ email_sent_at timestamptz,
29
+ email_message_id text,
30
+ email_error text,
31
+
32
+ created_at timestamptz NOT NULL DEFAULT now(),
33
+ updated_at timestamptz NOT NULL DEFAULT now()
34
+ );
35
+
36
+ CREATE INDEX IF NOT EXISTS idx_hazo_notify_inbox_user_unread
37
+ ON hazo_notify_inbox (user_id, created_at DESC)
38
+ WHERE read_at IS NULL;
39
+
40
+ CREATE UNIQUE INDEX IF NOT EXISTS uniq_hazo_notify_inbox_open_batch
41
+ ON hazo_notify_inbox (batch_key)
42
+ WHERE flushed_at IS NULL;
43
+
44
+ CREATE INDEX IF NOT EXISTS idx_hazo_notify_inbox_email_due
45
+ ON hazo_notify_inbox (flush_after)
46
+ WHERE flushed_at IS NULL
47
+ AND email_sent_at IS NULL
48
+ AND (channels->>'email')::boolean = true;
@@ -0,0 +1,63 @@
1
+ -- 004_inbox_upsert_rpc.sql
2
+ -- PostgREST RPC wrapper for the partial-index upsert that PostgREST HTTP cannot
3
+ -- express directly. Required when hazo_connect does not support raw() SQL
4
+ -- (e.g. PostgREST-only environments). Idempotent (CREATE OR REPLACE).
5
+
6
+ CREATE OR REPLACE FUNCTION hazo_notify_inbox_upsert(
7
+ p_scope_id text,
8
+ p_user_id text,
9
+ p_event_type text,
10
+ p_subject_id text,
11
+ p_batch_key text,
12
+ p_in_app_text text,
13
+ p_deep_link text,
14
+ p_payload jsonb,
15
+ p_channels jsonb,
16
+ p_flush_after timestamptz,
17
+ p_email_subject text,
18
+ p_email_body_text text,
19
+ p_email_body_html text,
20
+ p_email_template text,
21
+ p_email_template_vars jsonb
22
+ ) RETURNS jsonb
23
+ LANGUAGE plpgsql
24
+ SECURITY DEFINER
25
+ AS $$
26
+ DECLARE
27
+ v_id uuid;
28
+ v_xmax bigint;
29
+ v_inserted boolean;
30
+ BEGIN
31
+ INSERT INTO hazo_notify_inbox (
32
+ scope_id, user_id, event_type, subject_id, batch_key,
33
+ in_app_text, deep_link, payload, channels, flush_after,
34
+ email_subject, email_body_text, email_body_html,
35
+ email_template, email_template_vars
36
+ )
37
+ VALUES (
38
+ p_scope_id, p_user_id, p_event_type, p_subject_id, p_batch_key,
39
+ p_in_app_text, p_deep_link, p_payload, p_channels, p_flush_after,
40
+ p_email_subject, p_email_body_text, p_email_body_html,
41
+ p_email_template, p_email_template_vars
42
+ )
43
+ ON CONFLICT (batch_key) WHERE flushed_at IS NULL
44
+ DO UPDATE SET
45
+ aggregate_count = hazo_notify_inbox.aggregate_count + 1,
46
+ in_app_text = EXCLUDED.in_app_text,
47
+ email_subject = EXCLUDED.email_subject,
48
+ email_body_text = EXCLUDED.email_body_text,
49
+ email_body_html = EXCLUDED.email_body_html,
50
+ payload = EXCLUDED.payload,
51
+ updated_at = now()
52
+ RETURNING id INTO v_id;
53
+
54
+ GET DIAGNOSTICS v_xmax = ROW_COUNT;
55
+ -- If aggregate_count was updated (conflict path), xmax will be non-zero.
56
+ -- We approximate inserted=true when the row didn't previously exist.
57
+ -- True xmax check not possible via PL/pgSQL; use aggregate_count as proxy.
58
+ SELECT (aggregate_count = 1) INTO v_inserted
59
+ FROM hazo_notify_inbox WHERE id = v_id;
60
+
61
+ RETURN jsonb_build_object('id', v_id, 'inserted', v_inserted);
62
+ END;
63
+ $$;
@@ -0,0 +1,53 @@
1
+ -- migrations/005_inbox_v4_refactor.pg.sql
2
+ -- v4.0.0: rebuild hazo_notify_inbox.
3
+ -- Removes: channels, flush_after, flushed_at, all email_* columns.
4
+ -- Adds: surfaces (jsonb), batch_closed_at.
5
+ -- Renames: channels.{in_app,banner} → surfaces.{in_app,banner} via copy.
6
+
7
+ BEGIN;
8
+
9
+ -- Preserve the v3 table for migration 006 to read from.
10
+ ALTER TABLE IF EXISTS hazo_notify_inbox RENAME TO hazo_notify_inbox_v3_legacy;
11
+
12
+ CREATE TABLE hazo_notify_inbox (
13
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
14
+ scope_id uuid NOT NULL,
15
+ user_id uuid NOT NULL,
16
+ event_type text NOT NULL,
17
+ subject_id uuid,
18
+ batch_key text NOT NULL,
19
+ in_app_text text NOT NULL,
20
+ deep_link text NOT NULL,
21
+ payload jsonb NOT NULL DEFAULT '{}'::jsonb,
22
+ surfaces jsonb NOT NULL,
23
+ aggregate_count integer NOT NULL DEFAULT 1,
24
+ batch_closed_at timestamptz,
25
+ read_at timestamptz,
26
+ created_at timestamptz NOT NULL DEFAULT now(),
27
+ updated_at timestamptz NOT NULL DEFAULT now()
28
+ );
29
+
30
+ CREATE UNIQUE INDEX uniq_inbox_open_batch
31
+ ON hazo_notify_inbox (batch_key) WHERE batch_closed_at IS NULL;
32
+ CREATE INDEX idx_inbox_user_unread
33
+ ON hazo_notify_inbox (user_id, created_at DESC) WHERE read_at IS NULL;
34
+
35
+ -- Backfill from v3 legacy (skipped on fresh install — table doesn't exist).
36
+ INSERT INTO hazo_notify_inbox (
37
+ id, scope_id, user_id, event_type, subject_id, batch_key,
38
+ in_app_text, deep_link, payload, surfaces,
39
+ aggregate_count, batch_closed_at, read_at, created_at, updated_at
40
+ )
41
+ SELECT
42
+ id, scope_id, user_id, event_type, subject_id, batch_key,
43
+ in_app_text, deep_link, payload,
44
+ jsonb_build_object(
45
+ 'in_app', COALESCE((channels->>'in_app')::boolean, false),
46
+ 'banner', COALESCE((channels->>'banner')::boolean, false)
47
+ ),
48
+ aggregate_count, flushed_at, read_at, created_at, updated_at
49
+ FROM hazo_notify_inbox_v3_legacy
50
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables
51
+ WHERE table_name = 'hazo_notify_inbox_v3_legacy');
52
+
53
+ COMMIT;
@@ -0,0 +1,30 @@
1
+ -- migrations/005_inbox_v4_refactor.sqlite.sql
2
+ -- SQLite fresh-install variant. No v3 SQLite consumers exist, so no backfill.
3
+ -- (See spec §10.2 — v3 migrations 001-004 were Postgres-only.)
4
+
5
+ BEGIN;
6
+
7
+ CREATE TABLE IF NOT EXISTS hazo_notify_inbox (
8
+ id TEXT PRIMARY KEY,
9
+ scope_id TEXT NOT NULL,
10
+ user_id TEXT NOT NULL,
11
+ event_type TEXT NOT NULL,
12
+ subject_id TEXT,
13
+ batch_key TEXT NOT NULL,
14
+ in_app_text TEXT NOT NULL,
15
+ deep_link TEXT NOT NULL,
16
+ payload TEXT NOT NULL DEFAULT '{}',
17
+ surfaces TEXT NOT NULL,
18
+ aggregate_count INTEGER NOT NULL DEFAULT 1,
19
+ batch_closed_at TEXT,
20
+ read_at TEXT,
21
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
22
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
23
+ );
24
+
25
+ CREATE UNIQUE INDEX IF NOT EXISTS uniq_inbox_open_batch
26
+ ON hazo_notify_inbox (batch_key) WHERE batch_closed_at IS NULL;
27
+ CREATE INDEX IF NOT EXISTS idx_inbox_user_unread
28
+ ON hazo_notify_inbox (user_id, created_at DESC) WHERE read_at IS NULL;
29
+
30
+ COMMIT;
@@ -0,0 +1,61 @@
1
+ -- migrations/006_channel_deliveries.pg.sql
2
+ -- v4.0.0: create deliveries table; backfill email state from the v3 legacy
3
+ -- inbox rows preserved by 005; then drop the legacy table.
4
+
5
+ BEGIN;
6
+
7
+ CREATE TABLE hazo_notify_channel_deliveries (
8
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
9
+ inbox_id uuid NOT NULL REFERENCES hazo_notify_inbox(id) ON DELETE CASCADE,
10
+ channel_id text NOT NULL,
11
+ payload jsonb NOT NULL,
12
+ status text NOT NULL DEFAULT 'pending',
13
+ flush_after timestamptz NOT NULL,
14
+ attempt_count integer NOT NULL DEFAULT 0,
15
+ message_id text,
16
+ last_error text,
17
+ finalized_at timestamptz,
18
+ created_at timestamptz NOT NULL DEFAULT now(),
19
+ updated_at timestamptz NOT NULL DEFAULT now(),
20
+ CHECK (status IN ('pending','sent','failed'))
21
+ );
22
+
23
+ CREATE UNIQUE INDEX uniq_delivery_inbox_channel
24
+ ON hazo_notify_channel_deliveries (inbox_id, channel_id);
25
+ CREATE INDEX idx_delivery_due
26
+ ON hazo_notify_channel_deliveries (channel_id, flush_after) WHERE status = 'pending';
27
+
28
+ -- Backfill from v3 legacy.
29
+ INSERT INTO hazo_notify_channel_deliveries (
30
+ inbox_id, channel_id, payload, status, flush_after,
31
+ message_id, last_error, finalized_at, created_at, updated_at
32
+ )
33
+ SELECT
34
+ v3.id,
35
+ 'email',
36
+ jsonb_strip_nulls(jsonb_build_object(
37
+ 'subject', v3.email_subject,
38
+ 'body_text', v3.email_body_text,
39
+ 'body_html', v3.email_body_html,
40
+ 'template_name', v3.email_template,
41
+ 'template_vars', v3.email_template_vars
42
+ )),
43
+ CASE
44
+ WHEN v3.email_sent_at IS NOT NULL THEN 'sent'
45
+ WHEN v3.email_error IS NOT NULL THEN 'failed'
46
+ ELSE 'pending'
47
+ END,
48
+ v3.flush_after,
49
+ v3.email_message_id,
50
+ v3.email_error,
51
+ COALESCE(v3.email_sent_at,
52
+ CASE WHEN v3.email_error IS NOT NULL THEN v3.updated_at END),
53
+ v3.created_at, v3.updated_at
54
+ FROM hazo_notify_inbox_v3_legacy v3
55
+ WHERE (v3.channels->>'email')::boolean = true
56
+ AND EXISTS (SELECT 1 FROM information_schema.tables
57
+ WHERE table_name = 'hazo_notify_inbox_v3_legacy');
58
+
59
+ DROP TABLE IF EXISTS hazo_notify_inbox_v3_legacy;
60
+
61
+ COMMIT;
@@ -0,0 +1,26 @@
1
+ -- migrations/006_channel_deliveries.sqlite.sql
2
+ -- SQLite fresh install. No backfill (no v3 SQLite consumers).
3
+
4
+ BEGIN;
5
+
6
+ CREATE TABLE IF NOT EXISTS hazo_notify_channel_deliveries (
7
+ id TEXT PRIMARY KEY,
8
+ inbox_id TEXT NOT NULL REFERENCES hazo_notify_inbox(id) ON DELETE CASCADE,
9
+ channel_id TEXT NOT NULL,
10
+ payload TEXT NOT NULL,
11
+ status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','sent','failed')),
12
+ flush_after TEXT NOT NULL,
13
+ attempt_count INTEGER NOT NULL DEFAULT 0,
14
+ message_id TEXT,
15
+ last_error TEXT,
16
+ finalized_at TEXT,
17
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
18
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
19
+ );
20
+
21
+ CREATE UNIQUE INDEX IF NOT EXISTS uniq_delivery_inbox_channel
22
+ ON hazo_notify_channel_deliveries (inbox_id, channel_id);
23
+ CREATE INDEX IF NOT EXISTS idx_delivery_due
24
+ ON hazo_notify_channel_deliveries (channel_id, flush_after) WHERE status = 'pending';
25
+
26
+ COMMIT;
@@ -0,0 +1,17 @@
1
+ -- migrations/007_templates_bodies_jsonb.pg.sql
2
+ BEGIN;
3
+
4
+ ALTER TABLE hazo_notify_templates
5
+ ADD COLUMN IF NOT EXISTS bodies jsonb NOT NULL DEFAULT '{}'::jsonb;
6
+
7
+ UPDATE hazo_notify_templates
8
+ SET bodies = jsonb_strip_nulls(jsonb_build_object(
9
+ 'html', NULLIF(template_html, ''),
10
+ 'text', NULLIF(template_text, '')
11
+ ))
12
+ WHERE bodies = '{}'::jsonb;
13
+
14
+ ALTER TABLE hazo_notify_templates DROP COLUMN IF EXISTS template_html;
15
+ ALTER TABLE hazo_notify_templates DROP COLUMN IF EXISTS template_text;
16
+
17
+ COMMIT;
@@ -0,0 +1,18 @@
1
+ -- migrations/007_templates_bodies_jsonb.sqlite.sql
2
+ -- SQLite ALTER limitations: can ADD COLUMN, can DROP COLUMN (3.35+), no jsonb type.
3
+
4
+ BEGIN;
5
+
6
+ ALTER TABLE hazo_notify_templates ADD COLUMN bodies TEXT NOT NULL DEFAULT '{}';
7
+
8
+ UPDATE hazo_notify_templates
9
+ SET bodies = json_object(
10
+ 'html', NULLIF(template_html, ''),
11
+ 'text', NULLIF(template_text, '')
12
+ )
13
+ WHERE bodies = '{}';
14
+
15
+ ALTER TABLE hazo_notify_templates DROP COLUMN template_html;
16
+ ALTER TABLE hazo_notify_templates DROP COLUMN template_text;
17
+
18
+ COMMIT;