happy2 0.0.5

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 (373) hide show
  1. package/README.md +82 -0
  2. package/package.json +74 -0
  3. package/packages/happy2-server/Dockerfile +18 -0
  4. package/packages/happy2-server/README.md +418 -0
  5. package/packages/happy2-server/bin/happy2.js +3 -0
  6. package/packages/happy2-server/dist/cli.d.ts +3 -0
  7. package/packages/happy2-server/dist/cli.d.ts.map +1 -0
  8. package/packages/happy2-server/dist/cli.js +44 -0
  9. package/packages/happy2-server/dist/cli.js.map +1 -0
  10. package/packages/happy2-server/dist/index.d.ts +24 -0
  11. package/packages/happy2-server/dist/index.d.ts.map +1 -0
  12. package/packages/happy2-server/dist/index.js +22 -0
  13. package/packages/happy2-server/dist/index.js.map +1 -0
  14. package/packages/happy2-server/dist/modules/agents/builtin-images.d.ts +8 -0
  15. package/packages/happy2-server/dist/modules/agents/builtin-images.d.ts.map +1 -0
  16. package/packages/happy2-server/dist/modules/agents/builtin-images.js +283 -0
  17. package/packages/happy2-server/dist/modules/agents/builtin-images.js.map +1 -0
  18. package/packages/happy2-server/dist/modules/agents/command.d.ts +3 -0
  19. package/packages/happy2-server/dist/modules/agents/command.d.ts.map +1 -0
  20. package/packages/happy2-server/dist/modules/agents/command.js +7 -0
  21. package/packages/happy2-server/dist/modules/agents/command.js.map +1 -0
  22. package/packages/happy2-server/dist/modules/agents/daemon.d.ts +106 -0
  23. package/packages/happy2-server/dist/modules/agents/daemon.d.ts.map +1 -0
  24. package/packages/happy2-server/dist/modules/agents/daemon.js +522 -0
  25. package/packages/happy2-server/dist/modules/agents/daemon.js.map +1 -0
  26. package/packages/happy2-server/dist/modules/agents/docker.d.ts +51 -0
  27. package/packages/happy2-server/dist/modules/agents/docker.d.ts.map +1 -0
  28. package/packages/happy2-server/dist/modules/agents/docker.js +256 -0
  29. package/packages/happy2-server/dist/modules/agents/docker.js.map +1 -0
  30. package/packages/happy2-server/dist/modules/agents/docker.test.d.ts +2 -0
  31. package/packages/happy2-server/dist/modules/agents/docker.test.d.ts.map +1 -0
  32. package/packages/happy2-server/dist/modules/agents/docker.test.js +155 -0
  33. package/packages/happy2-server/dist/modules/agents/docker.test.js.map +1 -0
  34. package/packages/happy2-server/dist/modules/agents/index.d.ts +5 -0
  35. package/packages/happy2-server/dist/modules/agents/index.d.ts.map +1 -0
  36. package/packages/happy2-server/dist/modules/agents/index.js +4 -0
  37. package/packages/happy2-server/dist/modules/agents/index.js.map +1 -0
  38. package/packages/happy2-server/dist/modules/agents/service.d.ts +140 -0
  39. package/packages/happy2-server/dist/modules/agents/service.d.ts.map +1 -0
  40. package/packages/happy2-server/dist/modules/agents/service.js +1283 -0
  41. package/packages/happy2-server/dist/modules/agents/service.js.map +1 -0
  42. package/packages/happy2-server/dist/modules/auth/cloudflare-access.d.ts +15 -0
  43. package/packages/happy2-server/dist/modules/auth/cloudflare-access.d.ts.map +1 -0
  44. package/packages/happy2-server/dist/modules/auth/cloudflare-access.js +49 -0
  45. package/packages/happy2-server/dist/modules/auth/cloudflare-access.js.map +1 -0
  46. package/packages/happy2-server/dist/modules/auth/crypto.d.ts +4 -0
  47. package/packages/happy2-server/dist/modules/auth/crypto.d.ts.map +1 -0
  48. package/packages/happy2-server/dist/modules/auth/crypto.js +31 -0
  49. package/packages/happy2-server/dist/modules/auth/crypto.js.map +1 -0
  50. package/packages/happy2-server/dist/modules/auth/crypto.test.d.ts +2 -0
  51. package/packages/happy2-server/dist/modules/auth/crypto.test.d.ts.map +1 -0
  52. package/packages/happy2-server/dist/modules/auth/crypto.test.js +11 -0
  53. package/packages/happy2-server/dist/modules/auth/crypto.test.js.map +1 -0
  54. package/packages/happy2-server/dist/modules/auth/email.d.ts +3 -0
  55. package/packages/happy2-server/dist/modules/auth/email.d.ts.map +1 -0
  56. package/packages/happy2-server/dist/modules/auth/email.js +22 -0
  57. package/packages/happy2-server/dist/modules/auth/email.js.map +1 -0
  58. package/packages/happy2-server/dist/modules/auth/metadata.d.ts +5 -0
  59. package/packages/happy2-server/dist/modules/auth/metadata.d.ts.map +1 -0
  60. package/packages/happy2-server/dist/modules/auth/metadata.js +28 -0
  61. package/packages/happy2-server/dist/modules/auth/metadata.js.map +1 -0
  62. package/packages/happy2-server/dist/modules/auth/metadata.test.d.ts +2 -0
  63. package/packages/happy2-server/dist/modules/auth/metadata.test.d.ts.map +1 -0
  64. package/packages/happy2-server/dist/modules/auth/metadata.test.js +10 -0
  65. package/packages/happy2-server/dist/modules/auth/metadata.test.js.map +1 -0
  66. package/packages/happy2-server/dist/modules/auth/methods.d.ts +10 -0
  67. package/packages/happy2-server/dist/modules/auth/methods.d.ts.map +1 -0
  68. package/packages/happy2-server/dist/modules/auth/methods.js +21 -0
  69. package/packages/happy2-server/dist/modules/auth/methods.js.map +1 -0
  70. package/packages/happy2-server/dist/modules/auth/methods.test.d.ts +2 -0
  71. package/packages/happy2-server/dist/modules/auth/methods.test.d.ts.map +1 -0
  72. package/packages/happy2-server/dist/modules/auth/methods.test.js +16 -0
  73. package/packages/happy2-server/dist/modules/auth/methods.test.js.map +1 -0
  74. package/packages/happy2-server/dist/modules/auth/oidc.d.ts +9 -0
  75. package/packages/happy2-server/dist/modules/auth/oidc.d.ts.map +1 -0
  76. package/packages/happy2-server/dist/modules/auth/oidc.js +68 -0
  77. package/packages/happy2-server/dist/modules/auth/oidc.js.map +1 -0
  78. package/packages/happy2-server/dist/modules/auth/service.d.ts +44 -0
  79. package/packages/happy2-server/dist/modules/auth/service.d.ts.map +1 -0
  80. package/packages/happy2-server/dist/modules/auth/service.js +208 -0
  81. package/packages/happy2-server/dist/modules/auth/service.js.map +1 -0
  82. package/packages/happy2-server/dist/modules/auth/tokens.d.ts +21 -0
  83. package/packages/happy2-server/dist/modules/auth/tokens.d.ts.map +1 -0
  84. package/packages/happy2-server/dist/modules/auth/tokens.js +79 -0
  85. package/packages/happy2-server/dist/modules/auth/tokens.js.map +1 -0
  86. package/packages/happy2-server/dist/modules/automation/repository.d.ts +127 -0
  87. package/packages/happy2-server/dist/modules/automation/repository.d.ts.map +1 -0
  88. package/packages/happy2-server/dist/modules/automation/repository.js +821 -0
  89. package/packages/happy2-server/dist/modules/automation/repository.js.map +1 -0
  90. package/packages/happy2-server/dist/modules/collaboration/repository.d.ts +839 -0
  91. package/packages/happy2-server/dist/modules/collaboration/repository.d.ts.map +1 -0
  92. package/packages/happy2-server/dist/modules/collaboration/repository.js +5795 -0
  93. package/packages/happy2-server/dist/modules/collaboration/repository.js.map +1 -0
  94. package/packages/happy2-server/dist/modules/collaboration/repository.test.d.ts +2 -0
  95. package/packages/happy2-server/dist/modules/collaboration/repository.test.d.ts.map +1 -0
  96. package/packages/happy2-server/dist/modules/collaboration/repository.test.js +620 -0
  97. package/packages/happy2-server/dist/modules/collaboration/repository.test.js.map +1 -0
  98. package/packages/happy2-server/dist/modules/collaboration/types.d.ts +243 -0
  99. package/packages/happy2-server/dist/modules/collaboration/types.d.ts.map +1 -0
  100. package/packages/happy2-server/dist/modules/collaboration/types.js +8 -0
  101. package/packages/happy2-server/dist/modules/collaboration/types.js.map +1 -0
  102. package/packages/happy2-server/dist/modules/config/defaults.d.ts +8 -0
  103. package/packages/happy2-server/dist/modules/config/defaults.d.ts.map +1 -0
  104. package/packages/happy2-server/dist/modules/config/defaults.js +70 -0
  105. package/packages/happy2-server/dist/modules/config/defaults.js.map +1 -0
  106. package/packages/happy2-server/dist/modules/config/defaults.test.d.ts +2 -0
  107. package/packages/happy2-server/dist/modules/config/defaults.test.d.ts.map +1 -0
  108. package/packages/happy2-server/dist/modules/config/defaults.test.js +27 -0
  109. package/packages/happy2-server/dist/modules/config/defaults.test.js.map +1 -0
  110. package/packages/happy2-server/dist/modules/config/environment.d.ts +4 -0
  111. package/packages/happy2-server/dist/modules/config/environment.d.ts.map +1 -0
  112. package/packages/happy2-server/dist/modules/config/environment.js +92 -0
  113. package/packages/happy2-server/dist/modules/config/environment.js.map +1 -0
  114. package/packages/happy2-server/dist/modules/config/loader.d.ts +5 -0
  115. package/packages/happy2-server/dist/modules/config/loader.d.ts.map +1 -0
  116. package/packages/happy2-server/dist/modules/config/loader.js +251 -0
  117. package/packages/happy2-server/dist/modules/config/loader.js.map +1 -0
  118. package/packages/happy2-server/dist/modules/config/loader.test.d.ts +2 -0
  119. package/packages/happy2-server/dist/modules/config/loader.test.d.ts.map +1 -0
  120. package/packages/happy2-server/dist/modules/config/loader.test.js +108 -0
  121. package/packages/happy2-server/dist/modules/config/loader.test.js.map +1 -0
  122. package/packages/happy2-server/dist/modules/config/paths.d.ts +7 -0
  123. package/packages/happy2-server/dist/modules/config/paths.d.ts.map +1 -0
  124. package/packages/happy2-server/dist/modules/config/paths.js +15 -0
  125. package/packages/happy2-server/dist/modules/config/paths.js.map +1 -0
  126. package/packages/happy2-server/dist/modules/config/paths.test.d.ts +2 -0
  127. package/packages/happy2-server/dist/modules/config/paths.test.d.ts.map +1 -0
  128. package/packages/happy2-server/dist/modules/config/paths.test.js +22 -0
  129. package/packages/happy2-server/dist/modules/config/paths.test.js.map +1 -0
  130. package/packages/happy2-server/dist/modules/config/runtime.d.ts +6 -0
  131. package/packages/happy2-server/dist/modules/config/runtime.d.ts.map +1 -0
  132. package/packages/happy2-server/dist/modules/config/runtime.js +14 -0
  133. package/packages/happy2-server/dist/modules/config/runtime.js.map +1 -0
  134. package/packages/happy2-server/dist/modules/config/type.d.ts +88 -0
  135. package/packages/happy2-server/dist/modules/config/type.d.ts.map +1 -0
  136. package/packages/happy2-server/dist/modules/config/type.js +2 -0
  137. package/packages/happy2-server/dist/modules/config/type.js.map +1 -0
  138. package/packages/happy2-server/dist/modules/database.d.ts +105 -0
  139. package/packages/happy2-server/dist/modules/database.d.ts.map +1 -0
  140. package/packages/happy2-server/dist/modules/database.js +583 -0
  141. package/packages/happy2-server/dist/modules/database.js.map +1 -0
  142. package/packages/happy2-server/dist/modules/drizzle.d.ts +11 -0
  143. package/packages/happy2-server/dist/modules/drizzle.d.ts.map +1 -0
  144. package/packages/happy2-server/dist/modules/drizzle.js +31 -0
  145. package/packages/happy2-server/dist/modules/drizzle.js.map +1 -0
  146. package/packages/happy2-server/dist/modules/files/lock.d.ts +3 -0
  147. package/packages/happy2-server/dist/modules/files/lock.d.ts.map +1 -0
  148. package/packages/happy2-server/dist/modules/files/lock.js +83 -0
  149. package/packages/happy2-server/dist/modules/files/lock.js.map +1 -0
  150. package/packages/happy2-server/dist/modules/files/media.d.ts +18 -0
  151. package/packages/happy2-server/dist/modules/files/media.d.ts.map +1 -0
  152. package/packages/happy2-server/dist/modules/files/media.js +352 -0
  153. package/packages/happy2-server/dist/modules/files/media.js.map +1 -0
  154. package/packages/happy2-server/dist/modules/files/provider.d.ts +130 -0
  155. package/packages/happy2-server/dist/modules/files/provider.d.ts.map +1 -0
  156. package/packages/happy2-server/dist/modules/files/provider.js +448 -0
  157. package/packages/happy2-server/dist/modules/files/provider.js.map +1 -0
  158. package/packages/happy2-server/dist/modules/files/quota.d.ts +58 -0
  159. package/packages/happy2-server/dist/modules/files/quota.d.ts.map +1 -0
  160. package/packages/happy2-server/dist/modules/files/quota.js +180 -0
  161. package/packages/happy2-server/dist/modules/files/quota.js.map +1 -0
  162. package/packages/happy2-server/dist/modules/files/routes.test.d.ts +2 -0
  163. package/packages/happy2-server/dist/modules/files/routes.test.d.ts.map +1 -0
  164. package/packages/happy2-server/dist/modules/files/routes.test.js +163 -0
  165. package/packages/happy2-server/dist/modules/files/routes.test.js.map +1 -0
  166. package/packages/happy2-server/dist/modules/files/scanner.d.ts +27 -0
  167. package/packages/happy2-server/dist/modules/files/scanner.d.ts.map +1 -0
  168. package/packages/happy2-server/dist/modules/files/scanner.js +66 -0
  169. package/packages/happy2-server/dist/modules/files/scanner.js.map +1 -0
  170. package/packages/happy2-server/dist/modules/files/storage.d.ts +95 -0
  171. package/packages/happy2-server/dist/modules/files/storage.d.ts.map +1 -0
  172. package/packages/happy2-server/dist/modules/files/storage.js +855 -0
  173. package/packages/happy2-server/dist/modules/files/storage.js.map +1 -0
  174. package/packages/happy2-server/dist/modules/files/storage.test.d.ts +2 -0
  175. package/packages/happy2-server/dist/modules/files/storage.test.d.ts.map +1 -0
  176. package/packages/happy2-server/dist/modules/files/storage.test.js +170 -0
  177. package/packages/happy2-server/dist/modules/files/storage.test.js.map +1 -0
  178. package/packages/happy2-server/dist/modules/integrations/index.d.ts +6 -0
  179. package/packages/happy2-server/dist/modules/integrations/index.d.ts.map +1 -0
  180. package/packages/happy2-server/dist/modules/integrations/index.js +6 -0
  181. package/packages/happy2-server/dist/modules/integrations/index.js.map +1 -0
  182. package/packages/happy2-server/dist/modules/integrations/repository.d.ts +136 -0
  183. package/packages/happy2-server/dist/modules/integrations/repository.d.ts.map +1 -0
  184. package/packages/happy2-server/dist/modules/integrations/repository.js +1229 -0
  185. package/packages/happy2-server/dist/modules/integrations/repository.js.map +1 -0
  186. package/packages/happy2-server/dist/modules/integrations/repository.test.d.ts +2 -0
  187. package/packages/happy2-server/dist/modules/integrations/repository.test.d.ts.map +1 -0
  188. package/packages/happy2-server/dist/modules/integrations/repository.test.js +345 -0
  189. package/packages/happy2-server/dist/modules/integrations/repository.test.js.map +1 -0
  190. package/packages/happy2-server/dist/modules/integrations/routes.test.d.ts +2 -0
  191. package/packages/happy2-server/dist/modules/integrations/routes.test.d.ts.map +1 -0
  192. package/packages/happy2-server/dist/modules/integrations/routes.test.js +161 -0
  193. package/packages/happy2-server/dist/modules/integrations/routes.test.js.map +1 -0
  194. package/packages/happy2-server/dist/modules/integrations/secrets.d.ts +19 -0
  195. package/packages/happy2-server/dist/modules/integrations/secrets.d.ts.map +1 -0
  196. package/packages/happy2-server/dist/modules/integrations/secrets.js +69 -0
  197. package/packages/happy2-server/dist/modules/integrations/secrets.js.map +1 -0
  198. package/packages/happy2-server/dist/modules/integrations/ssrf.d.ts +32 -0
  199. package/packages/happy2-server/dist/modules/integrations/ssrf.d.ts.map +1 -0
  200. package/packages/happy2-server/dist/modules/integrations/ssrf.js +185 -0
  201. package/packages/happy2-server/dist/modules/integrations/ssrf.js.map +1 -0
  202. package/packages/happy2-server/dist/modules/integrations/ssrf.test.d.ts +2 -0
  203. package/packages/happy2-server/dist/modules/integrations/ssrf.test.d.ts.map +1 -0
  204. package/packages/happy2-server/dist/modules/integrations/ssrf.test.js +56 -0
  205. package/packages/happy2-server/dist/modules/integrations/ssrf.test.js.map +1 -0
  206. package/packages/happy2-server/dist/modules/integrations/transport.d.ts +21 -0
  207. package/packages/happy2-server/dist/modules/integrations/transport.d.ts.map +1 -0
  208. package/packages/happy2-server/dist/modules/integrations/transport.js +108 -0
  209. package/packages/happy2-server/dist/modules/integrations/transport.js.map +1 -0
  210. package/packages/happy2-server/dist/modules/integrations/transport.test.d.ts +2 -0
  211. package/packages/happy2-server/dist/modules/integrations/transport.test.d.ts.map +1 -0
  212. package/packages/happy2-server/dist/modules/integrations/transport.test.js +66 -0
  213. package/packages/happy2-server/dist/modules/integrations/transport.test.js.map +1 -0
  214. package/packages/happy2-server/dist/modules/integrations/types.d.ts +155 -0
  215. package/packages/happy2-server/dist/modules/integrations/types.d.ts.map +1 -0
  216. package/packages/happy2-server/dist/modules/integrations/types.js +26 -0
  217. package/packages/happy2-server/dist/modules/integrations/types.js.map +1 -0
  218. package/packages/happy2-server/dist/modules/operations/export-worker.d.ts +16 -0
  219. package/packages/happy2-server/dist/modules/operations/export-worker.d.ts.map +1 -0
  220. package/packages/happy2-server/dist/modules/operations/export-worker.js +56 -0
  221. package/packages/happy2-server/dist/modules/operations/export-worker.js.map +1 -0
  222. package/packages/happy2-server/dist/modules/operations/repository.d.ts +215 -0
  223. package/packages/happy2-server/dist/modules/operations/repository.d.ts.map +1 -0
  224. package/packages/happy2-server/dist/modules/operations/repository.js +2011 -0
  225. package/packages/happy2-server/dist/modules/operations/repository.js.map +1 -0
  226. package/packages/happy2-server/dist/modules/operations/repository.test.d.ts +2 -0
  227. package/packages/happy2-server/dist/modules/operations/repository.test.d.ts.map +1 -0
  228. package/packages/happy2-server/dist/modules/operations/repository.test.js +610 -0
  229. package/packages/happy2-server/dist/modules/operations/repository.test.js.map +1 -0
  230. package/packages/happy2-server/dist/modules/operations/types.d.ts +144 -0
  231. package/packages/happy2-server/dist/modules/operations/types.d.ts.map +1 -0
  232. package/packages/happy2-server/dist/modules/operations/types.js +9 -0
  233. package/packages/happy2-server/dist/modules/operations/types.js.map +1 -0
  234. package/packages/happy2-server/dist/modules/realtime/events.d.ts +99 -0
  235. package/packages/happy2-server/dist/modules/realtime/events.d.ts.map +1 -0
  236. package/packages/happy2-server/dist/modules/realtime/events.js +173 -0
  237. package/packages/happy2-server/dist/modules/realtime/events.js.map +1 -0
  238. package/packages/happy2-server/dist/modules/realtime/index.d.ts +4 -0
  239. package/packages/happy2-server/dist/modules/realtime/index.d.ts.map +1 -0
  240. package/packages/happy2-server/dist/modules/realtime/index.js +4 -0
  241. package/packages/happy2-server/dist/modules/realtime/index.js.map +1 -0
  242. package/packages/happy2-server/dist/modules/realtime/local.d.ts +37 -0
  243. package/packages/happy2-server/dist/modules/realtime/local.d.ts.map +1 -0
  244. package/packages/happy2-server/dist/modules/realtime/local.js +181 -0
  245. package/packages/happy2-server/dist/modules/realtime/local.js.map +1 -0
  246. package/packages/happy2-server/dist/modules/realtime/local.test.d.ts +2 -0
  247. package/packages/happy2-server/dist/modules/realtime/local.test.d.ts.map +1 -0
  248. package/packages/happy2-server/dist/modules/realtime/local.test.js +186 -0
  249. package/packages/happy2-server/dist/modules/realtime/local.test.js.map +1 -0
  250. package/packages/happy2-server/dist/modules/realtime/pubsub.d.ts +26 -0
  251. package/packages/happy2-server/dist/modules/realtime/pubsub.d.ts.map +1 -0
  252. package/packages/happy2-server/dist/modules/realtime/pubsub.js +7 -0
  253. package/packages/happy2-server/dist/modules/realtime/pubsub.js.map +1 -0
  254. package/packages/happy2-server/dist/modules/request/database-idempotency.d.ts +15 -0
  255. package/packages/happy2-server/dist/modules/request/database-idempotency.d.ts.map +1 -0
  256. package/packages/happy2-server/dist/modules/request/database-idempotency.js +141 -0
  257. package/packages/happy2-server/dist/modules/request/database-idempotency.js.map +1 -0
  258. package/packages/happy2-server/dist/modules/request/idempotency-hook.d.ts +12 -0
  259. package/packages/happy2-server/dist/modules/request/idempotency-hook.d.ts.map +1 -0
  260. package/packages/happy2-server/dist/modules/request/idempotency-hook.js +98 -0
  261. package/packages/happy2-server/dist/modules/request/idempotency-hook.js.map +1 -0
  262. package/packages/happy2-server/dist/modules/request/idempotency.d.ts +146 -0
  263. package/packages/happy2-server/dist/modules/request/idempotency.d.ts.map +1 -0
  264. package/packages/happy2-server/dist/modules/request/idempotency.js +312 -0
  265. package/packages/happy2-server/dist/modules/request/idempotency.js.map +1 -0
  266. package/packages/happy2-server/dist/modules/request/idempotency.test.d.ts +2 -0
  267. package/packages/happy2-server/dist/modules/request/idempotency.test.d.ts.map +1 -0
  268. package/packages/happy2-server/dist/modules/request/idempotency.test.js +191 -0
  269. package/packages/happy2-server/dist/modules/request/idempotency.test.js.map +1 -0
  270. package/packages/happy2-server/dist/modules/request/index.d.ts +5 -0
  271. package/packages/happy2-server/dist/modules/request/index.d.ts.map +1 -0
  272. package/packages/happy2-server/dist/modules/request/index.js +5 -0
  273. package/packages/happy2-server/dist/modules/request/index.js.map +1 -0
  274. package/packages/happy2-server/dist/modules/request/rate-limit.d.ts +100 -0
  275. package/packages/happy2-server/dist/modules/request/rate-limit.d.ts.map +1 -0
  276. package/packages/happy2-server/dist/modules/request/rate-limit.js +239 -0
  277. package/packages/happy2-server/dist/modules/request/rate-limit.js.map +1 -0
  278. package/packages/happy2-server/dist/modules/request/rate-limit.test.d.ts +2 -0
  279. package/packages/happy2-server/dist/modules/request/rate-limit.test.d.ts.map +1 -0
  280. package/packages/happy2-server/dist/modules/request/rate-limit.test.js +123 -0
  281. package/packages/happy2-server/dist/modules/request/rate-limit.test.js.map +1 -0
  282. package/packages/happy2-server/dist/modules/schema.d.ts +31454 -0
  283. package/packages/happy2-server/dist/modules/schema.d.ts.map +1 -0
  284. package/packages/happy2-server/dist/modules/schema.js +1081 -0
  285. package/packages/happy2-server/dist/modules/schema.js.map +1 -0
  286. package/packages/happy2-server/dist/modules/workspace/index.d.ts +3 -0
  287. package/packages/happy2-server/dist/modules/workspace/index.d.ts.map +1 -0
  288. package/packages/happy2-server/dist/modules/workspace/index.js +3 -0
  289. package/packages/happy2-server/dist/modules/workspace/index.js.map +1 -0
  290. package/packages/happy2-server/dist/modules/workspace/service.d.ts +54 -0
  291. package/packages/happy2-server/dist/modules/workspace/service.d.ts.map +1 -0
  292. package/packages/happy2-server/dist/modules/workspace/service.js +997 -0
  293. package/packages/happy2-server/dist/modules/workspace/service.js.map +1 -0
  294. package/packages/happy2-server/dist/modules/workspace/types.d.ts +58 -0
  295. package/packages/happy2-server/dist/modules/workspace/types.d.ts.map +1 -0
  296. package/packages/happy2-server/dist/modules/workspace/types.js +11 -0
  297. package/packages/happy2-server/dist/modules/workspace/types.js.map +1 -0
  298. package/packages/happy2-server/dist/routes/agents.d.ts +5 -0
  299. package/packages/happy2-server/dist/routes/agents.d.ts.map +1 -0
  300. package/packages/happy2-server/dist/routes/agents.js +225 -0
  301. package/packages/happy2-server/dist/routes/agents.js.map +1 -0
  302. package/packages/happy2-server/dist/routes/auth.d.ts +5 -0
  303. package/packages/happy2-server/dist/routes/auth.d.ts.map +1 -0
  304. package/packages/happy2-server/dist/routes/auth.js +128 -0
  305. package/packages/happy2-server/dist/routes/auth.js.map +1 -0
  306. package/packages/happy2-server/dist/routes/automation.d.ts +6 -0
  307. package/packages/happy2-server/dist/routes/automation.d.ts.map +1 -0
  308. package/packages/happy2-server/dist/routes/automation.js +315 -0
  309. package/packages/happy2-server/dist/routes/automation.js.map +1 -0
  310. package/packages/happy2-server/dist/routes/basic.d.ts +3 -0
  311. package/packages/happy2-server/dist/routes/basic.d.ts.map +1 -0
  312. package/packages/happy2-server/dist/routes/basic.js +5 -0
  313. package/packages/happy2-server/dist/routes/basic.js.map +1 -0
  314. package/packages/happy2-server/dist/routes/collaboration.d.ts +7 -0
  315. package/packages/happy2-server/dist/routes/collaboration.d.ts.map +1 -0
  316. package/packages/happy2-server/dist/routes/collaboration.js +1285 -0
  317. package/packages/happy2-server/dist/routes/collaboration.js.map +1 -0
  318. package/packages/happy2-server/dist/routes/files.d.ts +9 -0
  319. package/packages/happy2-server/dist/routes/files.d.ts.map +1 -0
  320. package/packages/happy2-server/dist/routes/files.js +397 -0
  321. package/packages/happy2-server/dist/routes/files.js.map +1 -0
  322. package/packages/happy2-server/dist/routes/integrations.d.ts +6 -0
  323. package/packages/happy2-server/dist/routes/integrations.d.ts.map +1 -0
  324. package/packages/happy2-server/dist/routes/integrations.js +486 -0
  325. package/packages/happy2-server/dist/routes/integrations.js.map +1 -0
  326. package/packages/happy2-server/dist/routes/operations.d.ts +5 -0
  327. package/packages/happy2-server/dist/routes/operations.d.ts.map +1 -0
  328. package/packages/happy2-server/dist/routes/operations.js +588 -0
  329. package/packages/happy2-server/dist/routes/operations.js.map +1 -0
  330. package/packages/happy2-server/dist/routes/operations.test.d.ts +2 -0
  331. package/packages/happy2-server/dist/routes/operations.test.d.ts.map +1 -0
  332. package/packages/happy2-server/dist/routes/operations.test.js +106 -0
  333. package/packages/happy2-server/dist/routes/operations.test.js.map +1 -0
  334. package/packages/happy2-server/dist/routes/sync.d.ts +6 -0
  335. package/packages/happy2-server/dist/routes/sync.d.ts.map +1 -0
  336. package/packages/happy2-server/dist/routes/sync.js +549 -0
  337. package/packages/happy2-server/dist/routes/sync.js.map +1 -0
  338. package/packages/happy2-server/dist/routes/workspace.d.ts +5 -0
  339. package/packages/happy2-server/dist/routes/workspace.d.ts.map +1 -0
  340. package/packages/happy2-server/dist/routes/workspace.js +240 -0
  341. package/packages/happy2-server/dist/routes/workspace.js.map +1 -0
  342. package/packages/happy2-server/dist/runner.d.ts +3 -0
  343. package/packages/happy2-server/dist/runner.d.ts.map +1 -0
  344. package/packages/happy2-server/dist/runner.js +30 -0
  345. package/packages/happy2-server/dist/runner.js.map +1 -0
  346. package/packages/happy2-server/dist/server.d.ts +32 -0
  347. package/packages/happy2-server/dist/server.d.ts.map +1 -0
  348. package/packages/happy2-server/dist/server.js +284 -0
  349. package/packages/happy2-server/dist/server.js.map +1 -0
  350. package/packages/happy2-server/dist/standalone.d.ts +13 -0
  351. package/packages/happy2-server/dist/standalone.d.ts.map +1 -0
  352. package/packages/happy2-server/dist/standalone.js +99 -0
  353. package/packages/happy2-server/dist/standalone.js.map +1 -0
  354. package/packages/happy2-server/dist/web/assets/figtree-latin-wght-normal-D_ZTVpCC.woff2 +0 -0
  355. package/packages/happy2-server/dist/web/assets/happy-otter-Q2O_g-DT.png +0 -0
  356. package/packages/happy2-server/dist/web/assets/index-COvbX8JP.css +2 -0
  357. package/packages/happy2-server/dist/web/assets/index-DdpugxMO.js +57 -0
  358. package/packages/happy2-server/dist/web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  359. package/packages/happy2-server/dist/web/assets/onboarding-CRUpq9xl.png +0 -0
  360. package/packages/happy2-server/dist/web/index.html +13 -0
  361. package/packages/happy2-server/drizzle/0000_initial.sql +13 -0
  362. package/packages/happy2-server/drizzle/0001_accounts_profiles_files.sql +42 -0
  363. package/packages/happy2-server/drizzle/0002_file_visibility_and_uploader.sql +5 -0
  364. package/packages/happy2-server/drizzle/0003_collaboration.sql +565 -0
  365. package/packages/happy2-server/drizzle/0004_collaboration_expansion.sql +1099 -0
  366. package/packages/happy2-server/drizzle/0005_ai_agents.sql +85 -0
  367. package/packages/happy2-server/drizzle/0006_rig_global_event_queue.sql +10 -0
  368. package/packages/happy2-server/drizzle/0007_rename_server_identity.sql +3 -0
  369. package/packages/happy2-server/drizzle/0008_agent_message_streaming.sql +47 -0
  370. package/packages/happy2-server/drizzle/0009_chat_workspace_binding_lookup.sql +2 -0
  371. package/packages/happy2-server/drizzle/0010_rig_secret_assignments.sql +21 -0
  372. package/packages/happy2-server/drizzle/meta/_journal.json +83 -0
  373. package/packages/happy2-server/happy2.example.toml +104 -0
