@atproto/ozone 0.1.173 → 0.1.174

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 (411) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +40 -0
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/moderation/emitEvent.d.ts.map +1 -1
  6. package/dist/api/moderation/emitEvent.js +31 -0
  7. package/dist/api/moderation/emitEvent.js.map +1 -1
  8. package/dist/api/queue/assignModerator.d.ts +4 -0
  9. package/dist/api/queue/assignModerator.d.ts.map +1 -0
  10. package/dist/api/queue/assignModerator.js +28 -0
  11. package/dist/api/queue/assignModerator.js.map +1 -0
  12. package/dist/api/queue/createQueue.d.ts +4 -0
  13. package/dist/api/queue/createQueue.d.ts.map +1 -0
  14. package/dist/api/queue/createQueue.js +44 -0
  15. package/dist/api/queue/createQueue.js.map +1 -0
  16. package/dist/api/queue/deleteQueue.d.ts +4 -0
  17. package/dist/api/queue/deleteQueue.d.ts.map +1 -0
  18. package/dist/api/queue/deleteQueue.js +40 -0
  19. package/dist/api/queue/deleteQueue.js.map +1 -0
  20. package/dist/api/queue/getAssignments.d.ts +4 -0
  21. package/dist/api/queue/getAssignments.d.ts.map +1 -0
  22. package/dist/api/queue/getAssignments.js +19 -0
  23. package/dist/api/queue/getAssignments.js.map +1 -0
  24. package/dist/api/queue/listQueues.d.ts +4 -0
  25. package/dist/api/queue/listQueues.d.ts.map +1 -0
  26. package/dist/api/queue/listQueues.js +29 -0
  27. package/dist/api/queue/listQueues.js.map +1 -0
  28. package/dist/api/queue/routeReports.d.ts +4 -0
  29. package/dist/api/queue/routeReports.d.ts.map +1 -0
  30. package/dist/api/queue/routeReports.js +33 -0
  31. package/dist/api/queue/routeReports.js.map +1 -0
  32. package/dist/api/queue/unassignModerator.d.ts +4 -0
  33. package/dist/api/queue/unassignModerator.d.ts.map +1 -0
  34. package/dist/api/queue/unassignModerator.js +24 -0
  35. package/dist/api/queue/unassignModerator.js.map +1 -0
  36. package/dist/api/queue/updateQueue.d.ts +4 -0
  37. package/dist/api/queue/updateQueue.d.ts.map +1 -0
  38. package/dist/api/queue/updateQueue.js +39 -0
  39. package/dist/api/queue/updateQueue.js.map +1 -0
  40. package/dist/api/report/assignModerator.d.ts +4 -0
  41. package/dist/api/report/assignModerator.d.ts.map +1 -0
  42. package/dist/api/report/assignModerator.js +33 -0
  43. package/dist/api/report/assignModerator.js.map +1 -0
  44. package/dist/api/report/createActivity.d.ts +4 -0
  45. package/dist/api/report/createActivity.d.ts.map +1 -0
  46. package/dist/api/report/createActivity.js +44 -0
  47. package/dist/api/report/createActivity.js.map +1 -0
  48. package/dist/api/report/getAssignments.d.ts +4 -0
  49. package/dist/api/report/getAssignments.d.ts.map +1 -0
  50. package/dist/api/report/getAssignments.js +19 -0
  51. package/dist/api/report/getAssignments.js.map +1 -0
  52. package/dist/api/report/getHistoricalStats.d.ts +4 -0
  53. package/dist/api/report/getHistoricalStats.d.ts.map +1 -0
  54. package/dist/api/report/getHistoricalStats.js +32 -0
  55. package/dist/api/report/getHistoricalStats.js.map +1 -0
  56. package/dist/api/report/getLatestReport.d.ts +4 -0
  57. package/dist/api/report/getLatestReport.d.ts.map +1 -0
  58. package/dist/api/report/getLatestReport.js +31 -0
  59. package/dist/api/report/getLatestReport.js.map +1 -0
  60. package/dist/api/report/getLiveStats.d.ts +4 -0
  61. package/dist/api/report/getLiveStats.d.ts.map +1 -0
  62. package/dist/api/report/getLiveStats.js +25 -0
  63. package/dist/api/report/getLiveStats.js.map +1 -0
  64. package/dist/api/report/getReport.d.ts +4 -0
  65. package/dist/api/report/getReport.d.ts.map +1 -0
  66. package/dist/api/report/getReport.js +35 -0
  67. package/dist/api/report/getReport.js.map +1 -0
  68. package/dist/api/report/listActivities.d.ts +4 -0
  69. package/dist/api/report/listActivities.d.ts.map +1 -0
  70. package/dist/api/report/listActivities.js +25 -0
  71. package/dist/api/report/listActivities.js.map +1 -0
  72. package/dist/api/report/queryReports.d.ts +4 -0
  73. package/dist/api/report/queryReports.d.ts.map +1 -0
  74. package/dist/api/report/queryReports.js +29 -0
  75. package/dist/api/report/queryReports.js.map +1 -0
  76. package/dist/api/report/reassignQueue.d.ts +4 -0
  77. package/dist/api/report/reassignQueue.d.ts.map +1 -0
  78. package/dist/api/report/reassignQueue.js +45 -0
  79. package/dist/api/report/reassignQueue.js.map +1 -0
  80. package/dist/api/report/refreshStats.d.ts +4 -0
  81. package/dist/api/report/refreshStats.d.ts.map +1 -0
  82. package/dist/api/report/refreshStats.js +26 -0
  83. package/dist/api/report/refreshStats.js.map +1 -0
  84. package/dist/api/report/unassignModerator.d.ts +4 -0
  85. package/dist/api/report/unassignModerator.d.ts.map +1 -0
  86. package/dist/api/report/unassignModerator.js +21 -0
  87. package/dist/api/report/unassignModerator.js.map +1 -0
  88. package/dist/api/util.d.ts +2 -0
  89. package/dist/api/util.d.ts.map +1 -1
  90. package/dist/api/util.js +9 -1
  91. package/dist/api/util.js.map +1 -1
  92. package/dist/assignment/index.d.ts +89 -0
  93. package/dist/assignment/index.d.ts.map +1 -0
  94. package/dist/assignment/index.js +537 -0
  95. package/dist/assignment/index.js.map +1 -0
  96. package/dist/config/config.d.ts +14 -0
  97. package/dist/config/config.d.ts.map +1 -1
  98. package/dist/config/config.js +9 -0
  99. package/dist/config/config.js.map +1 -1
  100. package/dist/config/env.d.ts +3 -0
  101. package/dist/config/env.d.ts.map +1 -1
  102. package/dist/config/env.js +3 -0
  103. package/dist/config/env.js.map +1 -1
  104. package/dist/context.d.ts +9 -0
  105. package/dist/context.d.ts.map +1 -1
  106. package/dist/context.js +31 -10
  107. package/dist/context.js.map +1 -1
  108. package/dist/daemon/context.d.ts +6 -0
  109. package/dist/daemon/context.d.ts.map +1 -1
  110. package/dist/daemon/context.js +28 -4
  111. package/dist/daemon/context.js.map +1 -1
  112. package/dist/daemon/job-cursor.d.ts +5 -0
  113. package/dist/daemon/job-cursor.d.ts.map +1 -0
  114. package/dist/daemon/job-cursor.js +28 -0
  115. package/dist/daemon/job-cursor.js.map +1 -0
  116. package/dist/daemon/queue-router.d.ts +17 -0
  117. package/dist/daemon/queue-router.d.ts.map +1 -0
  118. package/dist/daemon/queue-router.js +114 -0
  119. package/dist/daemon/queue-router.js.map +1 -0
  120. package/dist/daemon/stats-computer.d.ts +51 -0
  121. package/dist/daemon/stats-computer.d.ts.map +1 -0
  122. package/dist/daemon/stats-computer.js +117 -0
  123. package/dist/daemon/stats-computer.js.map +1 -0
  124. package/dist/daemon/strike-expiry-processor.d.ts.map +1 -1
  125. package/dist/daemon/strike-expiry-processor.js +4 -19
  126. package/dist/daemon/strike-expiry-processor.js.map +1 -1
  127. package/dist/db/migrations/20260219T164523000Z-create-report-table.d.ts +4 -0
  128. package/dist/db/migrations/20260219T164523000Z-create-report-table.d.ts.map +1 -0
  129. package/dist/db/migrations/20260219T164523000Z-create-report-table.js +126 -0
  130. package/dist/db/migrations/20260219T164523000Z-create-report-table.js.map +1 -0
  131. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.d.ts +4 -0
  132. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.d.ts.map +1 -0
  133. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.js +35 -0
  134. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.js.map +1 -0
  135. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.d.ts +4 -0
  136. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.d.ts.map +1 -0
  137. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.js +36 -0
  138. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.js.map +1 -0
  139. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.d.ts +4 -0
  140. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.d.ts.map +1 -0
  141. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.js +39 -0
  142. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.js.map +1 -0
  143. package/dist/db/migrations/20260318T152058935Z-add-report-stat.d.ts +4 -0
  144. package/dist/db/migrations/20260318T152058935Z-add-report-stat.d.ts.map +1 -0
  145. package/dist/db/migrations/20260318T152058935Z-add-report-stat.js +34 -0
  146. package/dist/db/migrations/20260318T152058935Z-add-report-stat.js.map +1 -0
  147. package/dist/db/migrations/index.d.ts +5 -0
  148. package/dist/db/migrations/index.d.ts.map +1 -1
  149. package/dist/db/migrations/index.js +6 -1
  150. package/dist/db/migrations/index.js.map +1 -1
  151. package/dist/db/pagination.d.ts +31 -0
  152. package/dist/db/pagination.d.ts.map +1 -1
  153. package/dist/db/pagination.js +74 -1
  154. package/dist/db/pagination.js.map +1 -1
  155. package/dist/db/schema/index.d.ts +6 -1
  156. package/dist/db/schema/index.d.ts.map +1 -1
  157. package/dist/db/schema/index.js.map +1 -1
  158. package/dist/db/schema/moderator_assignment.d.ts +14 -0
  159. package/dist/db/schema/moderator_assignment.d.ts.map +1 -0
  160. package/dist/db/schema/moderator_assignment.js +5 -0
  161. package/dist/db/schema/moderator_assignment.js.map +1 -0
  162. package/dist/db/schema/report.d.ts +25 -0
  163. package/dist/db/schema/report.d.ts.map +1 -0
  164. package/dist/db/schema/report.js +5 -0
  165. package/dist/db/schema/report.js.map +1 -0
  166. package/dist/db/schema/report_activity.d.ts +18 -0
  167. package/dist/db/schema/report_activity.d.ts.map +1 -0
  168. package/dist/db/schema/report_activity.js +5 -0
  169. package/dist/db/schema/report_activity.js.map +1 -0
  170. package/dist/db/schema/report_queue.d.ts +19 -0
  171. package/dist/db/schema/report_queue.d.ts.map +1 -0
  172. package/dist/db/schema/report_queue.js +5 -0
  173. package/dist/db/schema/report_queue.js.map +1 -0
  174. package/dist/db/schema/report_stat.d.ts +20 -0
  175. package/dist/db/schema/report_stat.d.ts.map +1 -0
  176. package/dist/db/schema/report_stat.js +5 -0
  177. package/dist/db/schema/report_stat.js.map +1 -0
  178. package/dist/lexicon/index.d.ts +50 -0
  179. package/dist/lexicon/index.d.ts.map +1 -1
  180. package/dist/lexicon/index.js +120 -2
  181. package/dist/lexicon/index.js.map +1 -1
  182. package/dist/lexicon/lexicons.d.ts +10535 -7389
  183. package/dist/lexicon/lexicons.d.ts.map +1 -1
  184. package/dist/lexicon/lexicons.js +1789 -122
  185. package/dist/lexicon/lexicons.js.map +1 -1
  186. package/dist/lexicon/types/app/bsky/embed/external.d.ts +2 -0
  187. package/dist/lexicon/types/app/bsky/embed/external.d.ts.map +1 -1
  188. package/dist/lexicon/types/app/bsky/embed/external.js.map +1 -1
  189. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts +19 -0
  190. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts.map +1 -1
  191. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.js +9 -0
  192. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.js.map +1 -1
  193. package/dist/lexicon/types/tools/ozone/queue/assignModerator.d.ts +27 -0
  194. package/dist/lexicon/types/tools/ozone/queue/assignModerator.d.ts.map +1 -0
  195. package/dist/lexicon/types/tools/ozone/queue/assignModerator.js +7 -0
  196. package/dist/lexicon/types/tools/ozone/queue/assignModerator.js.map +1 -0
  197. package/dist/lexicon/types/tools/ozone/queue/createQueue.d.ts +35 -0
  198. package/dist/lexicon/types/tools/ozone/queue/createQueue.d.ts.map +1 -0
  199. package/dist/lexicon/types/tools/ozone/queue/createQueue.js +7 -0
  200. package/dist/lexicon/types/tools/ozone/queue/createQueue.js.map +1 -0
  201. package/dist/lexicon/types/tools/ozone/queue/defs.d.ts +62 -0
  202. package/dist/lexicon/types/tools/ozone/queue/defs.d.ts.map +1 -0
  203. package/dist/lexicon/types/tools/ozone/queue/defs.js +34 -0
  204. package/dist/lexicon/types/tools/ozone/queue/defs.js.map +1 -0
  205. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.d.ts +29 -0
  206. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.d.ts.map +1 -0
  207. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.js +7 -0
  208. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.js.map +1 -0
  209. package/dist/lexicon/types/tools/ozone/queue/getAssignments.d.ts +30 -0
  210. package/dist/lexicon/types/tools/ozone/queue/getAssignments.d.ts.map +1 -0
  211. package/dist/lexicon/types/tools/ozone/queue/getAssignments.js +7 -0
  212. package/dist/lexicon/types/tools/ozone/queue/getAssignments.js.map +1 -0
  213. package/dist/lexicon/types/tools/ozone/queue/listQueues.d.ts +32 -0
  214. package/dist/lexicon/types/tools/ozone/queue/listQueues.d.ts.map +1 -0
  215. package/dist/lexicon/types/tools/ozone/queue/listQueues.js +7 -0
  216. package/dist/lexicon/types/tools/ozone/queue/listQueues.js.map +1 -0
  217. package/dist/lexicon/types/tools/ozone/queue/routeReports.d.ts +31 -0
  218. package/dist/lexicon/types/tools/ozone/queue/routeReports.d.ts.map +1 -0
  219. package/dist/lexicon/types/tools/ozone/queue/routeReports.js +7 -0
  220. package/dist/lexicon/types/tools/ozone/queue/routeReports.js.map +1 -0
  221. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.d.ts +18 -0
  222. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.d.ts.map +1 -0
  223. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.js +7 -0
  224. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.js.map +1 -0
  225. package/dist/lexicon/types/tools/ozone/queue/updateQueue.d.ts +32 -0
  226. package/dist/lexicon/types/tools/ozone/queue/updateQueue.d.ts.map +1 -0
  227. package/dist/lexicon/types/tools/ozone/queue/updateQueue.js +7 -0
  228. package/dist/lexicon/types/tools/ozone/queue/updateQueue.js.map +1 -0
  229. package/dist/lexicon/types/tools/ozone/report/assignModerator.d.ts +31 -0
  230. package/dist/lexicon/types/tools/ozone/report/assignModerator.d.ts.map +1 -0
  231. package/dist/lexicon/types/tools/ozone/report/assignModerator.js +7 -0
  232. package/dist/lexicon/types/tools/ozone/report/assignModerator.js.map +1 -0
  233. package/dist/lexicon/types/tools/ozone/report/createActivity.d.ts +37 -0
  234. package/dist/lexicon/types/tools/ozone/report/createActivity.d.ts.map +1 -0
  235. package/dist/lexicon/types/tools/ozone/report/createActivity.js +7 -0
  236. package/dist/lexicon/types/tools/ozone/report/createActivity.js.map +1 -0
  237. package/dist/lexicon/types/tools/ozone/report/defs.d.ts +185 -0
  238. package/dist/lexicon/types/tools/ozone/report/defs.d.ts.map +1 -1
  239. package/dist/lexicon/types/tools/ozone/report/defs.js +108 -0
  240. package/dist/lexicon/types/tools/ozone/report/defs.js.map +1 -1
  241. package/dist/lexicon/types/tools/ozone/report/getAssignments.d.ts +30 -0
  242. package/dist/lexicon/types/tools/ozone/report/getAssignments.d.ts.map +1 -0
  243. package/dist/lexicon/types/tools/ozone/report/getAssignments.js +7 -0
  244. package/dist/lexicon/types/tools/ozone/report/getAssignments.js.map +1 -0
  245. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.d.ts +36 -0
  246. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.d.ts.map +1 -0
  247. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.js +7 -0
  248. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.js.map +1 -0
  249. package/dist/lexicon/types/tools/ozone/report/getLatestReport.d.ts +21 -0
  250. package/dist/lexicon/types/tools/ozone/report/getLatestReport.d.ts.map +1 -0
  251. package/dist/lexicon/types/tools/ozone/report/getLatestReport.js +7 -0
  252. package/dist/lexicon/types/tools/ozone/report/getLatestReport.js.map +1 -0
  253. package/dist/lexicon/types/tools/ozone/report/getLiveStats.d.ts +27 -0
  254. package/dist/lexicon/types/tools/ozone/report/getLiveStats.d.ts.map +1 -0
  255. package/dist/lexicon/types/tools/ozone/report/getLiveStats.js +7 -0
  256. package/dist/lexicon/types/tools/ozone/report/getLiveStats.js.map +1 -0
  257. package/dist/lexicon/types/tools/ozone/report/getReport.d.ts +22 -0
  258. package/dist/lexicon/types/tools/ozone/report/getReport.d.ts.map +1 -0
  259. package/dist/lexicon/types/tools/ozone/report/getReport.js +7 -0
  260. package/dist/lexicon/types/tools/ozone/report/getReport.js.map +1 -0
  261. package/dist/lexicon/types/tools/ozone/report/listActivities.d.ts +26 -0
  262. package/dist/lexicon/types/tools/ozone/report/listActivities.d.ts.map +1 -0
  263. package/dist/lexicon/types/tools/ozone/report/listActivities.js +7 -0
  264. package/dist/lexicon/types/tools/ozone/report/listActivities.js.map +1 -0
  265. package/dist/lexicon/types/tools/ozone/report/queryReports.d.ts +48 -0
  266. package/dist/lexicon/types/tools/ozone/report/queryReports.d.ts.map +1 -0
  267. package/dist/lexicon/types/tools/ozone/report/queryReports.js +7 -0
  268. package/dist/lexicon/types/tools/ozone/report/queryReports.js.map +1 -0
  269. package/dist/lexicon/types/tools/ozone/report/reassignQueue.d.ts +31 -0
  270. package/dist/lexicon/types/tools/ozone/report/reassignQueue.d.ts.map +1 -0
  271. package/dist/lexicon/types/tools/ozone/report/reassignQueue.js +7 -0
  272. package/dist/lexicon/types/tools/ozone/report/reassignQueue.js.map +1 -0
  273. package/dist/lexicon/types/tools/ozone/report/refreshStats.d.ts +28 -0
  274. package/dist/lexicon/types/tools/ozone/report/refreshStats.d.ts.map +1 -0
  275. package/dist/lexicon/types/tools/ozone/report/refreshStats.js +7 -0
  276. package/dist/lexicon/types/tools/ozone/report/refreshStats.js.map +1 -0
  277. package/dist/lexicon/types/tools/ozone/report/unassignModerator.d.ts +25 -0
  278. package/dist/lexicon/types/tools/ozone/report/unassignModerator.d.ts.map +1 -0
  279. package/dist/lexicon/types/tools/ozone/report/unassignModerator.js +7 -0
  280. package/dist/lexicon/types/tools/ozone/report/unassignModerator.js.map +1 -0
  281. package/dist/mod-service/index.d.ts +3 -1
  282. package/dist/mod-service/index.d.ts.map +1 -1
  283. package/dist/mod-service/index.js +39 -2
  284. package/dist/mod-service/index.js.map +1 -1
  285. package/dist/mod-service/report.d.ts +64 -0
  286. package/dist/mod-service/report.d.ts.map +1 -0
  287. package/dist/mod-service/report.js +282 -0
  288. package/dist/mod-service/report.js.map +1 -0
  289. package/dist/mod-service/status.d.ts +20 -0
  290. package/dist/mod-service/status.d.ts.map +1 -1
  291. package/dist/queue/service.d.ts +86 -0
  292. package/dist/queue/service.d.ts.map +1 -0
  293. package/dist/queue/service.js +430 -0
  294. package/dist/queue/service.js.map +1 -0
  295. package/dist/report/activity.d.ts +77 -0
  296. package/dist/report/activity.d.ts.map +1 -0
  297. package/dist/report/activity.js +141 -0
  298. package/dist/report/activity.js.map +1 -0
  299. package/dist/report/handle-report-update.d.ts +47 -0
  300. package/dist/report/handle-report-update.d.ts.map +1 -0
  301. package/dist/report/handle-report-update.js +178 -0
  302. package/dist/report/handle-report-update.js.map +1 -0
  303. package/dist/report/reassign.d.ts +10 -0
  304. package/dist/report/reassign.d.ts.map +1 -0
  305. package/dist/report/reassign.js +75 -0
  306. package/dist/report/reassign.js.map +1 -0
  307. package/dist/report/stats.d.ts +105 -0
  308. package/dist/report/stats.d.ts.map +1 -0
  309. package/dist/report/stats.js +619 -0
  310. package/dist/report/stats.js.map +1 -0
  311. package/dist/report/views.d.ts +111 -0
  312. package/dist/report/views.d.ts.map +1 -0
  313. package/dist/report/views.js +156 -0
  314. package/dist/report/views.js.map +1 -0
  315. package/dist/team/index.d.ts +1 -0
  316. package/dist/team/index.d.ts.map +1 -1
  317. package/dist/team/index.js +11 -0
  318. package/dist/team/index.js.map +1 -1
  319. package/package.json +3 -3
  320. package/src/api/index.ts +40 -0
  321. package/src/api/moderation/emitEvent.ts +38 -0
  322. package/src/api/queue/assignModerator.ts +31 -0
  323. package/src/api/queue/createQueue.ts +62 -0
  324. package/src/api/queue/deleteQueue.ts +56 -0
  325. package/src/api/queue/getAssignments.ts +19 -0
  326. package/src/api/queue/listQueues.ts +39 -0
  327. package/src/api/queue/routeReports.ts +44 -0
  328. package/src/api/queue/unassignModerator.ts +26 -0
  329. package/src/api/queue/updateQueue.ts +54 -0
  330. package/src/api/report/assignModerator.ts +36 -0
  331. package/src/api/report/createActivity.ts +57 -0
  332. package/src/api/report/getAssignments.ts +20 -0
  333. package/src/api/report/getHistoricalStats.ts +41 -0
  334. package/src/api/report/getLatestReport.ts +44 -0
  335. package/src/api/report/getLiveStats.ts +26 -0
  336. package/src/api/report/getReport.ts +55 -0
  337. package/src/api/report/listActivities.ts +34 -0
  338. package/src/api/report/queryReports.ts +44 -0
  339. package/src/api/report/reassignQueue.ts +68 -0
  340. package/src/api/report/refreshStats.ts +27 -0
  341. package/src/api/report/unassignModerator.ts +21 -0
  342. package/src/api/util.ts +12 -0
  343. package/src/assignment/index.ts +731 -0
  344. package/src/config/config.ts +27 -0
  345. package/src/config/env.ts +8 -0
  346. package/src/context.ts +31 -0
  347. package/src/daemon/context.ts +34 -0
  348. package/src/daemon/job-cursor.ts +33 -0
  349. package/src/daemon/queue-router.ts +101 -0
  350. package/src/daemon/stats-computer.ts +101 -0
  351. package/src/daemon/strike-expiry-processor.ts +4 -20
  352. package/src/db/migrations/20260219T164523000Z-create-report-table.ts +155 -0
  353. package/src/db/migrations/20260219T165302248Z-moderator-assignment.ts +42 -0
  354. package/src/db/migrations/20260225T000000000Z-add-report-queue-table.ts +41 -0
  355. package/src/db/migrations/20260313T000000000Z-add-report-activity-table.ts +48 -0
  356. package/src/db/migrations/20260318T152058935Z-add-report-stat.ts +35 -0
  357. package/src/db/migrations/index.ts +5 -0
  358. package/src/db/pagination.ts +85 -0
  359. package/src/db/schema/index.ts +10 -0
  360. package/src/db/schema/moderator_assignment.ts +16 -0
  361. package/src/db/schema/report.ts +27 -0
  362. package/src/db/schema/report_activity.ts +22 -0
  363. package/src/db/schema/report_queue.ts +21 -0
  364. package/src/db/schema/report_stat.ts +27 -0
  365. package/src/lexicon/index.ts +280 -0
  366. package/src/lexicon/lexicons.ts +1910 -160
  367. package/src/lexicon/types/app/bsky/embed/external.ts +2 -0
  368. package/src/lexicon/types/tools/ozone/moderation/emitEvent.ts +24 -0
  369. package/src/lexicon/types/tools/ozone/queue/assignModerator.ts +46 -0
  370. package/src/lexicon/types/tools/ozone/queue/createQueue.ts +54 -0
  371. package/src/lexicon/types/tools/ozone/queue/defs.ts +99 -0
  372. package/src/lexicon/types/tools/ozone/queue/deleteQueue.ts +48 -0
  373. package/src/lexicon/types/tools/ozone/queue/getAssignments.ts +48 -0
  374. package/src/lexicon/types/tools/ozone/queue/listQueues.ts +50 -0
  375. package/src/lexicon/types/tools/ozone/queue/routeReports.ts +50 -0
  376. package/src/lexicon/types/tools/ozone/queue/unassignModerator.ts +37 -0
  377. package/src/lexicon/types/tools/ozone/queue/updateQueue.ts +51 -0
  378. package/src/lexicon/types/tools/ozone/report/assignModerator.ts +50 -0
  379. package/src/lexicon/types/tools/ozone/report/createActivity.ts +60 -0
  380. package/src/lexicon/types/tools/ozone/report/defs.ts +327 -0
  381. package/src/lexicon/types/tools/ozone/report/getAssignments.ts +48 -0
  382. package/src/lexicon/types/tools/ozone/report/getHistoricalStats.ts +54 -0
  383. package/src/lexicon/types/tools/ozone/report/getLatestReport.ts +39 -0
  384. package/src/lexicon/types/tools/ozone/report/getLiveStats.ts +45 -0
  385. package/src/lexicon/types/tools/ozone/report/getReport.ts +38 -0
  386. package/src/lexicon/types/tools/ozone/report/listActivities.ts +44 -0
  387. package/src/lexicon/types/tools/ozone/report/queryReports.ts +72 -0
  388. package/src/lexicon/types/tools/ozone/report/reassignQueue.ts +55 -0
  389. package/src/lexicon/types/tools/ozone/report/refreshStats.ts +46 -0
  390. package/src/lexicon/types/tools/ozone/report/unassignModerator.ts +44 -0
  391. package/src/mod-service/index.ts +45 -3
  392. package/src/mod-service/report.ts +408 -0
  393. package/src/queue/service.ts +599 -0
  394. package/src/report/activity.ts +234 -0
  395. package/src/report/handle-report-update.ts +209 -0
  396. package/src/report/reassign.ts +109 -0
  397. package/src/report/stats.ts +850 -0
  398. package/src/report/views.ts +241 -0
  399. package/src/team/index.ts +11 -0
  400. package/tests/get-report.test.ts +136 -0
  401. package/tests/query-reports.test.ts +608 -0
  402. package/tests/queue-assignment.test.ts +428 -0
  403. package/tests/queue-router.test.ts +306 -0
  404. package/tests/queues.test.ts +690 -0
  405. package/tests/report-action.test.ts +308 -0
  406. package/tests/report-activity.test.ts +567 -0
  407. package/tests/report-assignment.test.ts +517 -0
  408. package/tests/report-reassign-queue.test.ts +340 -0
  409. package/tests/report-routing.test.ts +245 -0
  410. package/tests/report-stats.test.ts +545 -0
  411. package/tsconfig.build.tsbuildinfo +1 -1
