@beechcms/api 0.6.0-preview.1 → 0.6.0-preview.3

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 +4 -4
  2. package/assets/dashboard/BeechLogo.svg +18 -18
  3. package/assets/dashboard/BeechLogoLIght.svg +48 -48
  4. package/assets/dashboard/assets/chart-Cws4Yj6K.js +39 -0
  5. package/assets/dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  6. package/assets/dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  7. package/assets/dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  8. package/assets/dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  9. package/assets/dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  10. package/assets/dashboard/assets/index-BjPpppHe.css +1 -0
  11. package/assets/dashboard/assets/index-CrW-zhkA.js +642 -0
  12. package/assets/dashboard/assets/lora-cyrillic-ext-wght-normal-YcVxMP-u.woff2 +0 -0
  13. package/assets/dashboard/assets/lora-cyrillic-wght-normal-UWPuZLjM.woff2 +0 -0
  14. package/assets/dashboard/assets/lora-latin-ext-wght-normal-C2Wlntb9.woff2 +0 -0
  15. package/assets/dashboard/assets/lora-latin-wght-normal-BiLcIKcI.woff2 +0 -0
  16. package/assets/dashboard/assets/lora-math-wght-normal-sOy7rEfW.woff2 +0 -0
  17. package/assets/dashboard/assets/lora-symbols-wght-normal-DQ5VrUkH.woff2 +0 -0
  18. package/assets/dashboard/assets/lora-vietnamese-wght-normal-CfJ7gtf3.woff2 +0 -0
  19. package/assets/dashboard/assets/pie-chart-recharts-CAxoDQp2.js +1 -0
  20. package/assets/dashboard/assets/timeseries-chart-recharts-CixDW-LM.js +1 -0
  21. package/assets/dashboard/beechLogoDark.svg +48 -48
  22. package/assets/dashboard/index.html +18 -18
  23. package/assets/dashboard/noResult.svg +42 -42
  24. package/assets/dashboard/sol.svg +3 -3
  25. package/assets/dashboard/undraw_enter_nwx3.svg +36 -36
  26. package/dist/auth/__fixtures__/in-memory-hash-provider.d.ts +5 -0
  27. package/dist/auth/__fixtures__/static-token-service.d.ts +6 -0
  28. package/dist/auth/bcrypt-hash-provider.d.ts +8 -0
  29. package/dist/auth/constants.d.ts +10 -0
  30. package/dist/auth/jose-token-service.d.ts +14 -0
  31. package/dist/auth/login.d.ts +32 -0
  32. package/dist/auth/refresh.d.ts +1 -0
  33. package/dist/factory.d.ts +39 -0
  34. package/dist/features/automations/action-executors/create-entry.executor.d.ts +7 -0
  35. package/dist/features/automations/action-executors/edit-field.executor.d.ts +7 -0
  36. package/dist/features/automations/action-executors/index.d.ts +13 -0
  37. package/dist/features/automations/action-executors/send-mail.executor.d.ts +7 -0
  38. package/dist/features/automations/action-executors/set-variable.executor.d.ts +15 -0
  39. package/dist/features/automations/action-executors/webhook.executor.d.ts +7 -0
  40. package/dist/features/automations/automation-runner.d.ts +13 -0
  41. package/dist/features/automations/automation-runner.utils.d.ts +3 -0
  42. package/dist/features/automations/automations.handler.d.ts +7 -0
  43. package/dist/features/automations/automations.schema.d.ts +191 -0
  44. package/dist/features/automations/context-resolver.d.ts +8 -0
  45. package/dist/features/automations/cron-runner.d.ts +9 -0
  46. package/dist/features/automations/cron-runner.utils.d.ts +1 -0
  47. package/dist/features/automations/filter-translation.d.ts +9 -0
  48. package/dist/features/automations/index.d.ts +7 -0
  49. package/dist/features/automations/template-grammar.d.ts +73 -0
  50. package/dist/features/automations/var-access-resolver.d.ts +6 -0
  51. package/dist/features/automations/when-evaluator.d.ts +3 -0
  52. package/dist/features/automations/when-pushdown.d.ts +2 -0
  53. package/dist/features/backrefs/backrefs.handler.d.ts +3 -0
  54. package/dist/features/backrefs/d1-backref.repository.d.ts +17 -0
  55. package/dist/features/backrefs/index.d.ts +1 -0
  56. package/dist/features/content/constants.d.ts +12 -0
  57. package/dist/features/content/handlers/bulk.handler.d.ts +3 -0
  58. package/dist/features/content/handlers/create.d.ts +3 -0
  59. package/dist/features/content/handlers/delete.d.ts +3 -0
  60. package/dist/features/content/handlers/facets.d.ts +3 -0
  61. package/dist/features/content/handlers/get.d.ts +4 -0
  62. package/dist/features/content/handlers/helpers.d.ts +12 -0
  63. package/dist/features/content/handlers/list.d.ts +3 -0
  64. package/dist/features/content/handlers/update.d.ts +3 -0
  65. package/dist/features/content/index.d.ts +4 -0
  66. package/dist/features/dashboard-layout/dashboard-layout.handler.d.ts +7 -0
  67. package/dist/features/dashboard-layout/index.d.ts +1 -0
  68. package/dist/features/draft/draft.handler.d.ts +4 -0
  69. package/dist/features/draft/draft.middleware.d.ts +9 -0
  70. package/dist/features/draft/index.d.ts +1 -0
  71. package/{src/features/email/email.provider.ts → dist/features/email/email.provider.d.ts} +37 -42
  72. package/dist/features/email/email.service.d.ts +13 -0
  73. package/dist/features/email/email.types.d.ts +94 -0
  74. package/{src/features/email/index.ts → dist/features/email/index.d.ts} +20 -33
  75. package/dist/features/email/providers/resend.d.ts +36 -0
  76. package/dist/features/email/providers/smtp.d.ts +11 -0
  77. package/dist/features/email/templates/automation-mail.d.ts +8 -0
  78. package/dist/features/email/templates/password-changed.d.ts +15 -0
  79. package/dist/features/email/templates/password-reset.d.ts +18 -0
  80. package/dist/features/email/templates/shell.d.ts +58 -0
  81. package/dist/features/notifications/index.d.ts +1 -0
  82. package/dist/features/notifications/notifications.handler.d.ts +15 -0
  83. package/dist/features/password-reset/index.d.ts +6 -0
  84. package/dist/features/password-reset/request.d.ts +10 -0
  85. package/dist/features/password-reset/reset.d.ts +9 -0
  86. package/dist/features/rotate-field/index.d.ts +1 -0
  87. package/dist/features/rotate-field/rotate-field.handler.d.ts +7 -0
  88. package/dist/features/rotate-field/rotate-field.schema.d.ts +11 -0
  89. package/dist/features/schema/schema.handler.d.ts +7 -0
  90. package/dist/features/seeds/index.d.ts +1 -0
  91. package/dist/features/seeds/seeds.handler.d.ts +6 -0
  92. package/dist/features/settings/settings.handler.d.ts +7 -0
  93. package/dist/features/setup/index.d.ts +7 -0
  94. package/dist/features/stats/index.d.ts +1 -0
  95. package/dist/features/stats/stats.handler.d.ts +7 -0
  96. package/dist/features/webhooks/index.d.ts +3 -0
  97. package/dist/index.d.ts +6 -0
  98. package/dist/index.js +9666 -0
  99. package/dist/media-utils.d.ts +25 -0
  100. package/dist/middleware/auth-providers.middleware.d.ts +8 -0
  101. package/dist/middleware/observability.middleware.d.ts +20 -0
  102. package/dist/middleware/rate-limit.middleware.d.ts +9 -0
  103. package/dist/middleware/repository.middleware.d.ts +34 -0
  104. package/dist/middleware/seed-registry.middleware.d.ts +10 -0
  105. package/dist/middleware/storage.middleware.d.ts +7 -0
  106. package/dist/middleware.d.ts +11 -0
  107. package/dist/public/access-policy.d.ts +12 -0
  108. package/dist/public/api-key-middleware.d.ts +6 -0
  109. package/dist/public/cache-utils.d.ts +10 -0
  110. package/dist/public/entry-projection.d.ts +2 -0
  111. package/dist/public/idempotency.d.ts +9 -0
  112. package/dist/public/index.d.ts +11 -0
  113. package/dist/public/problem-details.d.ts +31 -0
  114. package/dist/public/public-add.d.ts +3 -0
  115. package/dist/public/public-edit.d.ts +5 -0
  116. package/dist/public/public-errors.d.ts +13 -0
  117. package/dist/public/public-read.d.ts +3 -0
  118. package/dist/public/public-routes.d.ts +3 -0
  119. package/dist/public/query-builder.d.ts +28 -0
  120. package/dist/public/rate-limit-middleware.d.ts +3 -0
  121. package/dist/public/read-list.d.ts +26 -0
  122. package/dist/public/read-single.d.ts +22 -0
  123. package/dist/public/response-builder.d.ts +22 -0
  124. package/dist/public/sanitize.d.ts +23 -0
  125. package/dist/public/slug-utils.d.ts +11 -0
  126. package/dist/rate-limit/cloudflare-rate-limiter.d.ts +6 -0
  127. package/dist/rate-limit/in-memory-rate-limiter.d.ts +7 -0
  128. package/dist/rate-limit/no-op-rate-limiter.d.ts +4 -0
  129. package/dist/search-utils.d.ts +54 -0
  130. package/dist/search.d.ts +6 -0
  131. package/dist/shared/apply-policies.d.ts +10 -0
  132. package/dist/shared/automations.repository.d1.d.ts +12 -0
  133. package/dist/shared/background-notification-service.d.ts +18 -0
  134. package/dist/shared/base.repository.d1.d.ts +18 -0
  135. package/dist/shared/content-utils.d.ts +21 -0
  136. package/dist/shared/content.repository.d1.d.ts +68 -0
  137. package/dist/shared/d1-activity-log.repository.d.ts +13 -0
  138. package/dist/shared/d1-activity-logger.d.ts +20 -0
  139. package/dist/shared/d1-analytics.repository.d.ts +20 -0
  140. package/dist/shared/d1-content-scan.repository.d.ts +7 -0
  141. package/dist/shared/d1-notification.repository.d.ts +17 -0
  142. package/dist/shared/d1-password-reset-token.repository.d.ts +10 -0
  143. package/dist/shared/d1-search.repository.d.ts +14 -0
  144. package/dist/shared/d1-session.repository.d.ts +12 -0
  145. package/dist/shared/d1-setup-checklist.repository.d.ts +12 -0
  146. package/dist/shared/d1-user.repository.d.ts +18 -0
  147. package/dist/shared/d1-widget.repository.d.ts +31 -0
  148. package/dist/shared/dashboard-layout.repository.d1.d.ts +9 -0
  149. package/dist/shared/demo-data-sql.d.ts +1 -0
  150. package/dist/shared/demo-data.repository.d1.d.ts +6 -0
  151. package/dist/shared/execution-context-scheduler.d.ts +6 -0
  152. package/dist/shared/fixed-clock.d.ts +13 -0
  153. package/dist/shared/fts-sync.d.ts +1 -0
  154. package/dist/shared/idempotency.repository.d1.d.ts +16 -0
  155. package/dist/shared/in-memory-activity-logger.d.ts +11 -0
  156. package/dist/shared/in-memory-notification-service.d.ts +11 -0
  157. package/dist/shared/in-memory-seed.repository.d.ts +18 -0
  158. package/dist/shared/media.repository.d1.d.ts +35 -0
  159. package/dist/shared/qstash-notification-service.d.ts +18 -0
  160. package/dist/shared/query-utils.d.ts +36 -0
  161. package/dist/shared/request-utils.d.ts +13 -0
  162. package/dist/shared/schema-mutator.d1.d.ts +12 -0
  163. package/dist/shared/seed-layout.repository.d1.d.ts +9 -0
  164. package/dist/shared/seed-registry-cache.d.ts +12 -0
  165. package/dist/shared/seed.repository.d1.d.ts +13 -0
  166. package/dist/shared/sequential-id-generator.d.ts +13 -0
  167. package/dist/shared/site-settings.repository.d1.d.ts +7 -0
  168. package/dist/shared/storage/factory.d.ts +8 -0
  169. package/dist/shared/storage/s3-bucket.d.ts +43 -0
  170. package/dist/shared/storage-utils.d.ts +7 -0
  171. package/dist/shared/system-stats.repository.d1.d.ts +25 -0
  172. package/dist/types.d.ts +85 -0
  173. package/dist/upload.d.ts +16 -0
  174. package/dist/widget.d.ts +7 -0
  175. package/migrations/0000_v040_base.sql +265 -265
  176. package/migrations/0029_automations.sql +14 -14
  177. package/migrations/0030_test_seeds.sql +125 -125
  178. package/package.json +27 -18
  179. package/assets/dashboard/assets/index-BSjk0Sx9.js +0 -634
  180. package/assets/dashboard/assets/index-kRCYVN2B.css +0 -1
  181. package/src/auth/__fixtures__/in-memory-hash-provider.ts +0 -17
  182. package/src/auth/__fixtures__/static-token-service.ts +0 -22
  183. package/src/auth/bcrypt-hash-provider.ts +0 -24
  184. package/src/auth/constants.ts +0 -14
  185. package/src/auth/generate-refresh-token.test.ts +0 -23
  186. package/src/auth/hash-provider.test.ts +0 -55
  187. package/src/auth/jose-token-service.ts +0 -62
  188. package/src/auth/jwt-claims-passthrough.test.ts +0 -87
  189. package/src/auth/login.test.ts +0 -100
  190. package/src/auth/login.ts +0 -78
  191. package/src/auth/refresh.ts +0 -11
  192. package/src/auth/token-service.test.ts +0 -90
  193. package/src/factory.ts +0 -368
  194. package/src/features/automations/__tests__/action-executors.test.ts +0 -255
  195. package/src/features/automations/__tests__/automation-runner.test.ts +0 -196
  196. package/src/features/automations/__tests__/automation-runner.utils.test.ts +0 -60
  197. package/src/features/automations/__tests__/automations.handler.test.ts +0 -264
  198. package/src/features/automations/__tests__/automations.repository.test.ts +0 -163
  199. package/src/features/automations/__tests__/automations.schema.test.ts +0 -224
  200. package/src/features/automations/__tests__/context-resolver.test.ts +0 -126
  201. package/src/features/automations/__tests__/cron-runner.test.ts +0 -267
  202. package/src/features/automations/__tests__/cron-runner.utils.test.ts +0 -144
  203. package/src/features/automations/__tests__/set-variable.executor.test.ts +0 -383
  204. package/src/features/automations/__tests__/template-grammar.test.ts +0 -308
  205. package/src/features/automations/__tests__/webhook.executor.test.ts +0 -142
  206. package/src/features/automations/__tests__/when-evaluator.test.ts +0 -274
  207. package/src/features/automations/__tests__/when-pushdown.test.ts +0 -281
  208. package/src/features/automations/action-executors/create-entry.executor.ts +0 -27
  209. package/src/features/automations/action-executors/edit-field.executor.ts +0 -26
  210. package/src/features/automations/action-executors/index.ts +0 -37
  211. package/src/features/automations/action-executors/send-mail.executor.ts +0 -53
  212. package/src/features/automations/action-executors/set-variable.executor.ts +0 -159
  213. package/src/features/automations/action-executors/webhook.executor.ts +0 -67
  214. package/src/features/automations/automation-runner.ts +0 -85
  215. package/src/features/automations/automation-runner.utils.ts +0 -47
  216. package/src/features/automations/automations.handler.ts +0 -197
  217. package/src/features/automations/automations.schema.ts +0 -177
  218. package/src/features/automations/context-resolver.ts +0 -152
  219. package/src/features/automations/cron-runner.ts +0 -140
  220. package/src/features/automations/cron-runner.utils.ts +0 -44
  221. package/src/features/automations/filter-translation.ts +0 -46
  222. package/src/features/automations/index.ts +0 -16
  223. package/src/features/automations/template-grammar.ts +0 -245
  224. package/src/features/automations/var-access-resolver.ts +0 -140
  225. package/src/features/automations/when-evaluator.ts +0 -87
  226. package/src/features/automations/when-pushdown.ts +0 -57
  227. package/src/features/backrefs/__tests__/backrefs.handler.test.ts +0 -359
  228. package/src/features/backrefs/backrefs.handler.ts +0 -168
  229. package/src/features/backrefs/d1-backref.repository.ts +0 -84
  230. package/src/features/backrefs/index.ts +0 -5
  231. package/src/features/content/constants.ts +0 -16
  232. package/src/features/content/handlers/bulk.handler.ts +0 -185
  233. package/src/features/content/handlers/create.ts +0 -129
  234. package/src/features/content/handlers/delete.ts +0 -62
  235. package/src/features/content/handlers/facets.ts +0 -49
  236. package/src/features/content/handlers/get.ts +0 -120
  237. package/src/features/content/handlers/helpers.test.ts +0 -180
  238. package/src/features/content/handlers/helpers.ts +0 -93
  239. package/src/features/content/handlers/list.ts +0 -174
  240. package/src/features/content/handlers/update.ts +0 -174
  241. package/src/features/content/index.ts +0 -26
  242. package/src/features/draft/draft.handler.ts +0 -195
  243. package/src/features/draft/draft.middleware.ts +0 -66
  244. package/src/features/draft/index.ts +0 -5
  245. package/src/features/email/email.service.ts +0 -98
  246. package/src/features/email/email.types.ts +0 -119
  247. package/src/features/email/providers/resend.ts +0 -67
  248. package/src/features/email/providers/smtp.ts +0 -55
  249. package/src/features/email/templates/automation-mail.ts +0 -19
  250. package/src/features/email/templates/password-changed.ts +0 -63
  251. package/src/features/email/templates/password-reset.ts +0 -68
  252. package/src/features/email/templates/shell.ts +0 -96
  253. package/src/features/notifications/index.ts +0 -5
  254. package/src/features/notifications/notifications.handler.ts +0 -105
  255. package/src/features/password-reset/index.ts +0 -19
  256. package/src/features/password-reset/request.ts +0 -92
  257. package/src/features/password-reset/reset.ts +0 -102
  258. package/src/features/rotate-field/index.ts +0 -5
  259. package/src/features/rotate-field/rotate-field.handler.ts +0 -132
  260. package/src/features/rotate-field/rotate-field.schema.ts +0 -17
  261. package/src/features/schema/schema.handler.ts +0 -131
  262. package/src/features/seeds/index.ts +0 -5
  263. package/src/features/seeds/seeds.handler.test.ts +0 -632
  264. package/src/features/seeds/seeds.handler.ts +0 -693
  265. package/src/features/settings/__tests__/settings.handler.test.ts +0 -555
  266. package/src/features/settings/settings.handler.ts +0 -392
  267. package/src/features/setup/index.ts +0 -204
  268. package/src/features/stats/index.ts +0 -5
  269. package/src/features/stats/stats.handler.ts +0 -420
  270. package/src/features/webhooks/index.ts +0 -63
  271. package/src/index.ts +0 -65
  272. package/src/media-utils.ts +0 -82
  273. package/src/middleware/auth-providers.middleware.ts +0 -45
  274. package/src/middleware/observability.middleware.ts +0 -70
  275. package/src/middleware/rate-limit.middleware.ts +0 -45
  276. package/src/middleware/repository.middleware.ts +0 -114
  277. package/src/middleware/seed-registry.middleware.test.ts +0 -97
  278. package/src/middleware/seed-registry.middleware.ts +0 -21
  279. package/src/middleware/storage.middleware.ts +0 -25
  280. package/src/middleware.ts +0 -45
  281. package/src/public/access-policy.ts +0 -27
  282. package/src/public/api-key-middleware.ts +0 -57
  283. package/src/public/cache-utils.ts +0 -38
  284. package/src/public/entry-projection.ts +0 -46
  285. package/src/public/idempotency.ts +0 -23
  286. package/src/public/index.ts +0 -16
  287. package/src/public/problem-details.ts +0 -124
  288. package/src/public/public-add.ts +0 -114
  289. package/src/public/public-edit.ts +0 -163
  290. package/src/public/public-errors.ts +0 -19
  291. package/src/public/public-read.ts +0 -63
  292. package/src/public/public-routes.ts +0 -88
  293. package/src/public/query-builder.test.ts +0 -224
  294. package/src/public/query-builder.ts +0 -156
  295. package/src/public/rate-limit-middleware.ts +0 -34
  296. package/src/public/read-list.ts +0 -54
  297. package/src/public/read-single.ts +0 -48
  298. package/src/public/response-builder.ts +0 -30
  299. package/src/public/sanitize.ts +0 -69
  300. package/src/public/slug-utils.ts +0 -18
  301. package/src/rate-limit/cloudflare-rate-limiter.test.ts +0 -30
  302. package/src/rate-limit/cloudflare-rate-limiter.ts +0 -15
  303. package/src/rate-limit/in-memory-rate-limiter.test.ts +0 -37
  304. package/src/rate-limit/in-memory-rate-limiter.ts +0 -17
  305. package/src/rate-limit/no-op-rate-limiter.test.ts +0 -22
  306. package/src/rate-limit/no-op-rate-limiter.ts +0 -11
  307. package/src/search-utils.test.ts +0 -211
  308. package/src/search-utils.ts +0 -213
  309. package/src/search.ts +0 -65
  310. package/src/shared/apply-policies.test.ts +0 -81
  311. package/src/shared/apply-policies.ts +0 -67
  312. package/src/shared/automations.repository.d1.ts +0 -150
  313. package/src/shared/background-notification-service.test.ts +0 -62
  314. package/src/shared/background-notification-service.ts +0 -52
  315. package/src/shared/base.repository.d1.ts +0 -32
  316. package/src/shared/content-utils.test.ts +0 -165
  317. package/src/shared/content-utils.ts +0 -86
  318. package/src/shared/content.repository.d1.test.ts +0 -458
  319. package/src/shared/content.repository.d1.ts +0 -851
  320. package/src/shared/d1-activity-log.repository.test.ts +0 -140
  321. package/src/shared/d1-activity-log.repository.ts +0 -105
  322. package/src/shared/d1-activity-logger.test.ts +0 -86
  323. package/src/shared/d1-activity-logger.ts +0 -67
  324. package/src/shared/d1-analytics.repository.test.ts +0 -78
  325. package/src/shared/d1-analytics.repository.ts +0 -85
  326. package/src/shared/d1-content-scan.repository.test.ts +0 -80
  327. package/src/shared/d1-content-scan.repository.ts +0 -37
  328. package/src/shared/d1-notification.repository.test.ts +0 -128
  329. package/src/shared/d1-notification.repository.ts +0 -118
  330. package/src/shared/d1-password-reset-token.repository.test.ts +0 -81
  331. package/src/shared/d1-password-reset-token.repository.ts +0 -56
  332. package/src/shared/d1-search.repository.test.ts +0 -87
  333. package/src/shared/d1-search.repository.ts +0 -88
  334. package/src/shared/d1-session.repository.test.ts +0 -125
  335. package/src/shared/d1-session.repository.ts +0 -102
  336. package/src/shared/d1-setup-checklist.repository.ts +0 -36
  337. package/src/shared/d1-user.repository.test.ts +0 -151
  338. package/src/shared/d1-user.repository.ts +0 -119
  339. package/src/shared/d1-widget.repository.test.ts +0 -221
  340. package/src/shared/d1-widget.repository.ts +0 -341
  341. package/src/shared/demo-data-sql.ts +0 -54
  342. package/src/shared/demo-data.repository.d1.ts +0 -20
  343. package/src/shared/execution-context-scheduler.ts +0 -13
  344. package/src/shared/fixed-clock.ts +0 -25
  345. package/src/shared/fts-sync.ts +0 -8
  346. package/src/shared/idempotency.repository.d1.test.ts +0 -83
  347. package/src/shared/idempotency.repository.d1.ts +0 -60
  348. package/src/shared/in-memory-activity-logger.ts +0 -19
  349. package/src/shared/in-memory-notification-service.ts +0 -19
  350. package/src/shared/in-memory-seed.repository.ts +0 -51
  351. package/src/shared/media.repository.d1.test.ts +0 -107
  352. package/src/shared/media.repository.d1.ts +0 -68
  353. package/src/shared/qstash-notification-service.test.ts +0 -67
  354. package/src/shared/qstash-notification-service.ts +0 -55
  355. package/src/shared/query-utils.ts +0 -141
  356. package/src/shared/request-utils.ts +0 -26
  357. package/src/shared/schema-mutator.d1.ts +0 -64
  358. package/src/shared/seed-layout.repository.d1.test.ts +0 -114
  359. package/src/shared/seed-layout.repository.d1.ts +0 -62
  360. package/src/shared/seed-registry-cache.test.ts +0 -68
  361. package/src/shared/seed-registry-cache.ts +0 -49
  362. package/src/shared/seed.repository.d1.test.ts +0 -143
  363. package/src/shared/seed.repository.d1.ts +0 -98
  364. package/src/shared/sequential-id-generator.ts +0 -33
  365. package/src/shared/site-settings.repository.d1.ts +0 -53
  366. package/src/shared/storage/factory.ts +0 -41
  367. package/src/shared/storage/s3-bucket.ts +0 -195
  368. package/src/shared/storage-utils.ts +0 -40
  369. package/src/shared/system-stats.repository.d1.test.ts +0 -58
  370. package/src/shared/system-stats.repository.d1.ts +0 -48
  371. package/src/types.ts +0 -87
  372. package/src/upload.ts +0 -198
  373. package/src/widget.ts +0 -212
