Skip to content

Commit

Permalink
✨ Add collection and subjectType filters to queryEvents and queryStat…
Browse files Browse the repository at this point in the history
…uses (bluesky-social#2914)

* ✨ Add collection and subjectType filters to queryEvents and queryStatuses

* 📝 Add changeset

* ♻️ Refactor or query builder
  • Loading branch information
foysalit authored Oct 30, 2024
1 parent 91bd63b commit 19e36af
Show file tree
Hide file tree
Showing 17 changed files with 401 additions and 11 deletions.
6 changes: 6 additions & 0 deletions .changeset/flat-bees-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@atproto/ozone": patch
"@atproto/api": patch
---

Add collections and subjectType filters to ozone's queryEvents and queryStatuses endpoints
49 changes: 40 additions & 9 deletions lexicons/tools/ozone/moderation/queryEvents.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
"properties": {
"types": {
"type": "array",
"items": { "type": "string" },
"items": {
"type": "string"
},
"description": "The types of events (fully qualified string in the format of tools.ozone.moderation.defs#modEvent<name>) to filter by. If not specified, all events are returned."
},
"createdBy": {
Expand All @@ -33,11 +35,28 @@
"format": "datetime",
"description": "Retrieve events created before a given timestamp"
},
"subject": { "type": "string", "format": "uri" },
"subject": {
"type": "string",
"format": "uri"
},
"collections": {
"type": "array",
"maxLength": 20,
"description": "If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored.",
"items": {
"type": "string",
"format": "nsid"
}
},
"subjectType": {
"type": "string",
"description": "If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored.",
"knownValues": ["account", "record"]
},
"includeAllUserRecords": {
"type": "boolean",
"default": false,
"description": "If true, events on all record types (posts, lists, profile etc.) owned by the did are returned"
"description": "If true, events on all record types (posts, lists, profile etc.) or records from given 'collections' param, owned by the did are returned."
},
"limit": {
"type": "integer",
Expand All @@ -55,22 +74,30 @@
},
"addedLabels": {
"type": "array",
"items": { "type": "string" },
"items": {
"type": "string"
},
"description": "If specified, only events where all of these labels were added are returned"
},
"removedLabels": {
"type": "array",
"items": { "type": "string" },
"items": {
"type": "string"
},
"description": "If specified, only events where all of these labels were removed are returned"
},
"addedTags": {
"type": "array",
"items": { "type": "string" },
"items": {
"type": "string"
},
"description": "If specified, only events where all of these tags were added are returned"
},
"removedTags": {
"type": "array",
"items": { "type": "string" },
"items": {
"type": "string"
},
"description": "If specified, only events where all of these tags were removed are returned"
},
"reportTypes": {
Expand All @@ -79,7 +106,9 @@
"type": "string"
}
},
"cursor": { "type": "string" }
"cursor": {
"type": "string"
}
}
},
"output": {
Expand All @@ -88,7 +117,9 @@
"type": "object",
"required": ["events"],
"properties": {
"cursor": { "type": "string" },
"cursor": {
"type": "string"
},
"events": {
"type": "array",
"items": {
Expand Down
16 changes: 15 additions & 1 deletion lexicons/tools/ozone/moderation/queryStatuses.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"properties": {
"includeAllUserRecords": {
"type": "boolean",
"description": "All subjects belonging to the account specified in the 'subject' param will be returned."
"description": "All subjects, or subjects from given 'collections' param, belonging to the account specified in the 'subject' param will be returned."
},
"subject": {
"type": "string",
Expand Down Expand Up @@ -103,6 +103,20 @@
},
"cursor": {
"type": "string"
},
"collections": {
"type": "array",
"maxLength": 20,
"description": "If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored.",
"items": {
"type": "string",
"format": "nsid"
}
},
"subjectType": {
"type": "string",
"description": "If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored.",
"knownValues": ["account", "record"]
}
}
},
Expand Down
30 changes: 30 additions & 0 deletions packages/api/src/client/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11809,6 +11809,21 @@ export const schemaDict = {
type: 'string',
format: 'uri',
},
collections: {
type: 'array',
description:
"If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored.",
items: {
type: 'string',
format: 'nsid',
},
},
subjectType: {
type: 'string',
description:
"If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored.",
knownValues: ['account', 'record'],
},
includeAllUserRecords: {
type: 'boolean',
default: false,
Expand Down Expand Up @@ -12005,6 +12020,21 @@ export const schemaDict = {
cursor: {
type: 'string',
},
collections: {
type: 'array',
description:
"If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored.",
items: {
type: 'string',
format: 'nsid',
},
},
subjectType: {
type: 'string',
description:
"If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored.",
knownValues: ['account', 'record'],
},
},
},
output: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export interface QueryParams {
/** Retrieve events created before a given timestamp */
createdBefore?: string
subject?: string
/** If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored. */
collections?: string[]
/** If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. */
subjectType?: 'account' | 'record' | (string & {})
/** If true, events on all record types (posts, lists, profile etc.) owned by the did are returned */
includeAllUserRecords?: boolean
limit?: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export interface QueryParams {
tags?: string[]
excludeTags?: string[]
cursor?: string
/** If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored. */
collections?: string[]
/** If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. */
subjectType?: 'account' | 'record' | (string & {})
}

export type InputSchema = undefined
Expand Down
4 changes: 4 additions & 0 deletions packages/ozone/src/api/moderation/queryEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export default function (server: Server, ctx: AppContext) {
addedTags = [],
removedTags = [],
reportTypes,
collections = [],
subjectType,
} = params
const db = ctx.db
const modService = ctx.modService(db)
Expand All @@ -43,6 +45,8 @@ export default function (server: Server, ctx: AppContext) {
removedLabels,
removedTags,
reportTypes,
collections,
subjectType,
})
return {
encoding: 'application/json',
Expand Down
4 changes: 4 additions & 0 deletions packages/ozone/src/api/moderation/queryStatuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export default function (server: Server, ctx: AppContext) {
cursor,
tags = [],
excludeTags = [],
collections = [],
subjectType,
} = params
const db = ctx.db
const modService = ctx.modService(db)
Expand All @@ -49,6 +51,8 @@ export default function (server: Server, ctx: AppContext) {
cursor,
tags,
excludeTags,
collections,
subjectType,
})
const subjectStatuses = results.statuses.map((status) =>
modService.views.formatSubjectStatus(status),
Expand Down
30 changes: 30 additions & 0 deletions packages/ozone/src/lexicon/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11809,6 +11809,21 @@ export const schemaDict = {
type: 'string',
format: 'uri',
},
collections: {
type: 'array',
description:
"If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored.",
items: {
type: 'string',
format: 'nsid',
},
},
subjectType: {
type: 'string',
description:
"If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored.",
knownValues: ['account', 'record'],
},
includeAllUserRecords: {
type: 'boolean',
default: false,
Expand Down Expand Up @@ -12005,6 +12020,21 @@ export const schemaDict = {
cursor: {
type: 'string',
},
collections: {
type: 'array',
description:
"If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored.",
items: {
type: 'string',
format: 'nsid',
},
},
subjectType: {
type: 'string',
description:
"If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored.",
knownValues: ['account', 'record'],
},
},
},
output: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export interface QueryParams {
/** Retrieve events created before a given timestamp */
createdBefore?: string
subject?: string
/** If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored. */
collections?: string[]
/** If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. */
subjectType?: 'account' | 'record' | (string & {})
/** If true, events on all record types (posts, lists, profile etc.) owned by the did are returned */
includeAllUserRecords: boolean
limit: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export interface QueryParams {
tags?: string[]
excludeTags?: string[]
cursor?: string
/** If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored. */
collections?: string[]
/** If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. */
subjectType?: 'account' | 'record' | (string & {})
}

export type InputSchema = undefined
Expand Down
38 changes: 37 additions & 1 deletion packages/ozone/src/mod-service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ export class ModerationService {
addedTags: string[]
removedTags: string[]
reportTypes?: string[]
collections: string[]
subjectType?: string
}): Promise<{ cursor?: string; events: ModerationEventRow[] }> {
const {
subject,
Expand All @@ -164,6 +166,8 @@ export class ModerationService {
addedTags,
removedTags,
reportTypes,
collections,
subjectType,
} = opts
const { ref } = this.db.db.dynamic
let builder = this.db.db.selectFrom('moderation_event').selectAll()
Expand All @@ -181,6 +185,20 @@ export class ModerationService {
.if(!subjectUri, (q) => q.where('subjectUri', 'is', null))
.if(!!subjectUri, (q) => q.where('subjectUri', '=', subjectUri))
}
} else if (subjectType === 'account') {
builder = builder.where('subjectUri', 'is', null)
} else if (subjectType === 'record') {
builder = builder.where('subjectUri', 'is not', null)
}

// If subjectType is set to 'account' let that take priority and ignore collections filter
if (collections.length && subjectType !== 'account') {
builder = builder.where('subjectUri', 'is not', null).where((qb) => {
collections.forEach((collection) => {
qb = qb.orWhere('subjectUri', 'like', `%/${collection}/%`)
})
return qb
})
}

if (types.length) {
Expand Down Expand Up @@ -748,6 +766,8 @@ export class ModerationService {
subject,
tags,
excludeTags,
collections,
subjectType,
}: {
includeAllUserRecords?: boolean
cursor?: string
Expand All @@ -768,6 +788,8 @@ export class ModerationService {
sortField: 'lastReviewedAt' | 'lastReportedAt'
tags: string[]
excludeTags: string[]
collections: string[]
subjectType?: string
}) {
let builder = this.db.db.selectFrom('moderation_subject_status').selectAll()
const { ref } = this.db.db.dynamic
Expand All @@ -787,11 +809,25 @@ export class ModerationService {
: qb.where('recordPath', '=', ''),
)
}
} else if (subjectType === 'account') {
builder = builder.where('recordPath', '=', '')
} else if (subjectType === 'record') {
builder = builder.where('recordPath', '!=', '')
}

// If subjectType is set to 'account' let that take priority and ignore collections filter
if (collections.length && subjectType !== 'account') {
builder = builder.where('recordPath', '!=', '').where((qb) => {
collections.forEach((collection) => {
qb = qb.orWhere('recordPath', 'like', `${collection}/%`)
})
return qb
})
}

if (ignoreSubjects?.length) {
builder = builder
.where('moderation_subject_status.did', 'not in', ignoreSubjects)
.where('did', 'not in', ignoreSubjects)
.where('recordPath', 'not in', ignoreSubjects)
}

Expand Down
Loading

0 comments on commit 19e36af

Please sign in to comment.