Skip to content

Commit

Permalink
✨ Add reporter_stats materialized view and endpoint to fetch reporter…
Browse files Browse the repository at this point in the history
… stats
  • Loading branch information
foysalit committed Feb 7, 2025
1 parent f90eedc commit 881da85
Show file tree
Hide file tree
Showing 24 changed files with 914 additions and 1 deletion.
42 changes: 42 additions & 0 deletions lexicons/tools/ozone/moderation/defs.json
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,48 @@
"format": "datetime"
}
}
},
"reporterStats": {
"type": "object",
"required": ["did", "accountReportCount", "recordReportCount", "reportedAccountCount", "reportedRecordCount", "takendownAccountCount", "takendownRecordCount", "labeledAccountCount", "labeledRecordCount"],
"properties": {
"did": {
"type": "string",
"format": "did"
},
"accountReportCount": {
"type": "integer",
"description": "The total number of reports made by the user on accounts."
},
"recordReportCount": {
"type": "integer",
"description": "The total number of reports made by the user on records."
},
"reportedAccountCount": {
"type": "integer",
"description": "The total number of accounts reported by the user."
},
"reportedRecordCount": {
"type": "integer",
"description": "The total number of records reported by the user."
},
"takendownAccountCount": {
"type": "integer",
"description": "The total number of accounts taken down as a result of the user's reports."
},
"takendownRecordCount": {
"type": "integer",
"description": "The total number of records taken down as a result of the user's reports."
},
"labeledAccountCount": {
"type": "integer",
"description": "The total number of accounts labeled as a result of the user's reports."
},
"labeledRecordCount": {
"type": "integer",
"description": "The total number of records labeled as a result of the user's reports."
}
}
}
}
}
41 changes: 41 additions & 0 deletions lexicons/tools/ozone/moderation/getReporterStats.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"lexicon": 1,
"id": "tools.ozone.moderation.getReporterStats",
"defs": {
"main": {
"type": "query",
"description": "Get reporter stats for a list of users.",
"parameters": {
"type": "params",
"required": ["dids"],
"properties": {
"dids": {
"type": "array",
"maxLength": 100,
"items": {
"type": "string",
"format": "did"
}
}
}
},
"output": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["stats"],
"properties": {
"stats": {
"type": "array",
"items": {
"type": "ref",
"ref": "tools.ozone.moderation.defs#reporterStats"
}
}
}
}
}
}
}
}

14 changes: 14 additions & 0 deletions packages/api/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ import * as ToolsOzoneModerationGetEvent from './types/tools/ozone/moderation/ge
import * as ToolsOzoneModerationGetRecord from './types/tools/ozone/moderation/getRecord'
import * as ToolsOzoneModerationGetRecords from './types/tools/ozone/moderation/getRecords'
import * as ToolsOzoneModerationGetRepo from './types/tools/ozone/moderation/getRepo'
import * as ToolsOzoneModerationGetReporterStats from './types/tools/ozone/moderation/getReporterStats'
import * as ToolsOzoneModerationGetRepos from './types/tools/ozone/moderation/getRepos'
import * as ToolsOzoneModerationQueryEvents from './types/tools/ozone/moderation/queryEvents'
import * as ToolsOzoneModerationQueryStatuses from './types/tools/ozone/moderation/queryStatuses'
Expand Down Expand Up @@ -436,6 +437,7 @@ export * as ToolsOzoneModerationGetEvent from './types/tools/ozone/moderation/ge
export * as ToolsOzoneModerationGetRecord from './types/tools/ozone/moderation/getRecord'
export * as ToolsOzoneModerationGetRecords from './types/tools/ozone/moderation/getRecords'
export * as ToolsOzoneModerationGetRepo from './types/tools/ozone/moderation/getRepo'
export * as ToolsOzoneModerationGetReporterStats from './types/tools/ozone/moderation/getReporterStats'
export * as ToolsOzoneModerationGetRepos from './types/tools/ozone/moderation/getRepos'
export * as ToolsOzoneModerationQueryEvents from './types/tools/ozone/moderation/queryEvents'
export * as ToolsOzoneModerationQueryStatuses from './types/tools/ozone/moderation/queryStatuses'
Expand Down Expand Up @@ -3716,6 +3718,18 @@ export class ToolsOzoneModerationNS {
})
}