@@ -1,265 +1,265 @@
1
- -- =============================================================================
2
- -- Beech CMS v0.4.0 — Base Schema
3
- --
4
- -- Single migration for fresh installations. Creates all system tables.
5
- --
6
- -- Content tables (content_{slug}, fts_{slug}, content_{slug}_drafts) are
7
- -- NOT defined here — they are generated at deploy time by: beech seed:load
8
- -- FTS indexes text + richtext branches (policies.search !== false).
9
- --
10
- -- Usage:
11
- -- wrangler d1 execute beech-db --file=migrations/0000_v040_base.sql (remote)
12
- -- wrangler d1 execute beech-db --local --file=migrations/0000_v040_base.sql (local)
13
- --
14
- -- After this migration, run:
15
- -- beech seed:load → creates content_{slug} tables + FTS + triggers
16
- -- POST /auth/setup → creates first admin user
17
- -- =============================================================================
18
-
19
-
20
- -- =============================================================================
21
- -- 1. USERS
22
- -- Dashboard users (admins + editors). Passwords stored as bcrypt hashes.
23
- -- Profile fields (name, avatar_url, notification_prefs) merged in from
24
- -- the start — no incremental ALTER TABLE needed.
25
- -- =============================================================================
26
-
27
- CREATE TABLE IF NOT EXISTS users (
28
- id TEXT NOT NULL PRIMARY KEY,
29
- email TEXT NOT NULL UNIQUE,
30
- password_hash TEXT NOT NULL,
31
- role TEXT NOT NULL DEFAULT 'editor' CHECK (role IN ('admin', 'editor')),
32
- name TEXT,
33
- surname TEXT,
34
- avatar_url TEXT,
35
- notification_prefs TEXT NOT NULL DEFAULT '{}',
36
- created_at INTEGER NOT NULL DEFAULT (unixepoch())
37
- );
38
-
39
-
40
- -- =============================================================================
41
- -- 2. REFRESH TOKENS
42
- -- JWT refresh token rotation. Stored as SHA-256 hashes, never plaintext.
43
- -- revoked_at IS NULL = active token.
44
- -- =============================================================================
45
-
46
- CREATE TABLE IF NOT EXISTS refresh_tokens (
47
- id TEXT NOT NULL PRIMARY KEY,
48
- user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
49
- token_hash TEXT NOT NULL,
50
- expires_at INTEGER NOT NULL,
51
- created_at INTEGER NOT NULL DEFAULT (unixepoch()),
52
- revoked_at INTEGER DEFAULT NULL
53
- );
54
-
55
- CREATE INDEX IF NOT EXISTS idx_refresh_user ON refresh_tokens(user_id);
56
- CREATE INDEX IF NOT EXISTS idx_refresh_hash ON refresh_tokens(token_hash);
57
- CREATE INDEX IF NOT EXISTS idx_refresh_expires ON refresh_tokens(expires_at);
58
-
59
-
60
- -- =============================================================================
61
- -- 3. PASSWORD RESET TOKENS
62
- -- Single-use, 30-minute TTL, stored as SHA-256 hashes.
63
- -- used_at set on redemption to prevent replay attacks.
64
- -- =============================================================================
65
-
66
- CREATE TABLE IF NOT EXISTS password_reset_tokens (
67
- id TEXT NOT NULL PRIMARY KEY,
68
- user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
69
- token_hash TEXT NOT NULL,
70
- expires_at INTEGER NOT NULL,
71
- created_at INTEGER NOT NULL DEFAULT (unixepoch()),
72
- used_at INTEGER DEFAULT NULL
73
- );
74
-
75
- CREATE INDEX IF NOT EXISTS idx_prt_hash ON password_reset_tokens(token_hash);
76
- CREATE INDEX IF NOT EXISTS idx_prt_user ON password_reset_tokens(user_id);
77
-
78
-
79
- -- =============================================================================
80
- -- 4. PUBLIC API — IDEMPOTENCY KEYS
81
- -- Deduplicates POST requests from public consumers (e.g. contact forms).
82
- -- expires_at-based pruning keeps the table small.
83
- -- =============================================================================
84
-
85
- CREATE TABLE IF NOT EXISTS public_idempotency_keys (
86
- idempotency_key TEXT NOT NULL PRIMARY KEY,
87
- request_fingerprint TEXT NOT NULL,
88
- response_status INTEGER NOT NULL,
89
- response_body TEXT NOT NULL,
90
- created_at INTEGER NOT NULL,
91
- expires_at INTEGER NOT NULL
92
- );
93
-
94
- CREATE INDEX IF NOT EXISTS idx_idempotency_expires ON public_idempotency_keys(expires_at);
95
-
96
-
97
- -- =============================================================================
98
- -- 5. ANALYTICS
99
- -- Daily metric counters per seed and global (seed = '' sentinel).
100
- -- Metrics: 'requests' | 'visitors' | 'bandwidth_mb'
101
- -- =============================================================================
102
-
103
- CREATE TABLE IF NOT EXISTS analytics (
104
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
105
- day_ts INTEGER NOT NULL,
106
- metric TEXT NOT NULL,
107
- seed TEXT NOT NULL DEFAULT '',
108
- value INTEGER NOT NULL DEFAULT 0,
109
- UNIQUE(day_ts, metric, seed)
110
- );
111
-
112
- CREATE INDEX IF NOT EXISTS idx_analytics_day ON analytics(day_ts);
113
- CREATE INDEX IF NOT EXISTS idx_analytics_seed ON analytics(seed, day_ts);
114
-
115
-
116
- -- =============================================================================
117
- -- 6. SYSTEM STATS
118
- -- Persistent key-value store for system-level counters.
119
- -- 'total_storage_bytes' is kept for dashboard widgets;
120
- -- SUM(size_bytes) FROM media_objects is the authoritative source.
121
- -- =============================================================================
122
-
123
- CREATE TABLE IF NOT EXISTS system_stats (
124
- id TEXT NOT NULL PRIMARY KEY,
125
- value TEXT NOT NULL
126
- );
127
-
128
- INSERT OR IGNORE INTO system_stats (id, value) VALUES ('total_storage_bytes', '0');
129
-
130
-
131
- -- =============================================================================
132
- -- 7. ACTIVITY LOGS
133
- -- Append-only audit log. No FK on user_id — deleted users are retained
134
- -- for compliance. user_name denormalized to survive user deletions.
135
- -- Actions: 'create' | 'update' | 'delete' | 'upload'
136
- -- Entity types: 'content' | 'media'
137
- -- =============================================================================
138
-
139
- CREATE TABLE IF NOT EXISTS activity_logs (
140
- id TEXT NOT NULL PRIMARY KEY,
141
- user_id TEXT NOT NULL,
142
- user_email TEXT NOT NULL,
143
- user_name TEXT,
144
- action TEXT NOT NULL,
145
- entity_type TEXT NOT NULL,
146
- entity_id TEXT NOT NULL,
147
- entity_slug TEXT,
148
- details TEXT,
149
- created_at INTEGER NOT NULL DEFAULT (unixepoch())
150
- );
151
-
152
- CREATE INDEX IF NOT EXISTS idx_activity_user ON activity_logs(user_id);
153
- CREATE INDEX IF NOT EXISTS idx_activity_created ON activity_logs(created_at);
154
-
155
-
156
- -- =============================================================================
157
- -- 8. NOTIFICATIONS
158
- -- In-app notification inbox for system events (e.g. new form submission).
159
- -- is_read: 0 = unread, 1 = read.
160
- -- =============================================================================
161
-
162
- CREATE TABLE IF NOT EXISTS notifications (
163
- id TEXT NOT NULL PRIMARY KEY,
164
- title TEXT NOT NULL,
165
- message TEXT NOT NULL,
166
- type TEXT NOT NULL DEFAULT 'info' CHECK (type IN ('info', 'warning', 'error')),
167
- is_read INTEGER NOT NULL DEFAULT 0 CHECK (is_read IN (0, 1)),
168
- created_at INTEGER NOT NULL DEFAULT (unixepoch())
169
- );
170
-
171
- CREATE INDEX IF NOT EXISTS idx_notifications_created ON notifications(created_at);
172
- CREATE INDEX IF NOT EXISTS idx_notifications_unread ON notifications(is_read);
173
-
174
-
175
- -- =============================================================================
176
- -- 9. MEDIA OBJECTS
177
- -- Tracks every file uploaded to R2. Enables media library UI, orphan
178
- -- detection, and storage reporting. No FK on uploaded_by for D1 portability.
179
- -- =============================================================================
180
-
181
- CREATE TABLE IF NOT EXISTS media_objects (
182
- key TEXT NOT NULL PRIMARY KEY,
183
- filename TEXT NOT NULL,
184
- mime_type TEXT NOT NULL,
185
- size_bytes INTEGER NOT NULL,
186
- uploaded_by TEXT NOT NULL DEFAULT '',
187
- created_at INTEGER NOT NULL DEFAULT (unixepoch())
188
- );
189
-
190
- CREATE INDEX IF NOT EXISTS idx_media_user ON media_objects(uploaded_by);
191
- CREATE INDEX IF NOT EXISTS idx_media_created ON media_objects(created_at DESC);
192
-
193
-
194
- -- =============================================================================
195
- -- 10. CONTENT EVENT LOG
196
- -- Lightweight event log for activity feed and dashboard stats.
197
- -- Does NOT store field data — only event metadata (who did what, when).
198
- -- Replaces the legacy content_entries table as cross-seed event source.
199
- -- The actual content lives in content_{slug} tables (created by seed:load).
200
- -- =============================================================================
201
-
202
- CREATE TABLE IF NOT EXISTS content_event_log (
203
- id TEXT NOT NULL PRIMARY KEY,
204
- schema_slug TEXT NOT NULL,
205
- entry_id TEXT NOT NULL,
206
- action TEXT NOT NULL CHECK (action IN ('create', 'update', 'delete')),
207
- user_id TEXT,
208
- details TEXT,
209
- created_at INTEGER NOT NULL DEFAULT (unixepoch())
210
- );
211
-
212
- CREATE INDEX IF NOT EXISTS idx_event_log_schema_slug ON content_event_log(schema_slug);
213
- CREATE INDEX IF NOT EXISTS idx_event_log_created_at ON content_event_log(created_at DESC);
214
- CREATE INDEX IF NOT EXISTS idx_event_log_entry_id ON content_event_log(entry_id);
215
-
216
-
217
- -- =============================================================================
218
- -- 11. AUTOMATIONS
219
- -- Event-driven automation rules. Each automation defines one or more
220
- -- triggers (JSON array of {event, cron?}), optional WhenNode conditions,
221
- -- and a sequence of actions to execute.
222
- -- triggers: [{ event: 'create'|'update'|'delete'|'cron', cron?: string }]
223
- -- Max one cron trigger per automation, enforced at the application layer.
224
- -- =============================================================================
225
-
226
- CREATE TABLE IF NOT EXISTS automations (
227
- id TEXT NOT NULL PRIMARY KEY,
228
- seed_slug TEXT NOT NULL,
229
- name TEXT NOT NULL,
230
- enabled INTEGER NOT NULL DEFAULT 1,
231
- triggers TEXT NOT NULL DEFAULT '[]',
232
- trigger_conditions TEXT,
233
- actions TEXT NOT NULL,
234
- created_at INTEGER NOT NULL DEFAULT (unixepoch()),
235
- updated_at INTEGER NOT NULL DEFAULT (unixepoch())
236
- );
237
-
238
- CREATE INDEX IF NOT EXISTS idx_automations_seed_slug ON automations(seed_slug);
239
- CREATE INDEX IF NOT EXISTS idx_automations_enabled ON automations(enabled);
240
-
241
-
242
- -- =============================================================================
243
- -- 12. SITE SETTINGS
244
- -- Key-value store for site-level configuration (title, locale, timezone…).
245
- -- =============================================================================
246
-
247
- CREATE TABLE IF NOT EXISTS site_settings (
248
- key TEXT NOT NULL PRIMARY KEY,
249
- value TEXT NOT NULL
250
- );
251
-
252
-
253
- -- =============================================================================
254
- -- 13. SEED LAYOUTS
255
- -- Persists per-Seed custom editor form layouts (sprint 04a).
256
- -- layout column stores a FormLayout JSON blob.
257
- -- Reset = DELETE the row; client recomputes the generated default.
258
- -- =============================================================================
259
-
260
- CREATE TABLE IF NOT EXISTS seed_layouts (
261
- slug TEXT NOT NULL PRIMARY KEY,
262
- layout TEXT NOT NULL, -- JSON of FormLayout
263
- updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
264
- updated_by TEXT NOT NULL -- users.id of the writer
265
- );
1
+ -- =============================================================================
2
+ -- Beech CMS v0.4.0 — Base Schema
3
+ --
4
+ -- Single migration for fresh installations. Creates all system tables.
5
+ --
6
+ -- Content tables (content_{slug}, fts_{slug}, content_{slug}_drafts) are
7
+ -- NOT defined here — they are generated at deploy time by: beech seed:load
8
+ -- FTS indexes text + richtext branches (policies.search !== false).
9
+ --
10
+ -- Usage:
11
+ -- wrangler d1 execute beech-db --file=migrations/0000_v040_base.sql (remote)
12
+ -- wrangler d1 execute beech-db --local --file=migrations/0000_v040_base.sql (local)
13
+ --
14
+ -- After this migration, run:
15
+ -- beech seed:load → creates content_{slug} tables + FTS + triggers
16
+ -- POST /auth/setup → creates first admin user
17
+ -- =============================================================================
18
+
19
+
20
+ -- =============================================================================
21
+ -- 1. USERS
22
+ -- Dashboard users (admins + editors). Passwords stored as bcrypt hashes.
23
+ -- Profile fields (name, avatar_url, notification_prefs) merged in from
24
+ -- the start — no incremental ALTER TABLE needed.
25
+ -- =============================================================================
26
+
27
+ CREATE TABLE IF NOT EXISTS users (
28
+ id TEXT NOT NULL PRIMARY KEY,
29
+ email TEXT NOT NULL UNIQUE,
30
+ password_hash TEXT NOT NULL,
31
+ role TEXT NOT NULL DEFAULT 'editor' CHECK (role IN ('admin', 'editor')),
32
+ name TEXT,
33
+ surname TEXT,
34
+ avatar_url TEXT,
35
+ notification_prefs TEXT NOT NULL DEFAULT '{}',
36
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
37
+ );
38
+
39
+
40
+ -- =============================================================================
41
+ -- 2. REFRESH TOKENS
42
+ -- JWT refresh token rotation. Stored as SHA-256 hashes, never plaintext.
43
+ -- revoked_at IS NULL = active token.
44
+ -- =============================================================================
45
+
46
+ CREATE TABLE IF NOT EXISTS refresh_tokens (
47
+ id TEXT NOT NULL PRIMARY KEY,
48
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
49
+ token_hash TEXT NOT NULL,
50
+ expires_at INTEGER NOT NULL,
51
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
52
+ revoked_at INTEGER DEFAULT NULL
53
+ );
54
+
55
+ CREATE INDEX IF NOT EXISTS idx_refresh_user ON refresh_tokens(user_id);
56
+ CREATE INDEX IF NOT EXISTS idx_refresh_hash ON refresh_tokens(token_hash);
57
+ CREATE INDEX IF NOT EXISTS idx_refresh_expires ON refresh_tokens(expires_at);
58
+
59
+
60
+ -- =============================================================================
61
+ -- 3. PASSWORD RESET TOKENS
62
+ -- Single-use, 30-minute TTL, stored as SHA-256 hashes.
63
+ -- used_at set on redemption to prevent replay attacks.
64
+ -- =============================================================================
65
+
66
+ CREATE TABLE IF NOT EXISTS password_reset_tokens (
67
+ id TEXT NOT NULL PRIMARY KEY,
68
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
69
+ token_hash TEXT NOT NULL,
70
+ expires_at INTEGER NOT NULL,
71
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
72
+ used_at INTEGER DEFAULT NULL
73
+ );
74
+
75
+ CREATE INDEX IF NOT EXISTS idx_prt_hash ON password_reset_tokens(token_hash);
76
+ CREATE INDEX IF NOT EXISTS idx_prt_user ON password_reset_tokens(user_id);
77
+
78
+
79
+ -- =============================================================================
80
+ -- 4. PUBLIC API — IDEMPOTENCY KEYS
81
+ -- Deduplicates POST requests from public consumers (e.g. contact forms).
82
+ -- expires_at-based pruning keeps the table small.
83
+ -- =============================================================================
84
+
85
+ CREATE TABLE IF NOT EXISTS public_idempotency_keys (
86
+ idempotency_key TEXT NOT NULL PRIMARY KEY,
87
+ request_fingerprint TEXT NOT NULL,
88
+ response_status INTEGER NOT NULL,
89
+ response_body TEXT NOT NULL,
90
+ created_at INTEGER NOT NULL,
91
+ expires_at INTEGER NOT NULL
92
+ );
93
+
94
+ CREATE INDEX IF NOT EXISTS idx_idempotency_expires ON public_idempotency_keys(expires_at);
95
+
96
+
97
+ -- =============================================================================
98
+ -- 5. ANALYTICS
99
+ -- Daily metric counters per seed and global (seed = '' sentinel).
100
+ -- Metrics: 'requests' | 'visitors' | 'bandwidth_mb'
101
+ -- =============================================================================
102
+
103
+ CREATE TABLE IF NOT EXISTS analytics (
104
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
105
+ day_ts INTEGER NOT NULL,
106
+ metric TEXT NOT NULL,
107
+ seed TEXT NOT NULL DEFAULT '',
108
+ value INTEGER NOT NULL DEFAULT 0,
109
+ UNIQUE(day_ts, metric, seed)
110
+ );
111
+
112
+ CREATE INDEX IF NOT EXISTS idx_analytics_day ON analytics(day_ts);
113
+ CREATE INDEX IF NOT EXISTS idx_analytics_seed ON analytics(seed, day_ts);
114
+
115
+
116
+ -- =============================================================================
117
+ -- 6. SYSTEM STATS
118
+ -- Persistent key-value store for system-level counters.
119
+ -- 'total_storage_bytes' is kept for dashboard widgets;
120
+ -- SUM(size_bytes) FROM media_objects is the authoritative source.
121
+ -- =============================================================================
122
+
123
+ CREATE TABLE IF NOT EXISTS system_stats (
124
+ id TEXT NOT NULL PRIMARY KEY,
125
+ value TEXT NOT NULL
126
+ );
127
+
128
+ INSERT OR IGNORE INTO system_stats (id, value) VALUES ('total_storage_bytes', '0');
129
+
130
+
131
+ -- =============================================================================
132
+ -- 7. ACTIVITY LOGS
133
+ -- Append-only audit log. No FK on user_id — deleted users are retained
134
+ -- for compliance. user_name denormalized to survive user deletions.
135
+ -- Actions: 'create' | 'update' | 'delete' | 'upload'
136
+ -- Entity types: 'content' | 'media'
137
+ -- =============================================================================
138
+
139
+ CREATE TABLE IF NOT EXISTS activity_logs (
140
+ id TEXT NOT NULL PRIMARY KEY,
141
+ user_id TEXT NOT NULL,
142
+ user_email TEXT NOT NULL,
143
+ user_name TEXT,
144
+ action TEXT NOT NULL,
145
+ entity_type TEXT NOT NULL,
146
+ entity_id TEXT NOT NULL,
147
+ entity_slug TEXT,
148
+ details TEXT,
149
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
150
+ );
151
+
152
+ CREATE INDEX IF NOT EXISTS idx_activity_user ON activity_logs(user_id);
153
+ CREATE INDEX IF NOT EXISTS idx_activity_created ON activity_logs(created_at);
154
+
155
+
156
+ -- =============================================================================
157
+ -- 8. NOTIFICATIONS
158
+ -- In-app notification inbox for system events (e.g. new form submission).
159
+ -- is_read: 0 = unread, 1 = read.
160
+ -- =============================================================================
161
+
162
+ CREATE TABLE IF NOT EXISTS notifications (
163
+ id TEXT NOT NULL PRIMARY KEY,
164
+ title TEXT NOT NULL,
165
+ message TEXT NOT NULL,
166
+ type TEXT NOT NULL DEFAULT 'info' CHECK (type IN ('info', 'warning', 'error')),
167
+ is_read INTEGER NOT NULL DEFAULT 0 CHECK (is_read IN (0, 1)),
168
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
169
+ );
170
+
171
+ CREATE INDEX IF NOT EXISTS idx_notifications_created ON notifications(created_at);
172
+ CREATE INDEX IF NOT EXISTS idx_notifications_unread ON notifications(is_read);
173
+
174
+
175
+ -- =============================================================================
176
+ -- 9. MEDIA OBJECTS
177
+ -- Tracks every file uploaded to R2. Enables media library UI, orphan
178
+ -- detection, and storage reporting. No FK on uploaded_by for D1 portability.
179
+ -- =============================================================================
180
+
181
+ CREATE TABLE IF NOT EXISTS media_objects (
182
+ key TEXT NOT NULL PRIMARY KEY,
183
+ filename TEXT NOT NULL,
184
+ mime_type TEXT NOT NULL,
185
+ size_bytes INTEGER NOT NULL,
186
+ uploaded_by TEXT NOT NULL DEFAULT '',
187
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
188
+ );
189
+
190
+ CREATE INDEX IF NOT EXISTS idx_media_user ON media_objects(uploaded_by);
191
+ CREATE INDEX IF NOT EXISTS idx_media_created ON media_objects(created_at DESC);
192
+
193
+
194
+ -- =============================================================================
195
+ -- 10. CONTENT EVENT LOG
196
+ -- Lightweight event log for activity feed and dashboard stats.
197
+ -- Does NOT store field data — only event metadata (who did what, when).
198
+ -- Replaces the legacy content_entries table as cross-seed event source.
199
+ -- The actual content lives in content_{slug} tables (created by seed:load).
200
+ -- =============================================================================
201
+
202
+ CREATE TABLE IF NOT EXISTS content_event_log (
203
+ id TEXT NOT NULL PRIMARY KEY,
204
+ schema_slug TEXT NOT NULL,
205
+ entry_id TEXT NOT NULL,
206
+ action TEXT NOT NULL CHECK (action IN ('create', 'update', 'delete')),
207
+ user_id TEXT,
208
+ details TEXT,
209
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
210
+ );
211
+
212
+ CREATE INDEX IF NOT EXISTS idx_event_log_schema_slug ON content_event_log(schema_slug);
213
+ CREATE INDEX IF NOT EXISTS idx_event_log_created_at ON content_event_log(created_at DESC);
214
+ CREATE INDEX IF NOT EXISTS idx_event_log_entry_id ON content_event_log(entry_id);
215
+
216
+
217
+ -- =============================================================================
218
+ -- 11. AUTOMATIONS
219
+ -- Event-driven automation rules. Each automation defines one or more
220
+ -- triggers (JSON array of {event, cron?}), optional WhenNode conditions,
221
+ -- and a sequence of actions to execute.
222
+ -- triggers: [{ event: 'create'|'update'|'delete'|'cron', cron?: string }]
223
+ -- Max one cron trigger per automation, enforced at the application layer.
224
+ -- =============================================================================
225
+
226
+ CREATE TABLE IF NOT EXISTS automations (
227
+ id TEXT NOT NULL PRIMARY KEY,
228
+ seed_slug TEXT NOT NULL,
229
+ name TEXT NOT NULL,
230
+ enabled INTEGER NOT NULL DEFAULT 1,
231
+ triggers TEXT NOT NULL DEFAULT '[]',
232
+ trigger_conditions TEXT,
233
+ actions TEXT NOT NULL,
234
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
235
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
236
+ );
237
+
238
+ CREATE INDEX IF NOT EXISTS idx_automations_seed_slug ON automations(seed_slug);
239
+ CREATE INDEX IF NOT EXISTS idx_automations_enabled ON automations(enabled);
240
+
241
+
242
+ -- =============================================================================
243
+ -- 12. SITE SETTINGS
244
+ -- Key-value store for site-level configuration (title, locale, timezone…).
245
+ -- =============================================================================
246
+
247
+ CREATE TABLE IF NOT EXISTS site_settings (
248
+ key TEXT NOT NULL PRIMARY KEY,
249
+ value TEXT NOT NULL
250
+ );
251
+
252
+
253
+ -- =============================================================================
254
+ -- 13. SEED LAYOUTS
255
+ -- Persists per-Seed custom editor form layouts (sprint 04a).
256
+ -- layout column stores a FormLayout JSON blob.
257
+ -- Reset = DELETE the row; client recomputes the generated default.
258
+ -- =============================================================================
259
+
260
+ CREATE TABLE IF NOT EXISTS seed_layouts (
261
+ slug TEXT NOT NULL PRIMARY KEY,
262
+ layout TEXT NOT NULL, -- JSON of FormLayout
263
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
264
+ updated_by TEXT NOT NULL -- users.id of the writer
265
+ );
@@ -1,14 +1,14 @@
1
- CREATE TABLE IF NOT EXISTS automations (
2
- id TEXT NOT NULL PRIMARY KEY,
3
- seed_slug TEXT NOT NULL,
4
- name TEXT NOT NULL,
5
- enabled INTEGER NOT NULL DEFAULT 1,
6
- triggers TEXT NOT NULL DEFAULT '[]',
7
- trigger_conditions TEXT,
8
- actions TEXT NOT NULL,
9
- created_at INTEGER NOT NULL DEFAULT (unixepoch()),
10
- updated_at INTEGER NOT NULL DEFAULT (unixepoch())
11
- );
12
-
13
- CREATE INDEX IF NOT EXISTS idx_automations_seed_slug ON automations(seed_slug);
14
- CREATE INDEX IF NOT EXISTS idx_automations_enabled ON automations(enabled);
1
+ CREATE TABLE IF NOT EXISTS automations (
2
+ id TEXT NOT NULL PRIMARY KEY,
3
+ seed_slug TEXT NOT NULL,
4
+ name TEXT NOT NULL,
5
+ enabled INTEGER NOT NULL DEFAULT 1,
6
+ triggers TEXT NOT NULL DEFAULT '[]',
7
+ trigger_conditions TEXT,
8
+ actions TEXT NOT NULL,
9
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
10
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
11
+ );
12
+
13
+ CREATE INDEX IF NOT EXISTS idx_automations_seed_slug ON automations(seed_slug);
14
+ CREATE INDEX IF NOT EXISTS idx_automations_enabled ON automations(enabled);