@@ -0,0 +1,1099 @@
1
+ ALTER TABLE `accounts` ADD COLUMN `ban_expires_at` TEXT;
2
+ --> statement-breakpoint
3
+ ALTER TABLE `accounts` ADD COLUMN `ban_reason` TEXT;
4
+ --> statement-breakpoint
5
+ ALTER TABLE `accounts` ADD COLUMN `banned_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
6
+ --> statement-breakpoint
7
+ ALTER TABLE `server_sync_state` ADD COLUMN `automation_event_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`automation_event_sequence` >= 0);
8
+ --> statement-breakpoint
9
+ ALTER TABLE `server_settings` ADD COLUMN `default_retention_mode` TEXT NOT NULL DEFAULT 'forever' CHECK (`default_retention_mode` IN ('forever', 'duration'));
10
+ --> statement-breakpoint
11
+ ALTER TABLE `server_settings` ADD COLUMN `default_retention_seconds` INTEGER CHECK (`default_retention_seconds` IS NULL OR `default_retention_seconds` > 0);
12
+ --> statement-breakpoint
13
+ ALTER TABLE `server_settings` ADD COLUMN `default_file_quota_bytes` INTEGER CHECK (`default_file_quota_bytes` IS NULL OR `default_file_quota_bytes` > 0);
14
+ --> statement-breakpoint
15
+ ALTER TABLE `server_settings` ADD COLUMN `max_upload_bytes` INTEGER CHECK (`max_upload_bytes` IS NULL OR `max_upload_bytes` > 0);
16
+ --> statement-breakpoint
17
+ ALTER TABLE `server_settings` ADD COLUMN `sync_event_retention_seconds` INTEGER NOT NULL DEFAULT 2592000 CHECK (`sync_event_retention_seconds` > 0);
18
+ --> statement-breakpoint
19
+ ALTER TABLE `server_settings` ADD COLUMN `chat_update_retention_seconds` INTEGER NOT NULL DEFAULT 2592000 CHECK (`chat_update_retention_seconds` > 0);
20
+ --> statement-breakpoint
21
+ ALTER TABLE `server_settings` ADD COLUMN `idempotency_retention_seconds` INTEGER NOT NULL DEFAULT 604800 CHECK (`idempotency_retention_seconds` > 0);
22
+ --> statement-breakpoint
23
+ ALTER TABLE `files` ADD COLUMN `storage_provider` TEXT NOT NULL DEFAULT 'local' CHECK (length(trim(`storage_provider`)) > 0);
24
+ --> statement-breakpoint
25
+ ALTER TABLE `files` ADD COLUMN `storage_key` TEXT;
26
+ --> statement-breakpoint
27
+ UPDATE `files` SET `storage_key` = `storage_name` WHERE `storage_key` IS NULL;
28
+ --> statement-breakpoint
29
+ ALTER TABLE `files` ADD COLUMN `checksum_sha256` TEXT;
30
+ --> statement-breakpoint
31
+ ALTER TABLE `files` ADD COLUMN `access_scope` TEXT NOT NULL DEFAULT 'private' CHECK (`access_scope` IN ('private', 'chat', 'server', 'public'));
32
+ --> statement-breakpoint
33
+ UPDATE `files` SET `access_scope` = 'public' WHERE `is_public` = 1;
34
+ --> statement-breakpoint
35
+ ALTER TABLE `files` ADD COLUMN `upload_status` TEXT NOT NULL DEFAULT 'complete' CHECK (`upload_status` IN ('pending', 'uploading', 'processing', 'complete', 'failed', 'cancelled'));
36
+ --> statement-breakpoint
37
+ ALTER TABLE `files` ADD COLUMN `scan_status` TEXT NOT NULL DEFAULT 'unscanned' CHECK (`scan_status` IN ('unscanned', 'pending', 'clean', 'infected', 'failed', 'skipped'));
38
+ --> statement-breakpoint
39
+ ALTER TABLE `files` ADD COLUMN `scanned_at` TEXT;
40
+ --> statement-breakpoint
41
+ ALTER TABLE `files` ADD COLUMN `scan_result_json` TEXT;
42
+ --> statement-breakpoint
43
+ ALTER TABLE `files` ADD COLUMN `media_metadata_json` TEXT;
44
+ --> statement-breakpoint
45
+ ALTER TABLE `files` ADD COLUMN `codec` TEXT;
46
+ --> statement-breakpoint
47
+ ALTER TABLE `files` ADD COLUMN `preview_file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL;
48
+ --> statement-breakpoint
49
+ ALTER TABLE `files` ADD COLUMN `thumbnail_file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL;
50
+ --> statement-breakpoint
51
+ ALTER TABLE `files` ADD COLUMN `orphaned_at` TEXT;
52
+ --> statement-breakpoint
53
+ ALTER TABLE `files` ADD COLUMN `retention_until` TEXT;
54
+ --> statement-breakpoint
55
+ ALTER TABLE `files` ADD COLUMN `deleted_at` TEXT;
56
+ --> statement-breakpoint
57
+ ALTER TABLE `files` ADD COLUMN `deleted_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
58
+ --> statement-breakpoint
59
+ ALTER TABLE `files` ADD COLUMN `delete_reason` TEXT;
60
+ --> statement-breakpoint
61
+ CREATE TABLE `bot_identities` (
62
+ `id` TEXT PRIMARY KEY NOT NULL,
63
+ `name` TEXT NOT NULL CHECK (length(trim(`name`)) > 0),
64
+ `username` TEXT NOT NULL COLLATE NOCASE CHECK (length(trim(`username`)) > 0),
65
+ `description` TEXT,
66
+ `photo_file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL,
67
+ `owner_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
68
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
69
+ `active` INTEGER NOT NULL DEFAULT 1 CHECK (`active` IN (0, 1)),
70
+ `sync_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`sync_sequence` >= 0),
71
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
72
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
73
+ `deleted_at` TEXT
74
+ );
75
+ --> statement-breakpoint
76
+ CREATE UNIQUE INDEX `bot_identities_active_username_unique_idx`
77
+ ON `bot_identities` (`username`)
78
+ WHERE `deleted_at` IS NULL;
79
+ --> statement-breakpoint
80
+ CREATE INDEX `bot_identities_sync_sequence_idx` ON `bot_identities` (`sync_sequence`);
81
+ --> statement-breakpoint
82
+ CREATE TABLE `user_presence_settings` (
83
+ `user_id` TEXT PRIMARY KEY NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
84
+ `availability` TEXT NOT NULL DEFAULT 'automatic' CHECK (`availability` IN ('automatic', 'online', 'away', 'dnd')),
85
+ `custom_status_text` TEXT,
86
+ `custom_status_emoji` TEXT,
87
+ `status_expires_at` TEXT,
88
+ `dnd_until` TEXT,
89
+ `sync_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`sync_sequence` >= 0),
90
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
91
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
92
+ );
93
+ --> statement-breakpoint
94
+ CREATE INDEX `user_presence_settings_sync_idx` ON `user_presence_settings` (`sync_sequence`);
95
+ --> statement-breakpoint
96
+ CREATE INDEX `user_presence_settings_expiry_idx` ON `user_presence_settings` (`status_expires_at`, `dnd_until`);
97
+ --> statement-breakpoint
98
+ ALTER TABLE `chats` ADD COLUMN `dm_type` TEXT NOT NULL DEFAULT 'none' CHECK (`dm_type` IN ('none', 'direct', 'group'));
99
+ --> statement-breakpoint
100
+ UPDATE `chats` SET `dm_type` = 'direct' WHERE `kind` = 'dm';
101
+ --> statement-breakpoint
102
+ ALTER TABLE `chats` ADD COLUMN `visibility` TEXT NOT NULL DEFAULT 'private' CHECK (`visibility` IN ('direct', 'public', 'private'));
103
+ --> statement-breakpoint
104
+ UPDATE `chats`
105
+ SET `visibility` = CASE
106
+ WHEN `kind` = 'dm' THEN 'direct'
107
+ WHEN `kind` = 'public_channel' THEN 'public'
108
+ ELSE 'private'
109
+ END;
110
+ --> statement-breakpoint
111
+ ALTER TABLE `chats` ADD COLUMN `owner_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
112
+ --> statement-breakpoint
113
+ UPDATE `chats`
114
+ SET `owner_user_id` = (
115
+ SELECT `cm`.`user_id`
116
+ FROM `chat_members` AS `cm`
117
+ WHERE `cm`.`chat_id` = `chats`.`id`
118
+ AND `cm`.`role` = 'owner'
119
+ AND `cm`.`left_at` IS NULL
120
+ ORDER BY `cm`.`joined_at`, `cm`.`user_id`
121
+ LIMIT 1
122
+ )
123
+ WHERE `kind` != 'dm';
124
+ --> statement-breakpoint
125
+ ALTER TABLE `chats` ADD COLUMN `photo_file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL;
126
+ --> statement-breakpoint
127
+ ALTER TABLE `chats` ADD COLUMN `is_listed` INTEGER NOT NULL DEFAULT 1 CHECK (`is_listed` IN (0, 1));
128
+ --> statement-breakpoint
129
+ UPDATE `chats` SET `is_listed` = 0 WHERE `kind` = 'dm';
130
+ --> statement-breakpoint
131
+ ALTER TABLE `chats` ADD COLUMN `archived_at` TEXT;
132
+ --> statement-breakpoint
133
+ ALTER TABLE `chats` ADD COLUMN `archived_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
134
+ --> statement-breakpoint
135
+ ALTER TABLE `chats` ADD COLUMN `archive_reason` TEXT;
136
+ --> statement-breakpoint
137
+ ALTER TABLE `chats` ADD COLUMN `deleted_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
138
+ --> statement-breakpoint
139
+ ALTER TABLE `chats` ADD COLUMN `delete_reason` TEXT;
140
+ --> statement-breakpoint
141
+ ALTER TABLE `chats` ADD COLUMN `retention_mode` TEXT NOT NULL DEFAULT 'inherit' CHECK (`retention_mode` IN ('inherit', 'forever', 'duration'));
142
+ --> statement-breakpoint
143
+ ALTER TABLE `chats` ADD COLUMN `retention_seconds` INTEGER CHECK (`retention_seconds` IS NULL OR `retention_seconds` > 0);
144
+ --> statement-breakpoint
145
+ ALTER TABLE `chats` ADD COLUMN `default_expiry_mode` TEXT NOT NULL DEFAULT 'none' CHECK (`default_expiry_mode` IN ('none', 'after_send', 'after_read'));
146
+ --> statement-breakpoint
147
+ ALTER TABLE `chats` ADD COLUMN `default_self_destruct_seconds` INTEGER CHECK (`default_self_destruct_seconds` IS NULL OR `default_self_destruct_seconds` > 0);
148
+ --> statement-breakpoint
149
+ ALTER TABLE `chats` ADD COLUMN `default_after_read_scope` TEXT NOT NULL DEFAULT 'any_reader' CHECK (`default_after_read_scope` IN ('any_reader', 'all_readers'));
150
+ --> statement-breakpoint
151
+ ALTER TABLE `chats` ADD COLUMN `lifecycle_version` INTEGER NOT NULL DEFAULT 1 CHECK (`lifecycle_version` > 0);
152
+ --> statement-breakpoint
153
+ CREATE INDEX `chats_visibility_archive_idx` ON `chats` (`visibility`, `archived_at`, `deleted_at`, `id`);
154
+ --> statement-breakpoint
155
+ CREATE INDEX `chats_dm_type_key_idx` ON `chats` (`dm_type`, `dm_key`) WHERE `kind` = 'dm';
156
+ --> statement-breakpoint
157
+ CREATE INDEX `chats_owner_active_idx` ON `chats` (`owner_user_id`, `archived_at`, `deleted_at`);
158
+ --> statement-breakpoint
159
+ CREATE INDEX `chats_search_cursor_idx` ON `chats` (`updated_at` DESC, `id` DESC);
160
+ --> statement-breakpoint
161
+ CREATE INDEX `users_search_cursor_idx` ON `users` (`created_at` DESC, `id` DESC);
162
+ --> statement-breakpoint
163
+ ALTER TABLE `chat_members` ADD COLUMN `last_read_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL;
164
+ --> statement-breakpoint
165
+ ALTER TABLE `chat_members` ADD COLUMN `last_read_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`last_read_sequence` >= 0);
166
+ --> statement-breakpoint
167
+ ALTER TABLE `chat_members` ADD COLUMN `last_read_pts` INTEGER NOT NULL DEFAULT 0 CHECK (`last_read_pts` >= 0);
168
+ --> statement-breakpoint
169
+ ALTER TABLE `chat_members` ADD COLUMN `last_read_at` TEXT;
170
+ --> statement-breakpoint
171
+ ALTER TABLE `chat_members` ADD COLUMN `unread_count` INTEGER NOT NULL DEFAULT 0 CHECK (`unread_count` >= 0);
172
+ --> statement-breakpoint
173
+ ALTER TABLE `chat_members` ADD COLUMN `mention_count` INTEGER NOT NULL DEFAULT 0 CHECK (`mention_count` >= 0);
174
+ --> statement-breakpoint
175
+ ALTER TABLE `chat_members` ADD COLUMN `invited_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
176
+ --> statement-breakpoint
177
+ ALTER TABLE `chat_members` ADD COLUMN `removed_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
178
+ --> statement-breakpoint
179
+ CREATE INDEX `chat_members_unread_idx` ON `chat_members` (`user_id`, `unread_count`, `mention_count`, `left_at`);
180
+ --> statement-breakpoint
181
+ ALTER TABLE `user_chat_preferences` ADD COLUMN `notification_level` TEXT NOT NULL DEFAULT 'all' CHECK (`notification_level` IN ('all', 'mentions', 'none'));
182
+ --> statement-breakpoint
183
+ ALTER TABLE `user_chat_preferences` ADD COLUMN `muted_until` TEXT;
184
+ --> statement-breakpoint
185
+ ALTER TABLE `user_chat_preferences` ADD COLUMN `notify_thread_replies` INTEGER NOT NULL DEFAULT 1 CHECK (`notify_thread_replies` IN (0, 1));
186
+ --> statement-breakpoint
187
+ ALTER TABLE `user_chat_preferences` ADD COLUMN `show_message_previews` INTEGER NOT NULL DEFAULT 1 CHECK (`show_message_previews` IN (0, 1));
188
+ --> statement-breakpoint
189
+ CREATE INDEX `user_chat_preferences_notifications_idx`
190
+ ON `user_chat_preferences` (`user_id`, `notification_level`, `muted_until`, `chat_id`);
191
+ --> statement-breakpoint
192
+ ALTER TABLE `threads` ADD COLUMN `last_reply_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL;
193
+ --> statement-breakpoint
194
+ ALTER TABLE `threads` ADD COLUMN `last_reply_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`last_reply_sequence` >= 0);
195
+ --> statement-breakpoint
196
+ ALTER TABLE `threads` ADD COLUMN `participant_count` INTEGER NOT NULL DEFAULT 0 CHECK (`participant_count` >= 0);
197
+ --> statement-breakpoint
198
+ ALTER TABLE `messages` ADD COLUMN `sender_bot_id` TEXT REFERENCES `bot_identities`(`id`) ON DELETE SET NULL;
199
+ --> statement-breakpoint
200
+ ALTER TABLE `messages` ADD COLUMN `content_json` TEXT;
201
+ --> statement-breakpoint
202
+ ALTER TABLE `messages` ADD COLUMN `revision` INTEGER NOT NULL DEFAULT 1 CHECK (`revision` > 0);
203
+ --> statement-breakpoint
204
+ ALTER TABLE `messages` ADD COLUMN `edited_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
205
+ --> statement-breakpoint
206
+ ALTER TABLE `messages` ADD COLUMN `edit_reason` TEXT;
207
+ --> statement-breakpoint
208
+ ALTER TABLE `messages` ADD COLUMN `published_at` TEXT;
209
+ --> statement-breakpoint
210
+ UPDATE `messages` SET `published_at` = `created_at` WHERE `published_at` IS NULL;
211
+ --> statement-breakpoint
212
+ ALTER TABLE `messages` ADD COLUMN `expiry_mode` TEXT NOT NULL DEFAULT 'none' CHECK (`expiry_mode` IN ('none', 'after_send', 'after_read'));
213
+ --> statement-breakpoint
214
+ UPDATE `messages` SET `expiry_mode` = 'after_send' WHERE `expires_at` IS NOT NULL;
215
+ --> statement-breakpoint
216
+ ALTER TABLE `messages` ADD COLUMN `self_destruct_seconds` INTEGER CHECK (`self_destruct_seconds` IS NULL OR `self_destruct_seconds` > 0);
217
+ --> statement-breakpoint
218
+ ALTER TABLE `messages` ADD COLUMN `after_read_scope` TEXT NOT NULL DEFAULT 'any_reader' CHECK (`after_read_scope` IN ('any_reader', 'all_readers'));
219
+ --> statement-breakpoint
220
+ ALTER TABLE `messages` ADD COLUMN `first_read_at` TEXT;
221
+ --> statement-breakpoint
222
+ ALTER TABLE `messages` ADD COLUMN `hard_delete_at` TEXT;
223
+ --> statement-breakpoint
224
+ ALTER TABLE `messages` ADD COLUMN `delete_reason` TEXT;
225
+ --> statement-breakpoint
226
+ CREATE INDEX `messages_search_cursor_idx` ON `messages` (`created_at` DESC, `id` DESC);
227
+ --> statement-breakpoint
228
+ CREATE INDEX `messages_active_chat_cursor_idx` ON `messages` (`chat_id`, `deleted_at`, `created_at` DESC, `id` DESC);
229
+ --> statement-breakpoint
230
+ CREATE INDEX `messages_hard_delete_idx` ON `messages` (`hard_delete_at`) WHERE `hard_delete_at` IS NOT NULL;
231
+ --> statement-breakpoint
232
+ CREATE INDEX `messages_bot_idx` ON `messages` (`sender_bot_id`, `created_at` DESC);
233
+ --> statement-breakpoint
234
+ CREATE TABLE `message_revisions` (
235
+ `id` TEXT PRIMARY KEY NOT NULL,
236
+ `message_id` TEXT NOT NULL REFERENCES `messages`(`id`) ON DELETE CASCADE,
237
+ `revision` INTEGER NOT NULL CHECK (`revision` > 0),
238
+ `text` TEXT NOT NULL DEFAULT '',
239
+ `content_json` TEXT,
240
+ `edited_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
241
+ `edit_reason` TEXT,
242
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
243
+ UNIQUE (`message_id`, `revision`)
244
+ );
245
+ --> statement-breakpoint
246
+ CREATE INDEX `message_revisions_message_created_idx` ON `message_revisions` (`message_id`, `created_at` DESC);
247
+ --> statement-breakpoint
248
+ CREATE TABLE `message_mentions` (
249
+ `id` TEXT PRIMARY KEY NOT NULL,
250
+ `message_id` TEXT NOT NULL REFERENCES `messages`(`id`) ON DELETE CASCADE,
251
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('user', 'channel', 'here', 'everyone')),
252
+ `mentioned_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
253
+ `start_offset` INTEGER NOT NULL CHECK (`start_offset` >= 0),
254
+ `length` INTEGER NOT NULL CHECK (`length` > 0),
255
+ `raw_text` TEXT NOT NULL,
256
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
257
+ CHECK ((`kind` = 'user' AND `mentioned_user_id` IS NOT NULL) OR (`kind` != 'user' AND `mentioned_user_id` IS NULL)),
258
+ UNIQUE (`message_id`, `start_offset`, `length`)
259
+ );
260
+ --> statement-breakpoint
261
+ CREATE INDEX `message_mentions_user_message_idx` ON `message_mentions` (`mentioned_user_id`, `message_id`);
262
+ --> statement-breakpoint
263
+ CREATE INDEX `message_mentions_message_idx` ON `message_mentions` (`message_id`, `start_offset`);
264
+ --> statement-breakpoint
265
+ CREATE TABLE `message_receipts` (
266
+ `message_id` TEXT NOT NULL REFERENCES `messages`(`id`) ON DELETE CASCADE,
267
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
268
+ `delivered_at` TEXT,
269
+ `read_at` TEXT,
270
+ `expiry_triggered_at` TEXT,
271
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
272
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
273
+ PRIMARY KEY (`message_id`, `user_id`)
274
+ );
275
+ --> statement-breakpoint
276
+ CREATE INDEX `message_receipts_user_read_idx` ON `message_receipts` (`user_id`, `read_at`, `message_id`);
277
+ --> statement-breakpoint
278
+ CREATE INDEX `message_receipts_expiry_idx` ON `message_receipts` (`expiry_triggered_at`, `read_at`) WHERE `read_at` IS NOT NULL;
279
+ --> statement-breakpoint
280
+ CREATE TABLE `thread_user_states` (
281
+ `thread_root_message_id` TEXT NOT NULL REFERENCES `threads`(`root_message_id`) ON DELETE CASCADE,
282
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
283
+ `subscribed` INTEGER NOT NULL DEFAULT 1 CHECK (`subscribed` IN (0, 1)),
284
+ `notification_level` TEXT NOT NULL DEFAULT 'all' CHECK (`notification_level` IN ('all', 'mentions', 'none')),
285
+ `last_read_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL,
286
+ `last_read_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`last_read_sequence` >= 0),
287
+ `unread_count` INTEGER NOT NULL DEFAULT 0 CHECK (`unread_count` >= 0),
288
+ `mention_count` INTEGER NOT NULL DEFAULT 0 CHECK (`mention_count` >= 0),
289
+ `last_participated_at` TEXT,
290
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
291
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
292
+ PRIMARY KEY (`thread_root_message_id`, `user_id`)
293
+ );
294
+ --> statement-breakpoint
295
+ CREATE INDEX `thread_user_states_user_updated_idx` ON `thread_user_states` (`user_id`, `updated_at` DESC, `thread_root_message_id`);
296
+ --> statement-breakpoint
297
+ CREATE INDEX `thread_user_states_user_unread_idx` ON `thread_user_states` (`user_id`, `unread_count`, `mention_count`, `subscribed`);
298
+ --> statement-breakpoint
299
+ CREATE TABLE `thread_participants` (
300
+ `thread_root_message_id` TEXT NOT NULL REFERENCES `threads`(`root_message_id`) ON DELETE CASCADE,
301
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
302
+ `reply_count` INTEGER NOT NULL DEFAULT 0 CHECK (`reply_count` >= 0),
303
+ `first_participated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
304
+ `last_participated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
305
+ PRIMARY KEY (`thread_root_message_id`, `user_id`)
306
+ );
307
+ --> statement-breakpoint
308
+ CREATE INDEX `thread_participants_user_updated_idx` ON `thread_participants` (`user_id`, `last_participated_at` DESC);
309
+ --> statement-breakpoint
310
+ CREATE TABLE `notifications` (
311
+ `id` TEXT PRIMARY KEY NOT NULL,
312
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
313
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('mention', 'thread_reply', 'direct_message', 'reaction', 'call', 'system', 'moderation', 'automation')),
314
+ `chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE CASCADE,
315
+ `message_id` TEXT REFERENCES `messages`(`id`) ON DELETE CASCADE,
316
+ `thread_root_message_id` TEXT REFERENCES `threads`(`root_message_id`) ON DELETE CASCADE,
317
+ `actor_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
318
+ `actor_bot_id` TEXT REFERENCES `bot_identities`(`id`) ON DELETE SET NULL,
319
+ `payload_json` TEXT,
320
+ `sync_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`sync_sequence` >= 0),
321
+ `read_at` TEXT,
322
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
323
+ `expires_at` TEXT
324
+ );
325
+ --> statement-breakpoint
326
+ CREATE INDEX `notifications_user_cursor_idx` ON `notifications` (`user_id`, `created_at` DESC, `id` DESC);
327
+ --> statement-breakpoint
328
+ CREATE INDEX `notifications_user_unread_idx` ON `notifications` (`user_id`, `read_at`, `created_at` DESC);
329
+ --> statement-breakpoint
330
+ CREATE INDEX `notifications_sync_sequence_idx` ON `notifications` (`sync_sequence`);
331
+ --> statement-breakpoint
332
+ CREATE TABLE `user_notification_preferences` (
333
+ `user_id` TEXT PRIMARY KEY NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
334
+ `direct_messages` TEXT NOT NULL DEFAULT 'all' CHECK (`direct_messages` IN ('all', 'none')),
335
+ `mentions` TEXT NOT NULL DEFAULT 'all' CHECK (`mentions` IN ('all', 'none')),
336
+ `thread_replies` TEXT NOT NULL DEFAULT 'all' CHECK (`thread_replies` IN ('all', 'mentions', 'none')),
337
+ `reactions` TEXT NOT NULL DEFAULT 'all' CHECK (`reactions` IN ('all', 'none')),
338
+ `calls` TEXT NOT NULL DEFAULT 'all' CHECK (`calls` IN ('all', 'none')),
339
+ `email_notifications` INTEGER NOT NULL DEFAULT 0 CHECK (`email_notifications` IN (0, 1)),
340
+ `desktop_notifications` INTEGER NOT NULL DEFAULT 1 CHECK (`desktop_notifications` IN (0, 1)),
341
+ `dnd_start_minutes` INTEGER CHECK (`dnd_start_minutes` IS NULL OR (`dnd_start_minutes` >= 0 AND `dnd_start_minutes` < 1440)),
342
+ `dnd_end_minutes` INTEGER CHECK (`dnd_end_minutes` IS NULL OR (`dnd_end_minutes` >= 0 AND `dnd_end_minutes` < 1440)),
343
+ `timezone` TEXT,
344
+ `sync_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`sync_sequence` >= 0),
345
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
346
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
347
+ );
348
+ --> statement-breakpoint
349
+ CREATE INDEX `user_notification_preferences_sync_idx` ON `user_notification_preferences` (`sync_sequence`);
350
+ --> statement-breakpoint
351
+ CREATE TABLE `scheduled_messages` (
352
+ `id` TEXT PRIMARY KEY NOT NULL,
353
+ `chat_id` TEXT NOT NULL REFERENCES `chats`(`id`) ON DELETE CASCADE,
354
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
355
+ `sender_bot_id` TEXT REFERENCES `bot_identities`(`id`) ON DELETE SET NULL,
356
+ `text` TEXT NOT NULL DEFAULT '',
357
+ `content_json` TEXT,
358
+ `quoted_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL,
359
+ `thread_root_message_id` TEXT REFERENCES `threads`(`root_message_id`) ON DELETE SET NULL,
360
+ `forwarded_from_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL,
361
+ `scheduled_for` TEXT NOT NULL,
362
+ `timezone` TEXT,
363
+ `status` TEXT NOT NULL DEFAULT 'scheduled' CHECK (`status` IN ('scheduled', 'publishing', 'published', 'cancelled', 'failed')),
364
+ `published_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL,
365
+ `last_error` TEXT,
366
+ `client_mutation_id` TEXT,
367
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
368
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
369
+ `cancelled_at` TEXT,
370
+ `published_at` TEXT
371
+ );
372
+ --> statement-breakpoint
373
+ CREATE INDEX `scheduled_messages_due_idx` ON `scheduled_messages` (`status`, `scheduled_for`, `id`);
374
+ --> statement-breakpoint
375
+ CREATE INDEX `scheduled_messages_creator_idx` ON `scheduled_messages` (`created_by_user_id`, `created_at` DESC);
376
+ --> statement-breakpoint
377
+ CREATE UNIQUE INDEX `scheduled_messages_client_mutation_unique_idx`
378
+ ON `scheduled_messages` (`created_by_user_id`, `client_mutation_id`)
379
+ WHERE `client_mutation_id` IS NOT NULL;
380
+ --> statement-breakpoint
381
+ CREATE TABLE `scheduled_message_attachments` (
382
+ `scheduled_message_id` TEXT NOT NULL REFERENCES `scheduled_messages`(`id`) ON DELETE CASCADE,
383
+ `file_id` TEXT NOT NULL REFERENCES `files`(`id`) ON DELETE CASCADE,
384
+ `position` INTEGER NOT NULL DEFAULT 0 CHECK (`position` >= 0),
385
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
386
+ PRIMARY KEY (`scheduled_message_id`, `file_id`),
387
+ UNIQUE (`scheduled_message_id`, `position`)
388
+ );
389
+ --> statement-breakpoint
390
+ CREATE INDEX `scheduled_message_attachments_file_idx` ON `scheduled_message_attachments` (`file_id`, `scheduled_message_id`);
391
+ --> statement-breakpoint
392
+ CREATE TABLE `message_forward_metadata` (
393
+ `message_id` TEXT PRIMARY KEY NOT NULL REFERENCES `messages`(`id`) ON DELETE CASCADE,
394
+ `source_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL,
395
+ `source_chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE SET NULL,
396
+ `source_sender_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
397
+ `source_sender_bot_id` TEXT REFERENCES `bot_identities`(`id`) ON DELETE SET NULL,
398
+ `source_sender_name` TEXT,
399
+ `source_created_at` TEXT,
400
+ `source_text_snapshot` TEXT,
401
+ `forwarded_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
402
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
403
+ );
404
+ --> statement-breakpoint
405
+ CREATE INDEX `message_forward_metadata_source_idx` ON `message_forward_metadata` (`source_message_id`, `message_id`);
406
+ --> statement-breakpoint
407
+ CREATE TABLE `chat_pins` (
408
+ `id` TEXT PRIMARY KEY NOT NULL,
409
+ `chat_id` TEXT NOT NULL REFERENCES `chats`(`id`) ON DELETE CASCADE,
410
+ `message_id` TEXT NOT NULL REFERENCES `messages`(`id`) ON DELETE CASCADE,
411
+ `pinned_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
412
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
413
+ UNIQUE (`chat_id`, `message_id`)
414
+ );
415
+ --> statement-breakpoint
416
+ CREATE INDEX `chat_pins_chat_created_idx` ON `chat_pins` (`chat_id`, `created_at` DESC, `id` DESC);
417
+ --> statement-breakpoint
418
+ CREATE TABLE `chat_bookmarks` (
419
+ `id` TEXT PRIMARY KEY NOT NULL,
420
+ `chat_id` TEXT NOT NULL REFERENCES `chats`(`id`) ON DELETE CASCADE,
421
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('link', 'message', 'file')),
422
+ `title` TEXT NOT NULL CHECK (length(trim(`title`)) > 0),
423
+ `url` TEXT,
424
+ `message_id` TEXT REFERENCES `messages`(`id`) ON DELETE CASCADE,
425
+ `file_id` TEXT REFERENCES `files`(`id`) ON DELETE CASCADE,
426
+ `emoji` TEXT,
427
+ `sort_order` INTEGER NOT NULL DEFAULT 0,
428
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
429
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
430
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
431
+ CHECK (
432
+ (`kind` = 'link' AND `url` IS NOT NULL AND `message_id` IS NULL AND `file_id` IS NULL)
433
+ OR (`kind` = 'message' AND `url` IS NULL AND `message_id` IS NOT NULL AND `file_id` IS NULL)
434
+ OR (`kind` = 'file' AND `url` IS NULL AND `message_id` IS NULL AND `file_id` IS NOT NULL)
435
+ )
436
+ );
437
+ --> statement-breakpoint
438
+ CREATE INDEX `chat_bookmarks_chat_order_idx` ON `chat_bookmarks` (`chat_id`, `sort_order`, `id`);
439
+ --> statement-breakpoint
440
+ CREATE TABLE `user_bookmarks` (
441
+ `id` TEXT PRIMARY KEY NOT NULL,
442
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
443
+ `chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE CASCADE,
444
+ `message_id` TEXT REFERENCES `messages`(`id`) ON DELETE CASCADE,
445
+ `file_id` TEXT REFERENCES `files`(`id`) ON DELETE CASCADE,
446
+ `url` TEXT,
447
+ `title` TEXT,
448
+ `note` TEXT,
449
+ `sort_order` INTEGER NOT NULL DEFAULT 0,
450
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
451
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
452
+ CHECK (((`message_id` IS NOT NULL) + (`file_id` IS NOT NULL) + (`url` IS NOT NULL)) = 1)
453
+ );
454
+ --> statement-breakpoint
455
+ CREATE INDEX `user_bookmarks_user_order_idx` ON `user_bookmarks` (`user_id`, `sort_order`, `created_at` DESC, `id`);
456
+ --> statement-breakpoint
457
+ ALTER TABLE `custom_emojis` ADD COLUMN `deleted_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
458
+ --> statement-breakpoint
459
+ ALTER TABLE `custom_emojis` ADD COLUMN `promoted_at` TEXT;
460
+ --> statement-breakpoint
461
+ ALTER TABLE `custom_emojis` ADD COLUMN `promoted_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL;
462
+ --> statement-breakpoint
463
+ ALTER TABLE `reactions` ADD COLUMN `custom_emoji_name_snapshot` TEXT;
464
+ --> statement-breakpoint
465
+ ALTER TABLE `reactions` ADD COLUMN `custom_emoji_file_id_snapshot` TEXT;
466
+ --> statement-breakpoint
467
+ UPDATE `reactions`
468
+ SET
469
+ `custom_emoji_name_snapshot` = (
470
+ SELECT `ce`.`name` FROM `custom_emojis` AS `ce` WHERE `ce`.`id` = `reactions`.`custom_emoji_id`
471
+ ),
472
+ `custom_emoji_file_id_snapshot` = (
473
+ SELECT `ce`.`file_id` FROM `custom_emojis` AS `ce` WHERE `ce`.`id` = `reactions`.`custom_emoji_id`
474
+ )
475
+ WHERE `custom_emoji_id` IS NOT NULL;
476
+ --> statement-breakpoint
477
+ CREATE INDEX `reactions_custom_emoji_message_idx` ON `reactions` (`custom_emoji_id`, `message_id`);
478
+ --> statement-breakpoint
479
+ CREATE TABLE `custom_emoji_revisions` (
480
+ `id` TEXT PRIMARY KEY NOT NULL,
481
+ `custom_emoji_id` TEXT NOT NULL REFERENCES `custom_emojis`(`id`) ON DELETE CASCADE,
482
+ `name` TEXT NOT NULL,
483
+ `file_id` TEXT NOT NULL,
484
+ `changed_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
485
+ `change_kind` TEXT NOT NULL CHECK (`change_kind` IN ('created', 'renamed', 'replaced', 'deleted', 'restored')),
486
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
487
+ );
488
+ --> statement-breakpoint
489
+ CREATE INDEX `custom_emoji_revisions_emoji_created_idx` ON `custom_emoji_revisions` (`custom_emoji_id`, `created_at` DESC);
490
+ --> statement-breakpoint
491
+ CREATE TABLE `message_search_documents` (
492
+ `message_id` TEXT PRIMARY KEY NOT NULL REFERENCES `messages`(`id`) ON DELETE CASCADE,
493
+ `chat_id` TEXT NOT NULL REFERENCES `chats`(`id`) ON DELETE CASCADE,
494
+ `normalized_text` TEXT NOT NULL,
495
+ `normalized_length` INTEGER NOT NULL CHECK (`normalized_length` >= 0),
496
+ `gram_count` INTEGER NOT NULL DEFAULT 0 CHECK (`gram_count` >= 0),
497
+ `indexed_revision` INTEGER NOT NULL CHECK (`indexed_revision` > 0),
498
+ `content_hash` TEXT,
499
+ `message_created_at` TEXT NOT NULL,
500
+ `indexed_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
501
+ );
502
+ --> statement-breakpoint
503
+ CREATE INDEX `message_search_documents_chat_cursor_idx`
504
+ ON `message_search_documents` (`chat_id`, `message_created_at` DESC, `message_id` DESC);
505
+ --> statement-breakpoint
506
+ CREATE INDEX `message_search_documents_global_cursor_idx`
507
+ ON `message_search_documents` (`message_created_at` DESC, `message_id` DESC);
508
+ --> statement-breakpoint
509
+ CREATE TABLE `message_search_ngrams` (
510
+ `gram` TEXT NOT NULL COLLATE NOCASE CHECK (length(`gram`) BETWEEN 1 AND 3),
511
+ `message_id` TEXT NOT NULL REFERENCES `message_search_documents`(`message_id`) ON DELETE CASCADE,
512
+ `occurrences` INTEGER NOT NULL DEFAULT 1 CHECK (`occurrences` > 0),
513
+ PRIMARY KEY (`gram`, `message_id`)
514
+ ) WITHOUT ROWID;
515
+ --> statement-breakpoint
516
+ CREATE INDEX `message_search_ngrams_message_idx` ON `message_search_ngrams` (`message_id`, `gram`);
517
+ --> statement-breakpoint
518
+ INSERT INTO `message_search_documents` (
519
+ `message_id`,
520
+ `chat_id`,
521
+ `normalized_text`,
522
+ `normalized_length`,
523
+ `gram_count`,
524
+ `indexed_revision`,
525
+ `message_created_at`
526
+ )
527
+ SELECT
528
+ `id`,
529
+ `chat_id`,
530
+ lower(trim(`text`)),
531
+ length(lower(trim(`text`))),
532
+ CASE WHEN length(lower(trim(`text`))) >= 3 THEN length(lower(trim(`text`))) - 2 ELSE length(lower(trim(`text`))) END,
533
+ `revision`,
534
+ `created_at`
535
+ FROM `messages`
536
+ WHERE `deleted_at` IS NULL AND length(trim(`text`)) > 0;
537
+ --> statement-breakpoint
538
+ WITH RECURSIVE `gram_positions` (`message_id`, `normalized_text`, `position`) AS (
539
+ SELECT `message_id`, `normalized_text`, 1
540
+ FROM `message_search_documents`
541
+ WHERE `normalized_length` >= 3
542
+ UNION ALL
543
+ SELECT `message_id`, `normalized_text`, `position` + 1
544
+ FROM `gram_positions`
545
+ WHERE `position` + 2 < length(`normalized_text`)
546
+ )
547
+ INSERT INTO `message_search_ngrams` (`gram`, `message_id`, `occurrences`)
548
+ SELECT substr(`normalized_text`, `position`, 3), `message_id`, count(*)
549
+ FROM `gram_positions`
550
+ GROUP BY `message_id`, substr(`normalized_text`, `position`, 3);
551
+ --> statement-breakpoint
552
+ INSERT INTO `message_search_ngrams` (`gram`, `message_id`, `occurrences`)
553
+ SELECT `normalized_text`, `message_id`, 1
554
+ FROM `message_search_documents`
555
+ WHERE `normalized_length` BETWEEN 1 AND 2;
556
+ --> statement-breakpoint
557
+ CREATE TABLE `search_index_state` (
558
+ `entity_kind` TEXT PRIMARY KEY NOT NULL CHECK (`entity_kind` IN ('message', 'chat', 'user', 'bot', 'file')),
559
+ `version` INTEGER NOT NULL DEFAULT 1 CHECK (`version` > 0),
560
+ `status` TEXT NOT NULL DEFAULT 'ready' CHECK (`status` IN ('ready', 'rebuilding', 'failed')),
561
+ `last_indexed_id` TEXT,
562
+ `last_error` TEXT,
563
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
564
+ );
565
+ --> statement-breakpoint
566
+ INSERT INTO `search_index_state` (`entity_kind`) VALUES ('message'), ('chat'), ('user');
567
+ --> statement-breakpoint
568
+ CREATE INDEX `files_cleanup_idx` ON `files` (`upload_status`, `deleted_at`, `orphaned_at`, `retention_until`);
569
+ --> statement-breakpoint
570
+ CREATE INDEX `files_checksum_idx` ON `files` (`checksum_sha256`) WHERE `checksum_sha256` IS NOT NULL;
571
+ --> statement-breakpoint
572
+ CREATE INDEX `files_scan_idx` ON `files` (`scan_status`, `created_at`, `id`);
573
+ --> statement-breakpoint
574
+ CREATE TABLE `file_upload_sessions` (
575
+ `id` TEXT PRIMARY KEY NOT NULL,
576
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
577
+ `file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL,
578
+ `storage_provider` TEXT NOT NULL DEFAULT 'local' CHECK (length(trim(`storage_provider`)) > 0),
579
+ `storage_key` TEXT NOT NULL,
580
+ `original_name` TEXT NOT NULL,
581
+ `content_type` TEXT NOT NULL,
582
+ `expected_size` INTEGER NOT NULL CHECK (`expected_size` >= 0),
583
+ `received_size` INTEGER NOT NULL DEFAULT 0 CHECK (`received_size` >= 0),
584
+ `chunk_size` INTEGER NOT NULL CHECK (`chunk_size` > 0),
585
+ `checksum_sha256` TEXT,
586
+ `status` TEXT NOT NULL DEFAULT 'pending' CHECK (`status` IN ('pending', 'uploading', 'assembling', 'complete', 'failed', 'cancelled', 'expired')),
587
+ `client_mutation_id` TEXT,
588
+ `metadata_json` TEXT,
589
+ `last_error` TEXT,
590
+ `expires_at` TEXT NOT NULL,
591
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
592
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
593
+ `completed_at` TEXT,
594
+ UNIQUE (`storage_provider`, `storage_key`),
595
+ CHECK (`received_size` <= `expected_size`)
596
+ );
597
+ --> statement-breakpoint
598
+ CREATE INDEX `file_upload_sessions_user_created_idx` ON `file_upload_sessions` (`user_id`, `created_at` DESC, `id`);
599
+ --> statement-breakpoint
600
+ CREATE INDEX `file_upload_sessions_expiry_idx` ON `file_upload_sessions` (`status`, `expires_at`, `id`);
601
+ --> statement-breakpoint
602
+ CREATE UNIQUE INDEX `file_upload_sessions_client_mutation_unique_idx`
603
+ ON `file_upload_sessions` (`user_id`, `client_mutation_id`)
604
+ WHERE `client_mutation_id` IS NOT NULL;
605
+ --> statement-breakpoint
606
+ CREATE TABLE `file_upload_parts` (
607
+ `upload_session_id` TEXT NOT NULL REFERENCES `file_upload_sessions`(`id`) ON DELETE CASCADE,
608
+ `part_number` INTEGER NOT NULL CHECK (`part_number` >= 0),
609
+ `byte_offset` INTEGER NOT NULL CHECK (`byte_offset` >= 0),
610
+ `size` INTEGER NOT NULL CHECK (`size` > 0),
611
+ `checksum_sha256` TEXT,
612
+ `storage_etag` TEXT,
613
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
614
+ PRIMARY KEY (`upload_session_id`, `part_number`),
615
+ UNIQUE (`upload_session_id`, `byte_offset`)
616
+ );
617
+ --> statement-breakpoint
618
+ CREATE TABLE `file_access_grants` (
619
+ `id` TEXT PRIMARY KEY NOT NULL,
620
+ `file_id` TEXT NOT NULL REFERENCES `files`(`id`) ON DELETE CASCADE,
621
+ `principal_type` TEXT NOT NULL CHECK (`principal_type` IN ('user', 'chat', 'server', 'custom_emoji')),
622
+ `principal_id` TEXT NOT NULL,
623
+ `source_message_id` TEXT REFERENCES `messages`(`id`) ON DELETE CASCADE,
624
+ `granted_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
625
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
626
+ `expires_at` TEXT,
627
+ UNIQUE (`file_id`, `principal_type`, `principal_id`, `source_message_id`)
628
+ );
629
+ --> statement-breakpoint
630
+ CREATE INDEX `file_access_grants_principal_idx` ON `file_access_grants` (`principal_type`, `principal_id`, `file_id`);
631
+ --> statement-breakpoint
632
+ CREATE INDEX `file_access_grants_file_idx` ON `file_access_grants` (`file_id`, `expires_at`);
633
+ --> statement-breakpoint
634
+ CREATE UNIQUE INDEX `file_access_grants_without_source_unique_idx`
635
+ ON `file_access_grants` (`file_id`, `principal_type`, `principal_id`)
636
+ WHERE `source_message_id` IS NULL;
637
+ --> statement-breakpoint
638
+ CREATE TABLE `user_storage_quotas` (
639
+ `user_id` TEXT PRIMARY KEY NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
640
+ `quota_bytes` INTEGER CHECK (`quota_bytes` IS NULL OR `quota_bytes` > 0),
641
+ `used_bytes` INTEGER NOT NULL DEFAULT 0 CHECK (`used_bytes` >= 0),
642
+ `reserved_bytes` INTEGER NOT NULL DEFAULT 0 CHECK (`reserved_bytes` >= 0),
643
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
644
+ );
645
+ --> statement-breakpoint
646
+ CREATE TABLE `file_scan_events` (
647
+ `id` TEXT PRIMARY KEY NOT NULL,
648
+ `file_id` TEXT NOT NULL REFERENCES `files`(`id`) ON DELETE CASCADE,
649
+ `scanner` TEXT NOT NULL,
650
+ `status` TEXT NOT NULL CHECK (`status` IN ('pending', 'clean', 'infected', 'failed', 'skipped')),
651
+ `result_json` TEXT,
652
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
653
+ );
654
+ --> statement-breakpoint
655
+ CREATE INDEX `file_scan_events_file_created_idx` ON `file_scan_events` (`file_id`, `created_at` DESC);
656
+ --> statement-breakpoint
657
+ CREATE TABLE `file_derivatives` (
658
+ `source_file_id` TEXT NOT NULL REFERENCES `files`(`id`) ON DELETE CASCADE,
659
+ `derived_file_id` TEXT NOT NULL REFERENCES `files`(`id`) ON DELETE CASCADE,
660
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('thumbnail', 'preview', 'poster', 'transcode')),
661
+ `variant` TEXT NOT NULL DEFAULT 'default',
662
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
663
+ PRIMARY KEY (`source_file_id`, `kind`, `variant`),
664
+ UNIQUE (`derived_file_id`)
665
+ );
666
+ --> statement-breakpoint
667
+ CREATE TABLE `file_processing_jobs` (
668
+ `id` TEXT PRIMARY KEY NOT NULL,
669
+ `file_id` TEXT NOT NULL REFERENCES `files`(`id`) ON DELETE CASCADE,
670
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('probe', 'thumbnail', 'preview', 'transcode', 'scan', 'cleanup')),
671
+ `status` TEXT NOT NULL DEFAULT 'pending' CHECK (`status` IN ('pending', 'running', 'complete', 'failed', 'cancelled')),
672
+ `input_json` TEXT,
673
+ `result_json` TEXT,
674
+ `attempts` INTEGER NOT NULL DEFAULT 0 CHECK (`attempts` >= 0),
675
+ `run_after` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
676
+ `locked_at` TEXT,
677
+ `locked_by` TEXT,
678
+ `last_error` TEXT,
679
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
680
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
681
+ `completed_at` TEXT
682
+ );
683
+ --> statement-breakpoint
684
+ CREATE INDEX `file_processing_jobs_due_idx` ON `file_processing_jobs` (`status`, `run_after`, `id`);
685
+ --> statement-breakpoint
686
+ CREATE TABLE `integrations` (
687
+ `id` TEXT PRIMARY KEY NOT NULL,
688
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('app', 'incoming_webhook', 'outgoing_webhook', 'slash_command', 'service_account')),
689
+ `name` TEXT NOT NULL CHECK (length(trim(`name`)) > 0),
690
+ `description` TEXT,
691
+ `bot_id` TEXT REFERENCES `bot_identities`(`id`) ON DELETE SET NULL,
692
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
693
+ `scopes_json` TEXT NOT NULL DEFAULT '[]',
694
+ `config_json` TEXT,
695
+ `active` INTEGER NOT NULL DEFAULT 1 CHECK (`active` IN (0, 1)),
696
+ `sync_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`sync_sequence` >= 0),
697
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
698
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
699
+ `deleted_at` TEXT
700
+ );
701
+ --> statement-breakpoint
702
+ CREATE INDEX `integrations_active_kind_idx` ON `integrations` (`active`, `kind`, `deleted_at`);
703
+ --> statement-breakpoint
704
+ CREATE INDEX `integrations_sync_idx` ON `integrations` (`sync_sequence`);
705
+ --> statement-breakpoint
706
+ CREATE TABLE `api_credentials` (
707
+ `id` TEXT PRIMARY KEY NOT NULL,
708
+ `integration_id` TEXT REFERENCES `integrations`(`id`) ON DELETE CASCADE,
709
+ `user_id` TEXT REFERENCES `users`(`id`) ON DELETE CASCADE,
710
+ `bot_id` TEXT REFERENCES `bot_identities`(`id`) ON DELETE CASCADE,
711
+ `name` TEXT NOT NULL,
712
+ `token_prefix` TEXT NOT NULL,
713
+ `token_hash` TEXT NOT NULL UNIQUE,
714
+ `scopes_json` TEXT NOT NULL DEFAULT '[]',
715
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
716
+ `expires_at` TEXT,
717
+ `last_used_at` TEXT,
718
+ `revoked_at` TEXT,
719
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
720
+ CHECK (((`integration_id` IS NOT NULL) + (`user_id` IS NOT NULL) + (`bot_id` IS NOT NULL)) = 1)
721
+ );
722
+ --> statement-breakpoint
723
+ CREATE INDEX `api_credentials_prefix_idx` ON `api_credentials` (`token_prefix`, `revoked_at`, `expires_at`);
724
+ --> statement-breakpoint
725
+ CREATE TABLE `webhook_subscriptions` (
726
+ `id` TEXT PRIMARY KEY NOT NULL,
727
+ `integration_id` TEXT NOT NULL REFERENCES `integrations`(`id`) ON DELETE CASCADE,
728
+ `direction` TEXT NOT NULL CHECK (`direction` IN ('incoming', 'outgoing')),
729
+ `chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE CASCADE,
730
+ `url` TEXT,
731
+ `token_hash` TEXT,
732
+ `signing_secret_ciphertext` TEXT,
733
+ `event_types_json` TEXT NOT NULL DEFAULT '[]',
734
+ `active` INTEGER NOT NULL DEFAULT 1 CHECK (`active` IN (0, 1)),
735
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
736
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
737
+ CHECK (
738
+ (`direction` = 'incoming' AND `token_hash` IS NOT NULL)
739
+ OR (`direction` = 'outgoing' AND `url` IS NOT NULL AND `signing_secret_ciphertext` IS NOT NULL)
740
+ )
741
+ );
742
+ --> statement-breakpoint
743
+ CREATE UNIQUE INDEX `webhook_subscriptions_token_unique_idx` ON `webhook_subscriptions` (`token_hash`) WHERE `token_hash` IS NOT NULL;
744
+ --> statement-breakpoint
745
+ CREATE INDEX `webhook_subscriptions_outgoing_idx` ON `webhook_subscriptions` (`active`, `direction`, `chat_id`);
746
+ --> statement-breakpoint
747
+ CREATE TABLE `webhook_deliveries` (
748
+ `id` TEXT PRIMARY KEY NOT NULL,
749
+ `subscription_id` TEXT NOT NULL REFERENCES `webhook_subscriptions`(`id`) ON DELETE CASCADE,
750
+ `event_id` TEXT NOT NULL,
751
+ `event_type` TEXT NOT NULL,
752
+ `payload_json` TEXT NOT NULL,
753
+ `status` TEXT NOT NULL DEFAULT 'pending' CHECK (`status` IN ('pending', 'delivering', 'delivered', 'failed', 'cancelled')),
754
+ `attempts` INTEGER NOT NULL DEFAULT 0 CHECK (`attempts` >= 0),
755
+ `next_attempt_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
756
+ `response_status` INTEGER,
757
+ `response_body` TEXT,
758
+ `last_error` TEXT,
759
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
760
+ `delivered_at` TEXT,
761
+ UNIQUE (`subscription_id`, `event_id`)
762
+ );
763
+ --> statement-breakpoint
764
+ CREATE INDEX `webhook_deliveries_due_idx` ON `webhook_deliveries` (`status`, `next_attempt_at`, `id`);
765
+ --> statement-breakpoint
766
+ CREATE TABLE `slash_commands` (
767
+ `id` TEXT PRIMARY KEY NOT NULL,
768
+ `integration_id` TEXT NOT NULL REFERENCES `integrations`(`id`) ON DELETE CASCADE,
769
+ `command` TEXT NOT NULL COLLATE NOCASE CHECK (length(`command`) > 1 AND substr(`command`, 1, 1) = '/'),
770
+ `description` TEXT,
771
+ `usage_hint` TEXT,
772
+ `handler_url` TEXT NOT NULL,
773
+ `active` INTEGER NOT NULL DEFAULT 1 CHECK (`active` IN (0, 1)),
774
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
775
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
776
+ );
777
+ --> statement-breakpoint
778
+ CREATE UNIQUE INDEX `slash_commands_active_command_unique_idx`
779
+ ON `slash_commands` (`command`)
780
+ WHERE `active` = 1;
781
+ --> statement-breakpoint
782
+ CREATE TABLE `automations` (
783
+ `id` TEXT PRIMARY KEY NOT NULL,
784
+ `name` TEXT NOT NULL CHECK (length(trim(`name`)) > 0),
785
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
786
+ `bot_id` TEXT REFERENCES `bot_identities`(`id`) ON DELETE SET NULL,
787
+ `chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE CASCADE,
788
+ `trigger_type` TEXT NOT NULL CHECK (`trigger_type` IN ('schedule', 'event', 'webhook')),
789
+ `trigger_config_json` TEXT NOT NULL DEFAULT '{}',
790
+ `action_type` TEXT NOT NULL DEFAULT 'send_message' CHECK (`action_type` IN ('send_message', 'call_webhook', 'moderate')),
791
+ `action_config_json` TEXT NOT NULL DEFAULT '{}',
792
+ `timezone` TEXT,
793
+ `next_run_at` TEXT,
794
+ `active` INTEGER NOT NULL DEFAULT 1 CHECK (`active` IN (0, 1)),
795
+ `created_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`created_sequence` >= 0),
796
+ `last_run_at` TEXT,
797
+ `last_error` TEXT,
798
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
799
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
800
+ `deleted_at` TEXT
801
+ );
802
+ --> statement-breakpoint
803
+ CREATE INDEX `automations_due_idx` ON `automations` (`active`, `trigger_type`, `next_run_at`, `id`);
804
+ --> statement-breakpoint
805
+ CREATE INDEX `automations_chat_idx` ON `automations` (`chat_id`, `active`, `id`);
806
+ --> statement-breakpoint
807
+ CREATE TABLE `automation_runs` (
808
+ `id` TEXT PRIMARY KEY NOT NULL,
809
+ `automation_id` TEXT NOT NULL REFERENCES `automations`(`id`) ON DELETE CASCADE,
810
+ `trigger_event_id` TEXT,
811
+ `scheduled_for` TEXT,
812
+ `status` TEXT NOT NULL DEFAULT 'pending' CHECK (`status` IN ('pending', 'running', 'succeeded', 'failed', 'cancelled')),
813
+ `attempts` INTEGER NOT NULL DEFAULT 0 CHECK (`attempts` >= 0),
814
+ `input_json` TEXT,
815
+ `result_json` TEXT,
816
+ `last_error` TEXT,
817
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
818
+ `started_at` TEXT,
819
+ `completed_at` TEXT,
820
+ UNIQUE (`automation_id`, `trigger_event_id`)
821
+ );
822
+ --> statement-breakpoint
823
+ CREATE INDEX `automation_runs_status_created_idx` ON `automation_runs` (`status`, `created_at`, `id`);
824
+ --> statement-breakpoint
825
+ CREATE TABLE `calls` (
826
+ `id` TEXT PRIMARY KEY NOT NULL,
827
+ `chat_id` TEXT NOT NULL REFERENCES `chats`(`id`) ON DELETE CASCADE,
828
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
829
+ `kind` TEXT NOT NULL DEFAULT 'audio' CHECK (`kind` IN ('audio', 'video')),
830
+ `status` TEXT NOT NULL DEFAULT 'ringing' CHECK (`status` IN ('ringing', 'active', 'ended', 'cancelled', 'failed')),
831
+ `provider` TEXT NOT NULL DEFAULT 'webrtc',
832
+ `provider_room_id` TEXT,
833
+ `provider_data_json` TEXT,
834
+ `started_at` TEXT,
835
+ `ended_at` TEXT,
836
+ `end_reason` TEXT,
837
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
838
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
839
+ );
840
+ --> statement-breakpoint
841
+ CREATE INDEX `calls_chat_created_idx` ON `calls` (`chat_id`, `created_at` DESC, `id` DESC);
842
+ --> statement-breakpoint
843
+ CREATE INDEX `calls_active_idx` ON `calls` (`status`, `updated_at`, `id`);
844
+ --> statement-breakpoint
845
+ CREATE TABLE `call_participants` (
846
+ `call_id` TEXT NOT NULL REFERENCES `calls`(`id`) ON DELETE CASCADE,
847
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
848
+ `invited_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
849
+ `status` TEXT NOT NULL DEFAULT 'invited' CHECK (`status` IN ('invited', 'ringing', 'joined', 'declined', 'left', 'missed', 'removed')),
850
+ `invited_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
851
+ `ringing_at` TEXT,
852
+ `joined_at` TEXT,
853
+ `left_at` TEXT,
854
+ `last_seen_at` TEXT,
855
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
856
+ PRIMARY KEY (`call_id`, `user_id`)
857
+ );
858
+ --> statement-breakpoint
859
+ CREATE INDEX `call_participants_user_status_idx` ON `call_participants` (`user_id`, `status`, `updated_at` DESC);
860
+ --> statement-breakpoint
861
+ CREATE TABLE `call_events` (
862
+ `id` TEXT PRIMARY KEY NOT NULL,
863
+ `call_id` TEXT NOT NULL REFERENCES `calls`(`id`) ON DELETE CASCADE,
864
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('created', 'ringing', 'joined', 'left', 'declined', 'missed', 'ended', 'failed')),
865
+ `actor_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
866
+ `target_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
867
+ `payload_json` TEXT,
868
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
869
+ );
870
+ --> statement-breakpoint
871
+ CREATE INDEX `call_events_call_created_idx` ON `call_events` (`call_id`, `created_at`, `id`);
872
+ --> statement-breakpoint
873
+ CREATE TABLE `call_credential_leases` (
874
+ `id` TEXT PRIMARY KEY NOT NULL,
875
+ `call_id` TEXT NOT NULL REFERENCES `calls`(`id`) ON DELETE CASCADE,
876
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
877
+ `provider` TEXT NOT NULL,
878
+ `credential_username` TEXT NOT NULL,
879
+ `expires_at` TEXT NOT NULL,
880
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
881
+ `revoked_at` TEXT
882
+ );
883
+ --> statement-breakpoint
884
+ CREATE INDEX `call_credential_leases_expiry_idx` ON `call_credential_leases` (`expires_at`, `revoked_at`);
885
+ --> statement-breakpoint
886
+ ALTER TABLE `server_sync_state` ADD COLUMN `min_recoverable_sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`min_recoverable_sequence` >= 0);
887
+ --> statement-breakpoint
888
+ ALTER TABLE `server_sync_state` ADD COLUMN `last_compacted_at` TEXT;
889
+ --> statement-breakpoint
890
+ ALTER TABLE `server_sync_state` ADD COLUMN `compaction_version` INTEGER NOT NULL DEFAULT 0 CHECK (`compaction_version` >= 0);
891
+ --> statement-breakpoint
892
+ ALTER TABLE `client_mutations` ADD COLUMN `expires_at` TEXT;
893
+ --> statement-breakpoint
894
+ ALTER TABLE `client_mutations` ADD COLUMN `last_accessed_at` TEXT;
895
+ --> statement-breakpoint
896
+ CREATE INDEX `client_mutations_expiry_idx` ON `client_mutations` (`expires_at`, `created_at`);
897
+ --> statement-breakpoint
898
+ CREATE TABLE `sync_consumers` (
899
+ `id` TEXT PRIMARY KEY NOT NULL,
900
+ `user_id` TEXT NOT NULL REFERENCES `users`(`id`) ON DELETE CASCADE,
901
+ `device_id` TEXT NOT NULL,
902
+ `generation` TEXT NOT NULL,
903
+ `sequence` INTEGER NOT NULL DEFAULT 0 CHECK (`sequence` >= 0),
904
+ `last_seen_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
905
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
906
+ `revoked_at` TEXT,
907
+ UNIQUE (`user_id`, `device_id`)
908
+ );
909
+ --> statement-breakpoint
910
+ CREATE INDEX `sync_consumers_active_cursor_idx` ON `sync_consumers` (`generation`, `sequence`, `last_seen_at`) WHERE `revoked_at` IS NULL;
911
+ --> statement-breakpoint
912
+ CREATE TABLE `sync_compactions` (
913
+ `id` TEXT PRIMARY KEY NOT NULL,
914
+ `generation` TEXT NOT NULL,
915
+ `previous_min_sequence` INTEGER NOT NULL CHECK (`previous_min_sequence` >= 0),
916
+ `new_min_sequence` INTEGER NOT NULL CHECK (`new_min_sequence` >= 0),
917
+ `events_deleted` INTEGER NOT NULL DEFAULT 0 CHECK (`events_deleted` >= 0),
918
+ `mutations_deleted` INTEGER NOT NULL DEFAULT 0 CHECK (`mutations_deleted` >= 0),
919
+ `started_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
920
+ `completed_at` TEXT,
921
+ `details_json` TEXT,
922
+ CHECK (`new_min_sequence` >= `previous_min_sequence`)
923
+ );
924
+ --> statement-breakpoint
925
+ CREATE INDEX `sync_compactions_completed_idx` ON `sync_compactions` (`completed_at` DESC, `id` DESC);
926
+ --> statement-breakpoint
927
+ CREATE TABLE `chat_sync_compactions` (
928
+ `id` TEXT PRIMARY KEY NOT NULL,
929
+ `chat_id` TEXT NOT NULL REFERENCES `chats`(`id`) ON DELETE CASCADE,
930
+ `previous_min_pts` INTEGER NOT NULL CHECK (`previous_min_pts` >= 0),
931
+ `new_min_pts` INTEGER NOT NULL CHECK (`new_min_pts` >= 0),
932
+ `updates_deleted` INTEGER NOT NULL DEFAULT 0 CHECK (`updates_deleted` >= 0),
933
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
934
+ CHECK (`new_min_pts` >= `previous_min_pts`)
935
+ );
936
+ --> statement-breakpoint
937
+ CREATE INDEX `chat_sync_compactions_chat_created_idx` ON `chat_sync_compactions` (`chat_id`, `created_at` DESC);
938
+ --> statement-breakpoint
939
+ CREATE TABLE `idempotency_keys` (
940
+ `id` TEXT PRIMARY KEY NOT NULL,
941
+ `principal_type` TEXT NOT NULL CHECK (`principal_type` IN ('user', 'integration', 'system')),
942
+ `principal_id` TEXT NOT NULL,
943
+ `scope` TEXT NOT NULL,
944
+ `idempotency_key` TEXT NOT NULL,
945
+ `request_hash` TEXT NOT NULL,
946
+ `status` TEXT NOT NULL DEFAULT 'in_progress' CHECK (`status` IN ('in_progress', 'completed', 'failed')),
947
+ `response_status` INTEGER,
948
+ `response_json` TEXT,
949
+ `locked_until` TEXT,
950
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
951
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
952
+ `expires_at` TEXT NOT NULL,
953
+ UNIQUE (`principal_type`, `principal_id`, `scope`, `idempotency_key`)
954
+ );
955
+ --> statement-breakpoint
956
+ CREATE INDEX `idempotency_keys_expiry_idx` ON `idempotency_keys` (`expires_at`, `status`);
957
+ --> statement-breakpoint
958
+ CREATE TABLE `audit_log_entries` (
959
+ `id` TEXT PRIMARY KEY NOT NULL,
960
+ `actor_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
961
+ `actor_integration_id` TEXT REFERENCES `integrations`(`id`) ON DELETE SET NULL,
962
+ `action` TEXT NOT NULL,
963
+ `target_type` TEXT NOT NULL,
964
+ `target_id` TEXT,
965
+ `chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE SET NULL,
966
+ `before_json` TEXT,
967
+ `after_json` TEXT,
968
+ `metadata_json` TEXT,
969
+ `client_ip` TEXT,
970
+ `device` TEXT,
971
+ `app_version` TEXT,
972
+ `user_agent` TEXT,
973
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
974
+ );
975
+ --> statement-breakpoint
976
+ CREATE INDEX `audit_log_entries_cursor_idx` ON `audit_log_entries` (`created_at` DESC, `id` DESC);
977
+ --> statement-breakpoint
978
+ CREATE INDEX `audit_log_entries_actor_idx` ON `audit_log_entries` (`actor_user_id`, `created_at` DESC);
979
+ --> statement-breakpoint
980
+ CREATE INDEX `audit_log_entries_target_idx` ON `audit_log_entries` (`target_type`, `target_id`, `created_at` DESC);
981
+ --> statement-breakpoint
982
+ CREATE TABLE `account_bans` (
983
+ `id` TEXT PRIMARY KEY NOT NULL,
984
+ `account_id` TEXT NOT NULL REFERENCES `accounts`(`id`) ON DELETE CASCADE,
985
+ `banned_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
986
+ `reason` TEXT,
987
+ `banned_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
988
+ `expires_at` TEXT,
989
+ `revoked_at` TEXT,
990
+ `revoked_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
991
+ `revoke_reason` TEXT
992
+ );
993
+ --> statement-breakpoint
994
+ CREATE INDEX `account_bans_account_active_idx` ON `account_bans` (`account_id`, `revoked_at`, `expires_at`);
995
+ --> statement-breakpoint
996
+ CREATE TABLE `moderation_reports` (
997
+ `id` TEXT PRIMARY KEY NOT NULL,
998
+ `reported_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
999
+ `target_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
1000
+ `chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE SET NULL,
1001
+ `message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL,
1002
+ `file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL,
1003
+ `reason` TEXT NOT NULL,
1004
+ `details` TEXT,
1005
+ `status` TEXT NOT NULL DEFAULT 'open' CHECK (`status` IN ('open', 'reviewing', 'resolved', 'dismissed')),
1006
+ `assigned_to_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
1007
+ `resolution` TEXT,
1008
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
1009
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
1010
+ `resolved_at` TEXT,
1011
+ CHECK (((`target_user_id` IS NOT NULL) + (`chat_id` IS NOT NULL) + (`message_id` IS NOT NULL) + (`file_id` IS NOT NULL)) >= 1)
1012
+ );
1013
+ --> statement-breakpoint
1014
+ CREATE INDEX `moderation_reports_queue_idx` ON `moderation_reports` (`status`, `created_at`, `id`);
1015
+ --> statement-breakpoint
1016
+ CREATE INDEX `moderation_reports_reporter_idx` ON `moderation_reports` (`reported_by_user_id`, `created_at` DESC);
1017
+ --> statement-breakpoint
1018
+ CREATE TABLE `moderation_actions` (
1019
+ `id` TEXT PRIMARY KEY NOT NULL,
1020
+ `report_id` TEXT REFERENCES `moderation_reports`(`id`) ON DELETE SET NULL,
1021
+ `actor_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
1022
+ `target_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
1023
+ `chat_id` TEXT REFERENCES `chats`(`id`) ON DELETE SET NULL,
1024
+ `message_id` TEXT REFERENCES `messages`(`id`) ON DELETE SET NULL,
1025
+ `file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL,
1026
+ `action` TEXT NOT NULL CHECK (`action` IN ('warn', 'restrict', 'remove_message', 'remove_file', 'ban', 'unban', 'delete_user')),
1027
+ `reason` TEXT,
1028
+ `metadata_json` TEXT,
1029
+ `automation_run_id` TEXT UNIQUE REFERENCES `automation_runs`(`id`) ON DELETE SET NULL,
1030
+ `expires_at` TEXT,
1031
+ `revoked_at` TEXT,
1032
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
1033
+ );
1034
+ --> statement-breakpoint
1035
+ CREATE INDEX `moderation_actions_target_idx` ON `moderation_actions` (`target_user_id`, `created_at` DESC);
1036
+ --> statement-breakpoint
1037
+ CREATE INDEX `moderation_actions_file_idx` ON `moderation_actions` (`file_id`, `created_at` DESC);
1038
+ --> statement-breakpoint
1039
+ CREATE TABLE `data_export_jobs` (
1040
+ `id` TEXT PRIMARY KEY NOT NULL,
1041
+ `requested_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
1042
+ `kind` TEXT NOT NULL CHECK (`kind` IN ('user_data', 'server_data', 'audit_log', 'chat_history')),
1043
+ `target_id` TEXT,
1044
+ `status` TEXT NOT NULL DEFAULT 'pending' CHECK (`status` IN ('pending', 'running', 'complete', 'failed', 'cancelled', 'expired')),
1045
+ `output_file_id` TEXT REFERENCES `files`(`id`) ON DELETE SET NULL,
1046
+ `options_json` TEXT,
1047
+ `last_error` TEXT,
1048
+ `expires_at` TEXT,
1049
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
1050
+ `started_at` TEXT,
1051
+ `completed_at` TEXT
1052
+ );
1053
+ --> statement-breakpoint
1054
+ CREATE INDEX `data_export_jobs_queue_idx` ON `data_export_jobs` (`status`, `created_at`, `id`);
1055
+ --> statement-breakpoint
1056
+ CREATE TABLE `backup_records` (
1057
+ `id` TEXT PRIMARY KEY NOT NULL,
1058
+ `storage_provider` TEXT NOT NULL,
1059
+ `storage_key` TEXT NOT NULL,
1060
+ `checksum_sha256` TEXT,
1061
+ `size` INTEGER CHECK (`size` IS NULL OR `size` >= 0),
1062
+ `status` TEXT NOT NULL DEFAULT 'pending' CHECK (`status` IN ('pending', 'running', 'complete', 'failed', 'deleted')),
1063
+ `created_by_user_id` TEXT REFERENCES `users`(`id`) ON DELETE SET NULL,
1064
+ `metadata_json` TEXT,
1065
+ `last_error` TEXT,
1066
+ `created_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
1067
+ `completed_at` TEXT,
1068
+ `retention_until` TEXT,
1069
+ UNIQUE (`storage_provider`, `storage_key`)
1070
+ );
1071
+ --> statement-breakpoint
1072
+ CREATE INDEX `backup_records_retention_idx` ON `backup_records` (`status`, `retention_until`, `id`);
1073
+ --> statement-breakpoint
1074
+ CREATE TABLE `retention_runs` (
1075
+ `id` TEXT PRIMARY KEY NOT NULL,
1076
+ `scope` TEXT NOT NULL CHECK (`scope` IN ('messages', 'files', 'sync', 'idempotency', 'audit', 'backups')),
1077
+ `status` TEXT NOT NULL DEFAULT 'running' CHECK (`status` IN ('running', 'complete', 'failed')),
1078
+ `items_examined` INTEGER NOT NULL DEFAULT 0 CHECK (`items_examined` >= 0),
1079
+ `items_deleted` INTEGER NOT NULL DEFAULT 0 CHECK (`items_deleted` >= 0),
1080
+ `details_json` TEXT,
1081
+ `last_error` TEXT,
1082
+ `started_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
1083
+ `completed_at` TEXT
1084
+ );
1085
+ --> statement-breakpoint
1086
+ CREATE INDEX `retention_runs_scope_started_idx` ON `retention_runs` (`scope`, `started_at` DESC);
1087
+ --> statement-breakpoint
1088
+ CREATE TABLE `rate_limit_buckets` (
1089
+ `principal_key` TEXT NOT NULL,
1090
+ `action` TEXT NOT NULL,
1091
+ `window_started_at` TEXT NOT NULL,
1092
+ `window_seconds` INTEGER NOT NULL CHECK (`window_seconds` > 0),
1093
+ `request_count` INTEGER NOT NULL DEFAULT 0 CHECK (`request_count` >= 0),
1094
+ `blocked_until` TEXT,
1095
+ `updated_at` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
1096
+ PRIMARY KEY (`principal_key`, `action`, `window_started_at`)
1097
+ );
1098
+ --> statement-breakpoint
1099
+ CREATE INDEX `rate_limit_buckets_cleanup_idx` ON `rate_limit_buckets` (`window_started_at`, `blocked_until`);