@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.
- package/CHANGELOG.md +18 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +40 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/moderation/emitEvent.d.ts.map +1 -1
- package/dist/api/moderation/emitEvent.js +31 -0
- package/dist/api/moderation/emitEvent.js.map +1 -1
- package/dist/api/queue/assignModerator.d.ts +4 -0
- package/dist/api/queue/assignModerator.d.ts.map +1 -0
- package/dist/api/queue/assignModerator.js +28 -0
- package/dist/api/queue/assignModerator.js.map +1 -0
- package/dist/api/queue/createQueue.d.ts +4 -0
- package/dist/api/queue/createQueue.d.ts.map +1 -0
- package/dist/api/queue/createQueue.js +44 -0
- package/dist/api/queue/createQueue.js.map +1 -0
- package/dist/api/queue/deleteQueue.d.ts +4 -0
- package/dist/api/queue/deleteQueue.d.ts.map +1 -0
- package/dist/api/queue/deleteQueue.js +40 -0
- package/dist/api/queue/deleteQueue.js.map +1 -0
- package/dist/api/queue/getAssignments.d.ts +4 -0
- package/dist/api/queue/getAssignments.d.ts.map +1 -0
- package/dist/api/queue/getAssignments.js +19 -0
- package/dist/api/queue/getAssignments.js.map +1 -0
- package/dist/api/queue/listQueues.d.ts +4 -0
- package/dist/api/queue/listQueues.d.ts.map +1 -0
- package/dist/api/queue/listQueues.js +29 -0
- package/dist/api/queue/listQueues.js.map +1 -0
- package/dist/api/queue/routeReports.d.ts +4 -0
- package/dist/api/queue/routeReports.d.ts.map +1 -0
- package/dist/api/queue/routeReports.js +33 -0
- package/dist/api/queue/routeReports.js.map +1 -0
- package/dist/api/queue/unassignModerator.d.ts +4 -0
- package/dist/api/queue/unassignModerator.d.ts.map +1 -0
- package/dist/api/queue/unassignModerator.js +24 -0
- package/dist/api/queue/unassignModerator.js.map +1 -0
- package/dist/api/queue/updateQueue.d.ts +4 -0
- package/dist/api/queue/updateQueue.d.ts.map +1 -0
- package/dist/api/queue/updateQueue.js +39 -0
- package/dist/api/queue/updateQueue.js.map +1 -0
- package/dist/api/report/assignModerator.d.ts +4 -0
- package/dist/api/report/assignModerator.d.ts.map +1 -0
- package/dist/api/report/assignModerator.js +33 -0
- package/dist/api/report/assignModerator.js.map +1 -0
- package/dist/api/report/createActivity.d.ts +4 -0
- package/dist/api/report/createActivity.d.ts.map +1 -0
- package/dist/api/report/createActivity.js +44 -0
- package/dist/api/report/createActivity.js.map +1 -0
- package/dist/api/report/getAssignments.d.ts +4 -0
- package/dist/api/report/getAssignments.d.ts.map +1 -0
- package/dist/api/report/getAssignments.js +19 -0
- package/dist/api/report/getAssignments.js.map +1 -0
- package/dist/api/report/getHistoricalStats.d.ts +4 -0
- package/dist/api/report/getHistoricalStats.d.ts.map +1 -0
- package/dist/api/report/getHistoricalStats.js +32 -0
- package/dist/api/report/getHistoricalStats.js.map +1 -0
- package/dist/api/report/getLatestReport.d.ts +4 -0
- package/dist/api/report/getLatestReport.d.ts.map +1 -0
- package/dist/api/report/getLatestReport.js +31 -0
- package/dist/api/report/getLatestReport.js.map +1 -0
- package/dist/api/report/getLiveStats.d.ts +4 -0
- package/dist/api/report/getLiveStats.d.ts.map +1 -0
- package/dist/api/report/getLiveStats.js +25 -0
- package/dist/api/report/getLiveStats.js.map +1 -0
- package/dist/api/report/getReport.d.ts +4 -0
- package/dist/api/report/getReport.d.ts.map +1 -0
- package/dist/api/report/getReport.js +35 -0
- package/dist/api/report/getReport.js.map +1 -0
- package/dist/api/report/listActivities.d.ts +4 -0
- package/dist/api/report/listActivities.d.ts.map +1 -0
- package/dist/api/report/listActivities.js +25 -0
- package/dist/api/report/listActivities.js.map +1 -0
- package/dist/api/report/queryReports.d.ts +4 -0
- package/dist/api/report/queryReports.d.ts.map +1 -0
- package/dist/api/report/queryReports.js +29 -0
- package/dist/api/report/queryReports.js.map +1 -0
- package/dist/api/report/reassignQueue.d.ts +4 -0
- package/dist/api/report/reassignQueue.d.ts.map +1 -0
- package/dist/api/report/reassignQueue.js +45 -0
- package/dist/api/report/reassignQueue.js.map +1 -0
- package/dist/api/report/refreshStats.d.ts +4 -0
- package/dist/api/report/refreshStats.d.ts.map +1 -0
- package/dist/api/report/refreshStats.js +26 -0
- package/dist/api/report/refreshStats.js.map +1 -0
- package/dist/api/report/unassignModerator.d.ts +4 -0
- package/dist/api/report/unassignModerator.d.ts.map +1 -0
- package/dist/api/report/unassignModerator.js +21 -0
- package/dist/api/report/unassignModerator.js.map +1 -0
- package/dist/api/util.d.ts +2 -0
- package/dist/api/util.d.ts.map +1 -1
- package/dist/api/util.js +9 -1
- package/dist/api/util.js.map +1 -1
- package/dist/assignment/index.d.ts +89 -0
- package/dist/assignment/index.d.ts.map +1 -0
- package/dist/assignment/index.js +537 -0
- package/dist/assignment/index.js.map +1 -0
- package/dist/config/config.d.ts +14 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +9 -0
- package/dist/config/config.js.map +1 -1
- package/dist/config/env.d.ts +3 -0
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +3 -0
- package/dist/config/env.js.map +1 -1
- package/dist/context.d.ts +9 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +31 -10
- package/dist/context.js.map +1 -1
- package/dist/daemon/context.d.ts +6 -0
- package/dist/daemon/context.d.ts.map +1 -1
- package/dist/daemon/context.js +28 -4
- package/dist/daemon/context.js.map +1 -1
- package/dist/daemon/event-reverser.d.ts +1 -0
- package/dist/daemon/event-reverser.d.ts.map +1 -1
- package/dist/daemon/event-reverser.js +42 -1
- package/dist/daemon/event-reverser.js.map +1 -1
- package/dist/daemon/job-cursor.d.ts +5 -0
- package/dist/daemon/job-cursor.d.ts.map +1 -0
- package/dist/daemon/job-cursor.js +28 -0
- package/dist/daemon/job-cursor.js.map +1 -0
- package/dist/daemon/queue-router.d.ts +17 -0
- package/dist/daemon/queue-router.d.ts.map +1 -0
- package/dist/daemon/queue-router.js +114 -0
- package/dist/daemon/queue-router.js.map +1 -0
- package/dist/daemon/stats-computer.d.ts +51 -0
- package/dist/daemon/stats-computer.d.ts.map +1 -0
- package/dist/daemon/stats-computer.js +117 -0
- package/dist/daemon/stats-computer.js.map +1 -0
- package/dist/daemon/strike-expiry-processor.d.ts.map +1 -1
- package/dist/daemon/strike-expiry-processor.js +4 -19
- package/dist/daemon/strike-expiry-processor.js.map +1 -1
- package/dist/db/migrations/20260219T164523000Z-create-report-table.d.ts +4 -0
- package/dist/db/migrations/20260219T164523000Z-create-report-table.d.ts.map +1 -0
- package/dist/db/migrations/20260219T164523000Z-create-report-table.js +126 -0
- package/dist/db/migrations/20260219T164523000Z-create-report-table.js.map +1 -0
- package/dist/db/migrations/20260219T165302248Z-moderator-assignment.d.ts +4 -0
- package/dist/db/migrations/20260219T165302248Z-moderator-assignment.d.ts.map +1 -0
- package/dist/db/migrations/20260219T165302248Z-moderator-assignment.js +35 -0
- package/dist/db/migrations/20260219T165302248Z-moderator-assignment.js.map +1 -0
- package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.d.ts +4 -0
- package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.d.ts.map +1 -0
- package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.js +36 -0
- package/dist/db/migrations/20260225T000000000Z-add-report-queue-table.js.map +1 -0
- package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.d.ts +4 -0
- package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.d.ts.map +1 -0
- package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.js +39 -0
- package/dist/db/migrations/20260313T000000000Z-add-report-activity-table.js.map +1 -0
- package/dist/db/migrations/20260318T152058935Z-add-report-stat.d.ts +4 -0
- package/dist/db/migrations/20260318T152058935Z-add-report-stat.d.ts.map +1 -0
- package/dist/db/migrations/20260318T152058935Z-add-report-stat.js +34 -0
- package/dist/db/migrations/20260318T152058935Z-add-report-stat.js.map +1 -0
- package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.d.ts +4 -0
- package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.d.ts.map +1 -0
- package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.js +32 -0
- package/dist/db/migrations/20260428T000000000Z-add-expiring-tag-table.js.map +1 -0
- package/dist/db/migrations/index.d.ts +6 -0
- package/dist/db/migrations/index.d.ts.map +1 -1
- package/dist/db/migrations/index.js +7 -1
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/pagination.d.ts +31 -0
- package/dist/db/pagination.d.ts.map +1 -1
- package/dist/db/pagination.js +74 -1
- package/dist/db/pagination.js.map +1 -1
- package/dist/db/schema/expiring_tag.d.ts +15 -0
- package/dist/db/schema/expiring_tag.d.ts.map +1 -0
- package/dist/db/schema/expiring_tag.js +5 -0
- package/dist/db/schema/expiring_tag.js.map +1 -0
- package/dist/db/schema/index.d.ts +7 -1
- package/dist/db/schema/index.d.ts.map +1 -1
- package/dist/db/schema/index.js.map +1 -1
- package/dist/db/schema/moderator_assignment.d.ts +14 -0
- package/dist/db/schema/moderator_assignment.d.ts.map +1 -0
- package/dist/db/schema/moderator_assignment.js +5 -0
- package/dist/db/schema/moderator_assignment.js.map +1 -0
- package/dist/db/schema/report.d.ts +25 -0
- package/dist/db/schema/report.d.ts.map +1 -0
- package/dist/db/schema/report.js +5 -0
- package/dist/db/schema/report.js.map +1 -0
- package/dist/db/schema/report_activity.d.ts +18 -0
- package/dist/db/schema/report_activity.d.ts.map +1 -0
- package/dist/db/schema/report_activity.js +5 -0
- package/dist/db/schema/report_activity.js.map +1 -0
- package/dist/db/schema/report_queue.d.ts +19 -0
- package/dist/db/schema/report_queue.d.ts.map +1 -0
- package/dist/db/schema/report_queue.js +5 -0
- package/dist/db/schema/report_queue.js.map +1 -0
- package/dist/db/schema/report_stat.d.ts +20 -0
- package/dist/db/schema/report_stat.d.ts.map +1 -0
- package/dist/db/schema/report_stat.js +5 -0
- package/dist/db/schema/report_stat.js.map +1 -0
- package/dist/lexicon/index.d.ts +50 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +120 -2
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +11255 -7885
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +1900 -120
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/embed/external.d.ts +2 -0
- package/dist/lexicon/types/app/bsky/embed/external.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/embed/external.js.map +1 -1
- package/dist/lexicon/types/chat/bsky/actor/defs.d.ts +8 -2
- package/dist/lexicon/types/chat/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/chat/bsky/actor/defs.js +9 -0
- package/dist/lexicon/types/chat/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/defs.d.ts +37 -10
- package/dist/lexicon/types/chat/bsky/convo/defs.d.ts.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/defs.js +9 -0
- package/dist/lexicon/types/chat/bsky/convo/defs.js.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/getMessages.d.ts +3 -0
- package/dist/lexicon/types/chat/bsky/convo/getMessages.d.ts.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/getMessages.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts +2 -0
- package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/defs.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts +19 -0
- package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/emitEvent.js +9 -0
- package/dist/lexicon/types/tools/ozone/moderation/emitEvent.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/queue/assignModerator.d.ts +27 -0
- package/dist/lexicon/types/tools/ozone/queue/assignModerator.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/assignModerator.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/assignModerator.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/createQueue.d.ts +35 -0
- package/dist/lexicon/types/tools/ozone/queue/createQueue.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/createQueue.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/createQueue.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/defs.d.ts +62 -0
- package/dist/lexicon/types/tools/ozone/queue/defs.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/defs.js +34 -0
- package/dist/lexicon/types/tools/ozone/queue/defs.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/deleteQueue.d.ts +29 -0
- package/dist/lexicon/types/tools/ozone/queue/deleteQueue.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/deleteQueue.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/deleteQueue.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/getAssignments.d.ts +30 -0
- package/dist/lexicon/types/tools/ozone/queue/getAssignments.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/getAssignments.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/getAssignments.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/listQueues.d.ts +32 -0
- package/dist/lexicon/types/tools/ozone/queue/listQueues.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/listQueues.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/listQueues.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/routeReports.d.ts +31 -0
- package/dist/lexicon/types/tools/ozone/queue/routeReports.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/routeReports.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/routeReports.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/unassignModerator.d.ts +18 -0
- package/dist/lexicon/types/tools/ozone/queue/unassignModerator.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/unassignModerator.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/unassignModerator.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/updateQueue.d.ts +32 -0
- package/dist/lexicon/types/tools/ozone/queue/updateQueue.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/queue/updateQueue.js +7 -0
- package/dist/lexicon/types/tools/ozone/queue/updateQueue.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/assignModerator.d.ts +31 -0
- package/dist/lexicon/types/tools/ozone/report/assignModerator.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/assignModerator.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/assignModerator.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/createActivity.d.ts +37 -0
- package/dist/lexicon/types/tools/ozone/report/createActivity.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/createActivity.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/createActivity.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/defs.d.ts +185 -0
- package/dist/lexicon/types/tools/ozone/report/defs.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/report/defs.js +108 -0
- package/dist/lexicon/types/tools/ozone/report/defs.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/report/getAssignments.d.ts +30 -0
- package/dist/lexicon/types/tools/ozone/report/getAssignments.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getAssignments.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/getAssignments.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.d.ts +36 -0
- package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/getHistoricalStats.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getLatestReport.d.ts +21 -0
- package/dist/lexicon/types/tools/ozone/report/getLatestReport.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getLatestReport.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/getLatestReport.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getLiveStats.d.ts +27 -0
- package/dist/lexicon/types/tools/ozone/report/getLiveStats.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getLiveStats.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/getLiveStats.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getReport.d.ts +22 -0
- package/dist/lexicon/types/tools/ozone/report/getReport.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/getReport.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/getReport.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/listActivities.d.ts +26 -0
- package/dist/lexicon/types/tools/ozone/report/listActivities.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/listActivities.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/listActivities.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/queryReports.d.ts +48 -0
- package/dist/lexicon/types/tools/ozone/report/queryReports.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/queryReports.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/queryReports.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/reassignQueue.d.ts +31 -0
- package/dist/lexicon/types/tools/ozone/report/reassignQueue.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/reassignQueue.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/reassignQueue.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/refreshStats.d.ts +28 -0
- package/dist/lexicon/types/tools/ozone/report/refreshStats.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/refreshStats.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/refreshStats.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/unassignModerator.d.ts +25 -0
- package/dist/lexicon/types/tools/ozone/report/unassignModerator.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/report/unassignModerator.js +7 -0
- package/dist/lexicon/types/tools/ozone/report/unassignModerator.js.map +1 -0
- package/dist/mod-service/expiring-tags.d.ts +27 -0
- package/dist/mod-service/expiring-tags.d.ts.map +1 -0
- package/dist/mod-service/expiring-tags.js +62 -0
- package/dist/mod-service/expiring-tags.js.map +1 -0
- package/dist/mod-service/index.d.ts +3 -1
- package/dist/mod-service/index.d.ts.map +1 -1
- package/dist/mod-service/index.js +61 -2
- package/dist/mod-service/index.js.map +1 -1
- package/dist/mod-service/report.d.ts +64 -0
- package/dist/mod-service/report.d.ts.map +1 -0
- package/dist/mod-service/report.js +282 -0
- package/dist/mod-service/report.js.map +1 -0
- package/dist/mod-service/status.d.ts +24 -0
- package/dist/mod-service/status.d.ts.map +1 -1
- package/dist/queue/service.d.ts +86 -0
- package/dist/queue/service.d.ts.map +1 -0
- package/dist/queue/service.js +430 -0
- package/dist/queue/service.js.map +1 -0
- package/dist/report/activity.d.ts +77 -0
- package/dist/report/activity.d.ts.map +1 -0
- package/dist/report/activity.js +141 -0
- package/dist/report/activity.js.map +1 -0
- package/dist/report/handle-report-update.d.ts +47 -0
- package/dist/report/handle-report-update.d.ts.map +1 -0
- package/dist/report/handle-report-update.js +178 -0
- package/dist/report/handle-report-update.js.map +1 -0
- package/dist/report/reassign.d.ts +10 -0
- package/dist/report/reassign.d.ts.map +1 -0
- package/dist/report/reassign.js +75 -0
- package/dist/report/reassign.js.map +1 -0
- package/dist/report/stats.d.ts +105 -0
- package/dist/report/stats.d.ts.map +1 -0
- package/dist/report/stats.js +619 -0
- package/dist/report/stats.js.map +1 -0
- package/dist/report/views.d.ts +111 -0
- package/dist/report/views.d.ts.map +1 -0
- package/dist/report/views.js +156 -0
- package/dist/report/views.js.map +1 -0
- package/dist/team/index.d.ts +1 -0
- package/dist/team/index.d.ts.map +1 -1
- package/dist/team/index.js +11 -0
- package/dist/team/index.js.map +1 -1
- package/package.json +3 -3
- package/src/api/index.ts +40 -0
- package/src/api/moderation/emitEvent.ts +38 -0
- package/src/api/queue/assignModerator.ts +31 -0
- package/src/api/queue/createQueue.ts +62 -0
- package/src/api/queue/deleteQueue.ts +56 -0
- package/src/api/queue/getAssignments.ts +19 -0
- package/src/api/queue/listQueues.ts +39 -0
- package/src/api/queue/routeReports.ts +44 -0
- package/src/api/queue/unassignModerator.ts +26 -0
- package/src/api/queue/updateQueue.ts +54 -0
- package/src/api/report/assignModerator.ts +36 -0
- package/src/api/report/createActivity.ts +57 -0
- package/src/api/report/getAssignments.ts +20 -0
- package/src/api/report/getHistoricalStats.ts +41 -0
- package/src/api/report/getLatestReport.ts +44 -0
- package/src/api/report/getLiveStats.ts +26 -0
- package/src/api/report/getReport.ts +55 -0
- package/src/api/report/listActivities.ts +34 -0
- package/src/api/report/queryReports.ts +44 -0
- package/src/api/report/reassignQueue.ts +68 -0
- package/src/api/report/refreshStats.ts +27 -0
- package/src/api/report/unassignModerator.ts +21 -0
- package/src/api/util.ts +12 -0
- package/src/assignment/index.ts +731 -0
- package/src/config/config.ts +27 -0
- package/src/config/env.ts +8 -0
- package/src/context.ts +31 -0
- package/src/daemon/context.ts +34 -0
- package/src/daemon/event-reverser.ts +50 -1
- package/src/daemon/job-cursor.ts +33 -0
- package/src/daemon/queue-router.ts +101 -0
- package/src/daemon/stats-computer.ts +101 -0
- package/src/daemon/strike-expiry-processor.ts +4 -20
- package/src/db/migrations/20260219T164523000Z-create-report-table.ts +155 -0
- package/src/db/migrations/20260219T165302248Z-moderator-assignment.ts +42 -0
- package/src/db/migrations/20260225T000000000Z-add-report-queue-table.ts +41 -0
- package/src/db/migrations/20260313T000000000Z-add-report-activity-table.ts +48 -0
- package/src/db/migrations/20260318T152058935Z-add-report-stat.ts +35 -0
- package/src/db/migrations/20260428T000000000Z-add-expiring-tag-table.ts +32 -0
- package/src/db/migrations/index.ts +6 -0
- package/src/db/pagination.ts +85 -0
- package/src/db/schema/expiring_tag.ts +17 -0
- package/src/db/schema/index.ts +13 -1
- package/src/db/schema/moderator_assignment.ts +16 -0
- package/src/db/schema/report.ts +27 -0
- package/src/db/schema/report_activity.ts +22 -0
- package/src/db/schema/report_queue.ts +21 -0
- package/src/db/schema/report_stat.ts +27 -0
- package/src/lexicon/index.ts +280 -0
- package/src/lexicon/lexicons.ts +2083 -214
- package/src/lexicon/types/app/bsky/embed/external.ts +2 -0
- package/src/lexicon/types/chat/bsky/actor/defs.ts +17 -1
- package/src/lexicon/types/chat/bsky/convo/defs.ts +50 -10
- package/src/lexicon/types/chat/bsky/convo/getMessages.ts +3 -0
- package/src/lexicon/types/tools/ozone/moderation/defs.ts +2 -0
- package/src/lexicon/types/tools/ozone/moderation/emitEvent.ts +24 -0
- package/src/lexicon/types/tools/ozone/queue/assignModerator.ts +46 -0
- package/src/lexicon/types/tools/ozone/queue/createQueue.ts +54 -0
- package/src/lexicon/types/tools/ozone/queue/defs.ts +99 -0
- package/src/lexicon/types/tools/ozone/queue/deleteQueue.ts +48 -0
- package/src/lexicon/types/tools/ozone/queue/getAssignments.ts +48 -0
- package/src/lexicon/types/tools/ozone/queue/listQueues.ts +50 -0
- package/src/lexicon/types/tools/ozone/queue/routeReports.ts +50 -0
- package/src/lexicon/types/tools/ozone/queue/unassignModerator.ts +37 -0
- package/src/lexicon/types/tools/ozone/queue/updateQueue.ts +51 -0
- package/src/lexicon/types/tools/ozone/report/assignModerator.ts +50 -0
- package/src/lexicon/types/tools/ozone/report/createActivity.ts +60 -0
- package/src/lexicon/types/tools/ozone/report/defs.ts +327 -0
- package/src/lexicon/types/tools/ozone/report/getAssignments.ts +48 -0
- package/src/lexicon/types/tools/ozone/report/getHistoricalStats.ts +54 -0
- package/src/lexicon/types/tools/ozone/report/getLatestReport.ts +39 -0
- package/src/lexicon/types/tools/ozone/report/getLiveStats.ts +45 -0
- package/src/lexicon/types/tools/ozone/report/getReport.ts +38 -0
- package/src/lexicon/types/tools/ozone/report/listActivities.ts +44 -0
- package/src/lexicon/types/tools/ozone/report/queryReports.ts +72 -0
- package/src/lexicon/types/tools/ozone/report/reassignQueue.ts +55 -0
- package/src/lexicon/types/tools/ozone/report/refreshStats.ts +46 -0
- package/src/lexicon/types/tools/ozone/report/unassignModerator.ts +44 -0
- package/src/mod-service/expiring-tags.ts +98 -0
- package/src/mod-service/index.ts +71 -3
- package/src/mod-service/report.ts +408 -0
- package/src/queue/service.ts +599 -0
- package/src/report/activity.ts +234 -0
- package/src/report/handle-report-update.ts +209 -0
- package/src/report/reassign.ts +109 -0
- package/src/report/stats.ts +850 -0
- package/src/report/views.ts +241 -0
- package/src/team/index.ts +11 -0
- package/tests/expiring-tags.test.ts +231 -0
- package/tests/get-report.test.ts +136 -0
- package/tests/query-reports.test.ts +608 -0
- package/tests/queue-assignment.test.ts +428 -0
- package/tests/queue-router.test.ts +306 -0
- package/tests/queues.test.ts +690 -0
- package/tests/report-action.test.ts +308 -0
- package/tests/report-activity.test.ts +567 -0
- package/tests/report-assignment.test.ts +517 -0
- package/tests/report-reassign-queue.test.ts +340 -0
- package/tests/report-routing.test.ts +245 -0
- package/tests/report-stats.test.ts +545 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/report/stats.ts"],"names":[],"mappings":"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","sourcesContent":["import { Selectable, sql } from 'kysely'\nimport { MINUTE } from '@atproto/common'\nimport { Database } from '../db'\nimport { ComputedAtIdKeyset, paginate } from '../db/pagination'\nimport { ReportStat } from '../db/schema/report_stat'\nimport { jsonb } from '../db/types'\nimport { dbLogger } from '../logger'\n\n/**\n * Grouped report types. Stats are computed per group rather than per individual report type.\n */\nexport const REPORT_TYPE_GROUPS: Record<string, string[]> = {\n Legacy: [\n 'com.atproto.moderation.defs#reasonSpam',\n 'com.atproto.moderation.defs#reasonViolation',\n 'com.atproto.moderation.defs#reasonMisleading',\n 'com.atproto.moderation.defs#reasonSexual',\n 'com.atproto.moderation.defs#reasonRude',\n 'com.atproto.moderation.defs#reasonOther',\n 'com.atproto.moderation.defs#reasonAppeal',\n ],\n Appeal: ['tools.ozone.report.defs#reasonAppeal'],\n Violence: [\n 'tools.ozone.report.defs#reasonViolenceAnimalWelfare',\n 'tools.ozone.report.defs#reasonViolenceThreats',\n 'tools.ozone.report.defs#reasonViolenceGraphicContent',\n 'tools.ozone.report.defs#reasonViolenceSelfHarm',\n 'tools.ozone.report.defs#reasonViolenceGlorification',\n 'tools.ozone.report.defs#reasonViolenceExtremistContent',\n 'tools.ozone.report.defs#reasonViolenceTrafficking',\n 'tools.ozone.report.defs#reasonViolenceOther',\n ],\n Sexual: [\n 'tools.ozone.report.defs#reasonSexualAbuseContent',\n 'tools.ozone.report.defs#reasonSexualNCII',\n 'tools.ozone.report.defs#reasonSexualSextortion',\n 'tools.ozone.report.defs#reasonSexualDeepfake',\n 'tools.ozone.report.defs#reasonSexualAnimal',\n 'tools.ozone.report.defs#reasonSexualUnlabeled',\n 'tools.ozone.report.defs#reasonSexualOther',\n ],\n 'Child Safety': [\n 'tools.ozone.report.defs#reasonChildSafetyCSAM',\n 'tools.ozone.report.defs#reasonChildSafetyGroom',\n 'tools.ozone.report.defs#reasonChildSafetyMinorPrivacy',\n 'tools.ozone.report.defs#reasonChildSafetyEndangerment',\n 'tools.ozone.report.defs#reasonChildSafetyHarassment',\n 'tools.ozone.report.defs#reasonChildSafetyPromotion',\n 'tools.ozone.report.defs#reasonChildSafetyOther',\n ],\n Harassment: [\n 'tools.ozone.report.defs#reasonHarassmentTroll',\n 'tools.ozone.report.defs#reasonHarassmentTargeted',\n 'tools.ozone.report.defs#reasonHarassmentHateSpeech',\n 'tools.ozone.report.defs#reasonHarassmentDoxxing',\n 'tools.ozone.report.defs#reasonHarassmentOther',\n ],\n Misleading: [\n 'tools.ozone.report.defs#reasonMisleadingBot',\n 'tools.ozone.report.defs#reasonMisleadingImpersonation',\n 'tools.ozone.report.defs#reasonMisleadingSpam',\n 'tools.ozone.report.defs#reasonMisleadingScam',\n 'tools.ozone.report.defs#reasonMisleadingSyntheticContent',\n 'tools.ozone.report.defs#reasonMisleadingMisinformation',\n 'tools.ozone.report.defs#reasonMisleadingOther',\n ],\n 'Rule Violations': [\n 'tools.ozone.report.defs#reasonRuleSiteSecurity',\n 'tools.ozone.report.defs#reasonRuleStolenContent',\n 'tools.ozone.report.defs#reasonRuleProhibitedSales',\n 'tools.ozone.report.defs#reasonRuleBanEvasion',\n 'tools.ozone.report.defs#reasonRuleOther',\n ],\n Civic: [\n 'tools.ozone.report.defs#reasonCivicElectoralProcess',\n 'tools.ozone.report.defs#reasonCivicDisclosure',\n 'tools.ozone.report.defs#reasonCivicInterference',\n 'tools.ozone.report.defs#reasonCivicMisinformation',\n 'tools.ozone.report.defs#reasonCivicImpersonation',\n ],\n}\n\nconst REPORT_STAT_LIVE_TTL = 15 * MINUTE\n\nexport type ReportStatsServiceCreator = (db: Database) => ReportStatsService\n\nexport type ReportStatGroup = {\n queueId: number | null\n moderatorDid: string | null\n reportTypes: string[] | null\n}\nexport type AggregateStatistics = {\n inboundCount: number\n pendingCount: number\n actionedCount: number\n escalatedCount: number\n actionRate: number\n avgHandlingTimeSec?: number\n}\nexport type QueueStatistics = {\n inboundCount: number\n pendingCount: number\n actionedCount: number\n escalatedCount: number\n actionRate: number\n avgHandlingTimeSec?: number\n}\nexport type ModeratorStatistics = {\n inboundCount: number\n actionedCount: number\n avgHandlingTimeSec?: number\n}\nexport type ReportTypeStatistics = {\n inboundCount: number\n pendingCount: number\n actionedCount: number\n escalatedCount: number\n actionRate: number\n avgHandlingTimeSec?: number\n}\nexport type ReportStatistics =\n | QueueStatistics\n | ModeratorStatistics\n | AggregateStatistics\n | ReportTypeStatistics\n\n// Batched query result types\ntype QueueCountRow = {\n queueId: number | null\n count: string\n}\ntype QueueWindowRow = {\n queueId: number | null\n inboundCount: string\n actionedCount: string\n escalatedCount: string\n handlingTimeSum: string | null\n handlingTimeCount: string\n}\ntype TypeCountRow = {\n reportType: string\n count: string\n}\ntype TypeWindowRow = {\n reportType: string\n inboundCount: string\n actionedCount: string\n escalatedCount: string\n handlingTimeSum: string | null\n handlingTimeCount: string\n}\ntype ModeratorWindowRow = {\n did: string\n inboundCount: string\n actionedCount: string\n handlingTimeSum: string | null\n handlingTimeCount: string\n}\ntype BatchedStats = {\n queuePending: QueueCountRow[]\n queueWindow: QueueWindowRow[]\n typePending: TypeCountRow[]\n typeWindow: TypeWindowRow[]\n moderator: ModeratorWindowRow[]\n}\n\ntype UpsertRow = {\n date: string\n queueId: number | null\n moderatorDid: string | null\n reportTypes: string[] | null\n inboundCount: number | null\n pendingCount: number | null\n actionedCount: number | null\n escalatedCount: number | null\n actionRate: number | null\n avgHandlingTimeSec: number | null\n computedAt: string\n}\n\nexport class ReportStatsService {\n constructor(public db: Database) {}\n\n static creator(): ReportStatsServiceCreator {\n return (db: Database) => new ReportStatsService(db)\n }\n\n /**\n * Compute stats for today and finalize yesterday if needed.\n * Called periodically by the StatsComputer daemon.\n */\n async materializeAll(opts?: { force?: boolean }): Promise<void> {\n try {\n const start = Date.now()\n const today = toDateString(new Date())\n const yesterday = toDateString(new Date(Date.now() - 24 * 60 * 60 * 1000))\n\n // Always compute today's stats\n await this.materializeDate(today, opts)\n\n // Finalize yesterday if its snapshot is missing or stale\n if (!opts?.force) {\n const yesterdayRow = await this.db.db\n .selectFrom('report_stat')\n .select('computedAt')\n .where('date', '=', yesterday)\n .orderBy('computedAt', 'desc')\n .executeTakeFirst()\n const endOfYesterday = new Date(`${yesterday}T23:59:59.999Z`).getTime()\n if (\n !yesterdayRow ||\n new Date(yesterdayRow.computedAt).getTime() < endOfYesterday\n ) {\n await this.materializeDate(yesterday, { force: true })\n }\n } else {\n await this.materializeDate(yesterday, { force: true })\n }\n\n const duration = Date.now() - start\n dbLogger.info({ duration }, 'report stats materialization completed')\n } catch (err) {\n dbLogger.error({ err }, 'report stats materialization errored')\n }\n }\n\n /**\n * Compute stats for a specific date range. Used by the refreshStats endpoint.\n */\n async refreshDateRange(opts: {\n startDate: string\n endDate: string\n queueIds?: number[]\n }): Promise<void> {\n const start = new Date(opts.startDate)\n const end = new Date(opts.endDate)\n\n for (let d = new Date(start); d <= end; d.setUTCDate(d.getUTCDate() + 1)) {\n const dateStr = toDateString(d)\n if (opts.queueIds?.length) {\n // Recompute only specific queue groups for this date\n const batched = await this.computeBatchedStats(dateStr)\n const rows: UpsertRow[] = []\n for (const queueId of opts.queueIds) {\n const group: ReportStatGroup = {\n queueId,\n moderatorDid: null,\n reportTypes: null,\n }\n const stats = this.resolveGroupStats(group, batched)\n rows.push(this.buildUpsertRow(dateStr, group, stats))\n }\n await this.bulkUpsert(rows)\n } else {\n await this.materializeDate(dateStr, { force: true })\n }\n }\n }\n\n /** Compute and write all groups for a single date. */\n private async materializeDate(\n date: string,\n opts?: { force?: boolean },\n ): Promise<void> {\n const groups = await this.enumerateGroups()\n const batched = await this.computeBatchedStats(date)\n const today = toDateString(new Date())\n const isToday = date === today\n\n // Batch the cache check so we don't issue one SELECT per group.\n const existingByKey = !opts?.force\n ? await this.fetchExistingStatsByKey(date)\n : null\n\n const rows: UpsertRow[] = []\n for (const group of groups) {\n try {\n if (existingByKey) {\n const cached = existingByKey.get(groupKey(group))\n if (cached) {\n // Historical dates: never recompute. Today: recompute if stale.\n if (!isToday) continue\n const age = Date.now() - new Date(cached.computedAt).getTime()\n if (age < REPORT_STAT_LIVE_TTL) continue\n }\n }\n const stats = this.resolveGroupStats(group, batched)\n rows.push(this.buildUpsertRow(date, group, stats))\n } catch (err) {\n dbLogger.error(\n { err, group, date },\n 'error preparing report stats group',\n )\n }\n }\n\n await this.bulkUpsert(rows)\n }\n\n /** Fetch all stat rows for a date, keyed by groupKey for O(1) lookup. */\n private async fetchExistingStatsByKey(\n date: string,\n ): Promise<Map<string, Selectable<ReportStat>>> {\n const existing = await this.db.db\n .selectFrom('report_stat')\n .selectAll()\n .where('date', '=', date)\n .execute()\n const map = new Map<string, Selectable<ReportStat>>()\n for (const row of existing) {\n map.set(\n groupKey({\n queueId: row.queueId,\n moderatorDid: row.moderatorDid,\n reportTypes: row.reportTypes,\n }),\n row,\n )\n }\n return map\n }\n\n /** List out the groups to compute stats for. */\n private async enumerateGroups(): Promise<ReportStatGroup[]> {\n const groups: ReportStatGroup[] = []\n\n const queues = await this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('enabled', '=', true)\n .where('deletedAt', 'is', null)\n .execute()\n const members = await this.db.db\n .selectFrom('member')\n .select('did')\n .where('disabled', '=', false)\n .where('role', 'in', [\n 'tools.ozone.team.defs#roleAdmin',\n 'tools.ozone.team.defs#roleModerator',\n 'tools.ozone.team.defs#roleTriage',\n ])\n .execute()\n\n // aggregate\n groups.push({ queueId: null, moderatorDid: null, reportTypes: null })\n // per queue\n for (const queue of queues) {\n groups.push({ queueId: queue.id, moderatorDid: null, reportTypes: null })\n }\n // unqueued\n groups.push({ queueId: -1, moderatorDid: null, reportTypes: null })\n // per moderator\n for (const member of members) {\n groups.push({\n queueId: null,\n moderatorDid: member.did,\n reportTypes: null,\n })\n }\n // per report type group\n for (const groupTypes of Object.values(REPORT_TYPE_GROUPS)) {\n groups.push({\n queueId: null,\n moderatorDid: null,\n reportTypes: groupTypes,\n })\n }\n\n return groups\n }\n\n /**\n * Run batched GROUP BY queries for a calendar date.\n * Returns 5 result sets covering all group types.\n */\n private async computeBatchedStats(date: string): Promise<BatchedStats> {\n const dayStart = `${date}T00:00:00.000Z`\n const dayEnd = `${nextDate(date)}T00:00:00.000Z`\n\n const [queuePending, aggregatePending] = await Promise.all([\n // Pending count is a snapshot of all non-closed reports at time of computation\n this.db.db\n .selectFrom('report')\n .select(['queueId', sql<string>`count(*)`.as('count')])\n .where('status', '!=', 'closed')\n .where('queueId', 'is not', null)\n .groupBy('queueId')\n .execute(),\n // Aggregate pending (includes all reports, even un-routed)\n this.db.db\n .selectFrom('report')\n .select(sql<string>`count(*)`.as('count'))\n .where('status', '!=', 'closed')\n .executeTakeFirst(),\n ])\n\n const queueWindow = await this.db.db\n .selectFrom('report')\n .select([\n 'queueId',\n sql<string>`count(*)`.as('inboundCount'),\n sql<string>`count(*) filter (where \"status\" = 'closed' and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'actionedCount',\n ),\n sql<string>`count(*) filter (where \"status\" = 'escalated')`.as(\n 'escalatedCount',\n ),\n sql<string>`sum(extract(epoch from (\"closedAt\"::timestamp - \"createdAt\"::timestamp))) filter (where \"status\" = 'closed' and \"closedAt\" is not null and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'handlingTimeSum',\n ),\n sql<string>`count(*) filter (where \"status\" = 'closed' and \"closedAt\" is not null and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'handlingTimeCount',\n ),\n ])\n .where('createdAt', '>=', dayStart)\n .where('createdAt', '<', dayEnd)\n .where('queueId', 'is not', null)\n .groupBy('queueId')\n .execute()\n\n // Aggregate windowed (includes all reports)\n const aggregateWindow = await this.db.db\n .selectFrom('report')\n .select([\n sql<string>`count(*)`.as('inboundCount'),\n sql<string>`count(*) filter (where \"status\" = 'closed' and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'actionedCount',\n ),\n sql<string>`count(*) filter (where \"status\" = 'escalated')`.as(\n 'escalatedCount',\n ),\n sql<string>`sum(extract(epoch from (\"closedAt\"::timestamp - \"createdAt\"::timestamp))) filter (where \"status\" = 'closed' and \"closedAt\" is not null and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'handlingTimeSum',\n ),\n sql<string>`count(*) filter (where \"status\" = 'closed' and \"closedAt\" is not null and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'handlingTimeCount',\n ),\n ])\n .where('createdAt', '>=', dayStart)\n .where('createdAt', '<', dayEnd)\n .executeTakeFirst()\n\n const typePending = await this.db.db\n .selectFrom('report')\n .select(['reportType', sql<string>`count(*)`.as('count')])\n .where('status', '!=', 'closed')\n .groupBy('reportType')\n .execute()\n\n const typeWindow = await this.db.db\n .selectFrom('report')\n .select([\n 'reportType',\n sql<string>`count(*)`.as('inboundCount'),\n sql<string>`count(*) filter (where \"status\" = 'closed' and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'actionedCount',\n ),\n sql<string>`count(*) filter (where \"status\" = 'escalated')`.as(\n 'escalatedCount',\n ),\n sql<string>`sum(extract(epoch from (\"closedAt\"::timestamp - \"createdAt\"::timestamp))) filter (where \"status\" = 'closed' and \"closedAt\" is not null and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'handlingTimeSum',\n ),\n sql<string>`count(*) filter (where \"status\" = 'closed' and \"closedAt\" is not null and \"closedAt\" >= ${dayStart} and \"closedAt\" < ${dayEnd})`.as(\n 'handlingTimeCount',\n ),\n ])\n .where('createdAt', '>=', dayStart)\n .where('createdAt', '<', dayEnd)\n .groupBy('reportType')\n .execute()\n\n const moderator = await this.db.db\n .selectFrom('report as r')\n .innerJoin('moderator_assignment as ma', (join) =>\n join.onRef('ma.reportId', '=', 'r.id').on('ma.endAt', 'is', null),\n )\n .select([\n 'ma.did',\n sql<string>`count(*)`.as('inboundCount'),\n sql<string>`count(*) filter (where r.\"status\" = 'closed')`.as(\n 'actionedCount',\n ),\n sql<string>`sum(extract(epoch from (r.\"closedAt\"::timestamp - ma.\"startAt\"::timestamp))) filter (where r.\"status\" = 'closed' and r.\"closedAt\" is not null)`.as(\n 'handlingTimeSum',\n ),\n sql<string>`count(*) filter (where r.\"status\" = 'closed' and r.\"closedAt\" is not null)`.as(\n 'handlingTimeCount',\n ),\n ])\n .where('r.createdAt', '>=', dayStart)\n .where('r.createdAt', '<', dayEnd)\n .groupBy('ma.did')\n .execute()\n\n // Inject aggregate as a synthetic row with queueId=null so resolveQueueStats can find it\n const allQueuePending: QueueCountRow[] = [\n ...queuePending,\n { queueId: null, count: aggregatePending?.count ?? '0' },\n ]\n const allQueueWindow: QueueWindowRow[] = aggregateWindow\n ? [\n ...queueWindow,\n {\n queueId: null,\n inboundCount: aggregateWindow.inboundCount,\n actionedCount: aggregateWindow.actionedCount,\n escalatedCount: aggregateWindow.escalatedCount,\n handlingTimeSum: aggregateWindow.handlingTimeSum,\n handlingTimeCount: aggregateWindow.handlingTimeCount,\n },\n ]\n : queueWindow\n\n return {\n queuePending: allQueuePending,\n queueWindow: allQueueWindow,\n typePending,\n typeWindow,\n moderator,\n }\n }\n\n /** Resolve a single group's stats from batched query results (pure in-memory). */\n private resolveGroupStats(\n group: ReportStatGroup,\n batched: BatchedStats,\n ): ReportStatistics {\n if (group.moderatorDid) {\n return this.resolveModeratorStats(group.moderatorDid, batched.moderator)\n }\n if (group.reportTypes !== null) {\n return this.resolveReportTypeStats(group.reportTypes, batched)\n }\n return this.resolveQueueStats(group.queueId, batched)\n }\n\n private resolveQueueStats(\n queueId: number | null,\n batched: BatchedStats,\n ): AggregateStatistics | QueueStatistics {\n // queueId=null is the synthetic aggregate row\n const pending = batched.queuePending.find((r) => r.queueId === queueId)\n const window = batched.queueWindow.find((r) => r.queueId === queueId)\n\n const pendingCount = num(pending?.count)\n const inboundCount = num(window?.inboundCount)\n const actionedCount = num(window?.actionedCount)\n const escalatedCount = num(window?.escalatedCount)\n const handlingTimeSum = Number(window?.handlingTimeSum ?? 0)\n const handlingTimeCount = num(window?.handlingTimeCount)\n const actionRate =\n inboundCount > 0 ? Math.round((actionedCount / inboundCount) * 100) : 0\n const avgHandlingTimeSec =\n handlingTimeCount > 0\n ? Math.round(handlingTimeSum / handlingTimeCount)\n : undefined\n\n return {\n inboundCount,\n pendingCount,\n actionedCount,\n escalatedCount,\n actionRate,\n avgHandlingTimeSec,\n }\n }\n\n private resolveReportTypeStats(\n reportTypes: string[],\n batched: BatchedStats,\n ): ReportTypeStatistics {\n const types = new Set(reportTypes)\n\n const matchingPending = batched.typePending.filter((r) =>\n types.has(r.reportType),\n )\n const matchingWindow = batched.typeWindow.filter((r) =>\n types.has(r.reportType),\n )\n\n const pendingCount = sumNum(matchingPending, 'count')\n const inboundCount = sumNum(matchingWindow, 'inboundCount')\n const actionedCount = sumNum(matchingWindow, 'actionedCount')\n const escalatedCount = sumNum(matchingWindow, 'escalatedCount')\n const handlingTimeSum = matchingWindow.reduce(\n (sum, r) => sum + Number(r.handlingTimeSum ?? 0),\n 0,\n )\n const handlingTimeCount = sumNum(matchingWindow, 'handlingTimeCount')\n\n const actionRate =\n inboundCount > 0 ? Math.round((actionedCount / inboundCount) * 100) : 0\n const avgHandlingTimeSec =\n handlingTimeCount > 0\n ? Math.round(handlingTimeSum / handlingTimeCount)\n : undefined\n\n return {\n inboundCount,\n pendingCount,\n actionedCount,\n escalatedCount,\n actionRate,\n avgHandlingTimeSec,\n }\n }\n\n private resolveModeratorStats(\n moderatorDid: string,\n rows: ModeratorWindowRow[],\n ): ModeratorStatistics {\n const row = rows.find((r) => r.did === moderatorDid)\n\n const inboundCount = num(row?.inboundCount)\n const actionedCount = num(row?.actionedCount)\n const handlingTimeCount = num(row?.handlingTimeCount)\n const avgHandlingTimeSec =\n handlingTimeCount > 0 && row?.handlingTimeSum\n ? Math.round(Number(row.handlingTimeSum) / handlingTimeCount)\n : undefined\n\n return { inboundCount, actionedCount, avgHandlingTimeSec }\n }\n\n /** Build an upsert row from (date, group, stats). */\n private buildUpsertRow(\n date: string,\n group: ReportStatGroup,\n stats: ReportStatistics,\n ): UpsertRow {\n const pendingCount =\n 'pendingCount' in stats ? stats.pendingCount ?? null : null\n const escalatedCount =\n 'escalatedCount' in stats ? stats.escalatedCount ?? null : null\n const actionRate = 'actionRate' in stats ? stats.actionRate ?? null : null\n\n return {\n date,\n queueId: group.queueId,\n moderatorDid: group.moderatorDid,\n reportTypes: group.reportTypes,\n inboundCount: stats.inboundCount ?? null,\n pendingCount,\n actionedCount: stats.actionedCount ?? null,\n escalatedCount,\n actionRate,\n avgHandlingTimeSec: stats.avgHandlingTimeSec ?? null,\n computedAt: new Date().toISOString(),\n }\n }\n\n /**\n * Wraps a DELETE+INSERT for each row in a single transaction so we pay one\n * commit per cycle instead of one per group. NULL-aware WHERE clauses match\n * the existing PG <15 NULL semantics without needing a unique index.\n */\n private async bulkUpsert(rows: UpsertRow[]): Promise<void> {\n if (!rows.length) return\n\n await this.db.transaction(async (dbTxn) => {\n for (const r of rows) {\n let del = dbTxn.db.deleteFrom('report_stat').where('date', '=', r.date)\n del =\n r.queueId !== null\n ? del.where('queueId', '=', r.queueId)\n : del.where('queueId', 'is', null)\n del =\n r.moderatorDid !== null\n ? del.where('moderatorDid', '=', r.moderatorDid)\n : del.where('moderatorDid', 'is', null)\n del =\n r.reportTypes !== null\n ? del.where(\n sql`\"reportTypes\"::jsonb = ${jsonb(r.reportTypes)}::jsonb`,\n )\n : del.where('reportTypes', 'is', null)\n await del.execute()\n\n await dbTxn.db\n .insertInto('report_stat')\n .values({\n date: r.date,\n queueId: r.queueId,\n moderatorDid: r.moderatorDid,\n reportTypes: r.reportTypes !== null ? jsonb(r.reportTypes) : null,\n inboundCount: r.inboundCount,\n pendingCount: r.pendingCount,\n actionedCount: r.actionedCount,\n escalatedCount: r.escalatedCount,\n actionRate: r.actionRate,\n avgHandlingTimeSec: r.avgHandlingTimeSec,\n computedAt: r.computedAt,\n })\n .execute()\n }\n })\n }\n\n // ─── Read methods ───\n\n /** Get a single stat row for a date + group. */\n private async getStatForDate(\n date: string,\n group: ReportStatGroup,\n ): Promise<Selectable<ReportStat> | undefined> {\n let qb = this.db.db\n .selectFrom('report_stat')\n .selectAll()\n .where('date', '=', date)\n if (group.queueId !== null) {\n qb = qb.where('queueId', '=', group.queueId)\n } else {\n qb = qb.where('queueId', 'is', null)\n }\n if (group.moderatorDid) {\n qb = qb.where('moderatorDid', '=', group.moderatorDid)\n } else {\n qb = qb.where('moderatorDid', 'is', null)\n }\n if (group.reportTypes !== null) {\n qb = qb.where(\n sql`\"reportTypes\"::jsonb = ${jsonb(group.reportTypes)}::jsonb`,\n )\n } else {\n qb = qb.where('reportTypes', 'is', null)\n }\n return qb.executeTakeFirst()\n }\n\n /** Get today's live stats for a group. */\n async getLiveStats(\n group: ReportStatGroup,\n ): Promise<Selectable<ReportStat> | undefined> {\n const today = toDateString(new Date())\n return this.getStatForDate(today, group)\n }\n\n /** Get live stats for multiple queues in a single query. */\n async getLiveStatsForQueues(\n queueIds: number[],\n ): Promise<Map<number, Selectable<ReportStat>>> {\n if (!queueIds.length) return new Map()\n\n const today = toDateString(new Date())\n const rows = await this.db.db\n .selectFrom('report_stat')\n .selectAll()\n .where('date', '=', today)\n .where('queueId', 'in', queueIds)\n .where('moderatorDid', 'is', null)\n .where('reportTypes', 'is', null)\n .execute()\n\n const result = new Map<number, Selectable<ReportStat>>()\n for (const row of rows) {\n if (row.queueId !== null) {\n result.set(row.queueId, row)\n }\n }\n return result\n }\n\n /** Get historical stats for a date range, paginated. */\n async getHistoricalStats(opts: {\n group: ReportStatGroup\n startDate?: string\n endDate?: string\n limit: number\n cursor?: string\n }): Promise<{ stats: Selectable<ReportStat>[]; cursor?: string }> {\n const { group, startDate, endDate, limit } = opts\n const { queueId, moderatorDid, reportTypes } = group\n const { ref } = this.db.db.dynamic\n\n let qb = this.db.db.selectFrom('report_stat').selectAll()\n\n if (queueId !== null) {\n qb = qb.where('queueId', '=', queueId)\n } else {\n qb = qb.where('queueId', 'is', null)\n }\n if (moderatorDid) {\n qb = qb.where('moderatorDid', '=', moderatorDid)\n } else {\n qb = qb.where('moderatorDid', 'is', null)\n }\n if (reportTypes !== null) {\n qb = qb.where(sql`\"reportTypes\"::jsonb = ${jsonb(reportTypes)}::jsonb`)\n } else {\n qb = qb.where('reportTypes', 'is', null)\n }\n if (startDate) {\n qb = qb.where('date', '>=', toDateString(new Date(startDate)))\n }\n if (endDate) {\n qb = qb.where('date', '<=', toDateString(new Date(endDate)))\n }\n\n const keyset = new ComputedAtIdKeyset(ref('computedAt'), ref('id'))\n const paginatedBuilder = paginate(qb, {\n limit,\n cursor: opts.cursor,\n keyset,\n direction: 'desc',\n tryIndex: true,\n })\n\n const stats = await paginatedBuilder.execute()\n\n return { stats, cursor: keyset.packFromResult(stats) }\n }\n}\n\n// ─── Helpers ───\n\n/** Parse a pg bigint string to number, defaulting to 0. */\nfunction num(val: string | undefined | null): number {\n return val ? Number(val) : 0\n}\n\n/** Sum a numeric string field across rows. */\nfunction sumNum<T>(rows: T[], field: keyof T): number {\n return rows.reduce((sum, r) => sum + Number(r[field] ?? 0), 0)\n}\n\n/**\n * Stable cache-key for a stat group. Used to look up an existing row in the\n * batched cache map without issuing per-group SELECTs. Report types are\n * stringified in stored order, which matches REPORT_TYPE_GROUPS.\n */\nfunction groupKey(g: ReportStatGroup): string {\n return [\n g.queueId ?? 'null',\n g.moderatorDid ?? 'null',\n g.reportTypes ? JSON.stringify(g.reportTypes) : 'null',\n ].join('|')\n}\n\n/** Convert a Date to an ISO date string (YYYY-MM-DD). */\nfunction toDateString(d: Date): string {\n return d.toISOString().slice(0, 10)\n}\n\n/** Get the next calendar date string. */\nfunction nextDate(dateStr: string): string {\n const d = new Date(`${dateStr}T00:00:00.000Z`)\n d.setUTCDate(d.getUTCDate() + 1)\n return toDateString(d)\n}\n"]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Selectable } from 'kysely';
|
|
2
|
+
import { AppBskyActorDefs, ToolsOzoneModerationDefs, ToolsOzoneQueueDefs, ToolsOzoneReportDefs } from '@atproto/api';
|
|
3
|
+
import { ReportStat } from '../db/schema/report_stat';
|
|
4
|
+
import { AccountView } from '../lexicon/types/com/atproto/admin/defs';
|
|
5
|
+
import { RecordViewDetail, RepoView } from '../lexicon/types/tools/ozone/moderation/defs';
|
|
6
|
+
import { Member as TeamMember } from '../lexicon/types/tools/ozone/team/defs';
|
|
7
|
+
import { ReportWithEvent } from '../mod-service/report';
|
|
8
|
+
import { ParsedLabelers } from '../util';
|
|
9
|
+
type ReportViews = {
|
|
10
|
+
repoDetails(dids: string[], labelers?: ParsedLabelers): Promise<Map<string, RepoView>>;
|
|
11
|
+
recordDetails(subjects: {
|
|
12
|
+
uri: string;
|
|
13
|
+
}[], labelers?: ParsedLabelers): Promise<Map<string, RecordViewDetail>>;
|
|
14
|
+
getProfiles(dids: string[]): Promise<Map<string, AppBskyActorDefs.ProfileViewDetailed>>;
|
|
15
|
+
};
|
|
16
|
+
export type HydratedReport = {
|
|
17
|
+
partialRepos: Map<string, RepoView>;
|
|
18
|
+
accountInfo: Map<string, AccountView | null>;
|
|
19
|
+
recordInfo: Map<string, RecordViewDetail>;
|
|
20
|
+
profiles: Map<string, AppBskyActorDefs.ProfileViewDetailed>;
|
|
21
|
+
queues: Map<number, ToolsOzoneQueueDefs.QueueView>;
|
|
22
|
+
memberViews: Map<string, TeamMember>;
|
|
23
|
+
};
|
|
24
|
+
export declare function hydrateReportInfo(reports: ReportWithEvent[], views: ReportViews, getAccountInfos: (dids: string[]) => Promise<Map<string, AccountView | null>>, getQueues: (queueIds: number[]) => Promise<Map<number, ToolsOzoneQueueDefs.QueueView>>, getTeamMembers: (dids: string[]) => Promise<Map<string, TeamMember>>, labelers: ParsedLabelers): Promise<HydratedReport>;
|
|
25
|
+
export declare function buildReportView(report: ReportWithEvent, hydrated: HydratedReport, isModerator: boolean, actions?: ToolsOzoneModerationDefs.ModEventView[]): {
|
|
26
|
+
id: number;
|
|
27
|
+
eventId: number;
|
|
28
|
+
status: string;
|
|
29
|
+
subject: {
|
|
30
|
+
type: string;
|
|
31
|
+
subject: string;
|
|
32
|
+
repo: import("../lexicon/types/tools/ozone/moderation/defs").RepoViewDetail | undefined;
|
|
33
|
+
record: RecordViewDetail | undefined;
|
|
34
|
+
profile: {
|
|
35
|
+
$type: "app.bsky.actor.defs#profileViewDetailed";
|
|
36
|
+
did: string;
|
|
37
|
+
handle: string;
|
|
38
|
+
displayName?: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
pronouns?: string;
|
|
41
|
+
website?: string;
|
|
42
|
+
avatar?: string;
|
|
43
|
+
banner?: string;
|
|
44
|
+
followersCount?: number;
|
|
45
|
+
followsCount?: number;
|
|
46
|
+
postsCount?: number;
|
|
47
|
+
associated?: AppBskyActorDefs.ProfileAssociated;
|
|
48
|
+
joinedViaStarterPack?: import("@atproto/api/dist/client/types/app/bsky/graph/defs").StarterPackViewBasic;
|
|
49
|
+
indexedAt?: string;
|
|
50
|
+
createdAt?: string;
|
|
51
|
+
viewer?: AppBskyActorDefs.ViewerState;
|
|
52
|
+
labels?: import("@atproto/api/dist/client/types/com/atproto/label/defs").Label[];
|
|
53
|
+
pinnedPost?: import("@atproto/api/dist/client/types/com/atproto/repo/strongRef").Main;
|
|
54
|
+
verification?: AppBskyActorDefs.VerificationState;
|
|
55
|
+
status?: AppBskyActorDefs.StatusView;
|
|
56
|
+
debug?: { [_ in string]: unknown; };
|
|
57
|
+
} | undefined;
|
|
58
|
+
status: import("../lexicon/types/tools/ozone/moderation/defs").SubjectStatusView | undefined;
|
|
59
|
+
};
|
|
60
|
+
reportType: string;
|
|
61
|
+
reportedBy: string;
|
|
62
|
+
reporter: {
|
|
63
|
+
type: string;
|
|
64
|
+
subject: string;
|
|
65
|
+
repo: import("../lexicon/types/tools/ozone/moderation/defs").RepoViewDetail | undefined;
|
|
66
|
+
profile: {
|
|
67
|
+
$type: "app.bsky.actor.defs#profileViewDetailed";
|
|
68
|
+
did: string;
|
|
69
|
+
handle: string;
|
|
70
|
+
displayName?: string;
|
|
71
|
+
description?: string;
|
|
72
|
+
pronouns?: string;
|
|
73
|
+
website?: string;
|
|
74
|
+
avatar?: string;
|
|
75
|
+
banner?: string;
|
|
76
|
+
followersCount?: number;
|
|
77
|
+
followsCount?: number;
|
|
78
|
+
postsCount?: number;
|
|
79
|
+
associated?: AppBskyActorDefs.ProfileAssociated;
|
|
80
|
+
joinedViaStarterPack?: import("@atproto/api/dist/client/types/app/bsky/graph/defs").StarterPackViewBasic;
|
|
81
|
+
indexedAt?: string;
|
|
82
|
+
createdAt?: string;
|
|
83
|
+
viewer?: AppBskyActorDefs.ViewerState;
|
|
84
|
+
labels?: import("@atproto/api/dist/client/types/com/atproto/label/defs").Label[];
|
|
85
|
+
pinnedPost?: import("@atproto/api/dist/client/types/com/atproto/repo/strongRef").Main;
|
|
86
|
+
verification?: AppBskyActorDefs.VerificationState;
|
|
87
|
+
status?: AppBskyActorDefs.StatusView;
|
|
88
|
+
debug?: { [_ in string]: unknown; };
|
|
89
|
+
} | undefined;
|
|
90
|
+
status: import("../lexicon/types/tools/ozone/moderation/defs").SubjectStatusView | undefined;
|
|
91
|
+
};
|
|
92
|
+
comment: string | undefined;
|
|
93
|
+
createdAt: string;
|
|
94
|
+
updatedAt: string;
|
|
95
|
+
queuedAt: string | undefined;
|
|
96
|
+
actionEventIds: number[] | undefined;
|
|
97
|
+
actions: ToolsOzoneModerationDefs.ModEventView[] | undefined;
|
|
98
|
+
actionNote: string | undefined;
|
|
99
|
+
assignment: {
|
|
100
|
+
did: string;
|
|
101
|
+
moderator: TeamMember | undefined;
|
|
102
|
+
assignedAt: string;
|
|
103
|
+
} | undefined;
|
|
104
|
+
queue: ToolsOzoneQueueDefs.QueueView | undefined;
|
|
105
|
+
isMuted: boolean;
|
|
106
|
+
};
|
|
107
|
+
export declare function viewQueueStats(row?: Selectable<ReportStat>): ToolsOzoneQueueDefs.QueueStats;
|
|
108
|
+
export declare function viewLiveStats(row?: Selectable<ReportStat>): ToolsOzoneReportDefs.LiveStats;
|
|
109
|
+
export declare function viewHistoricalStats(row: Selectable<ReportStat>): ToolsOzoneReportDefs.HistoricalStats;
|
|
110
|
+
export {};
|
|
111
|
+
//# sourceMappingURL=views.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../src/report/views.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hydrateReportInfo = hydrateReportInfo;
|
|
4
|
+
exports.buildReportView = buildReportView;
|
|
5
|
+
exports.viewQueueStats = viewQueueStats;
|
|
6
|
+
exports.viewLiveStats = viewLiveStats;
|
|
7
|
+
exports.viewHistoricalStats = viewHistoricalStats;
|
|
8
|
+
const util_1 = require("../api/util");
|
|
9
|
+
async function hydrateReportInfo(reports, views, getAccountInfos, getQueues, getTeamMembers, labelers) {
|
|
10
|
+
const dids = new Set();
|
|
11
|
+
const uris = new Set();
|
|
12
|
+
const queueIds = new Set();
|
|
13
|
+
const assignmentDids = [];
|
|
14
|
+
for (const report of reports) {
|
|
15
|
+
dids.add(report.subjectDid);
|
|
16
|
+
dids.add(report.reportedBy);
|
|
17
|
+
if (report.subjectUri)
|
|
18
|
+
uris.add(report.subjectUri);
|
|
19
|
+
if (report.queueId && report.queueId > 0)
|
|
20
|
+
queueIds.add(report.queueId);
|
|
21
|
+
if (report.assignedTo) {
|
|
22
|
+
dids.add(report.assignedTo);
|
|
23
|
+
assignmentDids.push(report.assignedTo);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const didsArray = Array.from(dids);
|
|
27
|
+
const [partialRepos, accountInfo, recordInfo, profiles, queues, memberViews] = await Promise.all([
|
|
28
|
+
views.repoDetails(didsArray, labelers),
|
|
29
|
+
getAccountInfos(didsArray),
|
|
30
|
+
views.recordDetails(Array.from(uris).map((uri) => ({ uri })), labelers),
|
|
31
|
+
views.getProfiles(didsArray),
|
|
32
|
+
getQueues(Array.from(queueIds)),
|
|
33
|
+
getTeamMembers(assignmentDids),
|
|
34
|
+
]);
|
|
35
|
+
return {
|
|
36
|
+
partialRepos,
|
|
37
|
+
accountInfo,
|
|
38
|
+
recordInfo,
|
|
39
|
+
profiles,
|
|
40
|
+
queues,
|
|
41
|
+
memberViews,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function buildReportView(report, hydrated, isModerator, actions) {
|
|
45
|
+
const { partialRepos, accountInfo, recordInfo, profiles, queues, memberViews, } = hydrated;
|
|
46
|
+
const isRecord = !!report.subjectUri;
|
|
47
|
+
const did = report.subjectDid;
|
|
48
|
+
const partialRepo = partialRepos.get(did);
|
|
49
|
+
const repo = partialRepo
|
|
50
|
+
? (0, util_1.addAccountInfoToRepoViewDetail)(partialRepo, accountInfo.get(did) || null, isModerator)
|
|
51
|
+
: undefined;
|
|
52
|
+
const profile = profiles.get(did);
|
|
53
|
+
const record = isRecord ? recordInfo.get(report.subjectUri) : undefined;
|
|
54
|
+
const status = isRecord
|
|
55
|
+
? record?.moderation.subjectStatus
|
|
56
|
+
: repo?.moderation.subjectStatus;
|
|
57
|
+
const reportType = report.meta?.reportType;
|
|
58
|
+
const subject = isRecord ? report.subjectUri : report.subjectDid;
|
|
59
|
+
const subjectView = {
|
|
60
|
+
type: isRecord ? 'record' : 'account',
|
|
61
|
+
subject,
|
|
62
|
+
repo,
|
|
63
|
+
record,
|
|
64
|
+
profile: profile
|
|
65
|
+
? {
|
|
66
|
+
$type: 'app.bsky.actor.defs#profileViewDetailed',
|
|
67
|
+
...profile,
|
|
68
|
+
}
|
|
69
|
+
: undefined,
|
|
70
|
+
status,
|
|
71
|
+
};
|
|
72
|
+
const reporterDid = report.reportedBy;
|
|
73
|
+
const reporterPartialRepo = partialRepos.get(reporterDid);
|
|
74
|
+
const reporterRepo = reporterPartialRepo
|
|
75
|
+
? (0, util_1.addAccountInfoToRepoViewDetail)(reporterPartialRepo, accountInfo.get(reporterDid) || null, isModerator)
|
|
76
|
+
: undefined;
|
|
77
|
+
const reporterProfile = profiles.get(reporterDid);
|
|
78
|
+
const reporterStatus = reporterRepo?.moderation.subjectStatus;
|
|
79
|
+
const reporterView = {
|
|
80
|
+
type: 'account',
|
|
81
|
+
subject: reporterDid,
|
|
82
|
+
repo: reporterRepo,
|
|
83
|
+
profile: reporterProfile
|
|
84
|
+
? {
|
|
85
|
+
$type: 'app.bsky.actor.defs#profileViewDetailed',
|
|
86
|
+
...reporterProfile,
|
|
87
|
+
}
|
|
88
|
+
: undefined,
|
|
89
|
+
status: reporterStatus,
|
|
90
|
+
};
|
|
91
|
+
const assignmentView = report.assignedTo && report.assignedAt
|
|
92
|
+
? {
|
|
93
|
+
did: report.assignedTo,
|
|
94
|
+
moderator: memberViews.get(report.assignedTo),
|
|
95
|
+
assignedAt: report.assignedAt,
|
|
96
|
+
}
|
|
97
|
+
: undefined;
|
|
98
|
+
return {
|
|
99
|
+
id: report.id,
|
|
100
|
+
eventId: report.eventId,
|
|
101
|
+
status: report.status,
|
|
102
|
+
subject: subjectView,
|
|
103
|
+
reportType,
|
|
104
|
+
reportedBy: report.reportedBy,
|
|
105
|
+
reporter: reporterView,
|
|
106
|
+
comment: report.comment ?? undefined,
|
|
107
|
+
createdAt: report.createdAt,
|
|
108
|
+
updatedAt: report.updatedAt,
|
|
109
|
+
queuedAt: report.queuedAt ?? undefined,
|
|
110
|
+
actionEventIds: report.actionEventIds && Array.isArray(report.actionEventIds)
|
|
111
|
+
? report.actionEventIds
|
|
112
|
+
: undefined,
|
|
113
|
+
actions: actions && actions.length ? actions : undefined,
|
|
114
|
+
actionNote: report.actionNote ?? undefined,
|
|
115
|
+
assignment: assignmentView,
|
|
116
|
+
queue: report.queueId && report.queueId > 0
|
|
117
|
+
? queues.get(report.queueId)
|
|
118
|
+
: undefined,
|
|
119
|
+
isMuted: report.isMuted,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function viewQueueStats(row) {
|
|
123
|
+
return {
|
|
124
|
+
pendingCount: row?.pendingCount ?? undefined,
|
|
125
|
+
actionedCount: row?.actionedCount ?? undefined,
|
|
126
|
+
escalatedCount: row?.escalatedCount ?? undefined,
|
|
127
|
+
inboundCount: row?.inboundCount ?? undefined,
|
|
128
|
+
actionRate: row?.actionRate ?? undefined,
|
|
129
|
+
avgHandlingTimeSec: row?.avgHandlingTimeSec ?? undefined,
|
|
130
|
+
lastUpdated: row?.computedAt,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function viewLiveStats(row) {
|
|
134
|
+
return {
|
|
135
|
+
pendingCount: row?.pendingCount ?? undefined,
|
|
136
|
+
actionedCount: row?.actionedCount ?? undefined,
|
|
137
|
+
escalatedCount: row?.escalatedCount ?? undefined,
|
|
138
|
+
inboundCount: row?.inboundCount ?? undefined,
|
|
139
|
+
actionRate: row?.actionRate ?? undefined,
|
|
140
|
+
avgHandlingTimeSec: row?.avgHandlingTimeSec ?? undefined,
|
|
141
|
+
lastUpdated: row?.computedAt,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function viewHistoricalStats(row) {
|
|
145
|
+
return {
|
|
146
|
+
date: row.date,
|
|
147
|
+
computedAt: row.computedAt,
|
|
148
|
+
pendingCount: row.pendingCount ?? undefined,
|
|
149
|
+
actionedCount: row.actionedCount ?? undefined,
|
|
150
|
+
escalatedCount: row.escalatedCount ?? undefined,
|
|
151
|
+
inboundCount: row.inboundCount ?? undefined,
|
|
152
|
+
actionRate: row.actionRate ?? undefined,
|
|
153
|
+
avgHandlingTimeSec: row.avgHandlingTimeSec ?? undefined,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=views.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/report/views.ts"],"names":[],"mappings":"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","sourcesContent":["import { Selectable } from 'kysely'\nimport {\n AppBskyActorDefs,\n ToolsOzoneModerationDefs,\n ToolsOzoneQueueDefs,\n ToolsOzoneReportDefs,\n} from '@atproto/api'\nimport { addAccountInfoToRepoViewDetail } from '../api/util'\nimport { ReportStat } from '../db/schema/report_stat'\nimport { AccountView } from '../lexicon/types/com/atproto/admin/defs'\nimport {\n RecordViewDetail,\n RepoView,\n} from '../lexicon/types/tools/ozone/moderation/defs'\nimport { Member as TeamMember } from '../lexicon/types/tools/ozone/team/defs'\nimport { ReportWithEvent } from '../mod-service/report'\nimport { ParsedLabelers } from '../util'\n\ntype ReportViews = {\n repoDetails(\n dids: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RepoView>>\n recordDetails(\n subjects: { uri: string }[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RecordViewDetail>>\n getProfiles(\n dids: string[],\n ): Promise<Map<string, AppBskyActorDefs.ProfileViewDetailed>>\n}\n\nexport type HydratedReport = {\n partialRepos: Map<string, RepoView>\n accountInfo: Map<string, AccountView | null>\n recordInfo: Map<string, RecordViewDetail>\n profiles: Map<string, AppBskyActorDefs.ProfileViewDetailed>\n queues: Map<number, ToolsOzoneQueueDefs.QueueView>\n memberViews: Map<string, TeamMember>\n}\n\nexport async function hydrateReportInfo(\n reports: ReportWithEvent[],\n views: ReportViews,\n getAccountInfos: (dids: string[]) => Promise<Map<string, AccountView | null>>,\n getQueues: (\n queueIds: number[],\n ) => Promise<Map<number, ToolsOzoneQueueDefs.QueueView>>,\n getTeamMembers: (dids: string[]) => Promise<Map<string, TeamMember>>,\n labelers: ParsedLabelers,\n): Promise<HydratedReport> {\n const dids = new Set<string>()\n const uris = new Set<string>()\n const queueIds = new Set<number>()\n const assignmentDids: string[] = []\n\n for (const report of reports) {\n dids.add(report.subjectDid)\n dids.add(report.reportedBy)\n if (report.subjectUri) uris.add(report.subjectUri)\n if (report.queueId && report.queueId > 0) queueIds.add(report.queueId)\n if (report.assignedTo) {\n dids.add(report.assignedTo)\n assignmentDids.push(report.assignedTo)\n }\n }\n\n const didsArray = Array.from(dids)\n const [partialRepos, accountInfo, recordInfo, profiles, queues, memberViews] =\n await Promise.all([\n views.repoDetails(didsArray, labelers),\n getAccountInfos(didsArray),\n views.recordDetails(\n Array.from(uris).map((uri) => ({ uri })),\n labelers,\n ),\n views.getProfiles(didsArray),\n getQueues(Array.from(queueIds)),\n getTeamMembers(assignmentDids),\n ])\n\n return {\n partialRepos,\n accountInfo,\n recordInfo,\n profiles,\n queues,\n memberViews,\n }\n}\n\nexport function buildReportView(\n report: ReportWithEvent,\n hydrated: HydratedReport,\n isModerator: boolean,\n actions?: ToolsOzoneModerationDefs.ModEventView[],\n) {\n const {\n partialRepos,\n accountInfo,\n recordInfo,\n profiles,\n queues,\n memberViews,\n } = hydrated\n const isRecord = !!report.subjectUri\n const did = report.subjectDid\n const partialRepo = partialRepos.get(did)\n const repo = partialRepo\n ? addAccountInfoToRepoViewDetail(\n partialRepo,\n accountInfo.get(did) || null,\n isModerator,\n )\n : undefined\n const profile = profiles.get(did)\n const record = isRecord ? recordInfo.get(report.subjectUri!) : undefined\n const status = isRecord\n ? record?.moderation.subjectStatus\n : repo?.moderation.subjectStatus\n\n const reportType = report.meta?.reportType as string\n\n const subject = isRecord ? report.subjectUri! : report.subjectDid\n const subjectView = {\n type: isRecord ? 'record' : 'account',\n subject,\n repo,\n record,\n profile: profile\n ? {\n $type: 'app.bsky.actor.defs#profileViewDetailed' as const,\n ...profile,\n }\n : undefined,\n status,\n }\n\n const reporterDid = report.reportedBy\n const reporterPartialRepo = partialRepos.get(reporterDid)\n const reporterRepo = reporterPartialRepo\n ? addAccountInfoToRepoViewDetail(\n reporterPartialRepo,\n accountInfo.get(reporterDid) || null,\n isModerator,\n )\n : undefined\n const reporterProfile = profiles.get(reporterDid)\n const reporterStatus = reporterRepo?.moderation.subjectStatus\n\n const reporterView = {\n type: 'account',\n subject: reporterDid,\n repo: reporterRepo,\n profile: reporterProfile\n ? {\n $type: 'app.bsky.actor.defs#profileViewDetailed' as const,\n ...reporterProfile,\n }\n : undefined,\n status: reporterStatus,\n }\n\n const assignmentView =\n report.assignedTo && report.assignedAt\n ? {\n did: report.assignedTo,\n moderator: memberViews.get(report.assignedTo),\n assignedAt: report.assignedAt,\n }\n : undefined\n\n return {\n id: report.id,\n eventId: report.eventId,\n status: report.status,\n subject: subjectView,\n reportType,\n reportedBy: report.reportedBy,\n reporter: reporterView,\n comment: report.comment ?? undefined,\n createdAt: report.createdAt,\n updatedAt: report.updatedAt,\n queuedAt: report.queuedAt ?? undefined,\n actionEventIds:\n report.actionEventIds && Array.isArray(report.actionEventIds)\n ? (report.actionEventIds as number[])\n : undefined,\n actions: actions && actions.length ? actions : undefined,\n actionNote: report.actionNote ?? undefined,\n assignment: assignmentView,\n queue:\n report.queueId && report.queueId > 0\n ? queues.get(report.queueId)\n : undefined,\n isMuted: report.isMuted,\n }\n}\n\nexport function viewQueueStats(\n row?: Selectable<ReportStat>,\n): ToolsOzoneQueueDefs.QueueStats {\n return {\n pendingCount: row?.pendingCount ?? undefined,\n actionedCount: row?.actionedCount ?? undefined,\n escalatedCount: row?.escalatedCount ?? undefined,\n inboundCount: row?.inboundCount ?? undefined,\n actionRate: row?.actionRate ?? undefined,\n avgHandlingTimeSec: row?.avgHandlingTimeSec ?? undefined,\n lastUpdated: row?.computedAt,\n }\n}\n\nexport function viewLiveStats(\n row?: Selectable<ReportStat>,\n): ToolsOzoneReportDefs.LiveStats {\n return {\n pendingCount: row?.pendingCount ?? undefined,\n actionedCount: row?.actionedCount ?? undefined,\n escalatedCount: row?.escalatedCount ?? undefined,\n inboundCount: row?.inboundCount ?? undefined,\n actionRate: row?.actionRate ?? undefined,\n avgHandlingTimeSec: row?.avgHandlingTimeSec ?? undefined,\n lastUpdated: row?.computedAt,\n }\n}\n\nexport function viewHistoricalStats(\n row: Selectable<ReportStat>,\n): ToolsOzoneReportDefs.HistoricalStats {\n return {\n date: row.date,\n computedAt: row.computedAt,\n pendingCount: row.pendingCount ?? undefined,\n actionedCount: row.actionedCount ?? undefined,\n escalatedCount: row.escalatedCount ?? undefined,\n inboundCount: row.inboundCount ?? undefined,\n actionRate: row.actionRate ?? undefined,\n avgHandlingTimeSec: row.avgHandlingTimeSec ?? undefined,\n }\n}\n"]}
|
package/dist/team/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export declare class TeamService {
|
|
|
41
41
|
};
|
|
42
42
|
getProfiles(dids: string[]): Promise<Map<string, ProfileViewDetailed>>;
|
|
43
43
|
syncMemberProfiles(): Promise<void>;
|
|
44
|
+
viewByDids(dids: string[]): Promise<Map<string, TeamMember>>;
|
|
44
45
|
view(members: Selectable<Member>[]): Promise<TeamMember[]>;
|
|
45
46
|
}
|
|
46
47
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/team/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/team/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/team/index.ts"],"names":[],"mappings":"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"}
|
package/dist/team/index.js
CHANGED
|
@@ -191,6 +191,17 @@ class TeamService {
|
|
|
191
191
|
lastDid = dids.at(-1) || '';
|
|
192
192
|
} while (lastDid);
|
|
193
193
|
}
|
|
194
|
+
async viewByDids(dids) {
|
|
195
|
+
if (!dids.length)
|
|
196
|
+
return new Map();
|
|
197
|
+
const members = await this.db.db
|
|
198
|
+
.selectFrom('member')
|
|
199
|
+
.selectAll()
|
|
200
|
+
.where('did', 'in', dids)
|
|
201
|
+
.execute();
|
|
202
|
+
const memberViews = await this.view(members);
|
|
203
|
+
return new Map(memberViews.map((m) => [m.did, m]));
|
|
204
|
+
}
|
|
194
205
|
async view(members) {
|
|
195
206
|
const profiles = await this.getProfiles(members.map(({ did }) => did));
|
|
196
207
|
return members.map((member) => {
|
package/dist/team/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/team/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Selectable } from 'kysely'\nimport AtpAgent from '@atproto/api'\nimport { chunkArray } from '@atproto/common'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { Database } from '../db'\nimport { Member } from '../db/schema/member'\nimport { ids } from '../lexicon/lexicons'\nimport { ProfileViewDetailed } from '../lexicon/types/app/bsky/actor/defs'\nimport { Member as TeamMember } from '../lexicon/types/tools/ozone/team/defs'\nimport { httpLogger } from '../logger'\nimport { AuthHeaders } from '../mod-service/views'\n\nexport type TeamServiceCreator = (db: Database) => TeamService\n\nexport class TeamService {\n constructor(\n public db: Database,\n private appviewAgent: AtpAgent,\n private appviewDid: string,\n private createAuthHeaders: (\n aud: string,\n method: string,\n ) => Promise<AuthHeaders>,\n ) {}\n\n static creator(\n appviewAgent: AtpAgent,\n appviewDid: string,\n createAuthHeaders: (aud: string, method: string) => Promise<AuthHeaders>,\n ) {\n return (db: Database) =>\n new TeamService(db, appviewAgent, appviewDid, createAuthHeaders)\n }\n\n async list({\n cursor,\n limit = 25,\n roles,\n disabled,\n q,\n }: {\n q?: string\n cursor?: string\n limit?: number\n disabled?: boolean\n roles?: string[]\n }): Promise<{ members: Selectable<Member>[]; cursor?: string }> {\n let builder = this.db.db.selectFrom('member').selectAll()\n if (cursor) {\n builder = builder.where('createdAt', '>', new Date(cursor))\n }\n if (roles !== undefined) {\n const knownRoles = roles.filter(\n (r) =>\n r === 'tools.ozone.team.defs#roleAdmin' ||\n r === 'tools.ozone.team.defs#roleModerator' ||\n r === 'tools.ozone.team.defs#roleVerifier' ||\n r === 'tools.ozone.team.defs#roleTriage',\n )\n\n // Optimization: no need to query to know that no values will be returned\n if (!knownRoles.length) return { members: [] }\n\n builder = builder.where('role', 'in', knownRoles)\n }\n if (disabled !== undefined) {\n builder = builder.where('disabled', disabled ? 'is' : 'is not', true)\n }\n if (q) {\n builder = builder.where((qb) =>\n qb\n .orWhere('handle', 'ilike', `%${q}%`)\n .orWhere('displayName', 'ilike', `%${q}%`),\n )\n }\n\n const members = await builder\n .limit(limit)\n .orderBy('createdAt', 'asc')\n .orderBy('handle', 'asc')\n .execute()\n\n return { members, cursor: members.at(-1)?.createdAt.toISOString() }\n }\n\n async create({\n role,\n did,\n disabled,\n updatedAt,\n createdAt,\n lastUpdatedBy,\n }: Omit<Selectable<Member>, 'createdAt' | 'updatedAt'> & {\n createdAt?: Date\n updatedAt?: Date\n }): Promise<Selectable<Member>> {\n const now = new Date()\n const newMember = await this.db.db\n .insertInto('member')\n .values({\n role,\n did,\n disabled,\n lastUpdatedBy,\n updatedAt: updatedAt || now,\n createdAt: createdAt || now,\n })\n .returningAll()\n .executeTakeFirstOrThrow()\n\n return newMember\n }\n\n async upsert({\n role,\n did,\n lastUpdatedBy,\n }: Pick<\n Selectable<Member>,\n 'role' | 'did' | 'lastUpdatedBy'\n >): Promise<void> {\n const now = new Date()\n await this.db.db\n .insertInto('member')\n .values({\n role,\n did,\n lastUpdatedBy,\n disabled: false,\n updatedAt: now,\n createdAt: now,\n })\n .onConflict((oc) =>\n oc.column('did').doUpdateSet({ role, updatedAt: now, lastUpdatedBy }),\n )\n .execute()\n }\n\n async update(\n did: string,\n updates: Partial<\n Pick<\n Selectable<Member>,\n 'role' | 'disabled' | 'lastUpdatedBy' | 'updatedAt'\n >\n >,\n ): Promise<Selectable<Member>> {\n const { role, disabled, lastUpdatedBy, updatedAt = new Date() } = updates\n const updatedMember = await this.db.db\n .updateTable('member')\n .where('did', '=', did)\n .set({\n role,\n disabled,\n lastUpdatedBy,\n updatedAt,\n })\n .returningAll()\n .executeTakeFirstOrThrow()\n\n return updatedMember\n }\n\n async delete(did: string): Promise<void> {\n await this.db.db.deleteFrom('member').where('did', '=', did).execute()\n }\n\n async assertCanDelete(did: string): Promise<void> {\n const memberExists = await this.doesMemberExist(did)\n\n if (!memberExists) {\n throw new InvalidRequestError('member not found', 'MemberNotFound')\n }\n }\n\n async doesMemberExist(did: string): Promise<boolean> {\n const member = await this.db.db\n .selectFrom('member')\n .select('did')\n .where('did', '=', did)\n .executeTakeFirst()\n\n return !!member\n }\n\n async getMember(did: string): Promise<Selectable<Member> | undefined> {\n const member = await this.db.db\n .selectFrom('member')\n .selectAll()\n .where('did', '=', did)\n .executeTakeFirst()\n\n return member\n }\n\n getMemberRole(member?: Selectable<Member>) {\n const isAdmin = member?.role === 'tools.ozone.team.defs#roleAdmin'\n const isModerator =\n isAdmin || member?.role === 'tools.ozone.team.defs#roleModerator'\n const isTriage =\n isModerator || member?.role === 'tools.ozone.team.defs#roleTriage'\n const isVerifier =\n isAdmin || member?.role === 'tools.ozone.team.defs#roleVerifier'\n\n return {\n isModerator,\n isAdmin,\n isTriage,\n isVerifier,\n }\n }\n\n // getProfiles() only allows 25 DIDs at a time so we need to query in chunks\n async getProfiles(dids: string[]): Promise<Map<string, ProfileViewDetailed>> {\n const profiles = new Map<string, ProfileViewDetailed>()\n\n try {\n const headers = await this.createAuthHeaders(\n this.appviewDid,\n ids.AppBskyActorGetProfiles,\n )\n\n for (const actors of chunkArray(dids, 25)) {\n const { data } = await this.appviewAgent.getProfiles(\n { actors },\n headers,\n )\n\n data.profiles.forEach((profile) => {\n profiles.set(profile.did, profile)\n })\n }\n } catch (err) {\n httpLogger.error({ err, dids }, 'Failed to get profiles for team members')\n }\n\n return profiles\n }\n\n async syncMemberProfiles(): Promise<void> {\n let lastDid = ''\n // Max 25 profiles can be fetched at a time so let's pull 25 members at a time from the db and update their profile details\n do {\n const members = await this.db.db\n .selectFrom('member')\n .select(['did'])\n .limit(25)\n .if(!!lastDid, (q) => q.where('did', '>', lastDid))\n .orderBy('did', 'asc')\n .execute()\n\n const dids = members.map((member) => member.did)\n const profiles = await this.getProfiles(dids)\n\n for (const profile of profiles.values()) {\n await this.db.db\n .updateTable('member')\n .where('did', '=', profile.did)\n .set({\n handle: profile.handle,\n displayName: profile.displayName || null,\n })\n .execute()\n }\n\n lastDid = dids.at(-1) || ''\n } while (lastDid)\n }\n\n async view(members: Selectable<Member>[]): Promise<TeamMember[]> {\n const profiles = await this.getProfiles(members.map(({ did }) => did))\n return members.map((member) => {\n return {\n did: member.did,\n role: member.role,\n disabled: member.disabled,\n profile: profiles.get(member.did),\n createdAt: member.createdAt.toISOString(),\n updatedAt: member.updatedAt.toISOString(),\n lastUpdatedBy: member.lastUpdatedBy,\n }\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/team/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Selectable } from 'kysely'\nimport AtpAgent from '@atproto/api'\nimport { chunkArray } from '@atproto/common'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { Database } from '../db'\nimport { Member } from '../db/schema/member'\nimport { ids } from '../lexicon/lexicons'\nimport { ProfileViewDetailed } from '../lexicon/types/app/bsky/actor/defs'\nimport { Member as TeamMember } from '../lexicon/types/tools/ozone/team/defs'\nimport { httpLogger } from '../logger'\nimport { AuthHeaders } from '../mod-service/views'\n\nexport type TeamServiceCreator = (db: Database) => TeamService\n\nexport class TeamService {\n constructor(\n public db: Database,\n private appviewAgent: AtpAgent,\n private appviewDid: string,\n private createAuthHeaders: (\n aud: string,\n method: string,\n ) => Promise<AuthHeaders>,\n ) {}\n\n static creator(\n appviewAgent: AtpAgent,\n appviewDid: string,\n createAuthHeaders: (aud: string, method: string) => Promise<AuthHeaders>,\n ) {\n return (db: Database) =>\n new TeamService(db, appviewAgent, appviewDid, createAuthHeaders)\n }\n\n async list({\n cursor,\n limit = 25,\n roles,\n disabled,\n q,\n }: {\n q?: string\n cursor?: string\n limit?: number\n disabled?: boolean\n roles?: string[]\n }): Promise<{ members: Selectable<Member>[]; cursor?: string }> {\n let builder = this.db.db.selectFrom('member').selectAll()\n if (cursor) {\n builder = builder.where('createdAt', '>', new Date(cursor))\n }\n if (roles !== undefined) {\n const knownRoles = roles.filter(\n (r) =>\n r === 'tools.ozone.team.defs#roleAdmin' ||\n r === 'tools.ozone.team.defs#roleModerator' ||\n r === 'tools.ozone.team.defs#roleVerifier' ||\n r === 'tools.ozone.team.defs#roleTriage',\n )\n\n // Optimization: no need to query to know that no values will be returned\n if (!knownRoles.length) return { members: [] }\n\n builder = builder.where('role', 'in', knownRoles)\n }\n if (disabled !== undefined) {\n builder = builder.where('disabled', disabled ? 'is' : 'is not', true)\n }\n if (q) {\n builder = builder.where((qb) =>\n qb\n .orWhere('handle', 'ilike', `%${q}%`)\n .orWhere('displayName', 'ilike', `%${q}%`),\n )\n }\n\n const members = await builder\n .limit(limit)\n .orderBy('createdAt', 'asc')\n .orderBy('handle', 'asc')\n .execute()\n\n return { members, cursor: members.at(-1)?.createdAt.toISOString() }\n }\n\n async create({\n role,\n did,\n disabled,\n updatedAt,\n createdAt,\n lastUpdatedBy,\n }: Omit<Selectable<Member>, 'createdAt' | 'updatedAt'> & {\n createdAt?: Date\n updatedAt?: Date\n }): Promise<Selectable<Member>> {\n const now = new Date()\n const newMember = await this.db.db\n .insertInto('member')\n .values({\n role,\n did,\n disabled,\n lastUpdatedBy,\n updatedAt: updatedAt || now,\n createdAt: createdAt || now,\n })\n .returningAll()\n .executeTakeFirstOrThrow()\n\n return newMember\n }\n\n async upsert({\n role,\n did,\n lastUpdatedBy,\n }: Pick<\n Selectable<Member>,\n 'role' | 'did' | 'lastUpdatedBy'\n >): Promise<void> {\n const now = new Date()\n await this.db.db\n .insertInto('member')\n .values({\n role,\n did,\n lastUpdatedBy,\n disabled: false,\n updatedAt: now,\n createdAt: now,\n })\n .onConflict((oc) =>\n oc.column('did').doUpdateSet({ role, updatedAt: now, lastUpdatedBy }),\n )\n .execute()\n }\n\n async update(\n did: string,\n updates: Partial<\n Pick<\n Selectable<Member>,\n 'role' | 'disabled' | 'lastUpdatedBy' | 'updatedAt'\n >\n >,\n ): Promise<Selectable<Member>> {\n const { role, disabled, lastUpdatedBy, updatedAt = new Date() } = updates\n const updatedMember = await this.db.db\n .updateTable('member')\n .where('did', '=', did)\n .set({\n role,\n disabled,\n lastUpdatedBy,\n updatedAt,\n })\n .returningAll()\n .executeTakeFirstOrThrow()\n\n return updatedMember\n }\n\n async delete(did: string): Promise<void> {\n await this.db.db.deleteFrom('member').where('did', '=', did).execute()\n }\n\n async assertCanDelete(did: string): Promise<void> {\n const memberExists = await this.doesMemberExist(did)\n\n if (!memberExists) {\n throw new InvalidRequestError('member not found', 'MemberNotFound')\n }\n }\n\n async doesMemberExist(did: string): Promise<boolean> {\n const member = await this.db.db\n .selectFrom('member')\n .select('did')\n .where('did', '=', did)\n .executeTakeFirst()\n\n return !!member\n }\n\n async getMember(did: string): Promise<Selectable<Member> | undefined> {\n const member = await this.db.db\n .selectFrom('member')\n .selectAll()\n .where('did', '=', did)\n .executeTakeFirst()\n\n return member\n }\n\n getMemberRole(member?: Selectable<Member>) {\n const isAdmin = member?.role === 'tools.ozone.team.defs#roleAdmin'\n const isModerator =\n isAdmin || member?.role === 'tools.ozone.team.defs#roleModerator'\n const isTriage =\n isModerator || member?.role === 'tools.ozone.team.defs#roleTriage'\n const isVerifier =\n isAdmin || member?.role === 'tools.ozone.team.defs#roleVerifier'\n\n return {\n isModerator,\n isAdmin,\n isTriage,\n isVerifier,\n }\n }\n\n // getProfiles() only allows 25 DIDs at a time so we need to query in chunks\n async getProfiles(dids: string[]): Promise<Map<string, ProfileViewDetailed>> {\n const profiles = new Map<string, ProfileViewDetailed>()\n\n try {\n const headers = await this.createAuthHeaders(\n this.appviewDid,\n ids.AppBskyActorGetProfiles,\n )\n\n for (const actors of chunkArray(dids, 25)) {\n const { data } = await this.appviewAgent.getProfiles(\n { actors },\n headers,\n )\n\n data.profiles.forEach((profile) => {\n profiles.set(profile.did, profile)\n })\n }\n } catch (err) {\n httpLogger.error({ err, dids }, 'Failed to get profiles for team members')\n }\n\n return profiles\n }\n\n async syncMemberProfiles(): Promise<void> {\n let lastDid = ''\n // Max 25 profiles can be fetched at a time so let's pull 25 members at a time from the db and update their profile details\n do {\n const members = await this.db.db\n .selectFrom('member')\n .select(['did'])\n .limit(25)\n .if(!!lastDid, (q) => q.where('did', '>', lastDid))\n .orderBy('did', 'asc')\n .execute()\n\n const dids = members.map((member) => member.did)\n const profiles = await this.getProfiles(dids)\n\n for (const profile of profiles.values()) {\n await this.db.db\n .updateTable('member')\n .where('did', '=', profile.did)\n .set({\n handle: profile.handle,\n displayName: profile.displayName || null,\n })\n .execute()\n }\n\n lastDid = dids.at(-1) || ''\n } while (lastDid)\n }\n\n async viewByDids(dids: string[]): Promise<Map<string, TeamMember>> {\n if (!dids.length) return new Map()\n const members = await this.db.db\n .selectFrom('member')\n .selectAll()\n .where('did', 'in', dids)\n .execute()\n const memberViews = await this.view(members)\n return new Map(memberViews.map((m) => [m.did, m]))\n }\n\n async view(members: Selectable<Member>[]): Promise<TeamMember[]> {\n const profiles = await this.getProfiles(members.map(({ did }) => did))\n return members.map((member) => {\n return {\n did: member.did,\n role: member.role,\n disabled: member.disabled,\n profile: profiles.get(member.did),\n createdAt: member.createdAt.toISOString(),\n updatedAt: member.updatedAt.toISOString(),\n lastUpdatedBy: member.lastUpdatedBy,\n }\n })\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/ozone",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.174",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Backend service for moderating the Bluesky network.",
|
|
6
6
|
"keywords": [
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"uint8arrays": "3.0.0",
|
|
36
36
|
"undici": "^6.14.1",
|
|
37
37
|
"ws": "^8.12.0",
|
|
38
|
-
"@atproto/api": "^0.19.
|
|
38
|
+
"@atproto/api": "^0.19.16",
|
|
39
39
|
"@atproto/common": "^0.5.16",
|
|
40
40
|
"@atproto/crypto": "^0.4.5",
|
|
41
41
|
"@atproto/identity": "^0.4.12",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"ts-node": "^10.8.2",
|
|
57
57
|
"typescript": "^5.6.3",
|
|
58
58
|
"@atproto/lex-cli": "^0.9.9",
|
|
59
|
-
"@atproto/pds": "^0.4.
|
|
59
|
+
"@atproto/pds": "^0.4.221"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"codegen": "lex gen-server --yes ./src/lexicon ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*",
|