@aphexcms/cms-core 9.5.2 → 9.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/dist/api/documents.d.ts +28 -0
  2. package/dist/api/documents.d.ts.map +1 -1
  3. package/dist/api/documents.js +18 -0
  4. package/dist/api/schemas/documents.d.ts +19 -0
  5. package/dist/api/schemas/documents.d.ts.map +1 -1
  6. package/dist/api/schemas/documents.js +18 -0
  7. package/dist/client/api.d.ts +2 -0
  8. package/dist/client/api.d.ts.map +1 -0
  9. package/dist/client/api.js +11 -0
  10. package/dist/client/ui.d.ts +25 -0
  11. package/dist/client/ui.d.ts.map +1 -0
  12. package/dist/client/ui.js +53 -0
  13. package/dist/components/admin/ActivityView.svelte +227 -0
  14. package/dist/components/admin/ActivityView.svelte.d.ts +4 -0
  15. package/dist/components/admin/ActivityView.svelte.d.ts.map +1 -0
  16. package/dist/components/admin/DocumentEditor.svelte +197 -11
  17. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  18. package/dist/components/admin/ScheduleDialog.svelte +174 -0
  19. package/dist/components/admin/ScheduleDialog.svelte.d.ts +20 -0
  20. package/dist/components/admin/ScheduleDialog.svelte.d.ts.map +1 -0
  21. package/dist/components/admin/fields/ArrayField.svelte +10 -2
  22. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
  23. package/dist/components/layout/OrganizationSwitcher.svelte +3 -3
  24. package/dist/components/layout/sidebar/NavUser.svelte +5 -5
  25. package/dist/db/interfaces/events.d.ts +55 -0
  26. package/dist/db/interfaces/events.d.ts.map +1 -0
  27. package/dist/db/interfaces/events.js +1 -0
  28. package/dist/db/interfaces/index.d.ts +10 -2
  29. package/dist/db/interfaces/index.d.ts.map +1 -1
  30. package/dist/db/interfaces/plugin-storage.d.ts +39 -0
  31. package/dist/db/interfaces/plugin-storage.d.ts.map +1 -0
  32. package/dist/db/interfaces/plugin-storage.js +1 -0
  33. package/dist/events/catalog.d.ts +8 -0
  34. package/dist/events/catalog.d.ts.map +1 -0
  35. package/dist/events/catalog.js +11 -0
  36. package/dist/events/consumer.d.ts +79 -0
  37. package/dist/events/consumer.d.ts.map +1 -0
  38. package/dist/events/consumer.js +76 -0
  39. package/dist/events/define-event.d.ts +17 -0
  40. package/dist/events/define-event.d.ts.map +1 -0
  41. package/dist/events/define-event.js +7 -0
  42. package/dist/events/emit.d.ts +11 -0
  43. package/dist/events/emit.d.ts.map +1 -0
  44. package/dist/events/emit.js +20 -0
  45. package/dist/events/index.d.ts +4 -0
  46. package/dist/events/index.d.ts.map +1 -0
  47. package/dist/events/index.js +3 -0
  48. package/dist/field-validation/rule.d.ts.map +1 -1
  49. package/dist/field-validation/rule.js +15 -0
  50. package/dist/field-validation/utils.d.ts.map +1 -1
  51. package/dist/field-validation/utils.js +7 -1
  52. package/dist/forms/define-form.d.ts +25 -0
  53. package/dist/forms/define-form.d.ts.map +1 -0
  54. package/dist/forms/define-form.js +22 -0
  55. package/dist/forms/index.d.ts +4 -0
  56. package/dist/forms/index.d.ts.map +1 -0
  57. package/dist/forms/index.js +5 -0
  58. package/dist/forms/types.d.ts +49 -0
  59. package/dist/forms/types.d.ts.map +1 -0
  60. package/dist/forms/types.js +1 -0
  61. package/dist/forms/validate.d.ts +9 -0
  62. package/dist/forms/validate.d.ts.map +1 -0
  63. package/dist/forms/validate.js +18 -0
  64. package/dist/hooks.d.ts.map +1 -1
  65. package/dist/hooks.js +15 -0
  66. package/dist/index.d.ts +2 -0
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +6 -0
  69. package/dist/jobs/document-jobs.d.ts +27 -0
  70. package/dist/jobs/document-jobs.d.ts.map +1 -0
  71. package/dist/jobs/document-jobs.js +42 -0
  72. package/dist/jobs/embedded-runner.d.ts +25 -0
  73. package/dist/jobs/embedded-runner.d.ts.map +1 -0
  74. package/dist/jobs/embedded-runner.js +46 -0
  75. package/dist/jobs/index.d.ts +7 -0
  76. package/dist/jobs/index.d.ts.map +1 -0
  77. package/dist/jobs/index.js +8 -0
  78. package/dist/jobs/relay.d.ts +27 -0
  79. package/dist/jobs/relay.d.ts.map +1 -0
  80. package/dist/jobs/relay.js +60 -0
  81. package/dist/jobs/run-batch.d.ts +52 -0
  82. package/dist/jobs/run-batch.d.ts.map +1 -0
  83. package/dist/jobs/run-batch.js +61 -0
  84. package/dist/jobs/run-due-jobs.d.ts +30 -0
  85. package/dist/jobs/run-due-jobs.d.ts.map +1 -0
  86. package/dist/jobs/run-due-jobs.js +69 -0
  87. package/dist/jobs/types.d.ts +18 -0
  88. package/dist/jobs/types.d.ts.map +1 -0
  89. package/dist/jobs/types.js +1 -0
  90. package/dist/lib/api/documents.d.ts +28 -0
  91. package/dist/lib/api/documents.d.ts.map +1 -1
  92. package/dist/lib/api/documents.js +18 -0
  93. package/dist/lib/api/documents.js.map +1 -1
  94. package/dist/lib/api/schemas/documents.d.ts +19 -0
  95. package/dist/lib/api/schemas/documents.d.ts.map +1 -1
  96. package/dist/lib/api/schemas/documents.js +18 -0
  97. package/dist/lib/api/schemas/documents.js.map +1 -1
  98. package/dist/lib/client/api.d.ts +2 -0
  99. package/dist/lib/client/api.d.ts.map +1 -0
  100. package/dist/lib/client/api.js +12 -0
  101. package/dist/lib/client/api.js.map +1 -0
  102. package/dist/lib/client/ui.d.ts +25 -0
  103. package/dist/lib/client/ui.d.ts.map +1 -0
  104. package/dist/lib/client/ui.js +54 -0
  105. package/dist/lib/client/ui.js.map +1 -0
  106. package/dist/lib/db/interfaces/events.d.ts +55 -0
  107. package/dist/lib/db/interfaces/events.d.ts.map +1 -0
  108. package/dist/lib/db/interfaces/events.js +2 -0
  109. package/dist/lib/db/interfaces/events.js.map +1 -0
  110. package/dist/lib/db/interfaces/index.d.ts +10 -2
  111. package/dist/lib/db/interfaces/index.d.ts.map +1 -1
  112. package/dist/lib/db/interfaces/plugin-storage.d.ts +39 -0
  113. package/dist/lib/db/interfaces/plugin-storage.d.ts.map +1 -0
  114. package/dist/lib/db/interfaces/plugin-storage.js +2 -0
  115. package/dist/lib/db/interfaces/plugin-storage.js.map +1 -0
  116. package/dist/lib/events/catalog.d.ts +8 -0
  117. package/dist/lib/events/catalog.d.ts.map +1 -0
  118. package/dist/lib/events/catalog.js +12 -0
  119. package/dist/lib/events/catalog.js.map +1 -0
  120. package/dist/lib/events/consumer.d.ts +79 -0
  121. package/dist/lib/events/consumer.d.ts.map +1 -0
  122. package/dist/lib/events/consumer.js +77 -0
  123. package/dist/lib/events/consumer.js.map +1 -0
  124. package/dist/lib/events/define-event.d.ts +17 -0
  125. package/dist/lib/events/define-event.d.ts.map +1 -0
  126. package/dist/lib/events/define-event.js +8 -0
  127. package/dist/lib/events/define-event.js.map +1 -0
  128. package/dist/lib/events/emit.d.ts +11 -0
  129. package/dist/lib/events/emit.d.ts.map +1 -0
  130. package/dist/lib/events/emit.js +21 -0
  131. package/dist/lib/events/emit.js.map +1 -0
  132. package/dist/lib/events/index.d.ts +4 -0
  133. package/dist/lib/events/index.d.ts.map +1 -0
  134. package/dist/lib/events/index.js +4 -0
  135. package/dist/lib/events/index.js.map +1 -0
  136. package/dist/lib/field-validation/rule.d.ts.map +1 -1
  137. package/dist/lib/field-validation/rule.js +15 -0
  138. package/dist/lib/field-validation/rule.js.map +1 -1
  139. package/dist/lib/field-validation/utils.d.ts.map +1 -1
  140. package/dist/lib/field-validation/utils.js +7 -1
  141. package/dist/lib/field-validation/utils.js.map +1 -1
  142. package/dist/lib/forms/define-form.d.ts +25 -0
  143. package/dist/lib/forms/define-form.d.ts.map +1 -0
  144. package/dist/lib/forms/define-form.js +23 -0
  145. package/dist/lib/forms/define-form.js.map +1 -0
  146. package/dist/lib/forms/index.d.ts +4 -0
  147. package/dist/lib/forms/index.d.ts.map +1 -0
  148. package/dist/lib/forms/index.js +6 -0
  149. package/dist/lib/forms/index.js.map +1 -0
  150. package/dist/lib/forms/types.d.ts +49 -0
  151. package/dist/lib/forms/types.d.ts.map +1 -0
  152. package/dist/lib/forms/types.js +2 -0
  153. package/dist/lib/forms/types.js.map +1 -0
  154. package/dist/lib/forms/validate.d.ts +9 -0
  155. package/dist/lib/forms/validate.d.ts.map +1 -0
  156. package/dist/lib/forms/validate.js +19 -0
  157. package/dist/lib/forms/validate.js.map +1 -0
  158. package/dist/lib/hooks.d.ts.map +1 -1
  159. package/dist/lib/hooks.js +15 -0
  160. package/dist/lib/hooks.js.map +1 -1
  161. package/dist/lib/index.d.ts +2 -0
  162. package/dist/lib/index.d.ts.map +1 -1
  163. package/dist/lib/index.js +6 -0
  164. package/dist/lib/index.js.map +1 -1
  165. package/dist/lib/jobs/document-jobs.d.ts +27 -0
  166. package/dist/lib/jobs/document-jobs.d.ts.map +1 -0
  167. package/dist/lib/jobs/document-jobs.js +43 -0
  168. package/dist/lib/jobs/document-jobs.js.map +1 -0
  169. package/dist/lib/jobs/embedded-runner.d.ts +25 -0
  170. package/dist/lib/jobs/embedded-runner.d.ts.map +1 -0
  171. package/dist/lib/jobs/embedded-runner.js +47 -0
  172. package/dist/lib/jobs/embedded-runner.js.map +1 -0
  173. package/dist/lib/jobs/index.d.ts +7 -0
  174. package/dist/lib/jobs/index.d.ts.map +1 -0
  175. package/dist/lib/jobs/index.js +9 -0
  176. package/dist/lib/jobs/index.js.map +1 -0
  177. package/dist/lib/jobs/relay.d.ts +27 -0
  178. package/dist/lib/jobs/relay.d.ts.map +1 -0
  179. package/dist/lib/jobs/relay.js +61 -0
  180. package/dist/lib/jobs/relay.js.map +1 -0
  181. package/dist/lib/jobs/run-batch.d.ts +52 -0
  182. package/dist/lib/jobs/run-batch.d.ts.map +1 -0
  183. package/dist/lib/jobs/run-batch.js +62 -0
  184. package/dist/lib/jobs/run-batch.js.map +1 -0
  185. package/dist/lib/jobs/run-due-jobs.d.ts +30 -0
  186. package/dist/lib/jobs/run-due-jobs.d.ts.map +1 -0
  187. package/dist/lib/jobs/run-due-jobs.js +70 -0
  188. package/dist/lib/jobs/run-due-jobs.js.map +1 -0
  189. package/dist/lib/jobs/types.d.ts +18 -0
  190. package/dist/lib/jobs/types.d.ts.map +1 -0
  191. package/dist/lib/jobs/types.js +2 -0
  192. package/dist/lib/jobs/types.js.map +1 -0
  193. package/dist/lib/local-api/collection-api.d.ts +42 -0
  194. package/dist/lib/local-api/collection-api.d.ts.map +1 -1
  195. package/dist/lib/local-api/collection-api.js +200 -25
  196. package/dist/lib/local-api/collection-api.js.map +1 -1
  197. package/dist/lib/local-api/hooks.d.ts +7 -0
  198. package/dist/lib/local-api/hooks.d.ts.map +1 -0
  199. package/dist/lib/local-api/hooks.js +20 -0
  200. package/dist/lib/local-api/hooks.js.map +1 -0
  201. package/dist/lib/mcp/tools.js +1 -1
  202. package/dist/lib/mcp/tools.js.map +1 -1
  203. package/dist/lib/plugins/resolver.d.ts +12 -1
  204. package/dist/lib/plugins/resolver.d.ts.map +1 -1
  205. package/dist/lib/plugins/resolver.js +4 -1
  206. package/dist/lib/plugins/resolver.js.map +1 -1
  207. package/dist/lib/plugins/types.d.ts +47 -2
  208. package/dist/lib/plugins/types.d.ts.map +1 -1
  209. package/dist/lib/plugins/types.js.map +1 -1
  210. package/dist/lib/schema-utils/define-type.d.ts +32 -0
  211. package/dist/lib/schema-utils/define-type.d.ts.map +1 -0
  212. package/dist/lib/schema-utils/define-type.js +41 -0
  213. package/dist/lib/schema-utils/define-type.js.map +1 -0
  214. package/dist/lib/schema-utils/index.d.ts +1 -0
  215. package/dist/lib/schema-utils/index.d.ts.map +1 -1
  216. package/dist/lib/schema-utils/index.js +1 -0
  217. package/dist/lib/schema-utils/index.js.map +1 -1
  218. package/dist/lib/server/api/index.d.ts.map +1 -1
  219. package/dist/lib/server/api/index.js +8 -0
  220. package/dist/lib/server/api/index.js.map +1 -1
  221. package/dist/lib/server/api/routes/documents-publish.d.ts.map +1 -1
  222. package/dist/lib/server/api/routes/documents-publish.js +110 -0
  223. package/dist/lib/server/api/routes/documents-publish.js.map +1 -1
  224. package/dist/lib/server/api/routes/jobs.d.ts +4 -0
  225. package/dist/lib/server/api/routes/jobs.d.ts.map +1 -0
  226. package/dist/lib/server/api/routes/jobs.js +93 -0
  227. package/dist/lib/server/api/routes/jobs.js.map +1 -0
  228. package/dist/lib/server/api/routes/workers-run.d.ts +4 -0
  229. package/dist/lib/server/api/routes/workers-run.d.ts.map +1 -0
  230. package/dist/lib/server/api/routes/workers-run.js +41 -0
  231. package/dist/lib/server/api/routes/workers-run.js.map +1 -0
  232. package/dist/lib/server/index.d.ts +1 -0
  233. package/dist/lib/server/index.d.ts.map +1 -1
  234. package/dist/lib/server/index.js +2 -0
  235. package/dist/lib/server/index.js.map +1 -1
  236. package/dist/lib/services/version-service.d.ts +16 -0
  237. package/dist/lib/services/version-service.d.ts.map +1 -1
  238. package/dist/lib/services/version-service.js +72 -48
  239. package/dist/lib/services/version-service.js.map +1 -1
  240. package/dist/lib/types/config.d.ts +43 -0
  241. package/dist/lib/types/config.d.ts.map +1 -1
  242. package/dist/lib/types/events.d.ts +134 -0
  243. package/dist/lib/types/events.d.ts.map +1 -0
  244. package/dist/lib/types/events.js +4 -0
  245. package/dist/lib/types/events.js.map +1 -0
  246. package/dist/lib/types/index.d.ts +1 -0
  247. package/dist/lib/types/index.d.ts.map +1 -1
  248. package/dist/lib/types/index.js +1 -0
  249. package/dist/lib/types/index.js.map +1 -1
  250. package/dist/lib/types/schemas.d.ts +71 -0
  251. package/dist/lib/types/schemas.d.ts.map +1 -1
  252. package/dist/lib/utils/index.d.ts +1 -1
  253. package/dist/lib/utils/index.d.ts.map +1 -1
  254. package/dist/lib/utils/index.js.map +1 -1
  255. package/dist/local-api/collection-api.d.ts +42 -0
  256. package/dist/local-api/collection-api.d.ts.map +1 -1
  257. package/dist/local-api/collection-api.js +200 -25
  258. package/dist/local-api/hooks.d.ts +7 -0
  259. package/dist/local-api/hooks.d.ts.map +1 -0
  260. package/dist/local-api/hooks.js +19 -0
  261. package/dist/mcp/tools.js +1 -1
  262. package/dist/plugins/resolver.d.ts +12 -1
  263. package/dist/plugins/resolver.d.ts.map +1 -1
  264. package/dist/plugins/resolver.js +4 -1
  265. package/dist/plugins/types.d.ts +47 -2
  266. package/dist/plugins/types.d.ts.map +1 -1
  267. package/dist/schema-utils/define-type.d.ts +32 -0
  268. package/dist/schema-utils/define-type.d.ts.map +1 -0
  269. package/dist/schema-utils/define-type.js +40 -0
  270. package/dist/schema-utils/index.d.ts +1 -0
  271. package/dist/schema-utils/index.d.ts.map +1 -1
  272. package/dist/schema-utils/index.js +1 -0
  273. package/dist/server/api/index.d.ts.map +1 -1
  274. package/dist/server/api/index.js +8 -0
  275. package/dist/server/api/routes/documents-publish.d.ts.map +1 -1
  276. package/dist/server/api/routes/documents-publish.js +110 -0
  277. package/dist/server/api/routes/jobs.d.ts +4 -0
  278. package/dist/server/api/routes/jobs.d.ts.map +1 -0
  279. package/dist/server/api/routes/jobs.js +92 -0
  280. package/dist/server/api/routes/workers-run.d.ts +4 -0
  281. package/dist/server/api/routes/workers-run.d.ts.map +1 -0
  282. package/dist/server/api/routes/workers-run.js +40 -0
  283. package/dist/server/index.d.ts +1 -0
  284. package/dist/server/index.d.ts.map +1 -1
  285. package/dist/server/index.js +2 -0
  286. package/dist/services/version-service.d.ts +16 -0
  287. package/dist/services/version-service.d.ts.map +1 -1
  288. package/dist/services/version-service.js +72 -48
  289. package/dist/types/config.d.ts +43 -0
  290. package/dist/types/config.d.ts.map +1 -1
  291. package/dist/types/events.d.ts +134 -0
  292. package/dist/types/events.d.ts.map +1 -0
  293. package/dist/types/events.js +3 -0
  294. package/dist/types/index.d.ts +1 -0
  295. package/dist/types/index.d.ts.map +1 -1
  296. package/dist/types/index.js +1 -0
  297. package/dist/types/schemas.d.ts +71 -0
  298. package/dist/types/schemas.d.ts.map +1 -1
  299. package/dist/utils/index.d.ts +1 -1
  300. package/dist/utils/index.d.ts.map +1 -1
  301. package/package.json +2 -1
