@atproto/ozone 0.1.172 → 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 (450) hide show
  1. package/CHANGELOG.md +18 -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/event-reverser.d.ts +1 -0
  113. package/dist/daemon/event-reverser.d.ts.map +1 -1
  114. package/dist/daemon/event-reverser.js +42 -1
  115. package/dist/daemon/event-reverser.js.map +1 -1
  116. package/dist/daemon/job-cursor.d.ts +5 -0
  117. package/dist/daemon/job-cursor.d.ts.map +1 -0
  118. package/dist/daemon/job-cursor.js +28 -0
  119. package/dist/daemon/job-cursor.js.map +1 -0
  120. package/dist/daemon/queue-router.d.ts +17 -0
  121. package/dist/daemon/queue-router.d.ts.map +1 -0
  122. package/dist/daemon/queue-router.js +114 -0
  123. package/dist/daemon/queue-router.js.map +1 -0
  124. package/dist/daemon/stats-computer.d.ts +51 -0
  125. package/dist/daemon/stats-computer.d.ts.map +1 -0
  126. package/dist/daemon/stats-computer.js +117 -0
  127. package/dist/daemon/stats-computer.js.map +1 -0
  128. package/dist/daemon/strike-expiry-processor.d.ts.map +1 -1
  129. package/dist/daemon/strike-expiry-processor.js +4 -19
  130. package/dist/daemon/strike-expiry-processor.js.map +1 -1
  131. package/dist/db/migrations/20260219T164523000Z-create-report-table.d.ts +4 -0
  132. package/dist/db/migrations/20260219T164523000Z-create-report-table.d.ts.map +1 -0
  133. package/dist/db/migrations/20260219T164523000Z-create-report-table.js +126 -0
  134. package/dist/db/migrations/20260219T164523000Z-create-report-table.js.map +1 -0
  135. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.d.ts +4 -0
  136. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.d.ts.map +1 -0
  137. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.js +35 -0
  138. package/dist/db/migrations/20260219T165302248Z-moderator-assignment.js.map +1 -0
  139. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.d.ts +4 -0
  140. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.d.ts.map +1 -0
  141. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.js +36 -0
  142. package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.js.map +1 -0
  143. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.d.ts +4 -0
  144. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.d.ts.map +1 -0
  145. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.js +39 -0
  146. package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.js.map +1 -0
  147. package/dist/db/migrations/20260318T152058935Z-add-report-stat.d.ts +4 -0
  148. package/dist/db/migrations/20260318T152058935Z-add-report-stat.d.ts.map +1 -0
  149. package/dist/db/migrations/20260318T152058935Z-add-report-stat.js +34 -0
  150. package/dist/db/migrations/20260318T152058935Z-add-report-stat.js.map +1 -0
  151. package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.d.ts +4 -0
  152. package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.d.ts.map +1 -0
  153. package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.js +32 -0
  154. package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.js.map +1 -0
  155. package/dist/db/migrations/index.d.ts +6 -0
  156. package/dist/db/migrations/index.d.ts.map +1 -1
  157. package/dist/db/migrations/index.js +7 -1
  158. package/dist/db/migrations/index.js.map +1 -1
  159. package/dist/db/pagination.d.ts +31 -0
  160. package/dist/db/pagination.d.ts.map +1 -1
  161. package/dist/db/pagination.js +74 -1
  162. package/dist/db/pagination.js.map +1 -1
  163. package/dist/db/schema/expiring_tag.d.ts +15 -0
  164. package/dist/db/schema/expiring_tag.d.ts.map +1 -0
  165. package/dist/db/schema/expiring_tag.js +5 -0
  166. package/dist/db/schema/expiring_tag.js.map +1 -0
  167. package/dist/db/schema/index.d.ts +7 -1
  168. package/dist/db/schema/index.d.ts.map +1 -1
  169. package/dist/db/schema/index.js.map +1 -1
  170. package/dist/db/schema/moderator_assignment.d.ts +14 -0
  171. package/dist/db/schema/moderator_assignment.d.ts.map +1 -0
  172. package/dist/db/schema/moderator_assignment.js +5 -0
  173. package/dist/db/schema/moderator_assignment.js.map +1 -0
  174. package/dist/db/schema/report.d.ts +25 -0
  175. package/dist/db/schema/report.d.ts.map +1 -0
  176. package/dist/db/schema/report.js +5 -0
  177. package/dist/db/schema/report.js.map +1 -0
  178. package/dist/db/schema/report_activity.d.ts +18 -0
  179. package/dist/db/schema/report_activity.d.ts.map +1 -0
  180. package/dist/db/schema/report_activity.js +5 -0
  181. package/dist/db/schema/report_activity.js.map +1 -0
  182. package/dist/db/schema/report_queue.d.ts +19 -0
  183. package/dist/db/schema/report_queue.d.ts.map +1 -0
  184. package/dist/db/schema/report_queue.js +5 -0
  185. package/dist/db/schema/report_queue.js.map +1 -0
  186. package/dist/db/schema/report_stat.d.ts +20 -0
  187. package/dist/db/schema/report_stat.d.ts.map +1 -0
  188. package/dist/db/schema/report_stat.js +5 -0
  189. package/dist/db/schema/report_stat.js.map +1 -0
  190. package/dist/lexicon/index.d.ts +50 -0
  191. package/dist/lexicon/index.d.ts.map +1 -1
  192. package/dist/lexicon/index.js +120 -2
  193. package/dist/lexicon/index.js.map +1 -1
  194. package/dist/lexicon/lexicons.d.ts +11255 -7885
  195. package/dist/lexicon/lexicons.d.ts.map +1 -1
  196. package/dist/lexicon/lexicons.js +1900 -120
  197. package/dist/lexicon/lexicons.js.map +1 -1
  198. package/dist/lexicon/types/app/bsky/embed/external.d.ts +2 -0
  199. package/dist/lexicon/types/app/bsky/embed/external.d.ts.map +1 -1
  200. package/dist/lexicon/types/app/bsky/embed/external.js.map +1 -1
  201. package/dist/lexicon/types/chat/bsky/actor/defs.d.ts +8 -2
  202. package/dist/lexicon/types/chat/bsky/actor/defs.d.ts.map +1 -1
  203. package/dist/lexicon/types/chat/bsky/actor/defs.js +9 -0
  204. package/dist/lexicon/types/chat/bsky/actor/defs.js.map +1 -1
  205. package/dist/lexicon/types/chat/bsky/convo/defs.d.ts +37 -10
  206. package/dist/lexicon/types/chat/bsky/convo/defs.d.ts.map +1 -1
  207. package/dist/lexicon/types/chat/bsky/convo/defs.js +9 -0
  208. package/dist/lexicon/types/chat/bsky/convo/defs.js.map +1 -1
  209. package/dist/lexicon/types/chat/bsky/convo/getMessages.d.ts +3 -0
  210. package/dist/lexicon/types/chat/bsky/convo/getMessages.d.ts.map +1 -1
  211. package/dist/lexicon/types/chat/bsky/convo/getMessages.js.map +1 -1
  212. package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts +2 -0
  213. package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts.map +1 -1
  214. package/dist/lexicon/types/tools/ozone/moderation/defs.js.map +1 -1
  215. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts +19 -0
  216. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts.map +1 -1
  217. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.js +9 -0
  218. package/dist/lexicon/types/tools/ozone/moderation/emitEvent.js.map +1 -1
  219. package/dist/lexicon/types/tools/ozone/queue/assignModerator.d.ts +27 -0
  220. package/dist/lexicon/types/tools/ozone/queue/assignModerator.d.ts.map +1 -0
  221. package/dist/lexicon/types/tools/ozone/queue/assignModerator.js +7 -0
  222. package/dist/lexicon/types/tools/ozone/queue/assignModerator.js.map +1 -0
  223. package/dist/lexicon/types/tools/ozone/queue/createQueue.d.ts +35 -0
  224. package/dist/lexicon/types/tools/ozone/queue/createQueue.d.ts.map +1 -0
  225. package/dist/lexicon/types/tools/ozone/queue/createQueue.js +7 -0
  226. package/dist/lexicon/types/tools/ozone/queue/createQueue.js.map +1 -0
  227. package/dist/lexicon/types/tools/ozone/queue/defs.d.ts +62 -0
  228. package/dist/lexicon/types/tools/ozone/queue/defs.d.ts.map +1 -0
  229. package/dist/lexicon/types/tools/ozone/queue/defs.js +34 -0
  230. package/dist/lexicon/types/tools/ozone/queue/defs.js.map +1 -0
  231. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.d.ts +29 -0
  232. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.d.ts.map +1 -0
  233. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.js +7 -0
  234. package/dist/lexicon/types/tools/ozone/queue/deleteQueue.js.map +1 -0
  235. package/dist/lexicon/types/tools/ozone/queue/getAssignments.d.ts +30 -0
  236. package/dist/lexicon/types/tools/ozone/queue/getAssignments.d.ts.map +1 -0
  237. package/dist/lexicon/types/tools/ozone/queue/getAssignments.js +7 -0
  238. package/dist/lexicon/types/tools/ozone/queue/getAssignments.js.map +1 -0
  239. package/dist/lexicon/types/tools/ozone/queue/listQueues.d.ts +32 -0
  240. package/dist/lexicon/types/tools/ozone/queue/listQueues.d.ts.map +1 -0
  241. package/dist/lexicon/types/tools/ozone/queue/listQueues.js +7 -0
  242. package/dist/lexicon/types/tools/ozone/queue/listQueues.js.map +1 -0
  243. package/dist/lexicon/types/tools/ozone/queue/routeReports.d.ts +31 -0
  244. package/dist/lexicon/types/tools/ozone/queue/routeReports.d.ts.map +1 -0
  245. package/dist/lexicon/types/tools/ozone/queue/routeReports.js +7 -0
  246. package/dist/lexicon/types/tools/ozone/queue/routeReports.js.map +1 -0
  247. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.d.ts +18 -0
  248. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.d.ts.map +1 -0
  249. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.js +7 -0
  250. package/dist/lexicon/types/tools/ozone/queue/unassignModerator.js.map +1 -0
  251. package/dist/lexicon/types/tools/ozone/queue/updateQueue.d.ts +32 -0
  252. package/dist/lexicon/types/tools/ozone/queue/updateQueue.d.ts.map +1 -0
  253. package/dist/lexicon/types/tools/ozone/queue/updateQueue.js +7 -0
  254. package/dist/lexicon/types/tools/ozone/queue/updateQueue.js.map +1 -0
  255. package/dist/lexicon/types/tools/ozone/report/assignModerator.d.ts +31 -0
  256. package/dist/lexicon/types/tools/ozone/report/assignModerator.d.ts.map +1 -0
  257. package/dist/lexicon/types/tools/ozone/report/assignModerator.js +7 -0
  258. package/dist/lexicon/types/tools/ozone/report/assignModerator.js.map +1 -0
  259. package/dist/lexicon/types/tools/ozone/report/createActivity.d.ts +37 -0
  260. package/dist/lexicon/types/tools/ozone/report/createActivity.d.ts.map +1 -0
  261. package/dist/lexicon/types/tools/ozone/report/createActivity.js +7 -0
  262. package/dist/lexicon/types/tools/ozone/report/createActivity.js.map +1 -0
  263. package/dist/lexicon/types/tools/ozone/report/defs.d.ts +185 -0
  264. package/dist/lexicon/types/tools/ozone/report/defs.d.ts.map +1 -1
  265. package/dist/lexicon/types/tools/ozone/report/defs.js +108 -0
  266. package/dist/lexicon/types/tools/ozone/report/defs.js.map +1 -1
  267. package/dist/lexicon/types/tools/ozone/report/getAssignments.d.ts +30 -0
  268. package/dist/lexicon/types/tools/ozone/report/getAssignments.d.ts.map +1 -0
  269. package/dist/lexicon/types/tools/ozone/report/getAssignments.js +7 -0
  270. package/dist/lexicon/types/tools/ozone/report/getAssignments.js.map +1 -0
  271. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.d.ts +36 -0
  272. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.d.ts.map +1 -0
  273. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.js +7 -0
  274. package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.js.map +1 -0
  275. package/dist/lexicon/types/tools/ozone/report/getLatestReport.d.ts +21 -0
  276. package/dist/lexicon/types/tools/ozone/report/getLatestReport.d.ts.map +1 -0
  277. package/dist/lexicon/types/tools/ozone/report/getLatestReport.js +7 -0
  278. package/dist/lexicon/types/tools/ozone/report/getLatestReport.js.map +1 -0
  279. package/dist/lexicon/types/tools/ozone/report/getLiveStats.d.ts +27 -0
  280. package/dist/lexicon/types/tools/ozone/report/getLiveStats.d.ts.map +1 -0
  281. package/dist/lexicon/types/tools/ozone/report/getLiveStats.js +7 -0
  282. package/dist/lexicon/types/tools/ozone/report/getLiveStats.js.map +1 -0
  283. package/dist/lexicon/types/tools/ozone/report/getReport.d.ts +22 -0
  284. package/dist/lexicon/types/tools/ozone/report/getReport.d.ts.map +1 -0
  285. package/dist/lexicon/types/tools/ozone/report/getReport.js +7 -0
  286. package/dist/lexicon/types/tools/ozone/report/getReport.js.map +1 -0
  287. package/dist/lexicon/types/tools/ozone/report/listActivities.d.ts +26 -0
  288. package/dist/lexicon/types/tools/ozone/report/listActivities.d.ts.map +1 -0
  289. package/dist/lexicon/types/tools/ozone/report/listActivities.js +7 -0
  290. package/dist/lexicon/types/tools/ozone/report/listActivities.js.map +1 -0
  291. package/dist/lexicon/types/tools/ozone/report/queryReports.d.ts +48 -0
  292. package/dist/lexicon/types/tools/ozone/report/queryReports.d.ts.map +1 -0
  293. package/dist/lexicon/types/tools/ozone/report/queryReports.js +7 -0
  294. package/dist/lexicon/types/tools/ozone/report/queryReports.js.map +1 -0
  295. package/dist/lexicon/types/tools/ozone/report/reassignQueue.d.ts +31 -0
  296. package/dist/lexicon/types/tools/ozone/report/reassignQueue.d.ts.map +1 -0
  297. package/dist/lexicon/types/tools/ozone/report/reassignQueue.js +7 -0
  298. package/dist/lexicon/types/tools/ozone/report/reassignQueue.js.map +1 -0
  299. package/dist/lexicon/types/tools/ozone/report/refreshStats.d.ts +28 -0
  300. package/dist/lexicon/types/tools/ozone/report/refreshStats.d.ts.map +1 -0
  301. package/dist/lexicon/types/tools/ozone/report/refreshStats.js +7 -0
  302. package/dist/lexicon/types/tools/ozone/report/refreshStats.js.map +1 -0
  303. package/dist/lexicon/types/tools/ozone/report/unassignModerator.d.ts +25 -0
  304. package/dist/lexicon/types/tools/ozone/report/unassignModerator.d.ts.map +1 -0
  305. package/dist/lexicon/types/tools/ozone/report/unassignModerator.js +7 -0
  306. package/dist/lexicon/types/tools/ozone/report/unassignModerator.js.map +1 -0
  307. package/dist/mod-service/expiring-tags.d.ts +27 -0
  308. package/dist/mod-service/expiring-tags.d.ts.map +1 -0
  309. package/dist/mod-service/expiring-tags.js +62 -0
  310. package/dist/mod-service/expiring-tags.js.map +1 -0
  311. package/dist/mod-service/index.d.ts +3 -1
  312. package/dist/mod-service/index.d.ts.map +1 -1
  313. package/dist/mod-service/index.js +61 -2
  314. package/dist/mod-service/index.js.map +1 -1
  315. package/dist/mod-service/report.d.ts +64 -0
  316. package/dist/mod-service/report.d.ts.map +1 -0
  317. package/dist/mod-service/report.js +282 -0
  318. package/dist/mod-service/report.js.map +1 -0
  319. package/dist/mod-service/status.d.ts +24 -0
  320. package/dist/mod-service/status.d.ts.map +1 -1
  321. package/dist/queue/service.d.ts +86 -0
  322. package/dist/queue/service.d.ts.map +1 -0
  323. package/dist/queue/service.js +430 -0
  324. package/dist/queue/service.js.map +1 -0
  325. package/dist/report/activity.d.ts +77 -0
  326. package/dist/report/activity.d.ts.map +1 -0
  327. package/dist/report/activity.js +141 -0
  328. package/dist/report/activity.js.map +1 -0
  329. package/dist/report/handle-report-update.d.ts +47 -0
  330. package/dist/report/handle-report-update.d.ts.map +1 -0
  331. package/dist/report/handle-report-update.js +178 -0
  332. package/dist/report/handle-report-update.js.map +1 -0
  333. package/dist/report/reassign.d.ts +10 -0
  334. package/dist/report/reassign.d.ts.map +1 -0
  335. package/dist/report/reassign.js +75 -0
  336. package/dist/report/reassign.js.map +1 -0
  337. package/dist/report/stats.d.ts +105 -0
  338. package/dist/report/stats.d.ts.map +1 -0
  339. package/dist/report/stats.js +619 -0
  340. package/dist/report/stats.js.map +1 -0
  341. package/dist/report/views.d.ts +111 -0
  342. package/dist/report/views.d.ts.map +1 -0
  343. package/dist/report/views.js +156 -0
  344. package/dist/report/views.js.map +1 -0
  345. package/dist/team/index.d.ts +1 -0
  346. package/dist/team/index.d.ts.map +1 -1
  347. package/dist/team/index.js +11 -0
  348. package/dist/team/index.js.map +1 -1
  349. package/package.json +3 -3
  350. package/src/api/index.ts +40 -0
  351. package/src/api/moderation/emitEvent.ts +38 -0
  352. package/src/api/queue/assignModerator.ts +31 -0
  353. package/src/api/queue/createQueue.ts +62 -0
  354. package/src/api/queue/deleteQueue.ts +56 -0
  355. package/src/api/queue/getAssignments.ts +19 -0
  356. package/src/api/queue/listQueues.ts +39 -0
  357. package/src/api/queue/routeReports.ts +44 -0
  358. package/src/api/queue/unassignModerator.ts +26 -0
  359. package/src/api/queue/updateQueue.ts +54 -0
  360. package/src/api/report/assignModerator.ts +36 -0
  361. package/src/api/report/createActivity.ts +57 -0
  362. package/src/api/report/getAssignments.ts +20 -0
  363. package/src/api/report/getHistoricalStats.ts +41 -0
  364. package/src/api/report/getLatestReport.ts +44 -0
  365. package/src/api/report/getLiveStats.ts +26 -0
  366. package/src/api/report/getReport.ts +55 -0
  367. package/src/api/report/listActivities.ts +34 -0
  368. package/src/api/report/queryReports.ts +44 -0
  369. package/src/api/report/reassignQueue.ts +68 -0
  370. package/src/api/report/refreshStats.ts +27 -0
  371. package/src/api/report/unassignModerator.ts +21 -0
  372. package/src/api/util.ts +12 -0
  373. package/src/assignment/index.ts +731 -0
  374. package/src/config/config.ts +27 -0
  375. package/src/config/env.ts +8 -0
  376. package/src/context.ts +31 -0
  377. package/src/daemon/context.ts +34 -0
  378. package/src/daemon/event-reverser.ts +50 -1
  379. package/src/daemon/job-cursor.ts +33 -0
  380. package/src/daemon/queue-router.ts +101 -0
  381. package/src/daemon/stats-computer.ts +101 -0
  382. package/src/daemon/strike-expiry-processor.ts +4 -20
  383. package/src/db/migrations/20260219T164523000Z-create-report-table.ts +155 -0
  384. package/src/db/migrations/20260219T165302248Z-moderator-assignment.ts +42 -0
  385. package/src/db/migrations/20260225T000000000Z-add-report-queue-table.ts +41 -0
  386. package/src/db/migrations/20260313T000000000Z-add-report-activity-table.ts +48 -0
  387. package/src/db/migrations/20260318T152058935Z-add-report-stat.ts +35 -0
  388. package/src/db/migrations/20260428T000000000Z-add-expiring-tag-table.ts +32 -0
  389. package/src/db/migrations/index.ts +6 -0
  390. package/src/db/pagination.ts +85 -0
  391. package/src/db/schema/expiring_tag.ts +17 -0
  392. package/src/db/schema/index.ts +13 -1
  393. package/src/db/schema/moderator_assignment.ts +16 -0
  394. package/src/db/schema/report.ts +27 -0
  395. package/src/db/schema/report_activity.ts +22 -0
  396. package/src/db/schema/report_queue.ts +21 -0
  397. package/src/db/schema/report_stat.ts +27 -0
  398. package/src/lexicon/index.ts +280 -0
  399. package/src/lexicon/lexicons.ts +2083 -214
  400. package/src/lexicon/types/app/bsky/embed/external.ts +2 -0
  401. package/src/lexicon/types/chat/bsky/actor/defs.ts +17 -1
  402. package/src/lexicon/types/chat/bsky/convo/defs.ts +50 -10
  403. package/src/lexicon/types/chat/bsky/convo/getMessages.ts +3 -0
  404. package/src/lexicon/types/tools/ozone/moderation/defs.ts +2 -0
  405. package/src/lexicon/types/tools/ozone/moderation/emitEvent.ts +24 -0
  406. package/src/lexicon/types/tools/ozone/queue/assignModerator.ts +46 -0
  407. package/src/lexicon/types/tools/ozone/queue/createQueue.ts +54 -0
  408. package/src/lexicon/types/tools/ozone/queue/defs.ts +99 -0
  409. package/src/lexicon/types/tools/ozone/queue/deleteQueue.ts +48 -0
  410. package/src/lexicon/types/tools/ozone/queue/getAssignments.ts +48 -0
  411. package/src/lexicon/types/tools/ozone/queue/listQueues.ts +50 -0
  412. package/src/lexicon/types/tools/ozone/queue/routeReports.ts +50 -0
  413. package/src/lexicon/types/tools/ozone/queue/unassignModerator.ts +37 -0
  414. package/src/lexicon/types/tools/ozone/queue/updateQueue.ts +51 -0
  415. package/src/lexicon/types/tools/ozone/report/assignModerator.ts +50 -0
  416. package/src/lexicon/types/tools/ozone/report/createActivity.ts +60 -0
  417. package/src/lexicon/types/tools/ozone/report/defs.ts +327 -0
  418. package/src/lexicon/types/tools/ozone/report/getAssignments.ts +48 -0
  419. package/src/lexicon/types/tools/ozone/report/getHistoricalStats.ts +54 -0
  420. package/src/lexicon/types/tools/ozone/report/getLatestReport.ts +39 -0
  421. package/src/lexicon/types/tools/ozone/report/getLiveStats.ts +45 -0
  422. package/src/lexicon/types/tools/ozone/report/getReport.ts +38 -0
  423. package/src/lexicon/types/tools/ozone/report/listActivities.ts +44 -0
  424. package/src/lexicon/types/tools/ozone/report/queryReports.ts +72 -0
  425. package/src/lexicon/types/tools/ozone/report/reassignQueue.ts +55 -0
  426. package/src/lexicon/types/tools/ozone/report/refreshStats.ts +46 -0
  427. package/src/lexicon/types/tools/ozone/report/unassignModerator.ts +44 -0
  428. package/src/mod-service/expiring-tags.ts +98 -0
  429. package/src/mod-service/index.ts +71 -3
  430. package/src/mod-service/report.ts +408 -0
  431. package/src/queue/service.ts +599 -0
  432. package/src/report/activity.ts +234 -0
  433. package/src/report/handle-report-update.ts +209 -0
  434. package/src/report/reassign.ts +109 -0
  435. package/src/report/stats.ts +850 -0
  436. package/src/report/views.ts +241 -0
  437. package/src/team/index.ts +11 -0
  438. package/tests/expiring-tags.test.ts +231 -0
  439. package/tests/get-report.test.ts +136 -0
  440. package/tests/query-reports.test.ts +608 -0
  441. package/tests/queue-assignment.test.ts +428 -0
  442. package/tests/queue-router.test.ts +306 -0
  443. package/tests/queues.test.ts +690 -0
  444. package/tests/report-action.test.ts +308 -0
  445. package/tests/report-activity.test.ts +567 -0
  446. package/tests/report-assignment.test.ts +517 -0
  447. package/tests/report-reassign-queue.test.ts +340 -0
  448. package/tests/report-routing.test.ts +245 -0
  449. package/tests/report-stats.test.ts +545 -0
  450. package/tsconfig.build.tsbuildinfo +1 -1