@@ -0,0 +1,567 @@
1
+ import AtpAgent from '@atproto/api'
2
+ import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
3
+ import { ids } from '../src/lexicon/lexicons'
4
+ import { REASONSPAM } from '../src/lexicon/types/com/atproto/moderation/defs'
5
+
6
+ const DEFS = 'tools.ozone.report.defs'
7
+
8
+ describe('report-activity', () => {
9
+ let network: TestNetwork
10
+ let agent: AtpAgent
11
+ let sc: SeedClient
12
+
13
+ const modHeaders = async (nsid: string) =>
14
+ network.ozone.modHeaders(nsid, 'admin')
15
+
16
+ const createReport = async (subjectDid: string) => {
17
+ await sc.createReport({
18
+ reasonType: REASONSPAM,
19
+ subject: {
20
+ $type: 'com.atproto.admin.defs#repoRef',
21
+ did: subjectDid,
22
+ },
23
+ reportedBy: sc.dids.bob,
24
+ })
25
+ await network.processAll()
26
+
27
+ const { data } = await agent.tools.ozone.report.queryReports(
28
+ { status: 'open', subject: subjectDid },
29
+ { headers: await modHeaders(ids.ToolsOzoneReportQueryReports) },
30
+ )
31
+ const report = data.reports[0]
32
+ if (!report) throw new Error(`No report found for subject ${subjectDid}`)
33
+ return report
34
+ }
35
+
36
+ const createActivity = async (
37
+ input: {
38
+ reportId: number
39
+ activity: { $type: string; [k: string]: unknown }
40
+ internalNote?: string
41
+ publicNote?: string
42
+ isAutomated?: boolean
43
+ },
44
+ role: 'admin' | 'triage' = 'admin',
45
+ ) => {
46
+ return agent.tools.ozone.report.createActivity(input, {
47
+ encoding: 'application/json',
48
+ headers: await network.ozone.modHeaders(
49
+ ids.ToolsOzoneReportCreateActivity,
50
+ role,
51
+ ),
52
+ })
53
+ }
54
+
55
+ const listActivities = async (
56
+ params: { reportId: number; limit?: number; cursor?: string },
57
+ role: 'admin' | 'triage' = 'admin',
58
+ ) => {
59
+ return agent.tools.ozone.report.listActivities(params, {
60
+ headers: await network.ozone.modHeaders(
61
+ ids.ToolsOzoneReportListActivities,
62
+ role,
63
+ ),
64
+ })
65
+ }
66
+
67
+ beforeAll(async () => {
68
+ network = await TestNetwork.create({
69
+ dbPostgresSchema: 'ozone_report_activity',
70
+ })
71
+ agent = network.ozone.getAgent()
72
+ sc = network.getSeedClient()
73
+ await basicSeed(sc)
74
+ await network.processAll()
75
+ })
76
+
77
+ afterAll(async () => {
78
+ await network.close()
79
+ })
80
+
81
+ describe('createActivity — noteActivity', () => {
82
+ it('creates an internal note', async () => {
83
+ const report = await createReport(sc.dids.alice)
84
+ const { data } = await createActivity({
85
+ reportId: report.id,
86
+ activity: { $type: `${DEFS}#noteActivity` },
87
+ internalNote: 'Looks like this may be a bot account.',
88
+ })
89
+
90
+ expect(data.activity.reportId).toBe(report.id)
91
+ expect(data.activity.activity.$type).toBe(`${DEFS}#noteActivity`)
92
+ expect(data.activity.internalNote).toBe(
93
+ 'Looks like this may be a bot account.',
94
+ )
95
+ expect(data.activity.publicNote).toBeUndefined()
96
+ expect(data.activity.isAutomated).toBe(false)
97
+ expect(data.activity.createdBy).toBeDefined()
98
+ expect(data.activity.createdAt).toBeDefined()
99
+ expect(data.activity.id).toBeDefined()
100
+ })
101
+
102
+ it('creates a public note', async () => {
103
+ const report = await createReport(sc.dids.alice)
104
+ const { data } = await createActivity({
105
+ reportId: report.id,
106
+ activity: { $type: `${DEFS}#noteActivity` },
107
+ publicNote: 'We have reviewed your report.',
108
+ })
109
+
110
+ expect(data.activity.activity.$type).toBe(`${DEFS}#noteActivity`)
111
+ expect(data.activity.publicNote).toBe('We have reviewed your report.')
112
+ expect(data.activity.internalNote).toBeUndefined()
113
+ })
114
+
115
+ it('creates a note without text', async () => {
116
+ const report = await createReport(sc.dids.alice)
117
+ const { data } = await createActivity({
118
+ reportId: report.id,
119
+ activity: { $type: `${DEFS}#noteActivity` },
120
+ })
121
+
122
+ expect(data.activity.activity.$type).toBe(`${DEFS}#noteActivity`)
123
+ expect(data.activity.internalNote).toBeUndefined()
124
+ expect(data.activity.publicNote).toBeUndefined()
125
+ })
126
+
127
+ it('does not change report status', async () => {
128
+ const report = await createReport(sc.dids.alice)
129
+ await createActivity({
130
+ reportId: report.id,
131
+ activity: { $type: `${DEFS}#noteActivity` },
132
+ internalNote: 'Just noting this.',
133
+ })
134
+
135
+ const { data: updated } = await agent.tools.ozone.report.getReport(
136
+ { id: report.id },
137
+ { headers: await modHeaders(ids.ToolsOzoneReportGetReport) },
138
+ )
139
+ expect(updated.status).toBe('open')
140
+ })
141
+ })
142
+
143
+ describe('createActivity — state-change activities (valid transitions)', () => {
144
+ it('open → closed (closeActivity)', async () => {
145
+ const report = await createReport(sc.dids.alice)
146
+ const { data } = await createActivity({
147
+ reportId: report.id,
148
+ activity: { $type: `${DEFS}#closeActivity` },
149
+ })
150
+
151
+ expect(data.activity.activity.$type).toBe(`${DEFS}#closeActivity`)
152
+ if ('previousStatus' in data.activity.activity) {
153
+ expect(data.activity.activity.previousStatus).toBe('open')
154
+ }
155
+
156
+ const { data: updated } = await agent.tools.ozone.report.getReport(
157
+ { id: report.id },
158
+ { headers: await modHeaders(ids.ToolsOzoneReportGetReport) },
159
+ )
160
+ expect(updated.status).toBe('closed')
161
+ })
162
+
163
+ it('open → escalated (escalationActivity)', async () => {
164
+ const report = await createReport(sc.dids.alice)
165
+ const { data } = await createActivity({
166
+ reportId: report.id,
167
+ activity: { $type: `${DEFS}#escalationActivity` },
168
+ })
169
+
170
+ expect(data.activity.activity.$type).toBe(`${DEFS}#escalationActivity`)
171
+ if ('previousStatus' in data.activity.activity) {
172
+ expect(data.activity.activity.previousStatus).toBe('open')
173
+ }
174
+ })
175
+
176
+ it('open → queued (queueActivity)', async () => {
177
+ const report = await createReport(sc.dids.alice)
178
+ const { data } = await createActivity({
179
+ reportId: report.id,
180
+ activity: { $type: `${DEFS}#queueActivity` },
181
+ })
182
+
183
+ expect(data.activity.activity.$type).toBe(`${DEFS}#queueActivity`)
184
+ if ('previousStatus' in data.activity.activity) {
185
+ expect(data.activity.activity.previousStatus).toBe('open')
186
+ }
187
+ })
188
+
189
+ it('open → assigned (assignmentActivity)', async () => {
190
+ const report = await createReport(sc.dids.alice)
191
+ const { data } = await createActivity({
192
+ reportId: report.id,
193
+ activity: { $type: `${DEFS}#assignmentActivity` },
194
+ })
195
+
196
+ expect(data.activity.activity.$type).toBe(`${DEFS}#assignmentActivity`)
197
+ if ('previousStatus' in data.activity.activity) {
198
+ expect(data.activity.activity.previousStatus).toBe('open')
199
+ }
200
+ })
201
+
202
+ it('queued → assigned (assignmentActivity)', async () => {
203
+ const report = await createReport(sc.dids.alice)
204
+ await createActivity({
205
+ reportId: report.id,
206
+ activity: { $type: `${DEFS}#queueActivity` },
207
+ })
208
+ const { data } = await createActivity({
209
+ reportId: report.id,
210
+ activity: { $type: `${DEFS}#assignmentActivity` },
211
+ })
212
+
213
+ if ('previousStatus' in data.activity.activity) {
214
+ expect(data.activity.activity.previousStatus).toBe('queued')
215
+ }
216
+ })
217
+
218
+ it('escalated → closed (closeActivity)', async () => {
219
+ const report = await createReport(sc.dids.alice)
220
+ await createActivity({
221
+ reportId: report.id,
222
+ activity: { $type: `${DEFS}#escalationActivity` },
223
+ })
224
+ const { data } = await createActivity({
225
+ reportId: report.id,
226
+ activity: { $type: `${DEFS}#closeActivity` },
227
+ })
228
+
229
+ if ('previousStatus' in data.activity.activity) {
230
+ expect(data.activity.activity.previousStatus).toBe('escalated')
231
+ }
232
+ })
233
+
234
+ it('assigned → closed (closeActivity)', async () => {
235
+ const report = await createReport(sc.dids.alice)
236
+ await createActivity({
237
+ reportId: report.id,
238
+ activity: { $type: `${DEFS}#assignmentActivity` },
239
+ })
240
+ const { data } = await createActivity({
241
+ reportId: report.id,
242
+ activity: { $type: `${DEFS}#closeActivity` },
243
+ })
244
+
245
+ if ('previousStatus' in data.activity.activity) {
246
+ expect(data.activity.activity.previousStatus).toBe('assigned')
247
+ }
248
+ })
249
+
250
+ it('assigned → escalated (escalationActivity)', async () => {
251
+ const report = await createReport(sc.dids.alice)
252
+ await createActivity({
253
+ reportId: report.id,
254
+ activity: { $type: `${DEFS}#assignmentActivity` },
255
+ })
256
+ const { data } = await createActivity({
257
+ reportId: report.id,
258
+ activity: { $type: `${DEFS}#escalationActivity` },
259
+ })
260
+
261
+ if ('previousStatus' in data.activity.activity) {
262
+ expect(data.activity.activity.previousStatus).toBe('assigned')
263
+ }
264
+ })
265
+
266
+ it('closed → open (reopenActivity)', async () => {
267
+ const report = await createReport(sc.dids.alice)
268
+ await createActivity({
269
+ reportId: report.id,
270
+ activity: { $type: `${DEFS}#closeActivity` },
271
+ })
272
+ const { data } = await createActivity({
273
+ reportId: report.id,
274
+ activity: { $type: `${DEFS}#reopenActivity` },
275
+ })
276
+
277
+ expect(data.activity.activity.$type).toBe(`${DEFS}#reopenActivity`)
278
+ if ('previousStatus' in data.activity.activity) {
279
+ expect(data.activity.activity.previousStatus).toBe('closed')
280
+ }
281
+
282
+ const { data: updated } = await agent.tools.ozone.report.getReport(
283
+ { id: report.id },
284
+ { headers: await modHeaders(ids.ToolsOzoneReportGetReport) },
285
+ )
286
+ expect(updated.status).toBe('open')
287
+ })
288
+
289
+ it('attaches internalNote and publicNote alongside a state-change', async () => {
290
+ const report = await createReport(sc.dids.alice)
291
+ const { data } = await createActivity({
292
+ reportId: report.id,
293
+ activity: { $type: `${DEFS}#closeActivity` },
294
+ internalNote: 'Confirmed spam internally.',
295
+ publicNote: 'We have closed your report.',
296
+ })
297
+
298
+ expect(data.activity.activity.$type).toBe(`${DEFS}#closeActivity`)
299
+ expect(data.activity.internalNote).toBe('Confirmed spam internally.')
300
+ expect(data.activity.publicNote).toBe('We have closed your report.')
301
+ })
302
+ })
303
+
304
+ describe('createActivity — AlreadyInTargetState', () => {
305
+ it('rejects when report is already in the target status', async () => {
306
+ const report = await createReport(sc.dids.alice)
307
+ // Report starts as 'open', closeActivity targets 'closed'
308
+ await createActivity({
309
+ reportId: report.id,
310
+ activity: { $type: `${DEFS}#closeActivity` },
311
+ })
312
+ await expect(
313
+ createActivity({
314
+ reportId: report.id,
315
+ activity: { $type: `${DEFS}#closeActivity` },
316
+ }),
317
+ ).rejects.toMatchObject({ error: 'AlreadyInTargetState' })
318
+ })
319
+
320
+ it('does not record an activity when AlreadyInTargetState is thrown', async () => {
321
+ const report = await createReport(sc.dids.alice)
322
+ // queueActivity targets 'queued' — report already starts 'open' so first one works
323
+ await createActivity({
324
+ reportId: report.id,
325
+ activity: { $type: `${DEFS}#queueActivity` },
326
+ })
327
+ await expect(
328
+ createActivity({
329
+ reportId: report.id,
330
+ activity: { $type: `${DEFS}#queueActivity` },
331
+ }),
332
+ ).rejects.toMatchObject({ error: 'AlreadyInTargetState' })
333
+
334
+ const { data } = await listActivities({ reportId: report.id })
335
+ expect(data.activities).toHaveLength(1)
336
+ })
337
+ })
338
+
339
+ describe('createActivity — InvalidStateTransition', () => {
340
+ it('rejects closed → escalated', async () => {
341
+ const report = await createReport(sc.dids.alice)
342
+ await createActivity({
343
+ reportId: report.id,
344
+ activity: { $type: `${DEFS}#closeActivity` },
345
+ })
346
+ await expect(
347
+ createActivity({
348
+ reportId: report.id,
349
+ activity: { $type: `${DEFS}#escalationActivity` },
350
+ }),
351
+ ).rejects.toMatchObject({ error: 'InvalidStateTransition' })
352
+ })
353
+
354
+ it('rejects closed → queued', async () => {
355
+ const report = await createReport(sc.dids.alice)
356
+ await createActivity({
357
+ reportId: report.id,
358
+ activity: { $type: `${DEFS}#closeActivity` },
359
+ })
360
+ await expect(
361
+ createActivity({
362
+ reportId: report.id,
363
+ activity: { $type: `${DEFS}#queueActivity` },
364
+ }),
365
+ ).rejects.toMatchObject({ error: 'InvalidStateTransition' })
366
+ })
367
+
368
+ it('rejects escalated → queued', async () => {
369
+ const report = await createReport(sc.dids.alice)
370
+ await createActivity({
371
+ reportId: report.id,
372
+ activity: { $type: `${DEFS}#escalationActivity` },
373
+ })
374
+ await expect(
375
+ createActivity({
376
+ reportId: report.id,
377
+ activity: { $type: `${DEFS}#queueActivity` },
378
+ }),
379
+ ).rejects.toMatchObject({ error: 'InvalidStateTransition' })
380
+ })
381
+
382
+ it('rejects queued → closed', async () => {
383
+ const report = await createReport(sc.dids.alice)
384
+ await createActivity({
385
+ reportId: report.id,
386
+ activity: { $type: `${DEFS}#queueActivity` },
387
+ })
388
+ await expect(
389
+ createActivity({
390
+ reportId: report.id,
391
+ activity: { $type: `${DEFS}#closeActivity` },
392
+ }),
393
+ ).rejects.toMatchObject({ error: 'InvalidStateTransition' })
394
+ })
395
+
396
+ it('rejects reopenActivity on open report', async () => {
397
+ const report = await createReport(sc.dids.alice)
398
+ // report starts as 'open', reopenActivity only valid from 'closed'
399
+ await expect(
400
+ createActivity({
401
+ reportId: report.id,
402
+ activity: { $type: `${DEFS}#reopenActivity` },
403
+ }),
404
+ ).rejects.toMatchObject({ error: 'InvalidStateTransition' })
405
+ })
406
+
407
+ it('rejects reopenActivity on escalated report', async () => {
408
+ const report = await createReport(sc.dids.alice)
409
+ await createActivity({
410
+ reportId: report.id,
411
+ activity: { $type: `${DEFS}#escalationActivity` },
412
+ })
413
+ await expect(
414
+ createActivity({
415
+ reportId: report.id,
416
+ activity: { $type: `${DEFS}#reopenActivity` },
417
+ }),
418
+ ).rejects.toMatchObject({ error: 'InvalidStateTransition' })
419
+ })
420
+ })
421
+
422
+ describe('createActivity — input validation errors', () => {
423
+ it('rejects unknown activity type', async () => {
424
+ const report = await createReport(sc.dids.alice)
425
+ await expect(
426
+ createActivity({
427
+ reportId: report.id,
428
+ activity: { $type: `${DEFS}#unknownActivity` },
429
+ }),
430
+ ).rejects.toMatchObject({ error: 'InvalidActivityType' })
431
+ })
432
+
433
+ it('rejects unknown reportId', async () => {
434
+ await expect(
435
+ createActivity({
436
+ reportId: 999999,
437
+ activity: { $type: `${DEFS}#noteActivity` },
438
+ internalNote: 'Ghost report',
439
+ }),
440
+ ).rejects.toMatchObject({ error: 'ReportNotFound' })
441
+ })
442
+ })
443
+
444
+ describe('listActivities', () => {
445
+ it('returns empty list for report with no activities', async () => {
446
+ const report = await createReport(sc.dids.alice)
447
+ const { data } = await listActivities({ reportId: report.id })
448
+
449
+ expect(data.activities).toEqual([])
450
+ expect(data.cursor).toBeUndefined()
451
+ })
452
+
453
+ it('returns activities sorted most-recent-first', async () => {
454
+ const report = await createReport(sc.dids.alice)
455
+
456
+ await createActivity({
457
+ reportId: report.id,
458
+ activity: { $type: `${DEFS}#noteActivity` },
459
+ internalNote: 'First note',
460
+ })
461
+ await createActivity({
462
+ reportId: report.id,
463
+ activity: { $type: `${DEFS}#escalationActivity` },
464
+ })
465
+ await createActivity({
466
+ reportId: report.id,
467
+ activity: { $type: `${DEFS}#noteActivity` },
468
+ internalNote: 'Third note',
469
+ })
470
+
471
+ const { data } = await listActivities({ reportId: report.id })
472
+
473
+ expect(data.activities).toHaveLength(3)
474
+ expect(data.activities[0].id).toBeGreaterThan(data.activities[1].id)
475
+ expect(data.activities[1].id).toBeGreaterThan(data.activities[2].id)
476
+ expect(data.activities[0].internalNote).toBe('Third note')
477
+ expect(data.activities[2].internalNote).toBe('First note')
478
+ })
479
+
480
+ it('returns correct shape for each activity type', async () => {
481
+ const report = await createReport(sc.dids.alice)
482
+
483
+ await createActivity({
484
+ reportId: report.id,
485
+ activity: { $type: `${DEFS}#noteActivity` },
486
+ internalNote: 'n',
487
+ })
488
+ await createActivity({
489
+ reportId: report.id,
490
+ activity: { $type: `${DEFS}#closeActivity` },
491
+ })
492
+
493
+ const { data } = await listActivities({ reportId: report.id })
494
+ const [closeAct, noteAct] = data.activities // most-recent first
495
+
496
+ expect(closeAct.activity.$type).toBe(`${DEFS}#closeActivity`)
497
+ if ('previousStatus' in closeAct.activity) {
498
+ expect(closeAct.activity.previousStatus).toBe('open')
499
+ }
500
+ expect(closeAct.internalNote).toBeUndefined()
501
+ expect(closeAct.isAutomated).toBe(false)
502
+
503
+ expect(noteAct.activity.$type).toBe(`${DEFS}#noteActivity`)
504
+ expect('previousStatus' in noteAct.activity).toBe(false)
505
+ expect(noteAct.internalNote).toBe('n')
506
+ })
507
+
508
+ it('paginates correctly', async () => {
509
+ const report = await createReport(sc.dids.alice)
510
+
511
+ for (let i = 0; i < 5; i++) {
512
+ await createActivity({
513
+ reportId: report.id,
514
+ activity: { $type: `${DEFS}#noteActivity` },
515
+ internalNote: `Note ${i}`,
516
+ })
517
+ }
518
+
519
+ const firstPage = await listActivities({ reportId: report.id, limit: 2 })
520
+ expect(firstPage.data.activities).toHaveLength(2)
521
+ expect(firstPage.data.cursor).toBeDefined()
522
+
523
+ const secondPage = await listActivities({
524
+ reportId: report.id,
525
+ limit: 2,
526
+ cursor: firstPage.data.cursor,
527
+ })
528
+ expect(secondPage.data.activities).toHaveLength(2)
529
+ expect(secondPage.data.cursor).toBeDefined()
530
+
531
+ const thirdPage = await listActivities({
532
+ reportId: report.id,
533
+ limit: 2,
534
+ cursor: secondPage.data.cursor,
535
+ })
536
+ expect(thirdPage.data.activities).toHaveLength(1)
537
+ expect(thirdPage.data.cursor).toBeUndefined()
538
+
539
+ const allIds = [
540
+ ...firstPage.data.activities,
541
+ ...secondPage.data.activities,
542
+ ...thirdPage.data.activities,
543
+ ].map((a) => a.id)
544
+ expect(new Set(allIds).size).toBe(5)
545
+ })
546
+
547
+ it('only returns activities for the requested report', async () => {
548
+ const reportA = await createReport(sc.dids.alice)
549
+ const reportB = await createReport(sc.dids.bob)
550
+
551
+ await createActivity({
552
+ reportId: reportA.id,
553
+ activity: { $type: `${DEFS}#noteActivity` },
554
+ internalNote: 'Note on A',
555
+ })
556
+ await createActivity({
557
+ reportId: reportB.id,
558
+ activity: { $type: `${DEFS}#noteActivity` },
559
+ internalNote: 'Note on B',
560
+ })
561
+
562
+ const { data } = await listActivities({ reportId: reportA.id })
563
+ expect(data.activities.every((a) => a.reportId === reportA.id)).toBe(true)
564
+ expect(data.activities.some((a) => a.reportId === reportB.id)).toBe(false)
565
+ })
566
+ })
567
+ })