@@ -0,0 +1,93 @@
1
+ import { Hono } from 'hono';
2
+ import { z } from 'zod';
3
+ import { authToContext } from '../../../local-api/auth-helpers.js';
4
+ import { hasCapability } from '../../../types/capabilities.js';
5
+ import { cmsLogger } from '../../../utils/logger.js';
6
+ // Read-only history / observability for the durable spine. Gated on `document.read`:
7
+ // the operational log of publish work is visible to anyone who can read content.
8
+ // Mirrors JobStatus (types/events) as a zod enum — the API contract's source of truth.
9
+ const jobStatus = z.enum(['pending', 'leased', 'completed', 'failed', 'cancelled']);
10
+ const listJobsQuery = z.object({
11
+ status: jobStatus.optional(),
12
+ type: z.string().optional(),
13
+ limit: z.coerce.number().int().min(1).max(200).optional(),
14
+ offset: z.coerce.number().int().min(0).optional()
15
+ });
16
+ const listEventsQuery = z.object({
17
+ type: z.string().optional(),
18
+ limit: z.coerce.number().int().min(1).max(200).optional(),
19
+ offset: z.coerce.number().int().min(0).optional()
20
+ });
21
+ /** Map an adapter Page into the ApiResponse `pagination` shape the client expects. */
22
+ function toPagination(page) {
23
+ const pageSize = page.limit || 1;
24
+ return {
25
+ total: page.total,
26
+ page: Math.floor(page.offset / pageSize) + 1,
27
+ pageSize,
28
+ totalPages: Math.max(1, Math.ceil(page.total / pageSize)),
29
+ hasNextPage: page.offset + page.limit < page.total,
30
+ hasPrevPage: page.offset > 0
31
+ };
32
+ }
33
+ function requireHistoryAccess(c) {
34
+ const auth = c.var.auth;
35
+ if (!auth || auth.type === 'partial_session') {
36
+ return { error: c.json({ success: false, error: 'Authentication required' }, 401) };
37
+ }
38
+ if (!hasCapability(auth, 'document.read')) {
39
+ return { error: c.json({ success: false, error: 'Insufficient permissions' }, 403) };
40
+ }
41
+ return { organizationId: authToContext(auth).organizationId };
42
+ }
43
+ export const jobsRouter = new Hono()
44
+ .get('/jobs', async (c) => {
45
+ try {
46
+ const gate = requireHistoryAccess(c);
47
+ if ('error' in gate)
48
+ return gate.error;
49
+ const parsed = listJobsQuery.safeParse(c.req.query());
50
+ if (!parsed.success) {
51
+ return c.json({ success: false, error: 'Invalid query', issues: parsed.error.issues }, 400);
52
+ }
53
+ const { status, type, limit, offset } = parsed.data;
54
+ const { databaseAdapter } = c.var.aphexCMS;
55
+ const page = await databaseAdapter.listJobs({
56
+ organizationId: gate.organizationId,
57
+ status,
58
+ type,
59
+ limit,
60
+ offset
61
+ });
62
+ return c.json({ success: true, data: page.items, pagination: toPagination(page) });
63
+ }
64
+ catch (error) {
65
+ cmsLogger.error('Failed to list jobs:', error);
66
+ return c.json({ success: false, error: 'Failed to list jobs' }, 500);
67
+ }
68
+ })
69
+ .get('/events', async (c) => {
70
+ try {
71
+ const gate = requireHistoryAccess(c);
72
+ if ('error' in gate)
73
+ return gate.error;
74
+ const parsed = listEventsQuery.safeParse(c.req.query());
75
+ if (!parsed.success) {
76
+ return c.json({ success: false, error: 'Invalid query', issues: parsed.error.issues }, 400);
77
+ }
78
+ const { type, limit, offset } = parsed.data;
79
+ const { databaseAdapter } = c.var.aphexCMS;
80
+ const page = await databaseAdapter.listEvents({
81
+ organizationId: gate.organizationId,
82
+ type,
83
+ limit,
84
+ offset
85
+ });
86
+ return c.json({ success: true, data: page.items, pagination: toPagination(page) });
87
+ }
88
+ catch (error) {
89
+ cmsLogger.error('Failed to list events:', error);
90
+ return c.json({ success: false, error: 'Failed to list events' }, 500);
91
+ }
92
+ });
93
+ //# sourceMappingURL=jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../../../src/lib/server/api/routes/jobs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Hono } from 'hono';
2
+ import type { AphexEnv } from '../index.js';
3
+ export declare const workersRunRouter: Hono<AphexEnv, import("hono/types").BlankSchema, "/">;
4
+ //# sourceMappingURL=workers-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workers-run.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/api/routes/workers-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAezC,eAAO,MAAM,gBAAgB,uDAAuB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { Hono } from 'hono';
2
+ import { randomUUID, timingSafeEqual } from 'node:crypto';
3
+ import { runJobsBatch } from '../../../jobs/index.js';
4
+ /**
5
+ * Constant-time compare of the presented bearer token against the configured secret.
6
+ * Length is compared first (and short-circuits), which leaks only the secret's length —
7
+ * acceptable, and unavoidable without hashing both sides.
8
+ */
9
+ function secretMatches(presented, expected) {
10
+ const a = Buffer.from(presented);
11
+ const b = Buffer.from(expected);
12
+ if (a.length !== b.length)
13
+ return false;
14
+ return timingSafeEqual(a, b);
15
+ }
16
+ export const workersRunRouter = new Hono();
17
+ /**
18
+ * POST /api/internal/workers/run — drive one bounded batch of due jobs and return counts.
19
+ *
20
+ * Machine-to-machine: authorized by a shared secret (`Authorization: Bearer <secret>`),
21
+ * NOT the user capability system — platform cron (hosted) or a self-hosted worker loop
22
+ * calls it on a cadence. Disabled (404) unless `jobs.workerSecret` is configured, so it
23
+ * never exists as an unauthenticated surface by default. Bounded per call (batchSize), so
24
+ * a single invocation can't run unboundedly; the caller's cadence sets throughput.
25
+ */
26
+ workersRunRouter.post('/run', async (c) => {
27
+ const secret = c.var.aphexCMS.config.jobs?.workerSecret;
28
+ // Not configured → the endpoint doesn't exist. Don't advertise it or hint at auth.
29
+ if (!secret)
30
+ return c.json({ success: false, error: 'Not found' }, 404);
31
+ const header = c.req.header('authorization') ?? '';
32
+ const presented = header.startsWith('Bearer ') ? header.slice('Bearer '.length) : '';
33
+ if (!presented || !secretMatches(presented, secret)) {
34
+ return c.json({ success: false, error: 'Unauthorized' }, 401);
35
+ }
36
+ // Shared seam: builds the handler map (built-in + app-registered) and runs one batch.
37
+ // The embedded poll loop calls the same helper, so the two modes can't drift.
38
+ const result = await runJobsBatch(c.var.aphexCMS, { workerId: `endpoint-${randomUUID()}` });
39
+ return c.json({ success: true, result });
40
+ });
41
+ //# sourceMappingURL=workers-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workers-run.js","sourceRoot":"","sources":["../../../../../src/lib/server/api/routes/workers-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;GAIG;AACH,SAAS,aAAa,CAAC,SAAiB,EAAE,QAAgB;IACzD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,IAAI,EAAY,CAAC;AAErD;;;;;;;;GAQG;AACH,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACzC,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC;IAExD,mFAAmF;IACnF,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;IAExE,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IACnD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC;IAC/D,CAAC;IAED,sFAAsF;IACtF,8EAA8E;IAC9E,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,YAAY,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IAE5F,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC"}
@@ -16,6 +16,7 @@ export { AssetService } from '../services/asset-service.js';
16
16
  export { RolesService } from '../services/roles-service.js';
