@prenta/core 8.9.2 → 8.10.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 (290) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/dist/actions.d.ts +25 -0
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +51 -4
  5. package/dist/actions.js.map +1 -1
  6. package/dist/ai/batch-links.d.ts +105 -0
  7. package/dist/ai/batch-links.d.ts.map +1 -0
  8. package/dist/ai/batch-links.js +667 -0
  9. package/dist/ai/batch-links.js.map +1 -0
  10. package/dist/ai/batch-list.d.ts +127 -4
  11. package/dist/ai/batch-list.d.ts.map +1 -1
  12. package/dist/ai/batch-list.js +250 -14
  13. package/dist/ai/batch-list.js.map +1 -1
  14. package/dist/ai/providers/http.d.ts +4 -0
  15. package/dist/ai/providers/http.d.ts.map +1 -1
  16. package/dist/ai/providers/http.js +9 -8
  17. package/dist/ai/providers/http.js.map +1 -1
  18. package/dist/ai/tasks/editor-text.d.ts +39 -0
  19. package/dist/ai/tasks/editor-text.d.ts.map +1 -0
  20. package/dist/ai/tasks/editor-text.js +45 -0
  21. package/dist/ai/tasks/editor-text.js.map +1 -0
  22. package/dist/ai/tasks/link-embeddings.d.ts +22 -0
  23. package/dist/ai/tasks/link-embeddings.d.ts.map +1 -1
  24. package/dist/ai/tasks/link-embeddings.js +24 -10
  25. package/dist/ai/tasks/link-embeddings.js.map +1 -1
  26. package/dist/ai/usage.d.ts +7 -0
  27. package/dist/ai/usage.d.ts.map +1 -1
  28. package/dist/ai/usage.js +11 -0
  29. package/dist/ai/usage.js.map +1 -1
  30. package/dist/api/guarded-db.d.ts +6 -0
  31. package/dist/api/guarded-db.d.ts.map +1 -1
  32. package/dist/api/guarded-db.js +13 -1
  33. package/dist/api/guarded-db.js.map +1 -1
  34. package/dist/api/handlers.d.ts.map +1 -1
  35. package/dist/api/handlers.js +2 -0
  36. package/dist/api/handlers.js.map +1 -1
  37. package/dist/api/openapi.d.ts.map +1 -1
  38. package/dist/api/openapi.js +47 -0
  39. package/dist/api/openapi.js.map +1 -1
  40. package/dist/api/route-helpers/forms.d.ts.map +1 -1
  41. package/dist/api/route-helpers/forms.js +7 -1
  42. package/dist/api/route-helpers/forms.js.map +1 -1
  43. package/dist/api/routes/ai-authoring.d.ts.map +1 -1
  44. package/dist/api/routes/ai-authoring.js +1 -0
  45. package/dist/api/routes/ai-authoring.js.map +1 -1
  46. package/dist/api/routes/ai-seo.d.ts.map +1 -1
  47. package/dist/api/routes/ai-seo.js +20 -18
  48. package/dist/api/routes/ai-seo.js.map +1 -1
  49. package/dist/api/routes/media.d.ts.map +1 -1
  50. package/dist/api/routes/media.js +3 -1
  51. package/dist/api/routes/media.js.map +1 -1
  52. package/dist/api/routes/scheduling.d.ts.map +1 -1
  53. package/dist/api/routes/scheduling.js +33 -2
  54. package/dist/api/routes/scheduling.js.map +1 -1
  55. package/dist/appearance/color.d.ts +17 -0
  56. package/dist/appearance/color.d.ts.map +1 -1
  57. package/dist/appearance/color.js +162 -1
  58. package/dist/appearance/color.js.map +1 -1
  59. package/dist/appearance/index.d.ts +3 -3
  60. package/dist/appearance/index.d.ts.map +1 -1
  61. package/dist/appearance/index.js +2 -2
  62. package/dist/appearance/index.js.map +1 -1
  63. package/dist/appearance/resolve.d.ts.map +1 -1
  64. package/dist/appearance/resolve.js +4 -2
  65. package/dist/appearance/resolve.js.map +1 -1
  66. package/dist/appearance/theme-tokens.d.ts +60 -11
  67. package/dist/appearance/theme-tokens.d.ts.map +1 -1
  68. package/dist/appearance/theme-tokens.js +184 -175
  69. package/dist/appearance/theme-tokens.js.map +1 -1
  70. package/dist/appearance/types.d.ts +16 -2
  71. package/dist/appearance/types.d.ts.map +1 -1
  72. package/dist/astro-site.d.ts +1 -11
  73. package/dist/astro-site.d.ts.map +1 -1
  74. package/dist/astro-site.js +4 -0
  75. package/dist/astro-site.js.map +1 -1
  76. package/dist/auth/team.d.ts +1 -0
  77. package/dist/auth/team.d.ts.map +1 -1
  78. package/dist/auth/team.js +1 -1
  79. package/dist/auth/team.js.map +1 -1
  80. package/dist/cache/http.d.ts +20 -0
  81. package/dist/cache/http.d.ts.map +1 -1
  82. package/dist/cache/http.js +42 -0
  83. package/dist/cache/http.js.map +1 -1
  84. package/dist/chrome/announcement.d.ts +30 -0
  85. package/dist/chrome/announcement.d.ts.map +1 -0
  86. package/dist/chrome/announcement.js +190 -0
  87. package/dist/chrome/announcement.js.map +1 -0
  88. package/dist/chrome/codegen.d.ts +17 -0
  89. package/dist/chrome/codegen.d.ts.map +1 -0
  90. package/dist/chrome/codegen.js +96 -0
  91. package/dist/chrome/codegen.js.map +1 -0
  92. package/dist/chrome/contract.d.ts +142 -0
  93. package/dist/chrome/contract.d.ts.map +1 -0
  94. package/dist/chrome/contract.js +2 -0
  95. package/dist/chrome/contract.js.map +1 -0
  96. package/dist/chrome/memory-store.d.ts +15 -0
  97. package/dist/chrome/memory-store.d.ts.map +1 -0
  98. package/dist/chrome/memory-store.js +54 -0
  99. package/dist/chrome/memory-store.js.map +1 -0
  100. package/dist/chrome/parse.d.ts +36 -0
  101. package/dist/chrome/parse.d.ts.map +1 -0
  102. package/dist/chrome/parse.js +277 -0
  103. package/dist/chrome/parse.js.map +1 -0
  104. package/dist/chrome/prisma-store.d.ts +11 -0
  105. package/dist/chrome/prisma-store.d.ts.map +1 -0
  106. package/dist/chrome/prisma-store.js +48 -0
  107. package/dist/chrome/prisma-store.js.map +1 -0
  108. package/dist/chrome/public.d.ts +22 -0
  109. package/dist/chrome/public.d.ts.map +1 -0
  110. package/dist/chrome/public.js +181 -0
  111. package/dist/chrome/public.js.map +1 -0
  112. package/dist/chrome/resolve.d.ts +36 -0
  113. package/dist/chrome/resolve.d.ts.map +1 -0
  114. package/dist/chrome/resolve.js +165 -0
  115. package/dist/chrome/resolve.js.map +1 -0
  116. package/dist/chrome/revalidate.d.ts +9 -0
  117. package/dist/chrome/revalidate.d.ts.map +1 -0
  118. package/dist/chrome/revalidate.js +51 -0
  119. package/dist/chrome/revalidate.js.map +1 -0
  120. package/dist/chrome/routes.d.ts +14 -0
  121. package/dist/chrome/routes.d.ts.map +1 -0
  122. package/dist/chrome/routes.js +306 -0
  123. package/dist/chrome/routes.js.map +1 -0
  124. package/dist/chrome/schema.d.ts +231 -0
  125. package/dist/chrome/schema.d.ts.map +1 -0
  126. package/dist/chrome/schema.js +73 -0
  127. package/dist/chrome/schema.js.map +1 -0
  128. package/dist/chrome/service.d.ts +76 -0
  129. package/dist/chrome/service.d.ts.map +1 -0
  130. package/dist/chrome/service.js +286 -0
  131. package/dist/chrome/service.js.map +1 -0
  132. package/dist/chrome/settings.d.ts +14 -0
  133. package/dist/chrome/settings.d.ts.map +1 -0
  134. package/dist/chrome/settings.js +142 -0
  135. package/dist/chrome/settings.js.map +1 -0
  136. package/dist/chrome/store.d.ts +48 -0
  137. package/dist/chrome/store.d.ts.map +1 -0
  138. package/dist/chrome/store.js +26 -0
  139. package/dist/chrome/store.js.map +1 -0
  140. package/dist/chrome/values.d.ts +98 -0
  141. package/dist/chrome/values.d.ts.map +1 -0
  142. package/dist/chrome/values.js +491 -0
  143. package/dist/chrome/values.js.map +1 -0
  144. package/dist/config/define.d.ts +2 -0
  145. package/dist/config/define.d.ts.map +1 -1
  146. package/dist/config/define.js +2 -0
  147. package/dist/config/define.js.map +1 -1
  148. package/dist/db/model-types.d.ts +62 -0
  149. package/dist/db/model-types.d.ts.map +1 -1
  150. package/dist/forms/attribution-settings.d.ts +23 -0
  151. package/dist/forms/attribution-settings.d.ts.map +1 -0
  152. package/dist/forms/attribution-settings.js +42 -0
  153. package/dist/forms/attribution-settings.js.map +1 -0
  154. package/dist/forms/attribution.d.ts +5 -1
  155. package/dist/forms/attribution.d.ts.map +1 -1
  156. package/dist/forms/attribution.js +6 -4
  157. package/dist/forms/attribution.js.map +1 -1
  158. package/dist/forms/client-validation.d.ts.map +1 -1
  159. package/dist/forms/client-validation.js +3 -0
  160. package/dist/forms/client-validation.js.map +1 -1
  161. package/dist/forms/form-model.d.ts +109 -0
  162. package/dist/forms/form-model.d.ts.map +1 -0
  163. package/dist/forms/form-model.js +192 -0
  164. package/dist/forms/form-model.js.map +1 -0
  165. package/dist/forms/index.d.ts +2 -2
  166. package/dist/forms/index.d.ts.map +1 -1
  167. package/dist/forms/index.js +1 -1
  168. package/dist/forms/index.js.map +1 -1
  169. package/dist/forms/service.d.ts +19 -1
  170. package/dist/forms/service.d.ts.map +1 -1
  171. package/dist/forms/service.js +152 -0
  172. package/dist/forms/service.js.map +1 -1
  173. package/dist/forms/spam.d.ts +0 -12
  174. package/dist/forms/spam.d.ts.map +1 -1
  175. package/dist/forms/spam.js +30 -0
  176. package/dist/forms/spam.js.map +1 -1
  177. package/dist/forms/submission.d.ts +7 -0
  178. package/dist/forms/submission.d.ts.map +1 -1
  179. package/dist/forms/submission.js +33 -0
  180. package/dist/forms/submission.js.map +1 -1
  181. package/dist/forms/types.d.ts +26 -1
  182. package/dist/forms/types.d.ts.map +1 -1
  183. package/dist/forms/types.js +9 -1
  184. package/dist/forms/types.js.map +1 -1
  185. package/dist/generated/browser.d.ts +35 -3
  186. package/dist/generated/client.d.ts +35 -3
  187. package/dist/generated/internal/class.d.ts +44 -0
  188. package/dist/generated/internal/class.js +4 -4
  189. package/dist/generated/internal/prismaNamespace.d.ts +403 -1
  190. package/dist/generated/internal/prismaNamespace.js +95 -1
  191. package/dist/generated/internal/prismaNamespaceBrowser.d.ts +102 -0
  192. package/dist/generated/internal/prismaNamespaceBrowser.js +95 -1
  193. package/dist/generated/models/ChromeRegion.d.ts +1203 -0
  194. package/dist/generated/models/ChromeRegion.js +1 -0
  195. package/dist/generated/models/Job.d.ts +732 -5
  196. package/dist/generated/models/JobEvent.d.ts +1339 -0
  197. package/dist/generated/models/JobEvent.js +1 -0
  198. package/dist/generated/models/JobReviewItem.d.ts +1470 -0
  199. package/dist/generated/models/JobReviewItem.js +1 -0
  200. package/dist/generated/models/SystemSetting.d.ts +952 -0
  201. package/dist/generated/models/SystemSetting.js +1 -0
  202. package/dist/generated/models.d.ts +4 -0
  203. package/dist/index.d.ts +12 -5
  204. package/dist/index.d.ts.map +1 -1
  205. package/dist/index.js +8 -3
  206. package/dist/index.js.map +1 -1
  207. package/dist/jobs/batch-ai.d.ts +53 -0
  208. package/dist/jobs/batch-ai.d.ts.map +1 -0
  209. package/dist/jobs/batch-ai.js +314 -0
  210. package/dist/jobs/batch-ai.js.map +1 -0
  211. package/dist/jobs/contract.d.ts +186 -0
  212. package/dist/jobs/contract.d.ts.map +1 -0
  213. package/dist/jobs/contract.js +2 -0
  214. package/dist/jobs/contract.js.map +1 -0
  215. package/dist/jobs/error-text.d.ts +23 -0
  216. package/dist/jobs/error-text.d.ts.map +1 -0
  217. package/dist/jobs/error-text.js +110 -0
  218. package/dist/jobs/error-text.js.map +1 -0
  219. package/dist/jobs/handlers.d.ts.map +1 -1
  220. package/dist/jobs/handlers.js +48 -7
  221. package/dist/jobs/handlers.js.map +1 -1
  222. package/dist/jobs/memory-store.d.ts +26 -2
  223. package/dist/jobs/memory-store.d.ts.map +1 -1
  224. package/dist/jobs/memory-store.js +157 -3
  225. package/dist/jobs/memory-store.js.map +1 -1
  226. package/dist/jobs/outcomes.d.ts +46 -0
  227. package/dist/jobs/outcomes.d.ts.map +1 -0
  228. package/dist/jobs/outcomes.js +251 -0
  229. package/dist/jobs/outcomes.js.map +1 -0
  230. package/dist/jobs/prisma-store.d.ts +14 -2
  231. package/dist/jobs/prisma-store.d.ts.map +1 -1
  232. package/dist/jobs/prisma-store.js +257 -15
  233. package/dist/jobs/prisma-store.js.map +1 -1
  234. package/dist/jobs/queue.d.ts +62 -2
  235. package/dist/jobs/queue.d.ts.map +1 -1
  236. package/dist/jobs/queue.js +412 -36
  237. package/dist/jobs/queue.js.map +1 -1
  238. package/dist/jobs/retention.d.ts +11 -0
  239. package/dist/jobs/retention.d.ts.map +1 -0
  240. package/dist/jobs/retention.js +18 -0
  241. package/dist/jobs/retention.js.map +1 -0
  242. package/dist/jobs/review.d.ts +111 -0
  243. package/dist/jobs/review.d.ts.map +1 -0
  244. package/dist/jobs/review.js +461 -0
  245. package/dist/jobs/review.js.map +1 -0
  246. package/dist/jobs/routes.d.ts.map +1 -1
  247. package/dist/jobs/routes.js +491 -16
  248. package/dist/jobs/routes.js.map +1 -1
  249. package/dist/jobs/serialize.d.ts +40 -0
  250. package/dist/jobs/serialize.d.ts.map +1 -0
  251. package/dist/jobs/serialize.js +270 -0
  252. package/dist/jobs/serialize.js.map +1 -0
  253. package/dist/jobs/types.d.ts +141 -2
  254. package/dist/jobs/types.d.ts.map +1 -1
  255. package/dist/jobs/worker-status.d.ts +27 -0
  256. package/dist/jobs/worker-status.d.ts.map +1 -0
  257. package/dist/jobs/worker-status.js +66 -0
  258. package/dist/jobs/worker-status.js.map +1 -0
  259. package/dist/media/optimize.d.ts.map +1 -1
  260. package/dist/media/optimize.js +4 -2
  261. package/dist/media/optimize.js.map +1 -1
  262. package/dist/next-site.d.ts +1 -0
  263. package/dist/next-site.d.ts.map +1 -1
  264. package/dist/next-site.js +3 -0
  265. package/dist/next-site.js.map +1 -1
  266. package/dist/seo/audit-runner.d.ts.map +1 -1
  267. package/dist/seo/audit-runner.js +23 -2
  268. package/dist/seo/audit-runner.js.map +1 -1
  269. package/dist/seo/issue-fix-link-insert.d.ts +11 -0
  270. package/dist/seo/issue-fix-link-insert.d.ts.map +1 -1
  271. package/dist/seo/issue-fix-link-insert.js +122 -8
  272. package/dist/seo/issue-fix-link-insert.js.map +1 -1
  273. package/dist/server-site.d.ts.map +1 -1
  274. package/dist/server-site.js +15 -0
  275. package/dist/server-site.js.map +1 -1
  276. package/dist/site.d.ts +8 -0
  277. package/dist/site.d.ts.map +1 -1
  278. package/dist/site.js +6 -0
  279. package/dist/site.js.map +1 -1
  280. package/dist/webhooks/index.d.ts +3 -1
  281. package/dist/webhooks/index.d.ts.map +1 -1
  282. package/dist/webhooks/index.js.map +1 -1
  283. package/package.json +6 -1
  284. package/prisma/migrations/0025_job_cancel_review/down.sql +60 -0
  285. package/prisma/migrations/0025_job_cancel_review/migration.sql +56 -0
  286. package/prisma/migrations/0026_job_creator_system_settings/down.sql +30 -0
  287. package/prisma/migrations/0026_job_creator_system_settings/migration.sql +14 -0
  288. package/prisma/migrations/0027_chrome_regions/down.sql +24 -0
  289. package/prisma/migrations/0027_chrome_regions/migration.sql +16 -0
  290. package/prisma/schema.prisma +105 -15