package/src/api/index.ts CHANGED
@@ -24,7 +24,27 @@ import queryStatuses from './moderation/queryStatuses'
24
24
  import scheduleAction from './moderation/scheduleAction'
25
25
  import searchRepos from './moderation/searchRepos'
26
26
  import proxied from './proxied'
27
+ import assignQueueModerator from './queue/assignModerator'
28
+ import createQueue from './queue/createQueue'
29
+ import deleteQueue from './queue/deleteQueue'
30
+ import getQueueAssignments from './queue/getAssignments'
31
+ import listQueues from './queue/listQueues'
32
+ import routeReports from './queue/routeReports'
33
+ import unassignQueueModerator from './queue/unassignModerator'
34
+ import updateQueue from './queue/updateQueue'
35
+ import assignReportModerator from './report/assignModerator'
36
+ import createActivity from './report/createActivity'
27
37
  import createReport from './report/createReport'
38
+ import getReportAssignments from './report/getAssignments'
39
+ import getHistoricalStats from './report/getHistoricalStats'
40
+ import getLatestReport from './report/getLatestReport'
41
+ import getLiveStats from './report/getLiveStats'
42
+ import getReport from './report/getReport'
43
+ import listActivities from './report/listActivities'
44
+ import queryReports from './report/queryReports'
45
+ import reassignQueue from './report/reassignQueue'
46
+ import refreshStats from './report/refreshStats'
47
+ import unassignReportModerator from './report/unassignModerator'
28
48
  import addSafelinkRule from './safelink/addRule'