17
17
  export { GET as serveAssetCDN } from '../routes/assets-cdn.js';
18
18
  export { createAphexApi, mountAphexBuiltins, toHonoHandler, type AphexEnv } from './api/index.js';
19
+ export * from '../jobs/index.js';
19
20
  export * from '../schema-utils/index.js';
20
21
  export { createHashForPublishing } from '../utils/content-hash.js';
21
22
  export { getPreviewPerspective, type PreviewPerspective } from '../preview/perspective.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxF,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG/F,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGxF,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACN,iBAAiB,EACjB,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxF,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG/F,cAAc,eAAe,CAAC;AAG9B,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGxF,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACN,iBAAiB,EACjB,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,MAAM,cAAc,CAAC"}
@@ -32,6 +32,8 @@ export { GET as serveAssetCDN } from '../routes/assets-cdn.js';
32
32
  // Hono API app — exposed so user apps (and tests) can construct or extend
33
33
  // the same router the SK catch-all forwards to.
34
34
  export { createAphexApi, mountAphexBuiltins, toHonoHandler } from './api/index.js';
35
+ // Job execution — the DB-backed job runner (claim → run handler → complete/retry/fail).
36
+ export * from '../jobs/index.js';
35
37
  // Schema utilities
36
38
  export * from '../schema-utils/index.js';