@@ -1,37 +1,201 @@
1
+ import { canReadUnpublished } from '../actions.js';
2
+ import { AiCapRefusal, batchAiFeatureKey } from '../ai/batch-list.js';
3
+ import { embeddingsAvailableForProvider } from '../ai/embeddings.js';
4
+ import { runtimeErrorToResponse } from '../ai/runtime-response.js';
5
+ import { resolveFeatureRuntime } from '../ai/runtime.js';
1
6
  import { isAuthorizedCronRequest } from '../cron/index.js';
2
7
  import { guardedDb } from '../api/guarded-db.js';
3
- import { errorResponse, internalError, json, requireAuth } from '../api/route-helpers.js';
8
+ import { ADMIN_ROLES, actionError, aiGenerateLimiter, buildActionContext, checkRateLimitAsync, errorResponse, internalError, json, requireAuth, requireCollectionScope, requireMediaScope, requireStaffAccess, } from '../api/route-helpers.js';
9
+ import { roleHasPermission } from '../auth/roles.js';
10
+ import { createBatchAiJob, estimateBatchAi, parseBatchAiRequest, previewBatchAi, } from './batch-ai.js';
4
11
  import { createJobHandlers } from './handlers.js';
12
+ import { createJobNotes } from './outcomes.js';
5
13
  import { PrismaJobStore } from './prisma-store.js';