getReporterStats(
params?: ToolsOzoneModerationGetReporterStats.QueryParams,
opts?: ToolsOzoneModerationGetReporterStats.CallOptions,
): Promise<ToolsOzoneModerationGetReporterStats.Response> {
return this._client.call(
'tools.ozone.moderation.getReporterStats',
params,
undefined,
opts,
)
}

getRepos(
params?: ToolsOzoneModerationGetRepos.QueryParams,
opts?: ToolsOzoneModerationGetRepos.CallOptions,
Expand Down
100 changes: 100 additions & 0 deletions packages/api/src/client/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12213,6 +12213,64 @@ export const schemaDict = {
},
},
},
reporterStats: {
type: 'object',
required: [
'did',
'accountReportCount',
'recordReportCount',
'reportedAccountCount',
'reportedRecordCount',
'takendownAccountCount',
'takendownRecordCount',
'labeledAccountCount',
'labeledRecordCount',
],
properties: {
did: {
type: 'string',
format: 'did',
},
accountReportCount: {
type: 'integer',
description:
'The total number of reports made by the user on accounts.',
},
recordReportCount: {
type: 'integer',
description:
'The total number of reports made by the user on records.',
},
reportedAccountCount: {
type: 'integer',
description: 'The total number of accounts reported by the user.',
},
reportedRecordCount: {
type: 'integer',
description: 'The total number of records reported by the user.',
},
takendownAccountCount: {
type: 'integer',
description:
"The total number of accounts taken down as a result of the user's reports.",
},
takendownRecordCount: {
type: 'integer',
description:
"The total number of records taken down as a result of the user's reports.",
},
labeledAccountCount: {
type: 'integer',
description:
"The total number of accounts labeled as a result of the user's reports.",
},
labeledRecordCount: {
type: 'integer',
description:
"The total number of records labeled as a result of the user's reports.",
},
},
},
},
},
ToolsOzoneModerationEmitEvent: {
Expand Down Expand Up @@ -12424,6 +12482,46 @@ export const schemaDict = {
},
},
},
ToolsOzoneModerationGetReporterStats: {
lexicon: 1,
id: 'tools.ozone.moderation.getReporterStats',
defs: {
main: {
type: 'query',
description: 'Get reporter stats for a list of users.',
parameters: {
type: 'params',
required: ['dids'],
properties: {
dids: {
type: 'array',
maxLength: 100,
items: {
type: 'string',
format: 'did',
},
},
},
},
output: {
encoding: 'application/json',
schema: {
type: 'object',
required: ['stats'],
properties: {
stats: {
type: 'array',
items: {
type: 'ref',
ref: 'lex:tools.ozone.moderation.defs#reporterStats',
},
},
},
},
},
},
},
},
ToolsOzoneModerationGetRepos: {
lexicon: 1,
id: 'tools.ozone.moderation.getRepos',
Expand Down Expand Up @@ -14098,6 +14196,8 @@ export const ids = {
ToolsOzoneModerationGetRecord: 'tools.ozone.moderation.getRecord',
ToolsOzoneModerationGetRecords: 'tools.ozone.moderation.getRecords',
ToolsOzoneModerationGetRepo: 'tools.ozone.moderation.getRepo',
ToolsOzoneModerationGetReporterStats:
'tools.ozone.moderation.getReporterStats',
ToolsOzoneModerationGetRepos: 'tools.ozone.moderation.getRepos',
ToolsOzoneModerationQueryEvents: 'tools.ozone.moderation.queryEvents',
ToolsOzoneModerationQueryStatuses: 'tools.ozone.moderation.queryStatuses',
Expand Down
33 changes: 33 additions & 0 deletions packages/api/src/client/types/tools/ozone/moderation/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -931,3 +931,36 @@ export function isRecordHosting(v: unknown): v is RecordHosting {
export function validateRecordHosting(v: unknown): ValidationResult {
return lexicons.validate('tools.ozone.moderation.defs#recordHosting', v)
}

export interface ReporterStats {
did: string
/** The total number of reports made by the user on accounts. */
accountReportCount: number
/** The total number of reports made by the user on records. */
recordReportCount: number
/** The total number of accounts reported by the user. */
reportedAccountCount: number
/** The total number of records reported by the user. */
reportedRecordCount: number
/** The total number of accounts taken down as a result of the user's reports. */
takendownAccountCount: number
/** The total number of records taken down as a result of the user's reports. */
takendownRecordCount: number
/** The total number of accounts labeled as a result of the user's reports. */
labeledAccountCount: number
/** The total number of records labeled as a result of the user's reports. */
labeledRecordCount: number
[k: string]: unknown
}

export function isReporterStats(v: unknown): v is ReporterStats {
return (
isObj(v) &&
hasProp(v, '$type') &&
v.$type === 'tools.ozone.moderation.defs#reporterStats'
)
}

export function validateReporterStats(v: unknown): ValidationResult {
return lexicons.validate('tools.ozone.moderation.defs#reporterStats', v)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* GENERATED CODE - DO NOT MODIFY
*/
import { HeadersMap, XRPCError } from '@atproto/xrpc'
import { ValidationResult, BlobRef } from '@atproto/lexicon'
import { isObj, hasProp } from '../../../../util'
import { lexicons } from '../../../../lexicons'
import { CID } from 'multiformats/cid'
import * as ToolsOzoneModerationDefs from './defs'

export interface QueryParams {
dids: string[]
}

export type InputSchema = undefined

export interface OutputSchema {
stats: ToolsOzoneModerationDefs.ReporterStats[]
[k: string]: unknown
}

export interface CallOptions {
signal?: AbortSignal
headers?: HeadersMap
}

export interface Response {
success: boolean
headers: HeadersMap
data: OutputSchema
}

export function toKnownErr(e: any) {
return e
}
13 changes: 13 additions & 0 deletions packages/dev-env/src/moderator-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ export class ModeratorClient {
return result.data
}

async getReporterStats(dids: string[]) {
const result = await this.agent.tools.ozone.moderation.getReporterStats(
{ dids },
{
headers: await this.ozone.modHeaders(
'tools.ozone.moderation.getReporterStats',
'admin',
),
},
)
return result.data
}

async queryEvents(input: QueryEventsParams, role?: ModLevel) {
const result = await this.agent.tools.ozone.moderation.queryEvents(input, {
headers: await this.ozone.modHeaders(
Expand Down
2 changes: 2 additions & 0 deletions packages/ozone/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import getEvent from './moderation/getEvent'
import adminGetRecord from './moderation/getRecord'
import adminGetRecords from './moderation/getRecords'
import getRepo from './moderation/getRepo'
import getReporterStats from './moderation/getReporterStats'
import getRepos from './moderation/getRepos'
import queryEvents from './moderation/queryEvents'
import queryStatuses from './moderation/queryStatuses'
Expand Down Expand Up @@ -72,5 +73,6 @@ export default function (server: Server, ctx: AppContext) {
upsertOption(server, ctx)
listOptions(server, ctx)
removeOptions(server, ctx)
getReporterStats(server, ctx)
return server
}
18 changes: 18 additions & 0 deletions packages/ozone/src/api/moderation/getReporterStats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { AppContext } from '../../context'
import { Server } from '../../lexicon'

export default function (server: Server, ctx: AppContext) {
server.tools.ozone.moderation.getReporterStats({
auth: ctx.authVerifier.modOrAdminToken,
handler: async ({ params }) => {
const db = ctx.db

const stats = await ctx.modService(db).getReporterStats(params.dids)

return {
encoding: 'application/json',
body: { stats },
}
},
})
}
1 change: 1 addition & 0 deletions packages/ozone/src/daemon/materialized-view-refresher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class MaterializedViewRefresher extends PeriodicBackgroundTask {
'record_events_stats',
'account_record_events_stats',
'account_record_status_stats',
'reporter_stats',
]) {
if (signal.aborted) break

Expand Down
Loading

0 comments on commit 881da85

Please sign in to comment.