37
39
  // Content hash utilities (server-side)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/server/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,+DAA+D;AAE/D,sDAAsD;AACtD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAE/B,wBAAwB;AACxB,OAAO,EAAE,SAAS,EAAsB,MAAM,qBAAqB,CAAC;AAEpE,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,SAAS,EAAe,MAAM,iBAAiB,CAAC;AAEpE,aAAa;AACb,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,6CAA6C;AAC7C,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAqB,MAAM,UAAU,CAAC;AAExF,qFAAqF;AACrF,cAAc,wBAAwB,CAAC;AAEvC,kCAAkC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAE7C,iDAAiD;AACjD,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,4EAA4E;AAC5E,wEAAwE;AACxE,oEAAoE;AACpE,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE5D,0EAA0E;AAC1E,gDAAgD;AAChD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC;AAE/F,mBAAmB;AACnB,cAAc,uBAAuB,CAAC;AAEtC,uCAAuC;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,oBAAoB;AACpB,OAAO,EAAE,qBAAqB,EAA2B,MAAM,wBAAwB,CAAC;AAExF,yCAAyC;AACzC,OAAO,EACN,oBAAoB,EAIpB,MAAM,kBAAkB,CAAC;AAE1B,uCAAuC;AACvC,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EAMb,MAAM,oBAAoB,CAAC;AAE5B,4EAA4E;AAC5E,uEAAuE;AACvE,OAAO,EACN,iBAAiB,EAIjB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/server/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,+DAA+D;AAE/D,sDAAsD;AACtD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAE/B,wBAAwB;AACxB,OAAO,EAAE,SAAS,EAAsB,MAAM,qBAAqB,CAAC;AAEpE,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,SAAS,EAAe,MAAM,iBAAiB,CAAC;AAEpE,aAAa;AACb,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,6CAA6C;AAC7C,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAqB,MAAM,UAAU,CAAC;AAExF,qFAAqF;AACrF,cAAc,wBAAwB,CAAC;AAEvC,kCAAkC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAE7C,iDAAiD;AACjD,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,4EAA4E;AAC5E,wEAAwE;AACxE,oEAAoE;AACpE,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE5D,0EAA0E;AAC1E,gDAAgD;AAChD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC;AAE/F,wFAAwF;AACxF,cAAc,eAAe,CAAC;AAE9B,mBAAmB;AACnB,cAAc,uBAAuB,CAAC;AAEtC,uCAAuC;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,oBAAoB;AACpB,OAAO,EAAE,qBAAqB,EAA2B,MAAM,wBAAwB,CAAC;AAExF,yCAAyC;AACzC,OAAO,EACN,oBAAoB,EAIpB,MAAM,kBAAkB,CAAC;AAE1B,uCAAuC;AACvC,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EAMb,MAAM,oBAAoB,CAAC;AAE5B,4EAA4E;AAC5E,uEAAuE;AACvE,OAAO,EACN,iBAAiB,EAIjB,MAAM,cAAc,CAAC"}