6
- import { enqueueJob, processJobQueue } from './queue.js';
7
- const WORKER_BUDGET_MS = 20_000;
8
- function serializeJob(job) {
14
+ import { enqueueJob, processJobQueue, requestJobCancel, retryJob, runJobNow } from './queue.js';
15
+ import { ReviewError, approveAllReviewItems, approveReviewItem, getReviewItem, listReviewItems, loadReviewTarget, rejectReviewItem, resolveReviewMode, undoReviewItem, } from './review.js';
16
+ import { batchAiWriter, loadJobRefs, loadUserRefs, serializeJob, serializeJobEvent, serializeReviewItem, } from './serialize.js';
17
+ import { WORKER_BUDGET_MS, getWorkerStatus, recordWorkerTick } from './worker-status.js';
18
+ const LIST_LIMIT = 50;
19
+ const LIST_LIMIT_MAX = 100;
20
+ const EVENTS_LIMIT = 50;
21
+ const STATUSES = ['queued', 'running', 'succeeded', 'dead', 'cancelled'];
22
+ /** What "Run now" can start. A batch AI job starts from a set of documents instead. */
23
+ const RUNNABLE_TYPES = ['seo-scan', 'content-health'];
24
+ const REVIEW_STATUSES = ['pending', 'approved', 'rejected'];
25
+ const REVIEW_ACTIONS = ['approve', 'reject', 'undo'];
26
+ const UNDO_KEEPS_PUBLISHED = 'The document stays published. Undo put back the previous text, and the page shows it now.';
27
+ /** Approve-all stops starting new changes after this long; the client calls again for the rest. */
28
+ const APPROVE_ALL_BUDGET_MS = 20_000;
29
+ const LINKS_NEED_EMBEDDINGS = 'Adding internal links needs an AI provider that supports embeddings, such as OpenAI. Connect one in Settings > AI.';
30
+ /** `?status=pending&cursor=<item id>&limit=50`. */
31
+ function parseReviewQuery(url) {
32
+ const rawLimit = Number.parseInt(url.searchParams.get('limit') ?? '', 10);
33
+ const limit = Number.isFinite(rawLimit)
34
+ ? Math.min(Math.max(rawLimit, 1), LIST_LIMIT_MAX)
35
+ : LIST_LIMIT;
36
+ const status = url.searchParams.get('status')?.trim();
37
+ if (status && !REVIEW_STATUSES.includes(status)) {
38
+ return { error: `status must be one of: ${REVIEW_STATUSES.join(', ')}` };
39
+ }
40
+ const cursor = url.searchParams.get('cursor')?.trim();
9
41
  return {
10
- id: job.id,
11
- type: job.type,
12
- status: job.status,
13
- attempts: job.attempts,
14
- maxAttempts: job.maxAttempts,
15
- lastError: job.lastError,
16
- progress: job.progress,
17
- runAt: job.runAt.toISOString(),
18
- createdAt: job.createdAt.toISOString(),
19
- updatedAt: job.updatedAt.toISOString(),
42
+ limit,
43
+ ...(status ? { status: status } : {}),
44
+ ...(cursor ? { cursor } : {}),
20
45
  };
21
46
  }
47
+ function readOnApprove(value) {
48
+ return value === 'draft' || value === 'publish' ? value : null;
49
+ }
50
+ /** What the job's creator chose for "When a change is approved". */
51
+ function jobOnApprove(job) {
52
+ return readOnApprove(job.payload.onApprove) ?? 'draft';
53
+ }
54
+ /** `?limit=50&type=seo-scan&status=queued,running`. */
55
+ function parseListQuery(url) {
56
+ const rawLimit = Number.parseInt(url.searchParams.get('limit') ?? '', 10);
57
+ const limit = Number.isFinite(rawLimit)
58
+ ? Math.min(Math.max(rawLimit, 1), LIST_LIMIT_MAX)
59
+ : LIST_LIMIT;
60
+ const filter = {};
61
+ const type = url.searchParams.get('type')?.trim();
62
+ if (type)
63
+ filter.type = type;
64
+ const status = url.searchParams.get('status')?.trim();
65
+ if (status) {
66
+ const statuses = status.split(',').map((value) => value.trim());
67
+ const unknown = statuses.find((value) => !STATUSES.includes(value));
68
+ if (unknown !== undefined) {
69
+ return { error: `status must be one or more of: ${STATUSES.join(', ')}` };
70
+ }
71
+ filter.statuses = statuses;
72
+ }
73
+ return { limit, filter };
74
+ }
75
+ /** Whether the caller may write to a collection, or to the media library (`media`). */
76
+ function writeScopeDenial(session, collection) {
77
+ return collection === 'media'
78
+ ? requireMediaScope(session)
79
+ : requireCollectionScope(session, collection, 'update');
80
+ }
81
+ /**
82
+ * A job's review items are unpublished text from its documents, so listing them
83
+ * needs what reading those documents unpublished needs, for every collection
84
+ * the job writes: the API key's read scope (media scope for the media library),
85
+ * the collection's read rule, and a role that can edit content.
86
+ */
87
+ async function reviewReadDenial(job, session) {
88
+ if (!roleHasPermission(session.role, 'content.update')) {
89
+ return errorResponse('Only people who can edit content can read suggested changes', 403);
90
+ }
91
+ const ctx = buildActionContext(session, guardedDb());
92
+ for (const collection of batchAiWriter(job).collections) {
93
+ if (collection === 'media') {
94
+ const scopeErr = requireMediaScope(session);
95
+ if (scopeErr)
96
+ return scopeErr;
97
+ continue;
98
+ }
99
+ const scopeErr = requireCollectionScope(session, collection, 'read');
100
+ if (scopeErr)
101
+ return scopeErr;
102
+ if (!(await canReadUnpublished(collection, ctx))) {
103
+ return errorResponse(`Access denied: cannot read unpublished content in "${collection}"`, 403);
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ /**
109
+ * A retried batch keeps writing as the person who queued it, with the role
110
+ * stored on its items. So a non-admin may retry only their own batch, and only
111
+ * while their role is unchanged. An auto-apply batch, which only an admin can
112
+ * queue, needs an admin. Every collection it writes needs update scope, as when
113
+ * it was queued.
114
+ */
115
+ function batchRetryDenial(job, session) {
116
+ const writer = batchAiWriter(job);
117
+ for (const collection of writer.collections) {
118
+ const scopeErr = writeScopeDenial(session, collection);
119
+ if (scopeErr)
120
+ return scopeErr;
121
+ }
122
+ if (ADMIN_ROLES.has(session.role))
123
+ return null;
124
+ if (writer.autoApply) {
125
+ return errorResponse('Only an admin can retry a batch that applies changes directly', 403);
126
+ }
127
+ const sameWriter = writer.creatorId === session.userId && writer.roles.every((role) => role === session.role);
128
+ return sameWriter
129
+ ? null
130
+ : errorResponse('Only an admin or the person who queued this batch can retry it', 403);
131
+ }
132
+ /**
133
+ * The full error has the stack, with server paths and query text, so only a
134
+ * caller who could retry or cancel the job sees it. That's the check
135
+ * `requireStaffAccess` makes for a POST; for a GET it would also let read-only
136
+ * API keys through.
137
+ */
138
+ function seesFullError(session, request) {
139
+ return requireStaffAccess(session, new Request(request.url, { method: 'POST' })) === null;
140
+ }
141
+ /**
142
+ * The checks `create` and `preview` share: a write role, write access to the
143
+ * source, the AI generation rate limit, and the AI feature being set up (for
144
+ * `links`, on a provider that can embed). A batch that applies changes
145
+ * directly needs an admin to create it. Returns the plan, or the response to send.
146
+ */
147
+ async function checkBatchAiRequest(request, session, options) {
148
+ const roleErr = requireStaffAccess(session, request);
149
+ if (roleErr)
150
+ return roleErr;
151
+ const body = (await request.json().catch(() => null));
152
+ const plan = parseBatchAiRequest(body ?? {});
153
+ if ('error' in plan)
154
+ return errorResponse(plan.error, 400);
155
+ if (options.creating && resolveReviewMode(plan.review, ADMIN_ROLES.has(session.role)).forbidden) {
156
+ return errorResponse('Only an admin can apply changes automatically', 403);
157
+ }
158
+ const scopeErr = writeScopeDenial(session, plan.source);
159
+ if (scopeErr)
160
+ return scopeErr;
161
+ if (!(await checkRateLimitAsync(aiGenerateLimiter, `ai-batch:${session.userId}`))) {
162
+ return errorResponse('AI generation rate limit reached. Try again in an hour.', 429);
163
+ }
164
+ const feature = await resolveFeatureRuntime(guardedDb(), batchAiFeatureKey(plan.workerOperation));
165
+ if (!feature.ok)
166
+ return runtimeErrorToResponse(feature);
167
+ if (plan.workerOperation === 'links' && !embeddingsAvailableForProvider(feature.providerKey)) {
168
+ return runtimeErrorToResponse({
169
+ ok: false,
170
+ code: 'no_provider',
171
+ message: LINKS_NEED_EMBEDDINGS,
172
+ });
173
+ }
174
+ return { plan };
175
+ }
22
176
  export function registerJobRoutes(router) {
23
177
  const db = guardedDb;
178
+ async function serializeOne(job, options = {}) {
179
+ return serializeJob(job, await loadJobRefs(db(), [job]), options);
180
+ }
24
181
  const cronJobs = async (request) => {
25
182
  try {
26
183
  if (!isAuthorizedCronRequest(request.headers.get('authorization'))) {
27
184
  return errorResponse('Unauthorized', 401);
28
185
  }
29
186
  const client = db();
187
+ const started = Date.now();
30
188
  const summary = await processJobQueue({
31
189
  store: new PrismaJobStore(client),
32
190
  handlers: createJobHandlers(client),
33
191
  budgetMs: WORKER_BUDGET_MS,
192
+ notes: createJobNotes(client),
34
193
  });
194
+ // The worker strip reads this. Losing one stamp only makes the strip look a minute stale.
195
+ await recordWorkerTick(client, {
196
+ at: new Date(started),
197
+ ms: Date.now() - started,
198
+ }).catch(() => undefined);
35
199
  return json({ data: summary });
36
200
  }
37
201
  catch (err) {
@@ -45,13 +209,324 @@ export function registerJobRoutes(router) {
45
209
  const auth = await requireAuth(request);
46
210
  if (auth.error)
47
211
  return auth.error;
48
- const jobs = await new PrismaJobStore(db()).list(50);
49
- return json({ data: { jobs: jobs.map(serializeJob) } });
212
+ const query = parseListQuery(new URL(request.url));
213
+ if ('error' in query)
214
+ return errorResponse(query.error, 400);
215
+ const jobs = await new PrismaJobStore(db()).list(query.limit, query.filter);
216
+ const refs = await loadJobRefs(db(), jobs);
217
+ return json({ data: { jobs: jobs.map((job) => serializeJob(job, refs)) } });
50
218
  }
51
219
  catch (err) {
52
220
  return internalError(err, 'list jobs');
53
221
  }
54
222
  });
223
+ // Before `/jobs/:id`, so `worker` isn't read as a job id.
224
+ router.get('/jobs/worker', async (request) => {
225
+ try {
226
+ const auth = await requireAuth(request);
227
+ if (auth.error)
228
+ return auth.error;
229
+ const client = db();
230
+ return json({
231
+ data: await getWorkerStatus(client, new PrismaJobStore(client), new Date()),
232
+ });
233
+ }
234
+ catch (err) {
235
+ return internalError(err, 'job worker status');
236
+ }
237
+ });
238
+ router.get('/jobs/batch-ai/estimate', async (request) => {
239
+ try {
240
+ const auth = await requireAuth(request);
241
+ if (auth.error)
242
+ return auth.error;
243
+ const roleErr = requireStaffAccess(auth.session, request);
244
+ if (roleErr)
245
+ return roleErr;
246
+ const url = new URL(request.url);
247
+ const documentIds = url.searchParams.get('documentIds');
248
+ const plan = parseBatchAiRequest({
249
+ operation: url.searchParams.get('operation'),
250
+ source: url.searchParams.get('source'),
251
+ statusFilter: url.searchParams.get('statusFilter'),
252
+ field: url.searchParams.get('field'),
253
+ instruction: url.searchParams.get('instruction'),
254
+ ...(documentIds ? { filter: { documentIds: documentIds.split(',').filter(Boolean) } } : {}),
255
+ });
256
+ if ('error' in plan)
257
+ return errorResponse(plan.error, 400);
258
+ const scopeErr = plan.source === 'media'
259
+ ? requireMediaScope(auth.session)
260
+ : requireCollectionScope(auth.session, plan.source, 'read');
261
+ if (scopeErr)
262
+ return scopeErr;
263
+ return json({ data: await estimateBatchAi(db(), plan) });
264
+ }
265
+ catch (err) {
266
+ return internalError(err, 'estimate batch AI job');
267
+ }
268
+ });
269
+ router.get('/jobs/:id', async (request, params) => {
270
+ try {
271
+ const auth = await requireAuth(request);
272
+ if (auth.error)
273
+ return auth.error;
274
+ const job = await new PrismaJobStore(db()).get(params.id ?? '');
275
+ if (!job)
276
+ return errorResponse('Job not found', 404);
277
+ return json({
278
+ data: await serializeOne(job, {
279
+ detail: true,
280
+ fullError: seesFullError(auth.session, request),
281
+ }),
282
+ });
283
+ }
284
+ catch (err) {
285
+ return internalError(err, 'get job');
286
+ }
287
+ });
288
+ router.get('/jobs/:id/events', async (request, params) => {
289
+ try {
290
+ const auth = await requireAuth(request);
291
+ if (auth.error)
292
+ return auth.error;
293
+ const store = new PrismaJobStore(db());
294
+ const id = params.id ?? '';
295
+ if (!(await store.get(id)))
296
+ return errorResponse('Job not found', 404);
297
+ const events = await store.listEvents(id, EVENTS_LIMIT);
298
+ return json({ data: { events: events.map(serializeJobEvent) } });
299
+ }
300
+ catch (err) {
301
+ return internalError(err, 'job events');
302
+ }
303
+ });
304
+ router.get('/jobs/:id/review', async (request, params) => {
305
+ try {
306
+ const auth = await requireAuth(request);
307
+ if (auth.error)
308
+ return auth.error;
309
+ const id = params.id ?? '';
310
+ const job = await new PrismaJobStore(db()).get(id);
311
+ if (!job)
312
+ return errorResponse('Job not found', 404);
313
+ const denial = await reviewReadDenial(job, auth.session);
314
+ if (denial)
315
+ return denial;
316
+ const query = parseReviewQuery(new URL(request.url));
317
+ if ('error' in query)
318
+ return errorResponse(query.error, 400);
319
+ const page = await listReviewItems(db(), id, query);
320
+ const users = await loadUserRefs(db(), page.items.flatMap((item) => (item.decidedById ? [item.decidedById] : [])));
321
+ return json({
322
+ data: {
323
+ items: page.items.map((item) => serializeReviewItem(item, users)),
324
+ nextCursor: page.nextCursor,
325
+ },
326
+ });
327
+ }
328
+ catch (err) {
329
+ return internalError(err, 'job review items');
330
+ }
331
+ });
332
+ router.post('/jobs/run', async (request) => {
333
+ try {
334
+ const auth = await requireAuth(request);
335
+ if (auth.error)
336
+ return auth.error;
337
+ const roleErr = requireStaffAccess(auth.session, request);
338
+ if (roleErr)
339
+ return roleErr;
340
+ const body = (await request.json().catch(() => null));
341
+ const type = RUNNABLE_TYPES.find((value) => value === body?.type);
342
+ if (!type) {
343
+ return errorResponse(`type must be one of: ${RUNNABLE_TYPES.join(', ')}`, 400);
344
+ }
345
+ const { job, reused } = await runJobNow(new PrismaJobStore(db()), {
346
+ type,
347
+ createdById: auth.session.userId,
348
+ });
349
+ return json({ data: { job: await serializeOne(job), reused } }, reused ? 200 : 201);
350
+ }
351
+ catch (err) {
352
+ return internalError(err, 'run job');
353
+ }
354
+ });
355
+ router.post('/jobs/batch-ai', async (request) => {
356
+ try {
357
+ const auth = await requireAuth(request);
358
+ if (auth.error)
359
+ return auth.error;
360
+ const checked = await checkBatchAiRequest(request, auth.session, { creating: true });
361
+ if (checked instanceof Response)
362
+ return checked;
363
+ const job = await createBatchAiJob(db(), new PrismaJobStore(db()), checked.plan, auth.session);
364
+ if ('error' in job)
365
+ return errorResponse(job.error, 400);
366
+ return json({ data: await serializeOne(job) }, 201);
367
+ }
368
+ catch (err) {
369
+ return internalError(err, 'create batch AI job');
370
+ }
371
+ });
372
+ router.post('/jobs/batch-ai/preview', async (request) => {
373
+ try {
374
+ const auth = await requireAuth(request);
375
+ if (auth.error)
376
+ return auth.error;
377
+ const checked = await checkBatchAiRequest(request, auth.session, { creating: false });
378
+ if (checked instanceof Response)
379
+ return checked;
380
+ const items = await previewBatchAi(db(), checked.plan, auth.session);
381
+ return json({ data: { items } });
382
+ }
383
+ catch (err) {
384
+ if (err instanceof AiCapRefusal)
385
+ return errorResponse(err.message, 429);
386
+ return internalError(err, 'preview batch AI job');
387
+ }
388
+ });
389
+ router.post('/jobs/:id/cancel', async (request, params) => {
390
+ try {
391
+ const auth = await requireAuth(request);
392
+ if (auth.error)
393
+ return auth.error;
394
+ const roleErr = requireStaffAccess(auth.session, request);
395
+ if (roleErr)
396
+ return roleErr;
397
+ const id = params.id;
398
+ if (!id)
399
+ return errorResponse('Missing job id', 400);
400
+ const job = await requestJobCancel(new PrismaJobStore(db()), id, auth.session.userId, new Date());
401
+ if (!job)
402
+ return errorResponse('Job not found', 404);
403
+ return json({ data: await serializeOne(job) });
404
+ }
405
+ catch (err) {
406
+ return internalError(err, 'cancel job');
407
+ }
408
+ });
409
+ router.post('/jobs/:id/retry', async (request, params) => {
410
+ try {
411
+ const auth = await requireAuth(request);
412
+ if (auth.error)
413
+ return auth.error;
414
+ const roleErr = requireStaffAccess(auth.session, request);
415
+ if (roleErr)
416
+ return roleErr;
417
+ const store = new PrismaJobStore(db());
418
+ const id = params.id ?? '';
419
+ const existing = await store.get(id);
420
+ if (!existing)
421
+ return errorResponse('Job not found', 404);
422
+ if (existing.type === 'batch-ai') {
423
+ const denial = batchRetryDenial(existing, auth.session);
424
+ if (denial)
425
+ return denial;
426
+ }
427
+ const outcome = await retryJob(store, id, new Date());
428
+ if (!outcome)
429
+ return errorResponse('Job not found', 404);
430
+ if (!outcome.retried) {
431
+ return errorResponse('Only a failed job, or one waiting to retry, can be retried', 409);
432
+ }
433
+ return json({ data: await serializeOne(outcome.job) });
434
+ }
435
+ catch (err) {
436
+ return internalError(err, 'retry job');
437
+ }
438
+ });
439
+ // Before `/review/:itemId`, so `approve-all` isn't read as an item id.
440
+ router.post('/jobs/:id/review/approve-all', async (request, params) => {
441
+ try {
442
+ const auth = await requireAuth(request);
443
+ if (auth.error)
444
+ return auth.error;
445
+ const roleErr = requireStaffAccess(auth.session, request);
446
+ if (roleErr)
447
+ return roleErr;
448
+ const job = await new PrismaJobStore(db()).get(params.id ?? '');
449
+ if (!job)
450
+ return errorResponse('Job not found', 404);
451
+ const body = (await request.json().catch(() => null));
452
+ const onApprove = readOnApprove(body?.onApprove) ?? jobOnApprove(job);
453
+ const outcome = await approveAllReviewItems(db(), buildActionContext(auth.session, db()), job.id, {
454
+ onApprove,
455
+ canApprove: (target) => writeScopeDenial(auth.session, target.collection) === null,
456
+ deadline: Date.now() + APPROVE_ALL_BUDGET_MS,
457
+ });
458
+ return json({ data: outcome });
459
+ }
460
+ catch (err) {
461
+ return internalError(err, 'approve all job review items');
462
+ }
463
+ });
464
+ router.post('/jobs/:id/review/:itemId', async (request, params) => {
465
+ try {
466
+ const auth = await requireAuth(request);
467
+ if (auth.error)
468
+ return auth.error;
469
+ const roleErr = requireStaffAccess(auth.session, request);
470
+ if (roleErr)
471
+ return roleErr;
472
+ const job = await new PrismaJobStore(db()).get(params.id ?? '');
473
+ if (!job)
474
+ return errorResponse('Job not found', 404);
475
+ const item = await getReviewItem(db(), job.id, params.itemId ?? '');
476
+ if (!item)
477
+ return errorResponse('Review item not found', 404);
478
+ const body = (await request.json().catch(() => null));
479
+ const action = REVIEW_ACTIONS.find((value) => value === body?.action);
480
+ if (!action)
481
+ return errorResponse(`action must be one of: ${REVIEW_ACTIONS.join(', ')}`, 400);
482
+ if (body?.after !== undefined && typeof body.after !== 'string') {
483
+ return errorResponse('after must be a string', 400);
484
+ }
485
+ if (body?.onApprove !== undefined && !readOnApprove(body.onApprove)) {
486
+ return errorResponse('onApprove must be draft or publish', 400);
487
+ }
488
+ const target = await loadReviewTarget(db(), item);
489
+ if (target) {
490
+ const scopeErr = writeScopeDenial(auth.session, target.collection);
491
+ if (scopeErr)
492
+ return scopeErr;
493
+ }
494
+ const ctx = buildActionContext(auth.session, db());
495
+ let decided;
496
+ if (action === 'reject') {
497
+ decided = await rejectReviewItem(db(), auth.session.userId, item);
498
+ }
499
+ else if (action === 'undo') {
500
+ decided = await undoReviewItem(db(), ctx, item, target);
501
+ }
502
+ else {
503
+ if (!target) {
504
+ return errorResponse("The document no longer exists, so the change can't be applied.", 409);
505
+ }
506
+ decided = await approveReviewItem(db(), ctx, item, target, {
507
+ onApprove: readOnApprove(body?.onApprove) ?? jobOnApprove(job),
508
+ ...(typeof body?.after === 'string' ? { after: body.after } : {}),
509
+ });
510
+ }
511
+ const users = await loadUserRefs(db(), decided.decidedById ? [decided.decidedById] : []);
512
+ // The document's status after the decision. Undo restores the field only,
513
+ // so a document that an approval published stays published.
514
+ const after = target?.kind === 'document' ? await loadReviewTarget(db(), decided) : null;
515
+ const documentStatus = after?.status ?? null;
516
+ return json({
517
+ data: serializeReviewItem(decided, users),
518
+ documentStatus,
519
+ ...(action === 'undo' && item.status === 'approved' && documentStatus === 'PUBLISHED'
520
+ ? { notice: UNDO_KEEPS_PUBLISHED }
521
+ : {}),
522
+ });
523
+ }
524
+ catch (err) {
525
+ if (err instanceof ReviewError)
526
+ return errorResponse(err.message, err.status);
527
+ return actionError(err, 'decide job review item');
528
+ }
529
+ });
55
530
  }
56
531
  /** Queue a cron's work and return immediately. An active job of the same type is reused. */
57
532
  export async function enqueueCronJob(db, type) {
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/jobs/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/jobs/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { PrentaDB } from '../db/client-types.js';
2
+ import type { Job, JobEvent, JobReviewItem, UserRef } from './contract.js';
3
+ import type { StoredReviewItem } from './review.js';
4
+ import type { JobEventRecord, JobRecord } from './types.js';
5
+ type ReviewCounts = NonNullable<Job['review']>;
6
+ /** Users and review counts the serializer joins in. See {@link loadJobRefs}. */
7
+ export interface JobRefs {
8
+ users: ReadonlyMap<string, UserRef>;
9
+ review: ReadonlyMap<string, ReviewCounts>;
10
+ }
11
+ /**
12
+ * Who a batch AI job writes as, and where, for permission checks. Each item
13
+ * stores the user and role it was queued with, and the worker writes with them.
14
+ * `autoApply` is true only for a stored `review: 'auto'`. Rows from `/ai/batch`
15
+ * have no review mode: any editor could queue them.
16
+ */
17
+ export declare function batchAiWriter(job: JobRecord): {
18
+ creatorId: string | null;
19
+ roles: string[];
20
+ collections: string[];
21
+ autoApply: boolean;
22
+ };
23
+ /**
24
+ * The stored row in the contract shape (DATA_CONTRACTS §1). `lastError` is one
25
+ * summary line unless `fullError` is set, because the full text has the stack,
26
+ * with server paths and query text. `detail` adds scan results.
27
+ */
28
+ export declare function serializeJob(job: JobRecord, refs?: JobRefs, options?: {
29
+ detail?: boolean;
30
+ fullError?: boolean;
31
+ }): Job;
32
+ export declare function serializeJobEvent(event: JobEventRecord): JobEvent;
33
+ /** People by id, one query. An id with no user is left out; {@link userRef} fills it in. */
34
+ export declare function loadUserRefs(db: PrentaDB, ids: Iterable<string>): Promise<Map<string, UserRef>>;
35
+ /** One query for the people on these jobs and one for batch AI review counts. */
36
+ export declare function loadJobRefs(db: PrentaDB, jobs: JobRecord[]): Promise<JobRefs>;
37
+ /** A review item in the contract shape, with who decided it. */
38
+ export declare function serializeReviewItem(item: StoredReviewItem, users: ReadonlyMap<string, UserRef>): JobReviewItem;
39
+ export {};
40
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/jobs/serialize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAIV,GAAG,EACH,QAAQ,EACR,aAAa,EAEb,OAAO,EACR,MAAM,eAAe,CAAA;AAEtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3D,KAAK,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;AAE9C,gFAAgF;AAChF,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CAC1C;AA2FD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,SAAS,GAAG;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,SAAS,EAAE,OAAO,CAAA;CACnB,CAUA;AA4CD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,SAAS,EACd,IAAI,GAAE,OAAiB,EACvB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACtD,GAAG,CAwCL;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,QAAQ,CASjE;AAED,4FAA4F;AAC5F,wBAAsB,YAAY,CAChC,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,GACpB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAa/B;AAED,iFAAiF;AACjF,wBAAsB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CA4BnF;AAED,gEAAgE;AAChE,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,aAAa,CAgBf"}