29
49
  import querySafelinkEvents from './safelink/queryEvents'
30
50
  import querySafelinkRules from './safelink/queryRules'
@@ -62,6 +82,8 @@ export default function (server: Server, ctx: AppContext) {
62
82
  getRepos(server, ctx)
63
83
  getEvent(server, ctx)
64
84
  queryEvents(server, ctx)
85
+ getReport(server, ctx)
86
+ queryReports(server, ctx)
65
87
  queryStatuses(server, ctx)
66
88
  queryLabels(server, ctx)
67
89
  subscribeLabels(server, ctx)
@@ -77,6 +99,10 @@ export default function (server: Server, ctx: AppContext) {
77
99
  chat(server, ctx)
78
100
  proxied(server, ctx)
79
101
  getConfig(server, ctx)
102
+ createQueue(server, ctx)
103
+ listQueues(server, ctx)
104
+ updateQueue(server, ctx)
105
+ deleteQueue(server, ctx)
80
106
  setAddValues(server, ctx)
81
107
  setGetValues(server, ctx)
82
108
  querySets(server, ctx)
@@ -100,5 +126,19 @@ export default function (server: Server, ctx: AppContext) {
100
126
  scheduleAction(server, ctx)
101
127
  listScheduledActions(server, ctx)
102
128
  cancelScheduledActions(server, ctx)
129
+ routeReports(server, ctx)
130
+ getLiveStats(server, ctx)
131
+ getHistoricalStats(server, ctx)
132
+ refreshStats(server, ctx)
133
+ assignQueueModerator(server, ctx)
134
+ unassignQueueModerator(server, ctx)
135
+ getQueueAssignments(server, ctx)
136
+ getLatestReport(server, ctx)
137
+ assignReportModerator(server, ctx)
138
+ unassignReportModerator(server, ctx)
139
+ getReportAssignments(server, ctx)
140
+ createActivity(server, ctx)
141
+ listActivities(server, ctx)
142
+ reassignQueue(server, ctx)
103
143
  return server
104
144
  }
@@ -26,6 +26,7 @@ import {
26
26
  } from '../../lexicon/types/tools/ozone/moderation/defs'
27
27
  import { HandlerInput } from '../../lexicon/types/tools/ozone/moderation/emitEvent'
28
28
  import { httpLogger } from '../../logger'
29
+ import { processReportAction } from '../../mod-service/report'
29
30
  import { subjectFromInput } from '../../mod-service/subject'
30
31
  import { SettingService } from '../../setting/service'
31
32
  import { TagService } from '../../tag-service'
@@ -240,6 +241,21 @@ const handleModerationEvent = async ({
240
241
  }
241
242
  }
242
243
 
244
+ // Validate reportAction if provided (actual processing happens after event is logged)
245
+ if (input.body.reportAction) {
246
+ // Validate that at least one targeting criteria is provided
247
+ const { reportAction } = input.body
248
+ if (
249
+ !reportAction.ids?.length &&
250
+ !reportAction.types?.length &&
251
+ !reportAction.all
252
+ ) {
253
+ throw new InvalidRequestError(
254
+ 'reportAction must specify ids, types, or all',
255
+ )
256
+ }
257
+ }
258
+
243
259
  const result = await moderationTxn.logEvent({
244
260
  event,
245
261
  subject,
@@ -248,6 +264,28 @@ const handleModerationEvent = async ({
248
264
  externalId,
249
265
  })
250
266
 
267
+ // Update reports if reportAction was provided
268
+ if (input.body.reportAction) {
269
+ const subjectUri = subject.isRecord() ? subject.uri : null
270
+ try {
271
+ await processReportAction({
272
+ db: dbTxn,
273
+ reportAction: input.body.reportAction,
274
+ subjectDid: subject.did,
275
+ subjectUri,
276
+ eventId: result.event.id,
277
+ eventType: event.$type,
278
+ createdBy,
279
+ })
280
+ } catch (err) {
281
+ throw new InvalidRequestError(
282
+ err instanceof Error
283
+ ? err.message
284
+ : 'Failed to process report action',
285
+ )
286
+ }
287
+ }
288
+
251
289
  const tagService = new TagService(
252
290
  subject,
253
291
  result.subjectStatus,
@@ -0,0 +1,31 @@
1
+ import { ForbiddenError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+ import { getAuthDid } from '../util'
5
+
6
+ export default function (server: Server, ctx: AppContext) {
7
+ server.tools.ozone.queue.assignModerator({
8
+ auth: ctx.authVerifier.modOrAdminToken,
9
+ handler: async ({ input, auth }) => {
10
+ const { queueId, did } = input.body
11
+ const authDid = getAuthDid(auth, ctx.cfg.service.did)
12
+
13
+ // RBAC
14
+ if (!auth.credentials.isModerator) {
15
+ throw new ForbiddenError('Unauthorized')
16
+ }
17
+
18
+ // RuBAC
19
+ if (did !== authDid && !auth.credentials.isAdmin) {
20
+ throw new ForbiddenError('Unauthorized')
21
+ }
22
+
23
+ const result = await ctx.assignmentService.assignQueue({ did, queueId })
24
+
25
+ return {
26
+ encoding: 'application/json',
27
+ body: result,
28
+ }
29
+ },
30
+ })
31
+ }
@@ -0,0 +1,62 @@
1
+ import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+
5
+ const VALID_SUBJECT_TYPES = ['account', 'record', 'message']
6
+
7
+ export default function (server: Server, ctx: AppContext) {
8
+ server.tools.ozone.queue.createQueue({
9
+ auth: ctx.authVerifier.modOrAdminToken,
10
+ handler: async ({ input, auth }) => {
11
+ const access = auth.credentials
12
+
13
+ if (!access.isModerator) {
14
+ throw new AuthRequiredError('Must be a moderator to create a queue')
15
+ }
16
+
17
+ const { name, subjectTypes, collection, reportTypes, description } =
18
+ input.body
19
+ const createdBy =
20
+ access.type === 'admin_token' ? 'admin_token' : access.iss
21
+
22
+ const invalidTypes = subjectTypes.filter(
23
+ (t) => !VALID_SUBJECT_TYPES.includes(t),
24
+ )
25
+ if (invalidTypes.length > 0) {
26
+ throw new InvalidRequestError(
27
+ `Invalid subject types: ${invalidTypes.join(', ')}. Allowed values: ${VALID_SUBJECT_TYPES.join(', ')}`,
28
+ 'InvalidSubjectType',
29
+ )
30
+ }
31
+
32
+ if (collection && !subjectTypes.includes('record')) {
33
+ throw new InvalidRequestError(
34
+ 'collection can only be specified when subjectTypes includes "record"',
35
+ 'InvalidCollection',
36
+ )
37
+ }
38
+
39
+ const queueService = ctx.queueService(ctx.db)
40
+
41
+ await queueService.checkConflict({
42
+ subjectTypes,
43
+ collection,
44
+ reportTypes,
45
+ })
46
+
47
+ const queue = await queueService.create({
48
+ name,
49
+ subjectTypes,
50
+ collection,
51
+ reportTypes,
52
+ description,
53
+ createdBy,
54
+ })
55
+
56
+ return {
57
+ encoding: 'application/json',
58
+ body: { queue: queueService.view(queue) },
59
+ }
60
+ },
61
+ })
62
+ }
@@ -0,0 +1,56 @@
1
+ import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+
5
+ export default function (server: Server, ctx: AppContext) {
6
+ server.tools.ozone.queue.deleteQueue({
7
+ auth: ctx.authVerifier.modOrAdminToken,
8
+ handler: async ({ input, auth }) => {
9
+ const access = auth.credentials
10
+
11
+ if (!access.isModerator) {
12
+ throw new AuthRequiredError('Must be a moderator to delete a queue')
13
+ }
14
+
15
+ const { queueId, migrateToQueueId } = input.body
16
+
17
+ const queueService = ctx.queueService(ctx.db)
18
+
19
+ const existing = await queueService.getById(queueId)
20
+ if (!existing) {
21
+ throw new InvalidRequestError(
22
+ `Queue with id ${queueId} does not exist`,
23
+ 'QueueNotFound',
24
+ )
25
+ }
26
+
27
+ if (migrateToQueueId !== undefined) {
28
+ const targetQueue = await queueService.getById(migrateToQueueId)
29
+ if (!targetQueue) {
30
+ throw new InvalidRequestError(
31
+ `Target queue with id ${migrateToQueueId} does not exist`,
32
+ 'QueueNotFound',
33
+ )
34
+ }
35
+ }
36
+
37
+ // Migrate non-closed reports before soft-deleting the queue.
38
+ // Closed reports are left assigned to the deleted queue — their history is preserved.
39
+ // Non-closed reports go to migrateToQueueId if specified, otherwise to -1 (unmatched).
40
+ const reportsMigrated = await queueService.migrateReports(
41
+ queueId,
42
+ migrateToQueueId,
43
+ )
44
+
45
+ await queueService.delete(queueId)
46
+
47
+ return {
48
+ encoding: 'application/json',
49
+ body: {
50
+ deleted: true,
51
+ reportsMigrated,
52
+ },
53
+ }
54
+ },
55
+ })
56
+ }
@@ -0,0 +1,19 @@
1
+ import { AppContext } from '../../context'
2
+ import { Server } from '../../lexicon'
3
+
4
+ export default function (server: Server, ctx: AppContext) {
5
+ server.tools.ozone.queue.getAssignments({
6
+ auth: ctx.authVerifier.modOrAdminToken,
7
+ handler: async ({ params }) => {
8
+ const result = await ctx.assignmentService.getQueueAssignments(params)
9
+
10
+ return {
11
+ encoding: 'application/json',
12
+ body: {
13
+ assignments: result.assignments,
14
+ cursor: result.cursor,
15
+ },
16
+ }
17
+ },
18
+ })
19
+ }
@@ -0,0 +1,39 @@
1
+ import { AppContext } from '../../context'
2
+ import { Server } from '../../lexicon'
3
+
4
+ export default function (server: Server, ctx: AppContext) {
5
+ server.tools.ozone.queue.listQueues({
6
+ auth: ctx.authVerifier.modOrAdminToken,
7
+ handler: async ({ params }) => {
8
+ const {
9
+ limit = 50,
10
+ cursor,
11
+ enabled,
12
+ subjectType,
13
+ collection,
14
+ reportTypes,
15
+ } = params
16
+
17
+ const queueService = ctx.queueService(ctx.db)
18
+
19
+ const result = await queueService.list({
20
+ limit,
21
+ cursor,
22
+ enabled,
23
+ subjectType,
24
+ collection,
25
+ reportTypes,
26
+ })
27
+
28
+ const queues = await queueService.viewsWithStats(result.queues)
29
+
30
+ return {
31
+ encoding: 'application/json',
32
+ body: {
33
+ queues,
34
+ cursor: result.cursor,
35
+ },
36
+ }
37
+ },
38
+ })
39
+ }
@@ -0,0 +1,44 @@
1
+ import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+
5
+ const MAX_REPORTS = 5000
6
+
7
+ export default function (server: Server, ctx: AppContext) {
8
+ server.tools.ozone.queue.routeReports({
9
+ auth: ctx.authVerifier.modOrAdminToken,
10
+ handler: async ({ input, auth }) => {
11
+ const access = auth.credentials
12
+ const { startReportId, endReportId } = input.body
13
+
14
+ if (!access.isModerator) {
15
+ throw new AuthRequiredError('Must be an admin to re-route reports')
16
+ }
17
+ if (startReportId > endReportId) {
18
+ throw new InvalidRequestError(
19
+ 'startReportId must be less than or equal to endReportId',
20
+ )
21
+ }
22
+ if (endReportId - startReportId + 1 > MAX_REPORTS) {
23
+ throw new InvalidRequestError(
24
+ `Cannot route more than ${MAX_REPORTS} reports at a time`,
25
+ 'OutOfRange',
26
+ )
27
+ }
28
+
29
+ const queueService = ctx.queueService(ctx.db)
30
+ const { assigned, unmatched } = await queueService.assignReportBatch(
31
+ { start: startReportId, end: endReportId, limit: MAX_REPORTS },
32
+ { includeUnmatched: true },
33
+ )
34
+
35
+ return {
36
+ encoding: 'application/json',
37
+ body: {
38
+ assigned,
39
+ unmatched,
40
+ },
41
+ }
42
+ },
43
+ })
44
+ }
@@ -0,0 +1,26 @@
1
+ import { ForbiddenError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+ import { getAuthDid } from '../util'
5
+
6
+ export default function (server: Server, ctx: AppContext) {
7
+ server.tools.ozone.queue.unassignModerator({
8
+ auth: ctx.authVerifier.modOrAdminToken,
9
+ handler: async ({ input, auth }) => {
10
+ const { queueId, did } = input.body
11
+ const authDid = getAuthDid(auth, ctx.cfg.service.did)
12
+
13
+ // RBAC
14
+ if (!auth.credentials.isModerator) {
15
+ throw new ForbiddenError('Unauthorized')
16
+ }
17
+
18
+ // RuBAC
19
+ if (did !== authDid && !auth.credentials.isAdmin) {
20
+ throw new ForbiddenError('Unauthorized')
21
+ }
22
+
23
+ await ctx.assignmentService.unassignQueue({ did, queueId })
24
+ },
25
+ })
26
+ }
@@ -0,0 +1,54 @@
1
+ import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+
5
+ export default function (server: Server, ctx: AppContext) {
6
+ server.tools.ozone.queue.updateQueue({
7
+ auth: ctx.authVerifier.modOrAdminToken,
8
+ handler: async ({ input, auth }) => {
9
+ const access = auth.credentials
10
+
11
+ if (!access.isModerator) {
12
+ throw new AuthRequiredError('Must be a moderator to update a queue')
13
+ }
14
+
15
+ const { queueId, name, enabled, description } = input.body
16
+
17
+ if (
18
+ name === undefined &&
19
+ enabled === undefined &&
20
+ description === undefined
21
+ ) {
22
+ throw new InvalidRequestError(
23
+ 'At least one of name, enabled, or description must be provided',
24
+ )
25
+ }
26
+
27
+ const queueService = ctx.queueService(ctx.db)
28
+
29
+ const existing = await queueService.getById(queueId)
30
+ if (!existing) {
31
+ throw new InvalidRequestError(
32
+ `Queue with id ${queueId} does not exist`,
33
+ 'QueueNotFound',
34
+ )
35
+ }
36
+
37
+ const updates: {
38
+ name?: string
39
+ enabled?: boolean
40
+ description?: string
41
+ } = {}
42
+ if (name !== undefined) updates.name = name
43
+ if (enabled !== undefined) updates.enabled = enabled
44
+ if (description !== undefined) updates.description = description
45
+
46
+ const queue = await queueService.update(queueId, updates)
47
+
48
+ return {
49
+ encoding: 'application/json',
50
+ body: { queue: queueService.view(queue) },
51
+ }
52
+ },
53
+ })
54
+ }
@@ -0,0 +1,36 @@
1
+ import { ForbiddenError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+ import { getAuthDid } from '../util'
5
+
6
+ export default function (server: Server, ctx: AppContext) {
7
+ server.tools.ozone.report.assignModerator({
8
+ auth: ctx.authVerifier.modOrAdminToken,
9
+ handler: async ({ input, auth }) => {
10
+ const authDid = getAuthDid(auth, ctx.cfg.service.did)
11
+ const did = input.body.did ?? authDid
12
+
13
+ if (!did) {
14
+ throw new ForbiddenError('No one to assign report to')
15
+ }
16
+
17
+ // RuBAC: only admins can assign to a different user
18
+ if (did !== authDid && !auth.credentials.isAdmin) {
19
+ throw new ForbiddenError('Unauthorized')
20
+ }
21
+
22
+ const result = await ctx.assignmentService.assignReport({
23
+ did,
24
+ createdBy: authDid,
25
+ reportId: input.body.reportId,
26
+ queueId: input.body.queueId,
27
+ isPermanent: input.body.isPermanent,
28
+ })
29
+
30
+ return {
31
+ encoding: 'application/json',
32
+ body: result,
33
+ }
34
+ },
35
+ })
36
+ }
@@ -0,0 +1,57 @@
1
+ import { InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+ import {
5
+ ActivityType,
6
+ createReportActivity,
7
+ formatActivityView,
8
+ } from '../../report/activity'
9
+ import { getAuthDid } from '../util'
10
+
11
+ const VALID_ACTIVITY_TYPES = new Set<ActivityType>([
12
+ 'queueActivity',
13
+ 'assignmentActivity',
14
+ 'escalationActivity',
15
+ 'closeActivity',
16
+ 'reopenActivity',
17
+ 'noteActivity',
18
+ ])
19
+
20
+ const DEFS_PREFIX = 'tools.ozone.report.defs#'
21
+
22
+ export default function (server: Server, ctx: AppContext) {
23
+ server.tools.ozone.report.createActivity({
24
+ auth: ctx.authVerifier.modOrAdminToken,
25
+ handler: async ({ input, auth }) => {
26
+ const createdBy = getAuthDid(auth, ctx.cfg.service.did)
27
+ const { reportId, activity, internalNote, publicNote, isAutomated } =
28
+ input.body
29
+
30
+ const rawType = activity.$type ?? ''
31
+ const activityType = rawType.startsWith(DEFS_PREFIX)
32
+ ? rawType.slice(DEFS_PREFIX.length)
33
+ : rawType
34
+
35
+ if (!VALID_ACTIVITY_TYPES.has(activityType as ActivityType)) {
36
+ throw new InvalidRequestError(
37
+ `Unknown activity type: ${rawType}`,
38
+ 'InvalidActivityType',
39
+ )
40
+ }
41
+
42
+ const row = await createReportActivity(ctx.db, {
43
+ reportId,
44
+ activityType: activityType as ActivityType,
45
+ internalNote: internalNote ?? undefined,
46
+ publicNote: publicNote ?? undefined,
47
+ isAutomated: isAutomated ?? false,
48
+ createdBy: createdBy ?? ctx.cfg.service.did,
49
+ })
50
+
51
+ return {
52
+ encoding: 'application/json',
53
+ body: { activity: formatActivityView(row) },
54
+ }
55
+ },
56
+ })
57
+ }
@@ -0,0 +1,20 @@
1
+ import { AppContext } from '../../context'
2
+ import { Server } from '../../lexicon'
3
+
4
+ export default function (server: Server, ctx: AppContext) {
5
+ server.tools.ozone.report.getAssignments({
6
+ auth: ctx.authVerifier.modOrAdminToken,
7
+ handler: async ({ params }) => {
8
+ const { assignments, cursor } =
9
+ await ctx.assignmentService.getReportAssignments(params)
10
+
11
+ return {
12
+ encoding: 'application/json',
13
+ body: {
14
+ assignments,
15
+ cursor,
16
+ },
17
+ }
18
+ },
19
+ })
20
+ }
@@ -0,0 +1,41 @@
1
+ import { AppContext } from '../../context'
2
+ import { Server } from '../../lexicon'
3
+ import { viewHistoricalStats } from '../../report/views'
4
+
5
+ export default function (server: Server, ctx: AppContext) {
6
+ server.tools.ozone.report.getHistoricalStats({
7
+ auth: ctx.authVerifier.modOrAdminToken,
8
+ handler: async ({ params }) => {
9
+ const {
10
+ queueId,
11
+ moderatorDid,
12
+ reportTypes,
13
+ startDate,
14
+ endDate,
15
+ limit,
16
+ cursor,
17
+ } = params
18
+
19
+ const reportStatsService = ctx.reportStatsService(ctx.db)
20
+ const result = await reportStatsService.getHistoricalStats({
21
+ group: {
22
+ queueId: queueId ?? null,
23
+ moderatorDid: moderatorDid ?? null,
24
+ reportTypes: reportTypes?.length ? reportTypes : null,
25
+ },
26
+ startDate,
27
+ endDate,
28
+ limit: limit ?? 30,
29
+ cursor,
30
+ })
31
+
32
+ return {
33
+ encoding: 'application/json',
34
+ body: {
35
+ stats: result.stats.map(viewHistoricalStats),
36
+ cursor: result.cursor,
37
+ },
38
+ }
39
+ },
40
+ })
41
+ }
@@ -0,0 +1,44 @@
1
+ import { InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { AppContext } from '../../context'
3
+ import { Server } from '../../lexicon'
4
+ import { getLatestReport } from '../../mod-service/report'
5
+ import { buildReportView, hydrateReportInfo } from '../../report/views'
6
+ import { getPdsAccountInfos } from '../util'
7
+
8
+ export default function (server: Server, ctx: AppContext) {
9
+ server.tools.ozone.report.getLatestReport({
10
+ auth: ctx.authVerifier.modOrAdminToken,
11
+ handler: async ({ auth, req }) => {
12
+ const db = ctx.db
13
+ const modService = ctx.modService(db)
14
+ const labelers = ctx.reqLabelers(req)
15
+
16
+ const report = await getLatestReport(db)
17
+ if (!report) {
18
+ throw new InvalidRequestError('No report found', 'NotFound')
19
+ }
20
+
21
+ const queueService = ctx.queueService(db)
22
+ const teamService = ctx.teamService(db)
23
+ const hydrated = await hydrateReportInfo(
24
+ [report],
25
+ modService.views,
26
+ (dids) => getPdsAccountInfos(ctx, dids),
27
+ (queueIds) => queueService.getViewsByIds(queueIds),
28
+ (dids) => teamService.viewByDids(dids),
29
+ labelers,
30
+ )
31
+
32
+ return {
33
+ encoding: 'application/json',
34
+ body: {
35
+ report: buildReportView(
36
+ report,
37
+ hydrated,
38
+ auth.credentials.isModerator,
39
+ ),
40
+ },
41
+ }
42
+ },
43
+ })
44
+ }