@@ -17,6 +17,22 @@ export declare class VersionService {
17
17
  * Create a version snapshot and enforce rolling retention.
18
18
  */
19
19
  createVersion(db: DatabaseAdapter, organizationId: string, documentId: string, eventType: 'draft' | 'publish', data: any, userId?: string | null): Promise<DocumentVersion | null>;
20
+ /**
21
+ * Write a version snapshot on an already-transactional adapter. The caller owns
22
+ * the transaction boundary and retention (call `enforceRetentionFor` post-commit).
23
+ * No-op when the adapter has no versioning support.
24
+ */
25
+ snapshotTx(tx: DatabaseAdapter, organizationId: string, documentId: string, eventType: 'draft' | 'publish', data: any, userId?: string | null): Promise<void>;
26
+ /**
27
+ * Publish + snapshot on an already-transactional adapter. Caller owns the tx
28
+ * and retention. Returns the published document (or null if publish was a no-op).
29
+ */
30
+ publishTx(tx: DatabaseAdapter, organizationId: string, documentId: string): Promise<Document | null>;
31
+ /**
32
+ * Public retention trigger for callers that manage their own transaction and
33
+ * therefore can't rely on `saveWithVersion`/`publishWithVersion` to run it.
34
+ */
35
+ enforceRetentionFor(db: DatabaseAdapter, organizationId: string, documentId: string): Promise<void>;
20
36
  /**
21
37
  * Save draft and create version atomically using adapter transaction.
22
38
  */
@@ -1 +1 @@
1
- {"version":3,"file":"version-service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/version-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE7E;;;;;;GAMG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;IAI9C;;OAEG;IACG,aAAa,CAClB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAelC;;OAEG;IACG,eAAe,CACpB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA2B3B;;OAEG;IACG,kBAAkB,CACvB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAgB3B;;OAEG;IACG,cAAc,CACnB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAqCrB,YAAY,CACjB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,mBAAmB,CAAC;IAKzB,UAAU,CACf,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAKpB,gBAAgB;CAuB9B"}
1
+ {"version":3,"file":"version-service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/version-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG7E;;;;;;GAMG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;IAI9C;;OAEG;IACG,aAAa,CAClB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAelC;;;;OAIG;IACG,UAAU,CACf,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,IAAI,CAAC;IAWhB;;;OAGG;IACG,SAAS,CACd,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAoB3B;;;OAGG;IACG,mBAAmB,CACxB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAIhB;;OAEG;IACG,eAAe,CACpB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAgB3B;;OAEG;IACG,kBAAkB,CACvB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAiB3B;;OAEG;IACG,cAAc,CACnB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA0BrB,YAAY,CACjB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,mBAAmB,CAAC;IAKzB,UAAU,CACf,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAKpB,gBAAgB;CAuB9B"}
@@ -1,3 +1,4 @@
1
+ import { emitDocumentPublished } from '../events/emit.js';
1
2
  /**
2
3
  * VersionService — orchestrates document versioning with rolling retention.
3
4
  *
@@ -26,43 +27,77 @@ export class VersionService {
26
27
  await this.enforceRetention(db, documentId, organizationId);
27
28
  return version;
28
29
  }
30
+ /**
31
+ * Write a version snapshot on an already-transactional adapter. The caller owns
32
+ * the transaction boundary and retention (call `enforceRetentionFor` post-commit).
33
+ * No-op when the adapter has no versioning support.
34
+ */
35
+ async snapshotTx(tx, organizationId, documentId, eventType, data, userId) {
36
+ if (!tx.createDocumentVersion)
37
+ return;
38
+ await tx.createDocumentVersion({
39
+ documentId,
40
+ organizationId,
41
+ eventType,
42
+ data,
43
+ createdBy: userId
44
+ });
45
+ }
46
+ /**
47
+ * Publish + snapshot on an already-transactional adapter. Caller owns the tx
48
+ * and retention. Returns the published document (or null if publish was a no-op).
49
+ */
50
+ async publishTx(tx, organizationId, documentId) {
51
+ const result = await tx.publishDoc(organizationId, documentId);
52
+ if (result) {
53
+ await this.snapshotTx(tx, organizationId, documentId, 'publish', result.publishedData, result.updatedBy);
54
+ // Transactional outbox: record the durable fact in the same tx as the publish, so
55
+ // the event and the state change commit (or roll back) together — a consumer can
56
+ // never see a publish that didn't happen, nor miss one that did. The non-versioned
57
+ // publish path (collection-api) emits the same event via the same helper.
58
+ await emitDocumentPublished(tx, organizationId, result);
59
+ }
60
+ return result;
61
+ }
62
+ /**
63
+ * Public retention trigger for callers that manage their own transaction and
64
+ * therefore can't rely on `saveWithVersion`/`publishWithVersion` to run it.
65
+ */
66
+ async enforceRetentionFor(db, organizationId, documentId) {
67
+ await this.enforceRetention(db, documentId, organizationId);
68
+ }
29
69
  /**
30
70
  * Save draft and create version atomically using adapter transaction.
31
71
  */
32
72
  async saveWithVersion(db, organizationId, documentId, data, userId) {
33
- if (db.withTransaction && db.createDocumentVersion) {
34
- const updated = await db.withTransaction(async (txAdapter) => {
35
- const result = await txAdapter.updateDocDraft(organizationId, documentId, data, userId);
36
- if (result) {
37
- await txAdapter.createDocumentVersion({
38
- documentId,
39
- organizationId,
40
- eventType: 'draft',
41
- data,
42
- createdBy: userId
43
- });
44
- }
45
- return result;
46
- });
47
- if (updated)
48
- await this.enforceRetention(db, documentId, organizationId);
49
- return updated;
50
- }
51
- // Fallback: non-atomic
52
- const updated = await db.updateDocDraft(organizationId, documentId, data, userId);
53
- if (updated) {
54
- await this.createVersion(db, organizationId, documentId, 'draft', data, userId);
73
+ // No versioning support: a single write, atomic on its own.
74
+ if (!db.createDocumentVersion) {
75
+ return db.updateDocDraft(organizationId, documentId, data, userId);
55
76
  }
77
+ const updated = await db.withTransaction(async (txAdapter) => {
78
+ const result = await txAdapter.updateDocDraft(organizationId, documentId, data, userId);
79
+ if (result)
80
+ await this.snapshotTx(txAdapter, organizationId, documentId, 'draft', data, userId);
81
+ return result;
82
+ });
83
+ if (updated)
84
+ await this.enforceRetention(db, documentId, organizationId);
56
85
  return updated;
57
86
  }
58
87
  /**
59
88
  * Publish and create version.
60
89
  */
61
90
  async publishWithVersion(db, organizationId, documentId) {
62
- const published = await db.publishDoc(organizationId, documentId);
63
- if (!published)
64
- return null;
65
- await this.createVersion(db, organizationId, documentId, 'publish', published.publishedData, published.updatedBy);
91
+ // Publish + version snapshot must commit together: a crash between them
92
+ // would leave a published document with no 'publish' version row. Mirror
93
+ // saveWithVersion / restoreVersion and run both writes in one transaction.
94
+ // No versioning support: a single write, atomic on its own.
95
+ if (!db.createDocumentVersion) {
96
+ return db.publishDoc(organizationId, documentId);
97
+ }
98
+ const published = await db.withTransaction((txAdapter) => this.publishTx(txAdapter, organizationId, documentId));
99
+ if (published)
100
+ await this.enforceRetention(db, documentId, organizationId);
66
101
  return published;
67
102
  }
68
103
  /**
@@ -74,29 +109,18 @@ export class VersionService {
74
109
  const version = await db.getDocumentVersion(organizationId, documentId, versionNumber);
75
110
  if (!version)
76
111
  return null;
77
- if (db.withTransaction && db.createDocumentVersion) {
78
- const restored = await db.withTransaction(async (txAdapter) => {
79
- const result = await txAdapter.updateDocDraft(organizationId, documentId, version.data, userId);
80
- if (result) {
81
- await txAdapter.createDocumentVersion({
82
- documentId,
83
- organizationId,
84
- eventType: 'draft',
85
- data: version.data,
86
- createdBy: userId
87
- });
88
- }
89
- return result;
90
- });
91
- if (restored)
92
- await this.enforceRetention(db, documentId, organizationId);
93
- return restored;
94
- }
95
- // Fallback: non-atomic
96
- const restored = await db.updateDocDraft(organizationId, documentId, version.data, userId);
97
- if (restored) {
98
- await this.createVersion(db, organizationId, documentId, 'draft', version.data, userId);
112
+ // No versioning support: a single write, atomic on its own.
113
+ if (!db.createDocumentVersion) {
114
+ return db.updateDocDraft(organizationId, documentId, version.data, userId);
99
115
  }
116
+ const restored = await db.withTransaction(async (txAdapter) => {
117
+ const result = await txAdapter.updateDocDraft(organizationId, documentId, version.data, userId);
118
+ if (result)
119
+ await this.snapshotTx(txAdapter, organizationId, documentId, 'draft', version.data, userId);
120
+ return result;
121
+ });
122
+ if (restored)
123
+ await this.enforceRetention(db, documentId, organizationId);
100
124
  return restored;
101
125
  }
102
126
  async listVersions(db, organizationId, documentId, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"version-service.js","sourceRoot":"","sources":["../../../src/lib/services/version-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"version-service.js","sourceRoot":"","sources":["../../../src/lib/services/version-service.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import type { Logger } from '../utils/logger.js';
11
11
  import type { CMSPlugin } from '../plugins/types.js';
12
12
  import type { Auth } from './auth.js';
13
13
  import type { PreviewPerspective } from '../preview/perspective.js';
14
+ import type { JobHandlerMap } from '../jobs/types.js';
14
15
  export type { GraphQLConfig };
15
16
  export interface CMSConfig {
16
17
  schemaTypes: SchemaType[];
@@ -77,6 +78,48 @@ export interface CMSConfig {
77
78
  versioning?: {
78
79
  maxVersions?: number;
79
80
  };
81
+ /**
82
+ * Background job execution (the DB-backed job queue). Jobs are scheduled via the
83
+ * database adapter (`scheduleJob`) and driven by `runDueJobs`, which the protected
84
+ * worker endpoint (`POST /api/internal/workers/run`) and any self-hosted worker loop
85
+ * both call. Events and scheduling work without this; only *executing* jobs needs it.
86
+ */
87
+ jobs?: {
88
+ /**
89
+ * Map of job `type` → handler. A claimed job whose type has no handler is
90
+ * dead-lettered (an unknown type can never become runnable).
91
+ */
92
+ handlers?: JobHandlerMap;
93
+ /**
94
+ * Shared secret authorizing `POST /api/internal/workers/run`
95
+ * (`Authorization: Bearer <secret>`). Machine-to-machine — platform cron or a
96
+ * self-hosted worker loop, NOT the user capability system. When unset the endpoint
97
+ * is disabled (404), so it's never an unauthenticated surface by default; jobs can
98
+ * still be scheduled, they just won't run until a secret (and a driver) exist.
99
+ */
100
+ workerSecret?: string;
101
+ /** Max jobs claimed per worker run. Default 10. */
102
+ batchSize?: number;
103
+ /** Lease duration (ms) per claimed job before it's reclaimable. Default 30000. */
104
+ leaseMs?: number;
105
+ /**
106
+ * Max outbox rows the relay drains per worker run (events fanned out to consumer
107
+ * delivery jobs). Runs at the top of the same tick as job execution. Default 100 —
108
+ * fan-out is cheap (a few inserts), so it can clear more per pass than it executes.
109
+ */
110
+ relayBatchSize?: number;
111
+ /**
112
+ * Run an in-process job loop inside the app itself — no separate worker process, no
113
+ * `workerSecret`, no cron. It calls `runJobsBatch` directly on `embeddedIntervalMs`, so
114
+ * scheduled publishes and event consumers "just work" the moment the app is running. Ideal
115
+ * for local dev and single-instance self-hosting; for horizontally-scaled prod prefer the
116
+ * dedicated worker loop / platform cron so N app replicas don't each run a loop. Ticks never
117
+ * overlap (a slow tick is skipped, not stacked). Default off.
118
+ */
119
+ embedded?: boolean;
120
+ /** Interval (ms) between embedded loop ticks when `embedded` is on. Default 3000. */
121
+ embeddedIntervalMs?: number;
122
+ };
80
123
  /**
81
124
  * Live preview configuration.
82
125
  * - `stega`: Enable stega encoding in preview data pushes so field overlays work
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/types/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,MAAM,WAAW,SAAS;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QACf,QAAQ,CAAC,EAAE;YACV,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,KAAK,CAAC,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC/B,CAAC;KACF,CAAC;IACF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACxD;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACN,QAAQ,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,CAAC,EAAE,IAAI,CAAC;YAAC,GAAG,EAAE,GAAG,CAAA;SAAE,KAAK,kBAAkB,CAAC;KAC7E,CAAC;IACF,QAAQ,CAAC,EAAE;QACV;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B;;;;;;WAMG;QACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;CACpC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/types/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,MAAM,WAAW,SAAS;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QACf,QAAQ,CAAC,EAAE;YACV,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,KAAK,CAAC,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC/B,CAAC;KACF,CAAC;IACF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACxD;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACN,QAAQ,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF;;;;;OAKG;IACH,IAAI,CAAC,EAAE;QACN;;;WAGG;QACH,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB;;;;;;WAMG;QACH,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,mDAAmD;QACnD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,kFAAkF;QAClF,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB;;;;WAIG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB;;;;;;;WAOG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,qFAAqF;QACrF,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,CAAC,EAAE,IAAI,CAAC;YAAC,GAAG,EAAE,GAAG,CAAA;SAAE,KAAK,kBAAkB,CAAC;KAC7E,CAAC;IACF,QAAQ,CAAC,EAAE;QACV;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B;;;;;;WAMG;QACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;CACpC"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * A durable business fact. Append-only: written once (typically inside the same
3
+ * transaction as the state change that caused it) and never mutated. Payload carries
4
+ * identifiers + intentional metadata only — never secrets or full document copies.
5
+ */
6
+ export interface DomainEvent {
7
+ id: string;
8
+ organizationId: string;
9
+ type: string;
10
+ payload: Record<string, unknown>;
11
+ correlationId: string | null;
12
+ causationId: string | null;
13
+ createdBy: string | null;
14
+ createdAt: Date;
15
+ }
16
+ /** Input to append a domain event. */
17
+ export interface AppendEventInput {
18
+ organizationId: string;
19
+ type: string;
20
+ payload?: Record<string, unknown>;
21
+ correlationId?: string | null;
22
+ causationId?: string | null;
23
+ createdBy?: string | null;
24
+ }
25
+ export type JobStatus = 'pending' | 'leased' | 'completed' | 'failed' | 'cancelled';
26
+ /** A command to run now or later. Lifecycle: pending → leased → completed/failed/cancelled. */
27
+ export interface Job {
28
+ id: string;
29
+ organizationId: string;
30
+ type: string;
31
+ payload: Record<string, unknown>;
32
+ status: JobStatus;
33
+ runAt: Date;
34
+ attempts: number;
35
+ maxAttempts: number;
36
+ leaseOwner: string | null;
37
+ leaseExpiresAt: Date | null;
38
+ lastError: string | null;
39
+ idempotencyKey: string | null;
40
+ correlationId: string | null;
41
+ causationId: string | null;
42
+ createdBy: string | null;
43
+ createdAt: Date;
44
+ updatedAt: Date;
45
+ completedAt: Date | null;
46
+ }
47
+ /** Input to schedule a job. `idempotencyKey` (unique per org) makes enqueue safe to retry. */
48
+ export interface ScheduleJobInput {
49
+ organizationId: string;
50
+ type: string;
51
+ payload?: Record<string, unknown>;
52
+ runAt?: Date;
53
+ maxAttempts?: number;
54
+ idempotencyKey?: string | null;
55
+ correlationId?: string | null;
56
+ causationId?: string | null;
57
+ createdBy?: string | null;
58
+ }
59
+ /**
60
+ * Options for claiming due jobs with a lease. Omit `organizationId` to claim across all
61
+ * orgs (worker context — runs with override access); provide it to scope to one tenant.
62
+ */
63
+ export interface ClaimJobsOptions {
64
+ organizationId?: string;
65
+ limit: number;
66
+ workerId: string;
67
+ leaseMs: number;
68
+ now?: Date;
69
+ }
70
+ /**
71
+ * An outbox worklist row — the relay's unit of work. Written in the SAME transaction as
72
+ * the `domain_events` row it mirrors (so it can never exist without its event, nor be
73
+ * missed if the event committed), then drained by the relay: for each subscribed consumer
74
+ * it enqueues one delivery job, then stamps `processedAt`.
75
+ *
76
+ * Kept SEPARATE from `cms_domain_events` on purpose. The event log is an immutable ledger;
77
+ * this is a mutable, prunable worklist. And the relay claims rows by `processedAt IS NULL`
78
+ * (status), never by log position — so an event whose transaction commits late (with an
79
+ * early timestamp) is still picked up, which a cursor-scan over the append-only log would
80
+ * silently skip. `eventType`/`payload` are denormalized here so the relay fans out from a
81
+ * single-table read with no join back to the event log.
82
+ */
83
+ export interface OutboxRow {
84
+ id: string;
85
+ organizationId: string;
86
+ /** The `cms_domain_events` row this mirrors (FK; the canonical, immutable copy). */
87
+ eventId: string;
88
+ eventType: string;
89
+ payload: Record<string, unknown>;
90
+ correlationId: string | null;
91
+ causationId: string | null;
92
+ createdBy: string | null;
93
+ createdAt: Date;
94
+ /** Null until the relay has fanned this event out to every subscriber. */
95
+ processedAt: Date | null;
96
+ }
97
+ /**
98
+ * Options for reading the relay's pending work. Omit `organizationId` to read across all
99
+ * orgs (worker context — runs with override access), mirroring `claimDueJobs`. No lease:
100
+ * the relay's only side effect is idempotent job enqueue (keyed per event×consumer), so two
101
+ * workers processing the same row can't double-deliver — the job's unique idempotency key
102
+ * absorbs the duplicate. Oldest-first, so events relay in roughly causal order.
103
+ */
104
+ export interface ListUnprocessedOutboxOptions {
105
+ organizationId?: string;
106
+ /** Max rows returned per relay pass. */
107
+ limit: number;
108
+ }
109
+ /** A page of rows plus the unfiltered total, for offset pagination in the admin history views. */
110
+ export interface Page<T> {
111
+ items: T[];
112
+ total: number;
113
+ limit: number;
114
+ offset: number;
115
+ }
116
+ /** Query for the read-only event history. Newest first. */
117
+ export interface ListEventsOptions {
118
+ organizationId: string;
119
+ /** Filter by exact event type (e.g. `document.published`). */
120
+ type?: string;
121
+ limit?: number;
122
+ offset?: number;
123
+ }
124
+ /** Query for the read-only job history. Newest first. */
125
+ export interface ListJobsOptions {
126
+ organizationId: string;
127
+ /** Filter by one status or several (e.g. only `failed`). */
128
+ status?: JobStatus | JobStatus[];
129
+ /** Filter by exact job type. */
130
+ type?: string;
131
+ limit?: number;
132
+ offset?: number;
133
+ }
134
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/lib/types/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // Universal event + job types — dialect-agnostic shapes the adapters map their rows to.
2
+ // These mirror the `cms_domain_events` and `cms_jobs` tables but never depend on Drizzle.
3
+ export {};
4
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/lib/types/events.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,0FAA0F"}