@atproto/ozone 0.2.3 → 0.2.4
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 +17 -0
- package/dist/api/health.d.ts.map +1 -1
- package/dist/api/moderation/util.d.ts.map +1 -1
- package/dist/api/util.d.ts +2 -2
- package/dist/api/util.d.ts.map +1 -1
- package/dist/api/well-known.d.ts.map +1 -1
- package/dist/assignment/index.d.ts.map +1 -1
- package/dist/assignment/index.js.map +1 -1
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/background.d.ts.map +1 -1
- package/dist/background.js.map +1 -1
- package/dist/communication-service/template.d.ts.map +1 -1
- package/dist/communication-service/template.js.map +1 -1
- package/dist/communication-service/util.d.ts.map +1 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/secrets.d.ts.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/daemon/blob-diverter.d.ts.map +1 -1
- package/dist/daemon/blob-diverter.js.map +1 -1
- package/dist/daemon/context.d.ts.map +1 -1
- package/dist/daemon/context.js.map +1 -1
- package/dist/daemon/event-pusher.d.ts +1 -1
- package/dist/daemon/event-pusher.d.ts.map +1 -1
- package/dist/daemon/event-reverser.d.ts.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/materialized-view-refresher.d.ts.map +1 -1
- package/dist/daemon/queue-router.d.ts.map +1 -1
- package/dist/daemon/scheduled-action-processor.d.ts.map +1 -1
- package/dist/daemon/stats-computer.d.ts.map +1 -1
- package/dist/daemon/strike-expiry-processor.d.ts.map +1 -1
- package/dist/daemon/team-profile-synchronizer.d.ts.map +1 -1
- package/dist/daemon/verification-listener.d.ts.map +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/migrations/provider.d.ts.map +1 -1
- package/dist/db/migrations/provider.js.map +1 -1
- package/dist/db/pagination.d.ts +1 -1
- package/dist/db/pagination.d.ts.map +1 -1
- package/dist/db/pagination.js.map +1 -1
- package/dist/db/schema/index.d.ts.map +1 -1
- package/dist/db/types.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/jetstream/service.d.ts.map +1 -1
- package/dist/lexicon/index.d.ts +2 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +4 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +17160 -17038
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +68 -1
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/defs.d.ts +11 -0
- package/dist/lexicon/types/chat/bsky/convo/defs.d.ts.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/defs.js +7 -0
- package/dist/lexicon/types/chat/bsky/convo/defs.js.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/getUnreadCounts.d.ts +25 -0
- package/dist/lexicon/types/chat/bsky/convo/getUnreadCounts.d.ts.map +1 -0
- package/dist/lexicon/types/chat/bsky/convo/getUnreadCounts.js +5 -0
- package/dist/lexicon/types/chat/bsky/convo/getUnreadCounts.js.map +1 -0
- package/dist/lexicon/types/chat/bsky/convo/sendMessage.d.ts +1 -1
- package/dist/lexicon/types/chat/bsky/convo/sendMessage.d.ts.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/sendMessage.js.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/sendMessageBatch.d.ts +1 -1
- package/dist/lexicon/types/chat/bsky/convo/sendMessageBatch.d.ts.map +1 -1
- package/dist/lexicon/types/chat/bsky/convo/sendMessageBatch.js.map +1 -1
- package/dist/lexicon/util.d.ts.map +1 -1
- package/dist/mod-service/index.d.ts +38 -38
- package/dist/mod-service/index.d.ts.map +1 -1
- package/dist/mod-service/profile.d.ts.map +1 -1
- package/dist/mod-service/status.d.ts +80 -80
- package/dist/mod-service/status.d.ts.map +1 -1
- package/dist/mod-service/strike.d.ts.map +1 -1
- package/dist/mod-service/strike.js.map +1 -1
- package/dist/mod-service/subject.d.ts +4 -4
- package/dist/mod-service/subject.d.ts.map +1 -1
- package/dist/mod-service/util.d.ts +1 -1
- package/dist/mod-service/util.d.ts.map +1 -1
- package/dist/mod-service/views.d.ts.map +1 -1
- package/dist/mod-service/views.js.map +1 -1
- package/dist/queue/service.d.ts.map +1 -1
- package/dist/queue/service.js.map +1 -1
- package/dist/report/activity.d.ts +5 -5
- package/dist/report/activity.d.ts.map +1 -1
- package/dist/report/handle-report-update.d.ts.map +1 -1
- package/dist/report/handle-report-update.js.map +1 -1
- package/dist/report/stats.d.ts.map +1 -1
- package/dist/report/stats.js.map +1 -1
- package/dist/report/views.d.ts +2 -2
- package/dist/report/views.d.ts.map +1 -1
- package/dist/safelink/service.d.ts +3 -3
- package/dist/safelink/service.d.ts.map +1 -1
- package/dist/safelink/service.js.map +1 -1
- package/dist/scheduled-action/service.d.ts.map +1 -1
- package/dist/scheduled-action/service.js.map +1 -1
- package/dist/sequencer/outbox.d.ts.map +1 -1
- package/dist/sequencer/outbox.js.map +1 -1
- package/dist/sequencer/sequencer.d.ts.map +1 -1
- package/dist/sequencer/sequencer.js.map +1 -1
- package/dist/set/service.d.ts +1 -1
- package/dist/set/service.d.ts.map +1 -1
- package/dist/set/service.js.map +1 -1
- package/dist/setting/service.d.ts.map +1 -1
- package/dist/setting/service.js.map +1 -1
- package/dist/tag-service/content-tagger.d.ts.map +1 -1
- package/dist/tag-service/content-tagger.js.map +1 -1
- package/dist/tag-service/embed-tagger.d.ts.map +1 -1
- package/dist/tag-service/index.d.ts.map +1 -1
- package/dist/tag-service/index.js.map +1 -1
- package/dist/tag-service/language-tagger.d.ts.map +1 -1
- package/dist/tag-service/util.d.ts.map +1 -1
- package/dist/team/index.d.ts.map +1 -1
- package/dist/team/index.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/verification/issuer.d.ts +1 -1
- package/dist/verification/issuer.d.ts.map +1 -1
- package/dist/verification/service.d.ts +5 -5
- package/dist/verification/service.d.ts.map +1 -1
- package/dist/verification/service.js.map +1 -1
- package/dist/verification/util.d.ts.map +1 -1
- package/package.json +13 -14
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/mod-service/views.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'kysely'\nimport {\n AppBskyActorDefs,\n AtpAgent,\n ComAtprotoRepoGetRecord,\n} from '@atproto/api'\nimport { chunkArray, dedupeStrs } from '@atproto/common'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { BlobRef } from '@atproto/lexicon'\nimport { AtUri, INVALID_HANDLE, normalizeDatetimeAlways } from '@atproto/syntax'\nimport { Database } from '../db/index.js'\nimport { LabelRow } from '../db/schema/label.js'\nimport { ids } from '../lexicon/lexicons.js'\nimport { FeedViewPost } from '../lexicon/types/app/bsky/feed/defs.js'\nimport { AccountView } from '../lexicon/types/com/atproto/admin/defs.js'\nimport {\n Label,\n validateSelfLabels,\n} from '../lexicon/types/com/atproto/label/defs.js'\nimport { OutputSchema as ReportOutput } from '../lexicon/types/com/atproto/moderation/createReport.js'\nimport { REASONOTHER } from '../lexicon/types/com/atproto/moderation/defs.js'\nimport {\n BlobView,\n ModEventView,\n ModEventViewDetail,\n RecordView,\n RecordViewDetail,\n RepoView,\n SubjectStatusView,\n isAccountEvent,\n isAgeAssuranceEvent,\n isAgeAssuranceOverrideEvent,\n isIdentityEvent,\n isModEventAcknowledge,\n isModEventComment,\n isModEventEmail,\n isModEventEscalate,\n isModEventLabel,\n isModEventMute,\n isModEventMuteReporter,\n isModEventPriorityScore,\n isModEventReport,\n isModEventReverseTakedown,\n isModEventTag,\n isModEventTakedown,\n isRecordEvent,\n isScheduleTakedownEvent,\n} from '../lexicon/types/tools/ozone/moderation/defs.js'\nimport { Un$Typed, asPredicate } from '../lexicon/util.js'\nimport { dbLogger, httpLogger } from '../logger.js'\nimport { ParsedLabelers } from '../util.js'\nimport { moderationSubjectStatusQueryBuilder } from './status.js'\nimport {\n ModSubject,\n subjectFromEventRow,\n subjectFromStatusRow,\n} from './subject.js'\nimport {\n ModerationEventRowWithHandle,\n ModerationSubjectStatusRowWithHandle,\n} from './types.js'\nimport { formatLabel, getPdsAgentForRepo, signLabel } from './util.js'\n\nconst isValidSelfLabels = asPredicate(validateSelfLabels)\n\nconst ifString = (val: unknown): string | undefined =>\n typeof val === 'string' ? val : undefined\nconst ifBoolean = (val: unknown): boolean | undefined =>\n typeof val === 'boolean' ? val : undefined\nconst ifNumber = (val: unknown): number | undefined =>\n typeof val === 'number' ? val : undefined\n\nexport type AuthHeaders = {\n headers: {\n authorization: string\n 'atproto-accept-labelers'?: string\n }\n}\n\nexport class ModerationViews {\n constructor(\n private db: Database,\n private signingKey: Keypair,\n private signingKeyId: number,\n private appviewAgent: AtpAgent,\n private appviewAuth: (method: string) => Promise<AuthHeaders>,\n public idResolver: IdResolver,\n public devMode?: boolean,\n ) {}\n\n async getAccoutInfosByDid(dids: string[]): Promise<Map<string, AccountView>> {\n if (dids.length === 0) return new Map()\n const auth = await this.appviewAuth(ids.ComAtprotoAdminGetAccountInfos)\n if (!auth) return new Map()\n try {\n const res = await this.appviewAgent.com.atproto.admin.getAccountInfos(\n {\n dids: dedupeStrs(dids),\n },\n auth,\n )\n return res.data.infos.reduce((acc, cur) => {\n return acc.set(cur.did, cur)\n }, new Map<string, AccountView>())\n } catch (err) {\n httpLogger.error(\n { err, dids },\n 'failed to resolve account infos from appview',\n )\n return new Map()\n }\n }\n\n async repos(dids: string[]): Promise<Map<string, RepoView>> {\n if (dids.length === 0) return new Map()\n const [infos, subjectStatuses] = await Promise.all([\n this.getAccoutInfosByDid(dids),\n this.getSubjectStatus(dids),\n ])\n\n return dids.reduce((acc, did) => {\n const info = infos.get(did)\n if (!info) return acc\n const status = subjectStatuses.get(did)\n return acc.set(did, {\n // No email or invite info on appview\n did,\n handle: info.handle,\n relatedRecords: info.relatedRecords ?? [],\n indexedAt: info.indexedAt,\n moderation: {\n subjectStatus: status ? this.formatSubjectStatus(status) : undefined,\n },\n })\n }, new Map<string, RepoView>())\n }\n\n formatEvent(row: ModerationEventRowWithHandle): Un$Typed<ModEventView> {\n const eventView: Un$Typed<ModEventView> = {\n id: row.id,\n event: {\n $type: row.action,\n comment: row.comment ?? undefined,\n },\n subject: subjectFromEventRow(row).lex(),\n subjectBlobCids: row.subjectBlobCids ?? [],\n createdBy: row.createdBy,\n createdAt: row.createdAt,\n subjectHandle: row.subjectHandle ?? undefined,\n creatorHandle: row.creatorHandle ?? undefined,\n modTool: row.modTool\n ? {\n name: row.modTool.name,\n meta: sanitizeUnsafeIntegers(row.modTool.meta) as\n | Record<string, unknown>\n | undefined,\n }\n : undefined,\n }\n\n const { event } = eventView\n const meta = row.meta || {}\n\n if (\n isModEventMuteReporter(event) ||\n isModEventTakedown(event) ||\n isModEventLabel(event) ||\n isModEventMute(event)\n ) {\n event.durationInHours = row.durationInHours ?? undefined\n }\n\n if (\n (isModEventTakedown(event) || isModEventAcknowledge(event)) &&\n meta.acknowledgeAccountSubjects\n ) {\n event.acknowledgeAccountSubjects = ifBoolean(\n meta.acknowledgeAccountSubjects,\n )!\n }\n\n if (isModEventPriorityScore(event)) {\n event.score = ifNumber(meta?.priorityScore) ?? 0\n }\n\n if (\n isModEventTakedown(event) ||\n isModEventEmail(event) ||\n isModEventReverseTakedown(event)\n ) {\n if (typeof meta.policies === 'string' && meta.policies.length > 0) {\n event.policies = meta.policies.split(',')\n }\n\n event.strikeCount = ifNumber(row.strikeCount)\n event.severityLevel = ifString(row.severityLevel)\n\n if (isModEventTakedown(event) || isModEventEmail(event)) {\n event.strikeExpiresAt = ifString(row.strikeExpiresAt)\n }\n }\n\n if (isModEventTakedown(event)) {\n if (\n typeof meta.targetServices === 'string' &&\n meta.targetServices.length > 0\n ) {\n event.targetServices = meta.targetServices.split(',')\n }\n }\n\n if (isModEventLabel(event)) {\n event.createLabelVals = row.createLabelVals?.length\n ? row.createLabelVals.split(' ')\n : []\n event.negateLabelVals = row.negateLabelVals?.length\n ? row.negateLabelVals.split(' ')\n : []\n } else if (\n isModEventAcknowledge(event) ||\n isModEventTakedown(event) ||\n isModEventEscalate(event)\n ) {\n // This is for legacy data only, for new events, these types of events\n // won't have labels attached:\n\n if (row.createLabelVals?.length) {\n // @ts-expect-error legacy\n event.createLabelVals = row.createLabelVals.split(' ')\n }\n\n if (row.negateLabelVals?.length) {\n // @ts-expect-error legacy\n event.negateLabelVals = row.negateLabelVals.split(' ')\n }\n }\n\n if (isModEventReport(event)) {\n event.isReporterMuted = !!meta.isReporterMuted\n event.reportType = ifString(meta.reportType)!\n }\n\n if (isModEventEmail(event)) {\n event.content = ifString(meta.content)!\n event.subjectLine = ifString(meta.subjectLine)!\n event.isDelivered = ifBoolean(meta.isDelivered)\n }\n\n if (isModEventComment(event) && meta.sticky) {\n event.sticky = true\n }\n\n if (isModEventTag(event)) {\n event.add = row.addedTags || []\n event.remove = row.removedTags || []\n }\n\n if (isAccountEvent(event)) {\n event.active = !!meta.active\n event.timestamp = ifString(meta.timestamp)!\n event.status = ifString(meta.status)!\n }\n\n if (isIdentityEvent(event)) {\n event.timestamp = ifString(meta.timestamp)!\n event.handle = ifString(meta.handle)!\n event.pdsHost = ifString(meta.pdsHost)!\n event.tombstone = !!meta.tombstone\n }\n\n if (isRecordEvent(event)) {\n event.op = ifString(meta.op)!\n event.cid = ifString(meta.cid)!\n event.timestamp = ifString(meta.timestamp)!\n }\n\n if (isAgeAssuranceEvent(event)) {\n event.status = ifString(meta.status)!\n event.access = ifString(meta.access)!\n event.createdAt = ifString(meta.createdAt)!\n event.attemptId = ifString(meta.attemptId)!\n event.initIp = ifString(meta.initIp)\n event.initUa = ifString(meta.initUa)\n event.completeIp = ifString(meta.completeIp)\n event.completeUa = ifString(meta.completeUa)\n }\n\n if (isAgeAssuranceOverrideEvent(event)) {\n event.status = ifString(meta.status)!\n event.access = ifString(meta.access)!\n }\n\n if (isScheduleTakedownEvent(event)) {\n event.executeAt = ifString(meta.executeAt)\n event.executeAfter = ifString(meta.executeAfter)\n event.executeUntil = ifString(meta.executeUntil)\n }\n\n return eventView\n }\n\n async eventDetail(\n result: ModerationEventRowWithHandle,\n ): Promise<ModEventViewDetail> {\n const modSubject = subjectFromEventRow(result)\n const subject = await this.subject(modSubject)\n const eventView = this.formatEvent(result)\n const allBlobs = 'value' in subject ? findBlobRefs(subject.value) : []\n const subjectBlobs = await this.blob(\n allBlobs.filter((blob) =>\n eventView.subjectBlobCids.includes(blob.ref.toString()),\n ),\n )\n return {\n ...eventView,\n subject,\n subjectBlobs,\n }\n }\n\n async repoDetails(\n dids: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RepoView>> {\n const results = new Map<string, RepoView>()\n if (!dids.length) {\n return results\n }\n\n const [repos, localLabels, externalLabels] = await Promise.all([\n this.repos(dids),\n this.labels(dids),\n this.getExternalLabels(dids, labelers),\n ])\n\n repos.forEach((repo, did) => {\n const labels = [\n ...(localLabels.get(did) || []),\n ...(externalLabels.get(did) || []),\n ]\n const repoView = {\n ...repo,\n labels,\n moderation: {\n ...repo.moderation,\n },\n }\n results.set(did, repoView)\n })\n\n return results\n }\n\n async fetchRecord(\n params: ComAtprotoRepoGetRecord.QueryParams,\n appviewAuth: AuthHeaders,\n ) {\n try {\n const record = await this.appviewAgent.com.atproto.repo.getRecord(\n params,\n appviewAuth,\n )\n return record\n } catch (err) {\n if (err instanceof ComAtprotoRepoGetRecord.RecordNotFoundError) {\n // If pds fetch fails, just return null regardless of the error\n try {\n const { agent: pdsAgent } = await getPdsAgentForRepo(\n this.idResolver,\n params.repo,\n this.devMode,\n )\n if (!pdsAgent) {\n return null\n }\n\n const record = await pdsAgent.com.atproto.repo.getRecord(params)\n return record\n } catch (error) {\n return null\n }\n }\n\n return null\n }\n }\n\n async fetchRecords(\n subjects: RecordSubject[],\n ): Promise<Map<string, RecordInfo>> {\n const appviewAuth = await this.appviewAuth(ids.ComAtprotoRepoGetRecord)\n if (!appviewAuth) return new Map()\n\n const fetched = await Promise.all(\n subjects.map(async (subject) => {\n const uri = new AtUri(subject.uri)\n const params = {\n repo: uri.hostname,\n collection: uri.collection,\n rkey: uri.rkey,\n cid: subject.cid,\n }\n return this.fetchRecord(params, appviewAuth)\n }),\n )\n return fetched.reduce((acc, cur) => {\n if (!cur) return acc\n const data = cur.data\n const indexedAt = new Date().toISOString()\n return acc.set(data.uri, { ...data, cid: data.cid ?? '', indexedAt })\n }, new Map<string, RecordInfo>())\n }\n\n async records(subjects: RecordSubject[]) {\n const uris = subjects.map((record) => new AtUri(record.uri))\n const dids = uris.map((u) => u.hostname)\n\n const [repos, subjectStatuses, records] = await Promise.all([\n this.repos(dids),\n this.getSubjectStatus(subjects.map((s) => s.uri)),\n this.fetchRecords(subjects),\n ])\n\n const map = new Map<\n string,\n // Because the result of this function is used to build RecordViewDetail,\n // we explicitly type the result without the $type field, so can be used\n // as both RecordView and RecordViewDetail, without having to cast or\n // override the $type field.\n RecordView & {\n $type?: undefined\n moderation: { $type?: undefined; subjectStatus?: SubjectStatusView }\n }\n >()\n\n for (const uri of uris) {\n const repo = repos.get(uri.hostname)\n if (!repo) continue\n const record = records.get(uri.toString())\n if (!record) continue\n const subjectStatus = subjectStatuses.get(uri.toString())\n\n map.set(uri.toString(), {\n uri: uri.toString(),\n cid: record.cid,\n value: record.value,\n blobCids: findBlobRefs(record.value).map((blob) => blob.ref.toString()),\n indexedAt: record.indexedAt,\n repo,\n moderation: {\n subjectStatus: subjectStatus\n ? this.formatSubjectStatus(subjectStatus)\n : undefined,\n },\n })\n }\n\n return map\n }\n\n async recordDetails(\n subjects: RecordSubject[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RecordViewDetail>> {\n const results = new Map<string, RecordViewDetail>()\n if (!subjects.length) {\n return results\n }\n\n const subjectUris = subjects.map((s) => s.uri)\n const [records, subjectStatusesResult, localLabels, externalLabels] =\n await Promise.all([\n this.records(subjects),\n this.getSubjectStatus(subjectUris),\n this.labels(subjectUris),\n this.getExternalLabels(subjectUris, labelers),\n ])\n\n await Promise.all(\n Array.from(records.entries()).map(async ([uri, record]) => {\n const selfLabels = getSelfLabels({\n uri: record.uri,\n cid: record.cid,\n record: record.value,\n })\n\n const status = subjectStatusesResult.get(uri)\n const blobs = await this.blob(findBlobRefs(record.value))\n\n results.set(uri, {\n ...record,\n blobs,\n moderation: {\n ...record.moderation,\n subjectStatus: status\n ? this.formatSubjectStatus(status)\n : undefined,\n },\n labels: [\n ...(localLabels.get(uri) || []),\n ...selfLabels,\n ...(externalLabels.get(uri) || []),\n ],\n })\n }),\n )\n\n return results\n }\n\n async getExternalLabels(\n subjects: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, Label[]>> {\n const results = new Map<string, Label[]>()\n if (!labelers?.dids.length && !labelers?.redact.size) return results\n try {\n const {\n data: { labels },\n } = await this.appviewAgent.com.atproto.label.queryLabels({\n uriPatterns: subjects,\n sources: labelers.dids,\n })\n labels.forEach((label) => {\n if (!results.has(label.uri)) {\n results.set(label.uri, [label])\n return\n }\n results.get(label.uri)?.push(label)\n })\n return results\n } catch (err) {\n httpLogger.error(\n { err, subjects, labelers },\n 'failed to resolve labels from appview',\n )\n return results\n }\n }\n\n formatReport(report: ModerationEventRowWithHandle): ReportOutput {\n return {\n id: report.id,\n createdAt: report.createdAt,\n // Ideally, we would never have a report entry that does not have a reasonType but at the schema level\n // we are not guarantying that so in whatever case, if we end up with such entries, default to 'other'\n reasonType: report.meta?.reportType\n ? (report.meta?.reportType as string)\n : REASONOTHER,\n reason: report.comment ?? undefined,\n reportedBy: report.createdBy,\n subject: subjectFromEventRow(report).lex() as ReportOutput['subject'],\n }\n }\n // Partial view for subjects\n\n async subject(subject: ModSubject): Promise<SubjectView> {\n if (subject.isConvo()) {\n return {\n $type: 'tools.ozone.moderation.defs#convoView',\n did: subject.did,\n convoId: subject.convoId,\n }\n } else if (subject.isRepo()) {\n const repos = await this.repos([subject.did])\n const repo = repos.get(subject.did)\n if (repo) {\n return {\n ...repo,\n $type: 'tools.ozone.moderation.defs#repoView',\n }\n } else {\n return {\n $type: 'tools.ozone.moderation.defs#repoViewNotFound',\n did: subject.did,\n }\n }\n } else if (subject.isRecord()) {\n const uri = subject.uri\n const records = await this.records([{ uri }])\n const record = records.get(uri)\n if (record) {\n return {\n ...record,\n $type: 'tools.ozone.moderation.defs#recordView',\n }\n }\n }\n return {\n $type: 'tools.ozone.moderation.defs#repoViewNotFound',\n did: subject.did,\n }\n }\n\n // Partial view for blobs\n\n async blob(blobs: BlobRef[]): Promise<BlobView[]> {\n if (!blobs.length) return []\n const { ref } = this.db.db.dynamic\n const modStatusResults = await moderationSubjectStatusQueryBuilder(\n this.db.db,\n )\n .where(\n sql<string>`${ref(\n 'moderation_subject_status.blobCids',\n )} @> ${JSON.stringify(blobs.map((blob) => blob.ref.toString()))}`,\n )\n .executeTakeFirst()\n\n const statusByCid = (modStatusResults?.blobCids || [])?.reduce(\n (acc, cur) => Object.assign(acc, { [cur]: modStatusResults }),\n {},\n )\n // Intentionally missing details field, since we don't have any on appview.\n // We also don't know when the blob was created, so we use a canned creation time.\n const unknownTime = new Date(0).toISOString()\n return blobs.map((blob) => {\n const cid = blob.ref.toString()\n const subjectStatus = statusByCid[cid]\n ? this.formatSubjectStatus(statusByCid[cid])\n : undefined\n\n return {\n cid,\n mimeType: blob.mimeType,\n size: blob.size,\n createdAt: unknownTime,\n moderation: {\n subjectStatus,\n },\n }\n })\n }\n\n async labels(\n subjects: string[],\n includeNeg?: boolean,\n ): Promise<Map<string, Label[]>> {\n const now = new Date().toISOString()\n const labels = new Map<string, Label[]>()\n const res = await this.db.db\n .selectFrom('label')\n .where('label.uri', 'in', subjects)\n .where((qb) =>\n qb.where('label.exp', 'is', null).orWhere('label.exp', '>', now),\n )\n .if(!includeNeg, (qb) => qb.where('neg', '=', false))\n .selectAll()\n .execute()\n\n await Promise.all(\n res.map(async (labelRow) => {\n const signedLabel = await this.formatLabelAndEnsureSig(labelRow)\n\n const current = labels.get(labelRow.uri)\n if (current) current.push(signedLabel)\n else labels.set(labelRow.uri, [signedLabel])\n }),\n )\n return labels\n }\n\n async formatLabelAndEnsureSig(row: LabelRow) {\n const formatted = formatLabel(row)\n if (!!row.sig && row.signingKeyId === this.signingKeyId) {\n return formatted\n }\n const signed = await signLabel(formatted, this.signingKey)\n try {\n await this.db.db\n .updateTable('label')\n .set({ sig: Buffer.from(signed.sig), signingKeyId: this.signingKeyId })\n .where('id', '=', row.id)\n .execute()\n } catch (err) {\n dbLogger.error({ err, label: row }, 'failed to update resigned label')\n }\n return signed\n }\n\n async getSubjectStatus(\n subjects: string[],\n ): Promise<Map<string, ModerationSubjectStatusRowWithHandle>> {\n if (!subjects.length) return new Map()\n\n const parsedSubjects = subjects.map(parseSubjectId)\n\n const builder = moderationSubjectStatusQueryBuilder(this.db.db)\n //\n .where((qb) => {\n for (const sub of parsedSubjects) {\n qb = qb.orWhere((qb) =>\n qb\n .where('moderation_subject_status.did', '=', sub.did)\n .where(\n 'moderation_subject_status.recordPath',\n '=',\n sub.recordPath ?? '',\n )\n .where('moderation_subject_status.convoId', '=', ''),\n )\n }\n return qb\n })\n\n const [statusRes, accountsByDid] = await Promise.all([\n builder.execute(),\n this.getAccoutInfosByDid(parsedSubjects.map((s) => s.did)),\n ])\n\n return new Map(\n statusRes.map((row): [string, ModerationSubjectStatusRowWithHandle] => {\n const subjectId = formatSubjectId(row.did, row.recordPath)\n const handle = accountsByDid.get(row.did)?.handle ?? INVALID_HANDLE\n return [subjectId, { ...row, handle }]\n }),\n )\n }\n\n formatSubjectStatus(\n status: ModerationSubjectStatusRowWithHandle,\n ): SubjectStatusView {\n const statusView: SubjectStatusView = {\n id: status.id,\n reviewState: status.reviewState,\n createdAt: status.createdAt,\n updatedAt: status.updatedAt,\n comment: status.comment ?? undefined,\n lastReviewedBy: status.lastReviewedBy ?? undefined,\n lastReviewedAt: status.lastReviewedAt ?? undefined,\n lastReportedAt: status.lastReportedAt ?? undefined,\n lastAppealedAt: status.lastAppealedAt ?? undefined,\n muteUntil: status.muteUntil ?? undefined,\n muteReportingUntil: status.muteReportingUntil ?? undefined,\n suspendUntil: status.suspendUntil ?? undefined,\n takendown: status.takendown ?? undefined,\n appealed: status.appealed ?? undefined,\n subjectRepoHandle: status.handle ?? undefined,\n subjectBlobCids: status.blobCids || [],\n tags: status.tags || [],\n priorityScore: status.priorityScore,\n ageAssuranceState: status.ageAssuranceState ?? undefined,\n ageAssuranceUpdatedBy: status.ageAssuranceUpdatedBy ?? undefined,\n subject: subjectFromStatusRow(\n status,\n ).lex() as SubjectStatusView['subject'],\n\n accountStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#accountStats',\n\n // account_events_stats\n reportCount: status.reportCount ?? undefined,\n appealCount: status.appealCount ?? undefined,\n suspendCount: status.suspendCount ?? undefined,\n takedownCount: status.takedownCount ?? undefined,\n escalateCount: status.escalateCount ?? undefined,\n },\n\n recordsStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#recordsStats',\n\n // account_record_events_stats\n totalReports: status.totalReports ?? undefined,\n reportedCount: status.reportedCount ?? undefined,\n escalatedCount: status.escalatedCount ?? undefined,\n appealedCount: status.appealedCount ?? undefined,\n\n // account_record_status_stats\n subjectCount: status.subjectCount ?? undefined,\n pendingCount: status.pendingCount ?? undefined,\n processedCount: status.processedCount ?? undefined,\n takendownCount: status.takendownCount ?? undefined,\n },\n\n accountStrike:\n status.strikeCount !== null || status.totalStrikeCount !== null\n ? {\n $type: 'tools.ozone.moderation.defs#accountStrike',\n activeStrikeCount: status.strikeCount ?? undefined,\n totalStrikeCount: status.totalStrikeCount ?? undefined,\n firstStrikeAt: status.firstStrikeAt ?? undefined,\n lastStrikeAt: status.lastStrikeAt ?? undefined,\n }\n : undefined,\n }\n\n if (status.recordPath !== '') {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#recordHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n }\n } else {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#accountHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n deactivatedAt: status.hostingDeactivatedAt ?? undefined,\n reactivatedAt: status.hostingReactivatedAt ?? undefined,\n }\n }\n\n return statusView\n }\n\n async fetchAuthorFeed(actor: string): Promise<FeedViewPost[]> {\n const auth = await this.appviewAuth(ids.AppBskyFeedGetAuthorFeed)\n if (!auth) return []\n const {\n data: { feed },\n } = await this.appviewAgent.app.bsky.feed.getAuthorFeed({ actor }, auth)\n\n return feed\n }\n\n async getProfiles(dids: string[]) {\n const profiles = new Map<string, AppBskyActorDefs.ProfileViewDetailed>()\n\n const auth = await this.appviewAuth(ids.AppBskyActorGetProfiles)\n if (!auth) return profiles\n\n for (const actors of chunkArray(dids, 25)) {\n const { data } = await this.appviewAgent.getProfiles({ actors }, auth)\n\n data.profiles.forEach((profile) => {\n profiles.set(profile.did, profile)\n })\n }\n\n return profiles\n }\n}\n\ntype RecordSubject = { uri: string; cid?: string }\n\ntype SubjectView = ModEventViewDetail['subject']\n// @TODO tidy\n// type SubjectView = ModEventViewDetail['subject'] & ReportViewDetail['subject']\n\ntype RecordInfo = {\n uri: string\n cid: string\n value: Record<string, unknown>\n indexedAt: string\n}\n\nfunction parseSubjectId(subject: string): { did: string; recordPath?: string } {\n if (subject.startsWith('did:')) {\n return { did: subject }\n }\n const uri = new AtUri(subject)\n return { did: uri.hostname, recordPath: `${uri.collection}/${uri.rkey}` }\n}\n\nfunction formatSubjectId(did: string, recordPath?: string) {\n return recordPath ? `at://${did}/${recordPath}` : did\n}\n\nfunction findBlobRefs(value: unknown, refs: BlobRef[] = []) {\n if (value instanceof BlobRef) {\n refs.push(value)\n } else if (Array.isArray(value)) {\n value.forEach((val) => findBlobRefs(val, refs))\n } else if (value && typeof value === 'object') {\n Object.values(value).forEach((val) => findBlobRefs(val, refs))\n }\n return refs\n}\n\nexport function getSelfLabels(details: {\n uri: string | null\n cid: string | null\n record: Record<string, unknown> | null\n}): Label[] {\n const { uri, cid, record } = details\n if (!uri || !cid || !record) return []\n if (!isValidSelfLabels(record.labels)) return []\n const src = new AtUri(uri).host // record creator\n const cts =\n typeof record.createdAt === 'string'\n ? normalizeDatetimeAlways(record.createdAt)\n : new Date(0).toISOString()\n return record.labels.values.map(({ val }) => {\n return { src, uri, cid, val, cts }\n })\n}\n\n// The atproto data model requires all integers to fit within 53 bits\n// (Number.MAX_SAFE_INTEGER). External tools may write larger numbers into\n// \"unknown\"-typed fields like modTool.meta, which causes lex-json parse\n// failures on the client side. This helper converts unsafe integers to strings.\nfunction sanitizeUnsafeIntegers(value: unknown): unknown {\n if (typeof value === 'number') {\n return Number.isSafeInteger(value) ? value : String(value)\n }\n if (Array.isArray(value)) {\n return value.map(sanitizeUnsafeIntegers)\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value)) {\n out[k] = sanitizeUnsafeIntegers(v)\n }\n return out\n }\n return value\n}\n"]}
|
|
1
|
+
{"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/mod-service/views.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'kysely'\nimport {\n AppBskyActorDefs,\n AtpAgent,\n ComAtprotoRepoGetRecord,\n} from '@atproto/api'\nimport { chunkArray, dedupeStrs } from '@atproto/common'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { BlobRef } from '@atproto/lexicon'\nimport { AtUri, INVALID_HANDLE, normalizeDatetimeAlways } from '@atproto/syntax'\nimport { Database } from '../db/index.js'\nimport { LabelRow } from '../db/schema/label.js'\nimport { ids } from '../lexicon/lexicons.js'\nimport { FeedViewPost } from '../lexicon/types/app/bsky/feed/defs.js'\nimport { AccountView } from '../lexicon/types/com/atproto/admin/defs.js'\nimport {\n Label,\n validateSelfLabels,\n} from '../lexicon/types/com/atproto/label/defs.js'\nimport { OutputSchema as ReportOutput } from '../lexicon/types/com/atproto/moderation/createReport.js'\nimport { REASONOTHER } from '../lexicon/types/com/atproto/moderation/defs.js'\nimport {\n BlobView,\n ModEventView,\n ModEventViewDetail,\n RecordView,\n RecordViewDetail,\n RepoView,\n SubjectStatusView,\n isAccountEvent,\n isAgeAssuranceEvent,\n isAgeAssuranceOverrideEvent,\n isIdentityEvent,\n isModEventAcknowledge,\n isModEventComment,\n isModEventEmail,\n isModEventEscalate,\n isModEventLabel,\n isModEventMute,\n isModEventMuteReporter,\n isModEventPriorityScore,\n isModEventReport,\n isModEventReverseTakedown,\n isModEventTag,\n isModEventTakedown,\n isRecordEvent,\n isScheduleTakedownEvent,\n} from '../lexicon/types/tools/ozone/moderation/defs.js'\nimport { Un$Typed, asPredicate } from '../lexicon/util.js'\nimport { dbLogger, httpLogger } from '../logger.js'\nimport { ParsedLabelers } from '../util.js'\nimport { moderationSubjectStatusQueryBuilder } from './status.js'\nimport {\n ModSubject,\n subjectFromEventRow,\n subjectFromStatusRow,\n} from './subject.js'\nimport {\n ModerationEventRowWithHandle,\n ModerationSubjectStatusRowWithHandle,\n} from './types.js'\nimport { formatLabel, getPdsAgentForRepo, signLabel } from './util.js'\n\nconst isValidSelfLabels = asPredicate(validateSelfLabels)\n\nconst ifString = (val: unknown): string | undefined =>\n typeof val === 'string' ? val : undefined\nconst ifBoolean = (val: unknown): boolean | undefined =>\n typeof val === 'boolean' ? val : undefined\nconst ifNumber = (val: unknown): number | undefined =>\n typeof val === 'number' ? val : undefined\n\nexport type AuthHeaders = {\n headers: {\n authorization: string\n 'atproto-accept-labelers'?: string\n }\n}\n\nexport class ModerationViews {\n constructor(\n private db: Database,\n private signingKey: Keypair,\n private signingKeyId: number,\n private appviewAgent: AtpAgent,\n private appviewAuth: (method: string) => Promise<AuthHeaders>,\n public idResolver: IdResolver,\n public devMode?: boolean,\n ) {}\n\n async getAccoutInfosByDid(dids: string[]): Promise<Map<string, AccountView>> {\n if (dids.length === 0) return new Map()\n const auth = await this.appviewAuth(ids.ComAtprotoAdminGetAccountInfos)\n if (!auth) return new Map()\n try {\n const res = await this.appviewAgent.com.atproto.admin.getAccountInfos(\n {\n dids: dedupeStrs(dids),\n },\n auth,\n )\n return res.data.infos.reduce((acc, cur) => {\n return acc.set(cur.did, cur)\n }, new Map<string, AccountView>())\n } catch (err) {\n httpLogger.error(\n { err, dids },\n 'failed to resolve account infos from appview',\n )\n return new Map()\n }\n }\n\n async repos(dids: string[]): Promise<Map<string, RepoView>> {\n if (dids.length === 0) return new Map()\n const [infos, subjectStatuses] = await Promise.all([\n this.getAccoutInfosByDid(dids),\n this.getSubjectStatus(dids),\n ])\n\n return dids.reduce((acc, did) => {\n const info = infos.get(did)\n if (!info) return acc\n const status = subjectStatuses.get(did)\n return acc.set(did, {\n // No email or invite info on appview\n did,\n handle: info.handle,\n relatedRecords: info.relatedRecords ?? [],\n indexedAt: info.indexedAt,\n moderation: {\n subjectStatus: status ? this.formatSubjectStatus(status) : undefined,\n },\n })\n }, new Map<string, RepoView>())\n }\n\n formatEvent(row: ModerationEventRowWithHandle): Un$Typed<ModEventView> {\n const eventView: Un$Typed<ModEventView> = {\n id: row.id,\n event: {\n $type: row.action,\n comment: row.comment ?? undefined,\n },\n subject: subjectFromEventRow(row).lex(),\n subjectBlobCids: row.subjectBlobCids ?? [],\n createdBy: row.createdBy,\n createdAt: row.createdAt,\n subjectHandle: row.subjectHandle ?? undefined,\n creatorHandle: row.creatorHandle ?? undefined,\n modTool: row.modTool\n ? {\n name: row.modTool.name,\n meta: sanitizeUnsafeIntegers(row.modTool.meta) as\n | Record<string, unknown>\n | undefined,\n }\n : undefined,\n }\n\n const { event } = eventView\n const meta = row.meta || {}\n\n if (\n isModEventMuteReporter(event) ||\n isModEventTakedown(event) ||\n isModEventLabel(event) ||\n isModEventMute(event)\n ) {\n event.durationInHours = row.durationInHours ?? undefined\n }\n\n if (\n (isModEventTakedown(event) || isModEventAcknowledge(event)) &&\n meta.acknowledgeAccountSubjects\n ) {\n event.acknowledgeAccountSubjects = ifBoolean(\n meta.acknowledgeAccountSubjects,\n )!\n }\n\n if (isModEventPriorityScore(event)) {\n event.score = ifNumber(meta?.priorityScore) ?? 0\n }\n\n if (\n isModEventTakedown(event) ||\n isModEventEmail(event) ||\n isModEventReverseTakedown(event)\n ) {\n if (typeof meta.policies === 'string' && meta.policies.length > 0) {\n event.policies = meta.policies.split(',')\n }\n\n event.strikeCount = ifNumber(row.strikeCount)\n event.severityLevel = ifString(row.severityLevel)\n\n if (isModEventTakedown(event) || isModEventEmail(event)) {\n event.strikeExpiresAt = ifString(row.strikeExpiresAt)\n }\n }\n\n if (isModEventTakedown(event)) {\n if (\n typeof meta.targetServices === 'string' &&\n meta.targetServices.length > 0\n ) {\n event.targetServices = meta.targetServices.split(',')\n }\n }\n\n if (isModEventLabel(event)) {\n event.createLabelVals = row.createLabelVals?.length\n ? row.createLabelVals.split(' ')\n : []\n event.negateLabelVals = row.negateLabelVals?.length\n ? row.negateLabelVals.split(' ')\n : []\n } else if (\n isModEventAcknowledge(event) ||\n isModEventTakedown(event) ||\n isModEventEscalate(event)\n ) {\n // This is for legacy data only, for new events, these types of events\n // won't have labels attached:\n\n if (row.createLabelVals?.length) {\n // @ts-expect-error legacy\n event.createLabelVals = row.createLabelVals.split(' ')\n }\n\n if (row.negateLabelVals?.length) {\n // @ts-expect-error legacy\n event.negateLabelVals = row.negateLabelVals.split(' ')\n }\n }\n\n if (isModEventReport(event)) {\n event.isReporterMuted = !!meta.isReporterMuted\n event.reportType = ifString(meta.reportType)!\n }\n\n if (isModEventEmail(event)) {\n event.content = ifString(meta.content)!\n event.subjectLine = ifString(meta.subjectLine)!\n event.isDelivered = ifBoolean(meta.isDelivered)\n }\n\n if (isModEventComment(event) && meta.sticky) {\n event.sticky = true\n }\n\n if (isModEventTag(event)) {\n event.add = row.addedTags || []\n event.remove = row.removedTags || []\n }\n\n if (isAccountEvent(event)) {\n event.active = !!meta.active\n event.timestamp = ifString(meta.timestamp)!\n event.status = ifString(meta.status)!\n }\n\n if (isIdentityEvent(event)) {\n event.timestamp = ifString(meta.timestamp)!\n event.handle = ifString(meta.handle)!\n event.pdsHost = ifString(meta.pdsHost)!\n event.tombstone = !!meta.tombstone\n }\n\n if (isRecordEvent(event)) {\n event.op = ifString(meta.op)!\n event.cid = ifString(meta.cid)!\n event.timestamp = ifString(meta.timestamp)!\n }\n\n if (isAgeAssuranceEvent(event)) {\n event.status = ifString(meta.status)!\n event.access = ifString(meta.access)!\n event.createdAt = ifString(meta.createdAt)!\n event.attemptId = ifString(meta.attemptId)!\n event.initIp = ifString(meta.initIp)\n event.initUa = ifString(meta.initUa)\n event.completeIp = ifString(meta.completeIp)\n event.completeUa = ifString(meta.completeUa)\n }\n\n if (isAgeAssuranceOverrideEvent(event)) {\n event.status = ifString(meta.status)!\n event.access = ifString(meta.access)!\n }\n\n if (isScheduleTakedownEvent(event)) {\n event.executeAt = ifString(meta.executeAt)\n event.executeAfter = ifString(meta.executeAfter)\n event.executeUntil = ifString(meta.executeUntil)\n }\n\n return eventView\n }\n\n async eventDetail(\n result: ModerationEventRowWithHandle,\n ): Promise<ModEventViewDetail> {\n const modSubject = subjectFromEventRow(result)\n const subject = await this.subject(modSubject)\n const eventView = this.formatEvent(result)\n const allBlobs = 'value' in subject ? findBlobRefs(subject.value) : []\n const subjectBlobs = await this.blob(\n allBlobs.filter((blob) =>\n eventView.subjectBlobCids.includes(blob.ref.toString()),\n ),\n )\n return {\n ...eventView,\n subject,\n subjectBlobs,\n }\n }\n\n async repoDetails(\n dids: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RepoView>> {\n const results = new Map<string, RepoView>()\n if (!dids.length) {\n return results\n }\n\n const [repos, localLabels, externalLabels] = await Promise.all([\n this.repos(dids),\n this.labels(dids),\n this.getExternalLabels(dids, labelers),\n ])\n\n repos.forEach((repo, did) => {\n const labels = [\n ...(localLabels.get(did) || []),\n ...(externalLabels.get(did) || []),\n ]\n const repoView = {\n ...repo,\n labels,\n moderation: {\n ...repo.moderation,\n },\n }\n results.set(did, repoView)\n })\n\n return results\n }\n\n async fetchRecord(\n params: ComAtprotoRepoGetRecord.QueryParams,\n appviewAuth: AuthHeaders,\n ) {\n try {\n const record = await this.appviewAgent.com.atproto.repo.getRecord(\n params,\n appviewAuth,\n )\n return record\n } catch (err) {\n if (err instanceof ComAtprotoRepoGetRecord.RecordNotFoundError) {\n // If pds fetch fails, just return null regardless of the error\n try {\n const { agent: pdsAgent } = await getPdsAgentForRepo(\n this.idResolver,\n params.repo,\n this.devMode,\n )\n if (!pdsAgent) {\n return null\n }\n\n const record = await pdsAgent.com.atproto.repo.getRecord(params)\n return record\n } catch (error) {\n return null\n }\n }\n\n return null\n }\n }\n\n async fetchRecords(\n subjects: RecordSubject[],\n ): Promise<Map<string, RecordInfo>> {\n const appviewAuth = await this.appviewAuth(ids.ComAtprotoRepoGetRecord)\n if (!appviewAuth) return new Map()\n\n const fetched = await Promise.all(\n subjects.map(async (subject) => {\n const uri = new AtUri(subject.uri)\n const params = {\n repo: uri.hostname,\n collection: uri.collection,\n rkey: uri.rkey,\n cid: subject.cid,\n }\n return this.fetchRecord(params, appviewAuth)\n }),\n )\n return fetched.reduce((acc, cur) => {\n if (!cur) return acc\n const data = cur.data\n const indexedAt = new Date().toISOString()\n return acc.set(data.uri, { ...data, cid: data.cid ?? '', indexedAt })\n }, new Map<string, RecordInfo>())\n }\n\n async records(subjects: RecordSubject[]) {\n const uris = subjects.map((record) => new AtUri(record.uri))\n const dids = uris.map((u) => u.hostname)\n\n const [repos, subjectStatuses, records] = await Promise.all([\n this.repos(dids),\n this.getSubjectStatus(subjects.map((s) => s.uri)),\n this.fetchRecords(subjects),\n ])\n\n const map = new Map<\n string,\n // Because the result of this function is used to build RecordViewDetail,\n // we explicitly type the result without the $type field, so can be used\n // as both RecordView and RecordViewDetail, without having to cast or\n // override the $type field.\n RecordView & {\n $type?: undefined\n moderation: { $type?: undefined; subjectStatus?: SubjectStatusView }\n }\n >()\n\n for (const uri of uris) {\n const repo = repos.get(uri.hostname)\n if (!repo) continue\n const record = records.get(uri.toString())\n if (!record) continue\n const subjectStatus = subjectStatuses.get(uri.toString())\n\n map.set(uri.toString(), {\n uri: uri.toString(),\n cid: record.cid,\n value: record.value,\n blobCids: findBlobRefs(record.value).map((blob) => blob.ref.toString()),\n indexedAt: record.indexedAt,\n repo,\n moderation: {\n subjectStatus: subjectStatus\n ? this.formatSubjectStatus(subjectStatus)\n : undefined,\n },\n })\n }\n\n return map\n }\n\n async recordDetails(\n subjects: RecordSubject[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RecordViewDetail>> {\n const results = new Map<string, RecordViewDetail>()\n if (!subjects.length) {\n return results\n }\n\n const subjectUris = subjects.map((s) => s.uri)\n const [records, subjectStatusesResult, localLabels, externalLabels] =\n await Promise.all([\n this.records(subjects),\n this.getSubjectStatus(subjectUris),\n this.labels(subjectUris),\n this.getExternalLabels(subjectUris, labelers),\n ])\n\n await Promise.all(\n Array.from(records.entries()).map(async ([uri, record]) => {\n const selfLabels = getSelfLabels({\n uri: record.uri,\n cid: record.cid,\n record: record.value,\n })\n\n const status = subjectStatusesResult.get(uri)\n const blobs = await this.blob(findBlobRefs(record.value))\n\n results.set(uri, {\n ...record,\n blobs,\n moderation: {\n ...record.moderation,\n subjectStatus: status\n ? this.formatSubjectStatus(status)\n : undefined,\n },\n labels: [\n ...(localLabels.get(uri) || []),\n ...selfLabels,\n ...(externalLabels.get(uri) || []),\n ],\n })\n }),\n )\n\n return results\n }\n\n async getExternalLabels(\n subjects: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, Label[]>> {\n const results = new Map<string, Label[]>()\n if (!labelers?.dids.length && !labelers?.redact.size) return results\n try {\n const {\n data: { labels },\n } = await this.appviewAgent.com.atproto.label.queryLabels({\n uriPatterns: subjects,\n sources: labelers.dids,\n })\n labels.forEach((label) => {\n if (!results.has(label.uri)) {\n results.set(label.uri, [label])\n return\n }\n results.get(label.uri)?.push(label)\n })\n return results\n } catch (err) {\n httpLogger.error(\n { err, subjects, labelers },\n 'failed to resolve labels from appview',\n )\n return results\n }\n }\n\n formatReport(report: ModerationEventRowWithHandle): ReportOutput {\n return {\n id: report.id,\n createdAt: report.createdAt,\n // Ideally, we would never have a report entry that does not have a reasonType but at the schema level\n // we are not guarantying that so in whatever case, if we end up with such entries, default to 'other'\n reasonType: report.meta?.reportType\n ? (report.meta?.reportType as string)\n : REASONOTHER,\n reason: report.comment ?? undefined,\n reportedBy: report.createdBy,\n subject: subjectFromEventRow(report).lex() as ReportOutput['subject'],\n }\n }\n // Partial view for subjects\n\n async subject(subject: ModSubject): Promise<SubjectView> {\n if (subject.isConvo()) {\n return {\n $type: 'tools.ozone.moderation.defs#convoView',\n did: subject.did,\n convoId: subject.convoId,\n }\n } else if (subject.isRepo()) {\n const repos = await this.repos([subject.did])\n const repo = repos.get(subject.did)\n if (repo) {\n return {\n ...repo,\n $type: 'tools.ozone.moderation.defs#repoView',\n }\n } else {\n return {\n $type: 'tools.ozone.moderation.defs#repoViewNotFound',\n did: subject.did,\n }\n }\n } else if (subject.isRecord()) {\n const uri = subject.uri\n const records = await this.records([{ uri }])\n const record = records.get(uri)\n if (record) {\n return {\n ...record,\n $type: 'tools.ozone.moderation.defs#recordView',\n }\n }\n }\n return {\n $type: 'tools.ozone.moderation.defs#repoViewNotFound',\n did: subject.did,\n }\n }\n\n // Partial view for blobs\n\n async blob(blobs: BlobRef[]): Promise<BlobView[]> {\n if (!blobs.length) return []\n const { ref } = this.db.db.dynamic\n const modStatusResults = await moderationSubjectStatusQueryBuilder(\n this.db.db,\n )\n .where(\n sql<string>`${ref(\n 'moderation_subject_status.blobCids',\n )} @> ${JSON.stringify(blobs.map((blob) => blob.ref.toString()))}`,\n )\n .executeTakeFirst()\n\n const statusByCid = (modStatusResults?.blobCids || [])?.reduce(\n (acc, cur) => Object.assign(acc, { [cur]: modStatusResults }),\n {},\n )\n // Intentionally missing details field, since we don't have any on appview.\n // We also don't know when the blob was created, so we use a canned creation time.\n const unknownTime = new Date(0).toISOString()\n return blobs.map((blob) => {\n const cid = blob.ref.toString()\n const subjectStatus = statusByCid[cid]\n ? this.formatSubjectStatus(statusByCid[cid])\n : undefined\n\n return {\n cid,\n mimeType: blob.mimeType,\n size: blob.size,\n createdAt: unknownTime,\n moderation: {\n subjectStatus,\n },\n }\n })\n }\n\n async labels(\n subjects: string[],\n includeNeg?: boolean,\n ): Promise<Map<string, Label[]>> {\n const now = new Date().toISOString()\n const labels = new Map<string, Label[]>()\n const res = await this.db.db\n .selectFrom('label')\n .where('label.uri', 'in', subjects)\n .where((qb) =>\n qb.where('label.exp', 'is', null).orWhere('label.exp', '>', now),\n )\n .if(!includeNeg, (qb) => qb.where('neg', '=', false))\n .selectAll()\n .execute()\n\n await Promise.all(\n res.map(async (labelRow) => {\n const signedLabel = await this.formatLabelAndEnsureSig(labelRow)\n\n const current = labels.get(labelRow.uri)\n if (current) current.push(signedLabel)\n else labels.set(labelRow.uri, [signedLabel])\n }),\n )\n return labels\n }\n\n async formatLabelAndEnsureSig(row: LabelRow) {\n const formatted = formatLabel(row)\n if (!!row.sig && row.signingKeyId === this.signingKeyId) {\n return formatted\n }\n const signed = await signLabel(formatted, this.signingKey)\n try {\n await this.db.db\n .updateTable('label')\n .set({ sig: Buffer.from(signed.sig), signingKeyId: this.signingKeyId })\n .where('id', '=', row.id)\n .execute()\n } catch (err) {\n dbLogger.error({ err, label: row }, 'failed to update resigned label')\n }\n return signed\n }\n\n async getSubjectStatus(\n subjects: string[],\n ): Promise<Map<string, ModerationSubjectStatusRowWithHandle>> {\n if (!subjects.length) return new Map()\n\n const parsedSubjects = subjects.map(parseSubjectId)\n\n const builder = moderationSubjectStatusQueryBuilder(this.db.db)\n //\n .where((qb) => {\n for (const sub of parsedSubjects) {\n qb = qb.orWhere((qb) =>\n qb\n .where('moderation_subject_status.did', '=', sub.did)\n .where(\n 'moderation_subject_status.recordPath',\n '=',\n sub.recordPath ?? '',\n )\n .where('moderation_subject_status.convoId', '=', ''),\n )\n }\n return qb\n })\n\n const [statusRes, accountsByDid] = await Promise.all([\n builder.execute(),\n this.getAccoutInfosByDid(parsedSubjects.map((s) => s.did)),\n ])\n\n return new Map(\n statusRes.map((row): [string, ModerationSubjectStatusRowWithHandle] => {\n const subjectId = formatSubjectId(row.did, row.recordPath)\n const handle = accountsByDid.get(row.did)?.handle ?? INVALID_HANDLE\n return [subjectId, { ...row, handle }]\n }),\n )\n }\n\n formatSubjectStatus(\n status: ModerationSubjectStatusRowWithHandle,\n ): SubjectStatusView {\n const statusView: SubjectStatusView = {\n id: status.id,\n reviewState: status.reviewState,\n createdAt: status.createdAt,\n updatedAt: status.updatedAt,\n comment: status.comment ?? undefined,\n lastReviewedBy: status.lastReviewedBy ?? undefined,\n lastReviewedAt: status.lastReviewedAt ?? undefined,\n lastReportedAt: status.lastReportedAt ?? undefined,\n lastAppealedAt: status.lastAppealedAt ?? undefined,\n muteUntil: status.muteUntil ?? undefined,\n muteReportingUntil: status.muteReportingUntil ?? undefined,\n suspendUntil: status.suspendUntil ?? undefined,\n takendown: status.takendown ?? undefined,\n appealed: status.appealed ?? undefined,\n subjectRepoHandle: status.handle ?? undefined,\n subjectBlobCids: status.blobCids || [],\n tags: status.tags || [],\n priorityScore: status.priorityScore,\n ageAssuranceState: status.ageAssuranceState ?? undefined,\n ageAssuranceUpdatedBy: status.ageAssuranceUpdatedBy ?? undefined,\n subject: subjectFromStatusRow(\n status,\n ).lex() as SubjectStatusView['subject'],\n\n accountStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#accountStats',\n\n // account_events_stats\n reportCount: status.reportCount ?? undefined,\n appealCount: status.appealCount ?? undefined,\n suspendCount: status.suspendCount ?? undefined,\n takedownCount: status.takedownCount ?? undefined,\n escalateCount: status.escalateCount ?? undefined,\n },\n\n recordsStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#recordsStats',\n\n // account_record_events_stats\n totalReports: status.totalReports ?? undefined,\n reportedCount: status.reportedCount ?? undefined,\n escalatedCount: status.escalatedCount ?? undefined,\n appealedCount: status.appealedCount ?? undefined,\n\n // account_record_status_stats\n subjectCount: status.subjectCount ?? undefined,\n pendingCount: status.pendingCount ?? undefined,\n processedCount: status.processedCount ?? undefined,\n takendownCount: status.takendownCount ?? undefined,\n },\n\n accountStrike:\n status.strikeCount !== null || status.totalStrikeCount !== null\n ? {\n $type: 'tools.ozone.moderation.defs#accountStrike',\n activeStrikeCount: status.strikeCount ?? undefined,\n totalStrikeCount: status.totalStrikeCount ?? undefined,\n firstStrikeAt: status.firstStrikeAt ?? undefined,\n lastStrikeAt: status.lastStrikeAt ?? undefined,\n }\n : undefined,\n }\n\n if (status.recordPath !== '') {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#recordHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n }\n } else {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#accountHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n deactivatedAt: status.hostingDeactivatedAt ?? undefined,\n reactivatedAt: status.hostingReactivatedAt ?? undefined,\n }\n }\n\n return statusView\n }\n\n async fetchAuthorFeed(actor: string): Promise<FeedViewPost[]> {\n const auth = await this.appviewAuth(ids.AppBskyFeedGetAuthorFeed)\n if (!auth) return []\n const {\n data: { feed },\n } = await this.appviewAgent.app.bsky.feed.getAuthorFeed({ actor }, auth)\n\n return feed\n }\n\n async getProfiles(dids: string[]) {\n const profiles = new Map<string, AppBskyActorDefs.ProfileViewDetailed>()\n\n const auth = await this.appviewAuth(ids.AppBskyActorGetProfiles)\n if (!auth) return profiles\n\n for (const actors of chunkArray(dids, 25)) {\n const { data } = await this.appviewAgent.getProfiles({ actors }, auth)\n\n data.profiles.forEach((profile) => {\n profiles.set(profile.did, profile)\n })\n }\n\n return profiles\n }\n}\n\ntype RecordSubject = { uri: string; cid?: string }\n\ntype SubjectView = ModEventViewDetail['subject']\n// @TODO tidy\n// type SubjectView = ModEventViewDetail['subject'] & ReportViewDetail['subject']\n\ntype RecordInfo = {\n uri: string\n cid: string\n value: Record<string, unknown>\n indexedAt: string\n}\n\nfunction parseSubjectId(subject: string): { did: string; recordPath?: string } {\n if (subject.startsWith('did:')) {\n return { did: subject }\n }\n const uri = new AtUri(subject)\n return { did: uri.hostname, recordPath: `${uri.collection}/${uri.rkey}` }\n}\n\nfunction formatSubjectId(did: string, recordPath?: string) {\n return recordPath ? `at://${did}/${recordPath}` : did\n}\n\nfunction findBlobRefs(value: unknown, refs: BlobRef[] = []) {\n if (value instanceof BlobRef) {\n refs.push(value)\n } else if (Array.isArray(value)) {\n value.forEach((val) => findBlobRefs(val, refs))\n } else if (value && typeof value === 'object') {\n Object.values(value).forEach((val) => findBlobRefs(val, refs))\n }\n return refs\n}\n\nexport function getSelfLabels(details: {\n uri: string | null\n cid: string | null\n record: Record<string, unknown> | null\n}): Label[] {\n const { uri, cid, record } = details\n if (!uri || !cid || !record) return []\n if (!isValidSelfLabels(record.labels)) return []\n const src = new AtUri(uri).host // record creator\n const cts =\n typeof record.createdAt === 'string'\n ? normalizeDatetimeAlways(record.createdAt)\n : new Date(0).toISOString()\n return record.labels.values.map(({ val }) => {\n return { src, uri, cid, val, cts }\n })\n}\n\n// The atproto data model requires all integers to fit within 53 bits\n// (Number.MAX_SAFE_INTEGER). External tools may write larger numbers into\n// \"unknown\"-typed fields like modTool.meta, which causes lex-json parse\n// failures on the client side. This helper converts unsafe integers to strings.\nfunction sanitizeUnsafeIntegers(value: unknown): unknown {\n if (typeof value === 'number') {\n return Number.isSafeInteger(value) ? value : String(value)\n }\n if (Array.isArray(value)) {\n return value.map(sanitizeUnsafeIntegers)\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value)) {\n out[k] = sanitizeUnsafeIntegers(v)\n }\n return out\n }\n return value\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/queue/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAO,MAAM,QAAQ,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGlD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AA6B1D,MAAM,MAAM,mBAAmB,GAAG,CAAC,EAAE,EAAE,QAAQ,KAAK,YAAY,CAAA;AAEhE,qBAAa,YAAY;IACJ,EAAE,EAAE,QAAQ;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/queue/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/queue/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Selectable, sql } from 'kysely'\nimport { ToolsOzoneQueueDefs } from '@atproto/api'\nimport { AtUri } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { Database } from '../db/index.js'\nimport { TimeIdKeyset, paginate } from '../db/pagination.js'\nimport { ReportQueue } from '../db/schema/report_queue.js'\nimport { jsonb } from '../db/types.js'\nimport { handleReportUpdate } from '../report/handle-report-update.js'\nimport { ReportStatsService } from '../report/stats.js'\nimport { viewQueueStats } from '../report/views.js'\n\nconst MOD_EVENT_REPORT_ACTION = 'tools.ozone.moderation.defs#modEventReport'\nconst REASON_OTHER = 'com.atproto.moderation.defs#reasonOther'\n\ntype SubjectType = 'account' | 'record' | 'message' | 'conversation'\n\ntype ResolvedAssignment = {\n queueId: number\n queuedAt: string | null\n status: 'queued' | 'open'\n}\n\nfunction resolveAssignment(\n subjectType: SubjectType,\n collection: string | null,\n reportType: string,\n queues: Selectable<ReportQueue>[],\n now: string,\n): ResolvedAssignment {\n const matched = findMatchingQueue(queues, subjectType, collection, reportType)\n if (matched) return { queueId: matched.id, queuedAt: now, status: 'queued' }\n return { queueId: -1, queuedAt: null, status: 'open' }\n}\n\nexport type QueueServiceCreator = (db: Database) => QueueService\n\nexport class QueueService {\n constructor(public db: Database) {}\n\n static creator() {\n return (db: Database) => new QueueService(db)\n }\n\n async checkConflict({\n subjectTypes,\n collection,\n reportTypes,\n excludeId,\n }: {\n subjectTypes: string[]\n collection?: string | null\n reportTypes: string[]\n excludeId?: number\n }): Promise<void> {\n // It's not ideal to load all rows and perform in memory checks in case we end up with a LOT of queues\n // but we are not foreseeing a lot of queue rows so this should be fine for the\n let qb = this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('deletedAt', 'is', null)\n\n if (excludeId !== undefined) {\n qb = qb.where('id', '!=', excludeId)\n }\n\n const existingQueues = await qb.execute()\n\n for (const existing of existingQueues) {\n const subjectTypesOverlap = subjectTypes.some((st) =>\n existing.subjectTypes.includes(st),\n )\n const collectionMatch = (collection ?? null) === existing.collection\n const reportTypesOverlap = reportTypes.some((rt) =>\n existing.reportTypes.includes(rt),\n )\n\n if (subjectTypesOverlap && collectionMatch && reportTypesOverlap) {\n throw new InvalidRequestError(\n `Queue configuration conflicts with existing queue: ${existing.name}`,\n 'ConflictingQueue',\n )\n }\n }\n }\n\n async create({\n name,\n subjectTypes,\n collection,\n reportTypes,\n description,\n createdBy,\n }: {\n name: string\n subjectTypes: string[]\n collection?: string | null\n reportTypes: string[]\n description?: string | null\n createdBy: string\n }): Promise<Selectable<ReportQueue>> {\n const now = new Date().toISOString()\n return await this.db.db\n .insertInto('report_queue')\n .values({\n name,\n subjectTypes: jsonb(subjectTypes),\n collection: collection ?? null,\n reportTypes: jsonb(reportTypes),\n description: description ?? null,\n createdBy,\n enabled: true,\n createdAt: now,\n updatedAt: now,\n })\n .returningAll()\n .executeTakeFirstOrThrow()\n }\n\n async getById(id: number): Promise<Selectable<ReportQueue> | undefined> {\n return await this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('id', '=', id)\n .where('deletedAt', 'is', null)\n .executeTakeFirst()\n }\n\n async getViewsByIds(\n ids: number[],\n ): Promise<Map<number, ToolsOzoneQueueDefs.QueueView>> {\n if (!ids.length) return new Map()\n const rows = await this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('id', 'in', ids)\n .execute()\n return new Map(rows.map((r) => [r.id, this.view(r)]))\n }\n\n async update(\n id: number,\n updates: { name?: string; enabled?: boolean; description?: string },\n ): Promise<Selectable<ReportQueue>> {\n const now = new Date().toISOString()\n return await this.db.db\n .updateTable('report_queue')\n .set({ ...updates, updatedAt: now })\n .where('id', '=', id)\n .returningAll()\n .executeTakeFirstOrThrow()\n }\n\n async delete(id: number): Promise<void> {\n const now = new Date().toISOString()\n await this.db.db\n .updateTable('report_queue')\n .set({ deletedAt: now })\n .where('id', '=', id)\n .execute()\n }\n\n async migrateReports(\n fromQueueId: number,\n toQueueId?: number,\n ): Promise<number> {\n const now = new Date().toISOString()\n const results = await this.db.db\n .updateTable('report')\n .set({\n queueId: toQueueId ?? -1,\n queuedAt: toQueueId ? now : null,\n updatedAt: now,\n })\n .where('queueId', '=', fromQueueId)\n .where('status', '!=', 'closed')\n .execute()\n return results.reduce((sum, r) => sum + Number(r.numUpdatedRows), 0)\n }\n\n async list({\n limit,\n cursor,\n enabled,\n subjectType,\n collection,\n reportTypes,\n }: {\n limit: number\n cursor?: string\n enabled?: boolean\n subjectType?: string\n collection?: string\n reportTypes?: string[]\n }): Promise<{ queues: Selectable<ReportQueue>[]; cursor?: string }> {\n const { ref } = this.db.db.dynamic\n let qb = this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('deletedAt', 'is', null)\n\n if (enabled !== undefined) {\n qb = qb.where('enabled', '=', enabled)\n }\n\n if (subjectType !== undefined) {\n qb = qb.where(sql`\"subjectTypes\" @> ${jsonb([subjectType])}`)\n }\n\n if (collection !== undefined) {\n qb = qb.where('collection', '=', collection)\n }\n\n if (reportTypes && reportTypes.length > 0) {\n const conditions = reportTypes.map(\n (t) => sql`\"reportTypes\" @> ${jsonb([t])}`,\n )\n qb = qb.where(sql`(${sql.join(conditions, sql` OR `)})`)\n }\n\n const keyset = new TimeIdKeyset(ref('createdAt'), ref('id'))\n const paginatedBuilder = paginate(qb, {\n limit,\n cursor,\n keyset,\n direction: 'asc',\n tryIndex: true,\n })\n\n const queues = await paginatedBuilder.execute()\n\n return {\n queues,\n cursor: keyset.packFromResult(queues),\n }\n }\n\n view(queue: Selectable<ReportQueue>): ToolsOzoneQueueDefs.QueueView {\n return {\n id: queue.id,\n name: queue.name,\n subjectTypes: queue.subjectTypes,\n collection: queue.collection ?? undefined,\n reportTypes: queue.reportTypes,\n description: queue.description ?? undefined,\n createdBy: queue.createdBy,\n createdAt: queue.createdAt,\n updatedAt: queue.updatedAt,\n enabled: queue.enabled,\n deletedAt: queue.deletedAt ?? undefined,\n stats: {\n pendingCount: 0,\n actionedCount: 0,\n escalatedCount: 0,\n inboundCount: 0,\n actionRate: 0,\n },\n }\n }\n\n async viewsWithStats(\n queues: Selectable<ReportQueue>[],\n ): Promise<ToolsOzoneQueueDefs.QueueView[]> {\n const statsService = new ReportStatsService(this.db)\n const queueIds = queues.map((q) => q.id)\n const statsMap = await statsService.getLiveStatsForQueues(queueIds)\n\n return queues.map((queue) => {\n const view = this.view(queue)\n view.stats = viewQueueStats(statsMap.get(queue.id))\n return view\n })\n }\n\n /**\n * Re-route a range of existing reports against the current queue config.\n * Used by the manual `tools.ozone.queue.routeReports` endpoint to pick up\n * reports after queues are created or modified. New reports are inserted\n * by the daemon via `insertReportsFromEvents`, not here.\n */\n async assignReportBatch(\n params: { start: number; end: number; limit: number },\n opts?: { includeUnmatched?: boolean; serviceDid?: string },\n ): Promise<{\n processed: number\n assigned: number\n unmatched: number\n maxId: number\n }> {\n const { queues } = await this.list({ limit: 1000, enabled: true })\n\n if (!queues.length) {\n return { processed: 0, assigned: 0, unmatched: 0, maxId: 0 }\n }\n\n let query = this.db.db\n .selectFrom('report as r')\n .select([\n 'r.id',\n 'r.status',\n 'r.reportType',\n 'r.recordPath',\n 'r.subjectMessageId',\n ])\n .where('r.status', '!=', 'closed')\n .where('r.id', '>=', params.start)\n .where('r.id', '<=', params.end)\n .orderBy('r.id', 'asc')\n .limit(params.limit)\n\n if (opts?.includeUnmatched) {\n query = query.where((qb) => {\n return qb.orWhere('r.queueId', 'is', null).orWhere('r.queueId', '=', -1)\n })\n } else {\n query = query.where('r.queueId', 'is', null)\n }\n\n const reports = await query.execute()\n\n if (!reports.length) {\n return { processed: 0, assigned: 0, unmatched: 0, maxId: 0 }\n }\n\n const now = new Date().toISOString()\n\n // Resolve each report's destination in memory — no DB calls in this loop\n type MatchedEntry = {\n id: number\n queueId: number\n nextStatus: string | null\n activity: { activityType: string; previousStatus: string } | null\n }\n\n const matchedByQueue = new Map<number, MatchedEntry[]>()\n const unmatchedIds: number[] = []\n let maxReportId = 0\n\n for (const report of reports) {\n const subjectType: SubjectType = report.subjectMessageId\n ? 'message'\n : report.recordPath\n ? 'record'\n : 'account'\n\n // recordPath is 'collection/rkey' for records, '' for accounts\n const slashIdx = report.recordPath.indexOf('/')\n const collection =\n slashIdx > 0 ? report.recordPath.slice(0, slashIdx) : null\n\n const assignment = resolveAssignment(\n subjectType,\n collection,\n report.reportType,\n queues,\n now,\n )\n\n if (assignment.queueId !== -1) {\n // Existing-row UPDATE path uses handleReportUpdate so that already\n // escalated/closed/etc. reports keep their status — only open → queued\n // transitions emit a status change and an activity row.\n const result = handleReportUpdate(report.status, { type: 'queue' })\n const group = matchedByQueue.get(assignment.queueId) ?? []\n group.push({\n id: report.id,\n queueId: assignment.queueId,\n nextStatus: result.nextStatus,\n activity: result.activity,\n })\n matchedByQueue.set(assignment.queueId, group)\n } else {\n unmatchedIds.push(report.id)\n }\n\n if (report.id > maxReportId) maxReportId = report.id\n }\n\n // Bulk UPDATE matched reports — split by whether status should change.\n // handleReportUpdate returns nextStatus only for open → queued;\n // other statuses keep their current status but still get routed.\n for (const [queueId, group] of matchedByQueue) {\n const withTransition = group\n .filter((r) => r.nextStatus !== null)\n .map((r) => r.id)\n const withoutTransition = group\n .filter((r) => r.nextStatus === null)\n .map((r) => r.id)\n\n if (withTransition.length) {\n await this.db.db\n .updateTable('report')\n .set({ queueId, queuedAt: now, status: 'queued', updatedAt: now })\n .where('id', 'in', withTransition)\n .execute()\n }\n if (withoutTransition.length) {\n await this.db.db\n .updateTable('report')\n .set({ queueId, queuedAt: now, updatedAt: now })\n .where('id', 'in', withoutTransition)\n .execute()\n }\n }\n\n // Bulk UPDATE unmatched reports — status stays unchanged\n if (unmatchedIds.length) {\n await this.db.db\n .updateTable('report')\n .set({ queueId: -1, queuedAt: null, updatedAt: now })\n .where('id', 'in', unmatchedIds)\n .execute()\n }\n\n // Bulk INSERT activities for matched reports that changed status.\n if (opts?.serviceDid) {\n const withActivities = [...matchedByQueue.values()]\n .flat()\n .filter((r) => r.activity !== null)\n if (withActivities.length) {\n await this.db.db\n .insertInto('report_activity')\n .values(\n withActivities.map((r) => ({\n reportId: r.id,\n activityType: r.activity!.activityType,\n previousStatus: r.activity!.previousStatus,\n internalNote: null,\n publicNote: null,\n meta: null,\n isAutomated: true,\n createdBy: opts.serviceDid!,\n createdAt: now,\n })),\n )\n .execute()\n }\n }\n\n const assigned = [...matchedByQueue.values()].reduce(\n (sum, g) => sum + g.length,\n 0,\n )\n\n return {\n processed: reports.length,\n assigned,\n unmatched: unmatchedIds.length,\n maxId: maxReportId,\n }\n }\n\n /**\n * Read newly-created modEventReport rows from `moderation_event` and\n * insert corresponding `report` rows with `queueId` already resolved.\n * Used by the queue-router daemon. Idempotent via `ON CONFLICT (eventId)\n * DO NOTHING` — safe to re-run on the same range.\n *\n * Even when no queues are configured, report rows are still inserted with\n * `queueId = -1` so the invariant \"every modEventReport has a `report` row\"\n * holds.\n */\n async insertReportsFromEvents(params: {\n cursor: number | null\n limit: number\n }): Promise<{\n processed: number\n assigned: number\n unmatched: number\n maxEventId: number\n }> {\n const { queues } = await this.list({ limit: 1000, enabled: true })\n\n let query = this.db.db\n .selectFrom('moderation_event')\n .select([\n 'id',\n 'subjectDid',\n 'subjectUri',\n 'subjectMessageId',\n 'subjectConvoId',\n 'meta',\n 'createdAt',\n ])\n .where('action', '=', MOD_EVENT_REPORT_ACTION)\n .orderBy('id', 'asc')\n .limit(params.limit)\n\n if (params.cursor !== null) {\n query = query.where('id', '>', params.cursor)\n }\n\n const events = await query.execute()\n\n if (!events.length) {\n return { processed: 0, assigned: 0, unmatched: 0, maxEventId: 0 }\n }\n\n const now = new Date().toISOString()\n let maxEventId = 0\n let assigned = 0\n let unmatched = 0\n\n const rows = events.map((event) => {\n const subjectType: SubjectType = event.subjectMessageId\n ? 'message'\n : event.subjectConvoId\n ? 'conversation'\n : event.subjectUri\n ? 'record'\n : 'account'\n\n let collection: string | null = null\n let recordPath = ''\n if (event.subjectUri) {\n const uri = new AtUri(event.subjectUri)\n collection = uri.collection\n recordPath = `${uri.collection}/${uri.rkey}`\n }\n\n const reportType =\n (event.meta?.reportType as string | undefined) ?? REASON_OTHER\n\n const assignment = resolveAssignment(\n subjectType,\n collection,\n reportType,\n queues,\n now,\n )\n\n if (assignment.queueId === -1) unmatched++\n else assigned++\n if (event.id > maxEventId) maxEventId = event.id\n\n const isMuted =\n !!event.meta?.isReporterMuted || !!event.meta?.isSubjectMuted\n\n return {\n eventId: event.id,\n queueId: assignment.queueId,\n queuedAt: assignment.queuedAt,\n actionEventIds: null,\n actionNote: null,\n isMuted,\n status: assignment.status,\n reportType,\n did: event.subjectDid,\n recordPath,\n subjectMessageId: event.subjectMessageId,\n subjectConvoId: event.subjectConvoId,\n createdAt: now,\n updatedAt: now,\n }\n })\n\n // ON CONFLICT (eventId) DO NOTHING covers any race where a report row\n // already exists for the event (e.g. transitional code paths or retries\n // after a crash mid-batch).\n await this.db.db\n .insertInto('report')\n .values(rows)\n .onConflict((oc) => oc.column('eventId').doNothing())\n .execute()\n\n // Activity rows are intentionally not emitted: a freshly-inserted report\n // has no prior state to \"transition\" from. Activity rows record state\n // changes, and being born already-queued is not a state change. This\n // matches `handleReportUpdate`'s design where activity is only emitted\n // on real transitions.\n\n return {\n processed: events.length,\n assigned,\n unmatched,\n maxEventId,\n }\n }\n}\n\nexport function findMatchingQueue(\n queues: Selectable<ReportQueue>[],\n subjectType: string,\n collection: string | null,\n reportType: string | undefined,\n): Selectable<ReportQueue> | null {\n if (!reportType) return null\n\n for (const queue of queues) {\n const subjectTypeMatch = queue.subjectTypes.includes(subjectType)\n const collectionMatch =\n subjectType === 'record' && queue.collection !== null\n ? (collection ?? null) === queue.collection\n : true\n const reportTypeMatch = queue.reportTypes.includes(reportType)\n\n if (subjectTypeMatch && collectionMatch && reportTypeMatch) {\n return queue\n }\n }\n\n return null\n}\n"]}
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/queue/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Selectable, sql } from 'kysely'\nimport { ToolsOzoneQueueDefs } from '@atproto/api'\nimport { AtUri } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { Database } from '../db/index.js'\nimport { TimeIdKeyset, paginate } from '../db/pagination.js'\nimport { ReportQueue } from '../db/schema/report_queue.js'\nimport { jsonb } from '../db/types.js'\nimport { handleReportUpdate } from '../report/handle-report-update.js'\nimport { ReportStatsService } from '../report/stats.js'\nimport { viewQueueStats } from '../report/views.js'\n\nconst MOD_EVENT_REPORT_ACTION = 'tools.ozone.moderation.defs#modEventReport'\nconst REASON_OTHER = 'com.atproto.moderation.defs#reasonOther'\n\ntype SubjectType = 'account' | 'record' | 'message' | 'conversation'\n\ntype ResolvedAssignment = {\n queueId: number\n queuedAt: string | null\n status: 'queued' | 'open'\n}\n\nfunction resolveAssignment(\n subjectType: SubjectType,\n collection: string | null,\n reportType: string,\n queues: Selectable<ReportQueue>[],\n now: string,\n): ResolvedAssignment {\n const matched = findMatchingQueue(queues, subjectType, collection, reportType)\n if (matched) return { queueId: matched.id, queuedAt: now, status: 'queued' }\n return { queueId: -1, queuedAt: null, status: 'open' }\n}\n\nexport type QueueServiceCreator = (db: Database) => QueueService\n\nexport class QueueService {\n constructor(public db: Database) {}\n\n static creator() {\n return (db: Database) => new QueueService(db)\n }\n\n async checkConflict({\n subjectTypes,\n collection,\n reportTypes,\n excludeId,\n }: {\n subjectTypes: string[]\n collection?: string | null\n reportTypes: string[]\n excludeId?: number\n }): Promise<void> {\n // It's not ideal to load all rows and perform in memory checks in case we end up with a LOT of queues\n // but we are not foreseeing a lot of queue rows so this should be fine for the\n let qb = this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('deletedAt', 'is', null)\n\n if (excludeId !== undefined) {\n qb = qb.where('id', '!=', excludeId)\n }\n\n const existingQueues = await qb.execute()\n\n for (const existing of existingQueues) {\n const subjectTypesOverlap = subjectTypes.some((st) =>\n existing.subjectTypes.includes(st),\n )\n const collectionMatch = (collection ?? null) === existing.collection\n const reportTypesOverlap = reportTypes.some((rt) =>\n existing.reportTypes.includes(rt),\n )\n\n if (subjectTypesOverlap && collectionMatch && reportTypesOverlap) {\n throw new InvalidRequestError(\n `Queue configuration conflicts with existing queue: ${existing.name}`,\n 'ConflictingQueue',\n )\n }\n }\n }\n\n async create({\n name,\n subjectTypes,\n collection,\n reportTypes,\n description,\n createdBy,\n }: {\n name: string\n subjectTypes: string[]\n collection?: string | null\n reportTypes: string[]\n description?: string | null\n createdBy: string\n }): Promise<Selectable<ReportQueue>> {\n const now = new Date().toISOString()\n return await this.db.db\n .insertInto('report_queue')\n .values({\n name,\n subjectTypes: jsonb(subjectTypes),\n collection: collection ?? null,\n reportTypes: jsonb(reportTypes),\n description: description ?? null,\n createdBy,\n enabled: true,\n createdAt: now,\n updatedAt: now,\n })\n .returningAll()\n .executeTakeFirstOrThrow()\n }\n\n async getById(id: number): Promise<Selectable<ReportQueue> | undefined> {\n return await this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('id', '=', id)\n .where('deletedAt', 'is', null)\n .executeTakeFirst()\n }\n\n async getViewsByIds(\n ids: number[],\n ): Promise<Map<number, ToolsOzoneQueueDefs.QueueView>> {\n if (!ids.length) return new Map()\n const rows = await this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('id', 'in', ids)\n .execute()\n return new Map(rows.map((r) => [r.id, this.view(r)]))\n }\n\n async update(\n id: number,\n updates: { name?: string; enabled?: boolean; description?: string },\n ): Promise<Selectable<ReportQueue>> {\n const now = new Date().toISOString()\n return await this.db.db\n .updateTable('report_queue')\n .set({ ...updates, updatedAt: now })\n .where('id', '=', id)\n .returningAll()\n .executeTakeFirstOrThrow()\n }\n\n async delete(id: number): Promise<void> {\n const now = new Date().toISOString()\n await this.db.db\n .updateTable('report_queue')\n .set({ deletedAt: now })\n .where('id', '=', id)\n .execute()\n }\n\n async migrateReports(\n fromQueueId: number,\n toQueueId?: number,\n ): Promise<number> {\n const now = new Date().toISOString()\n const results = await this.db.db\n .updateTable('report')\n .set({\n queueId: toQueueId ?? -1,\n queuedAt: toQueueId ? now : null,\n updatedAt: now,\n })\n .where('queueId', '=', fromQueueId)\n .where('status', '!=', 'closed')\n .execute()\n return results.reduce((sum, r) => sum + Number(r.numUpdatedRows), 0)\n }\n\n async list({\n limit,\n cursor,\n enabled,\n subjectType,\n collection,\n reportTypes,\n }: {\n limit: number\n cursor?: string\n enabled?: boolean\n subjectType?: string\n collection?: string\n reportTypes?: string[]\n }): Promise<{ queues: Selectable<ReportQueue>[]; cursor?: string }> {\n const { ref } = this.db.db.dynamic\n let qb = this.db.db\n .selectFrom('report_queue')\n .selectAll()\n .where('deletedAt', 'is', null)\n\n if (enabled !== undefined) {\n qb = qb.where('enabled', '=', enabled)\n }\n\n if (subjectType !== undefined) {\n qb = qb.where(sql`\"subjectTypes\" @> ${jsonb([subjectType])}`)\n }\n\n if (collection !== undefined) {\n qb = qb.where('collection', '=', collection)\n }\n\n if (reportTypes && reportTypes.length > 0) {\n const conditions = reportTypes.map(\n (t) => sql`\"reportTypes\" @> ${jsonb([t])}`,\n )\n qb = qb.where(sql`(${sql.join(conditions, sql` OR `)})`)\n }\n\n const keyset = new TimeIdKeyset(ref('createdAt'), ref('id'))\n const paginatedBuilder = paginate(qb, {\n limit,\n cursor,\n keyset,\n direction: 'asc',\n tryIndex: true,\n })\n\n const queues = await paginatedBuilder.execute()\n\n return {\n queues,\n cursor: keyset.packFromResult(queues),\n }\n }\n\n view(queue: Selectable<ReportQueue>): ToolsOzoneQueueDefs.QueueView {\n return {\n id: queue.id,\n name: queue.name,\n subjectTypes: queue.subjectTypes,\n collection: queue.collection ?? undefined,\n reportTypes: queue.reportTypes,\n description: queue.description ?? undefined,\n createdBy: queue.createdBy,\n createdAt: queue.createdAt,\n updatedAt: queue.updatedAt,\n enabled: queue.enabled,\n deletedAt: queue.deletedAt ?? undefined,\n stats: {\n pendingCount: 0,\n actionedCount: 0,\n escalatedCount: 0,\n inboundCount: 0,\n actionRate: 0,\n },\n }\n }\n\n async viewsWithStats(\n queues: Selectable<ReportQueue>[],\n ): Promise<ToolsOzoneQueueDefs.QueueView[]> {\n const statsService = new ReportStatsService(this.db)\n const queueIds = queues.map((q) => q.id)\n const statsMap = await statsService.getLiveStatsForQueues(queueIds)\n\n return queues.map((queue) => {\n const view = this.view(queue)\n view.stats = viewQueueStats(statsMap.get(queue.id))\n return view\n })\n }\n\n /**\n * Re-route a range of existing reports against the current queue config.\n * Used by the manual `tools.ozone.queue.routeReports` endpoint to pick up\n * reports after queues are created or modified. New reports are inserted\n * by the daemon via `insertReportsFromEvents`, not here.\n */\n async assignReportBatch(\n params: { start: number; end: number; limit: number },\n opts?: { includeUnmatched?: boolean; serviceDid?: string },\n ): Promise<{\n processed: number\n assigned: number\n unmatched: number\n maxId: number\n }> {\n const { queues } = await this.list({ limit: 1000, enabled: true })\n\n if (!queues.length) {\n return { processed: 0, assigned: 0, unmatched: 0, maxId: 0 }\n }\n\n let query = this.db.db\n .selectFrom('report as r')\n .select([\n 'r.id',\n 'r.status',\n 'r.reportType',\n 'r.recordPath',\n 'r.subjectMessageId',\n ])\n .where('r.status', '!=', 'closed')\n .where('r.id', '>=', params.start)\n .where('r.id', '<=', params.end)\n .orderBy('r.id', 'asc')\n .limit(params.limit)\n\n if (opts?.includeUnmatched) {\n query = query.where((qb) => {\n return qb.orWhere('r.queueId', 'is', null).orWhere('r.queueId', '=', -1)\n })\n } else {\n query = query.where('r.queueId', 'is', null)\n }\n\n const reports = await query.execute()\n\n if (!reports.length) {\n return { processed: 0, assigned: 0, unmatched: 0, maxId: 0 }\n }\n\n const now = new Date().toISOString()\n\n // Resolve each report's destination in memory — no DB calls in this loop\n type MatchedEntry = {\n id: number\n queueId: number\n nextStatus: string | null\n activity: { activityType: string; previousStatus: string } | null\n }\n\n const matchedByQueue = new Map<number, MatchedEntry[]>()\n const unmatchedIds: number[] = []\n let maxReportId = 0\n\n for (const report of reports) {\n const subjectType: SubjectType = report.subjectMessageId\n ? 'message'\n : report.recordPath\n ? 'record'\n : 'account'\n\n // recordPath is 'collection/rkey' for records, '' for accounts\n const slashIdx = report.recordPath.indexOf('/')\n const collection =\n slashIdx > 0 ? report.recordPath.slice(0, slashIdx) : null\n\n const assignment = resolveAssignment(\n subjectType,\n collection,\n report.reportType,\n queues,\n now,\n )\n\n if (assignment.queueId !== -1) {\n // Existing-row UPDATE path uses handleReportUpdate so that already\n // escalated/closed/etc. reports keep their status — only open → queued\n // transitions emit a status change and an activity row.\n const result = handleReportUpdate(report.status, { type: 'queue' })\n const group = matchedByQueue.get(assignment.queueId) ?? []\n group.push({\n id: report.id,\n queueId: assignment.queueId,\n nextStatus: result.nextStatus,\n activity: result.activity,\n })\n matchedByQueue.set(assignment.queueId, group)\n } else {\n unmatchedIds.push(report.id)\n }\n\n if (report.id > maxReportId) maxReportId = report.id\n }\n\n // Bulk UPDATE matched reports — split by whether status should change.\n // handleReportUpdate returns nextStatus only for open → queued;\n // other statuses keep their current status but still get routed.\n for (const [queueId, group] of matchedByQueue) {\n const withTransition = group\n .filter((r) => r.nextStatus !== null)\n .map((r) => r.id)\n const withoutTransition = group\n .filter((r) => r.nextStatus === null)\n .map((r) => r.id)\n\n if (withTransition.length) {\n await this.db.db\n .updateTable('report')\n .set({ queueId, queuedAt: now, status: 'queued', updatedAt: now })\n .where('id', 'in', withTransition)\n .execute()\n }\n if (withoutTransition.length) {\n await this.db.db\n .updateTable('report')\n .set({ queueId, queuedAt: now, updatedAt: now })\n .where('id', 'in', withoutTransition)\n .execute()\n }\n }\n\n // Bulk UPDATE unmatched reports — status stays unchanged\n if (unmatchedIds.length) {\n await this.db.db\n .updateTable('report')\n .set({ queueId: -1, queuedAt: null, updatedAt: now })\n .where('id', 'in', unmatchedIds)\n .execute()\n }\n\n // Bulk INSERT activities for matched reports that changed status.\n if (opts?.serviceDid) {\n const withActivities = [...matchedByQueue.values()]\n .flat()\n .filter((r) => r.activity !== null)\n if (withActivities.length) {\n await this.db.db\n .insertInto('report_activity')\n .values(\n withActivities.map((r) => ({\n reportId: r.id,\n activityType: r.activity!.activityType,\n previousStatus: r.activity!.previousStatus,\n internalNote: null,\n publicNote: null,\n meta: null,\n isAutomated: true,\n createdBy: opts.serviceDid!,\n createdAt: now,\n })),\n )\n .execute()\n }\n }\n\n const assigned = [...matchedByQueue.values()].reduce(\n (sum, g) => sum + g.length,\n 0,\n )\n\n return {\n processed: reports.length,\n assigned,\n unmatched: unmatchedIds.length,\n maxId: maxReportId,\n }\n }\n\n /**\n * Read newly-created modEventReport rows from `moderation_event` and\n * insert corresponding `report` rows with `queueId` already resolved.\n * Used by the queue-router daemon. Idempotent via `ON CONFLICT (eventId)\n * DO NOTHING` — safe to re-run on the same range.\n *\n * Even when no queues are configured, report rows are still inserted with\n * `queueId = -1` so the invariant \"every modEventReport has a `report` row\"\n * holds.\n */\n async insertReportsFromEvents(params: {\n cursor: number | null\n limit: number\n }): Promise<{\n processed: number\n assigned: number\n unmatched: number\n maxEventId: number\n }> {\n const { queues } = await this.list({ limit: 1000, enabled: true })\n\n let query = this.db.db\n .selectFrom('moderation_event')\n .select([\n 'id',\n 'subjectDid',\n 'subjectUri',\n 'subjectMessageId',\n 'subjectConvoId',\n 'meta',\n 'createdAt',\n ])\n .where('action', '=', MOD_EVENT_REPORT_ACTION)\n .orderBy('id', 'asc')\n .limit(params.limit)\n\n if (params.cursor !== null) {\n query = query.where('id', '>', params.cursor)\n }\n\n const events = await query.execute()\n\n if (!events.length) {\n return { processed: 0, assigned: 0, unmatched: 0, maxEventId: 0 }\n }\n\n const now = new Date().toISOString()\n let maxEventId = 0\n let assigned = 0\n let unmatched = 0\n\n const rows = events.map((event) => {\n const subjectType: SubjectType = event.subjectMessageId\n ? 'message'\n : event.subjectConvoId\n ? 'conversation'\n : event.subjectUri\n ? 'record'\n : 'account'\n\n let collection: string | null = null\n let recordPath = ''\n if (event.subjectUri) {\n const uri = new AtUri(event.subjectUri)\n collection = uri.collection\n recordPath = `${uri.collection}/${uri.rkey}`\n }\n\n const reportType =\n (event.meta?.reportType as string | undefined) ?? REASON_OTHER\n\n const assignment = resolveAssignment(\n subjectType,\n collection,\n reportType,\n queues,\n now,\n )\n\n if (assignment.queueId === -1) unmatched++\n else assigned++\n if (event.id > maxEventId) maxEventId = event.id\n\n const isMuted =\n !!event.meta?.isReporterMuted || !!event.meta?.isSubjectMuted\n\n return {\n eventId: event.id,\n queueId: assignment.queueId,\n queuedAt: assignment.queuedAt,\n actionEventIds: null,\n actionNote: null,\n isMuted,\n status: assignment.status,\n reportType,\n did: event.subjectDid,\n recordPath,\n subjectMessageId: event.subjectMessageId,\n subjectConvoId: event.subjectConvoId,\n createdAt: now,\n updatedAt: now,\n }\n })\n\n // ON CONFLICT (eventId) DO NOTHING covers any race where a report row\n // already exists for the event (e.g. transitional code paths or retries\n // after a crash mid-batch).\n await this.db.db\n .insertInto('report')\n .values(rows)\n .onConflict((oc) => oc.column('eventId').doNothing())\n .execute()\n\n // Activity rows are intentionally not emitted: a freshly-inserted report\n // has no prior state to \"transition\" from. Activity rows record state\n // changes, and being born already-queued is not a state change. This\n // matches `handleReportUpdate`'s design where activity is only emitted\n // on real transitions.\n\n return {\n processed: events.length,\n assigned,\n unmatched,\n maxEventId,\n }\n }\n}\n\nexport function findMatchingQueue(\n queues: Selectable<ReportQueue>[],\n subjectType: string,\n collection: string | null,\n reportType: string | undefined,\n): Selectable<ReportQueue> | null {\n if (!reportType) return null\n\n for (const queue of queues) {\n const subjectTypeMatch = queue.subjectTypes.includes(subjectType)\n const collectionMatch =\n subjectType === 'record' && queue.collection !== null\n ? (collection ?? null) === queue.collection\n : true\n const reportTypeMatch = queue.reportTypes.includes(reportType)\n\n if (subjectTypeMatch && collectionMatch && reportTypeMatch) {\n return queue\n }\n }\n\n return null\n}\n"]}
|
|
@@ -35,16 +35,16 @@ export type ListActivitiesParams = {
|
|
|
35
35
|
};
|
|
36
36
|
export declare function listReportActivities(db: Database, params: ListActivitiesParams): Promise<{
|
|
37
37
|
activities: {
|
|
38
|
-
|
|
39
|
-
meta: unknown;
|
|
38
|
+
activityType: string;
|
|
40
39
|
createdAt: string;
|
|
41
40
|
createdBy: string;
|
|
42
|
-
|
|
41
|
+
id: number;
|
|
43
42
|
internalNote: string | null;
|
|
44
|
-
publicNote: string | null;
|
|
45
43
|
isAutomated: boolean;
|
|
44
|
+
meta: unknown;
|
|
46
45
|
previousStatus: string | null;
|
|
47
|
-
|
|
46
|
+
publicNote: string | null;
|
|
47
|
+
reportId: number;
|
|
48
48
|
}[];
|
|
49
49
|
cursor: string | undefined;
|
|
50
50
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../src/report/activity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAOlE,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,oBAAoB,GACpB,oBAAoB,GACpB,eAAe,GACf,gBAAgB,GAChB,cAAc,CAAA;AAElB,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,kFAAkF;IAClF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,oBAAoB,kGAkF7B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,kBAAkB,EAAE,iBAmBjC;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,oBAAoB;;;;;;;;;;;;;;GA6B7B;AAaD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE;IACR,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,OAAO,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,EACD,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC
|
|
1
|
+
{"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../src/report/activity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAOlE,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,oBAAoB,GACpB,oBAAoB,GACpB,eAAe,GACf,gBAAgB,GAChB,cAAc,CAAA;AAElB,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,kFAAkF;IAClF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,oBAAoB,kGAkF7B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,kBAAkB,EAAE,iBAmBjC;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,oBAAoB;;;;;;;;;;;;;;GA6B7B;AAaD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE;IACR,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,OAAO,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,EACD,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAG/B,EAAE;IACF,QAAQ;IACR,QAAQ;;eA1BA,MAAM;;IA8Bd,YAAY;IACZ,UAAU;IACV,IAAI;IACJ,WAAW;IACX,SAAS;IACT,SAAS;IACT,SAAS;EAEZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-report-update.d.ts","sourceRoot":"","sources":["../../src/report/handle-report-update.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,qBAAa,oBAAqB,SAAQ,KAAK;IAEpC,aAAa,EAAE,MAAM;IACrB,YAAY,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"handle-report-update.d.ts","sourceRoot":"","sources":["../../src/report/handle-report-update.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,qBAAa,oBAAqB,SAAQ,KAAK;IAEpC,aAAa,EAAE,MAAM;IACrB,YAAY,EAAE,MAAM;IAF7B,YACS,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EAI5B;CACF;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAEtC,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,MAAM;IAFzB,YACS,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAIxB;CACF;AAMD,yEAAyE;AACzE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAMtD,CAAA;AA6CD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAMrB,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAA;CAChC,CAAA;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,kBAAkB,GACzB,kBAAkB,CASpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-report-update.js","sourceRoot":"","sources":["../../src/report/handle-report-update.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, synchronous state-transition logic for reports.\n *\n * Every code path that changes a report's status or creates a report activity\n * should call `handleReportUpdate` to determine the next status and the\n * activity record to insert. This keeps the state machine in one place and\n * decouples it from DB operations so it works for both single-row transactions\n * and bulk updates.\n */\n\n// ---------------------------------------------------------------------------\n// Error types — callers decide how to surface these (throw, skip, etc.)\n// ---------------------------------------------------------------------------\n\nexport class AlreadyInTargetState extends Error {\n constructor(\n public currentStatus: string,\n public targetStatus: string,\n ) {\n super(`Report is already in '${targetStatus}' status`)\n this.name = 'AlreadyInTargetState'\n }\n}\n\nexport class InvalidStateTransition extends Error {\n constructor(\n public fromStatus: string,\n public toStatus: string,\n ) {\n super(`Cannot transition report from '${fromStatus}' to '${toStatus}'`)\n this.name = 'InvalidStateTransition'\n }\n}\n\n// ---------------------------------------------------------------------------\n// State machine tables\n// ---------------------------------------------------------------------------\n\n/** Valid state transitions: key = fromState, value = allowed toStates */\nexport const VALID_TRANSITIONS: Record<string, string[]> = {\n open: ['closed', 'escalated', 'queued', 'assigned'],\n closed: ['open'],\n escalated: ['open', 'closed'],\n queued: ['assigned', 'open'],\n assigned: ['open', 'closed', 'escalated', 'queued'],\n}\n\n/** Activity types that map to a specific target status */\nconst ACTIVITY_TO_STATE: Record<string, string> = {\n queueActivity: 'queued',\n assignmentActivity: 'assigned',\n escalationActivity: 'escalated',\n closeActivity: 'closed',\n reopenActivity: 'open',\n}\n\n/** Activity types that are only valid from specific source states */\nconst ACTIVITY_VALID_FROM_STATES: Record<string, string[]> = {\n reopenActivity: ['closed'],\n}\n\n/** Moderation event types → target status (+ activity type) */\nconst EVENT_TYPE_MAP: Record<string, { status: string; activityType: string }> =\n {\n 'tools.ozone.moderation.defs#modEventAcknowledge': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventTakedown': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventLabel': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventComment': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventEscalate': {\n status: 'escalated',\n activityType: 'escalationActivity',\n },\n }\n\n// ---------------------------------------------------------------------------\n// Action types — the three ways a report's status can change\n// ---------------------------------------------------------------------------\n\nexport type ReportUpdateAction =\n | { type: 'activity'; activityType: string }\n | { type: 'event'; eventType: string }\n | { type: 'queue' }\n\n// ---------------------------------------------------------------------------\n// Result type\n// ---------------------------------------------------------------------------\n\nexport type ActivityRecord = {\n activityType: string\n previousStatus: string\n}\n\nexport type ReportUpdateResult = {\n nextStatus: string | null\n activity: ActivityRecord | null\n}\n\n// ---------------------------------------------------------------------------\n// Core function\n// ---------------------------------------------------------------------------\n\n/**\n * Determines the next status and activity record for a report update.\n *\n * @throws AlreadyInTargetState if the report is already in the target status\n * @throws InvalidStateTransition if the transition is not allowed\n * @returns nextStatus (null = no change) and activity (null = nothing to record)\n */\nexport function handleReportUpdate(\n currentStatus: string,\n action: ReportUpdateAction,\n): ReportUpdateResult {\n switch (action.type) {\n case 'activity':\n return handleActivityAction(currentStatus, action.activityType)\n case 'event':\n return handleEventAction(currentStatus, action.eventType)\n case 'queue':\n return handleQueueAction(currentStatus)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Action handlers\n// ---------------------------------------------------------------------------\n\nfunction handleActivityAction(\n currentStatus: string,\n activityType: string,\n): ReportUpdateResult {\n const toState = ACTIVITY_TO_STATE[activityType] ?? null\n\n // Note-type activities — no state change, but still produce an activity record\n if (toState === null) {\n return { nextStatus: null, activity: null }\n }\n\n // Check activity-specific source-state constraints\n const validFromStates = ACTIVITY_VALID_FROM_STATES[activityType]\n if (validFromStates && !validFromStates.includes(currentStatus)) {\n throw new InvalidStateTransition(currentStatus, toState)\n }\n\n validateTransition(currentStatus, toState)\n\n return {\n nextStatus: toState,\n activity: { activityType, previousStatus: currentStatus },\n }\n}\n\nfunction handleEventAction(\n currentStatus: string,\n eventType: string,\n): ReportUpdateResult {\n const mapping = EVENT_TYPE_MAP[eventType]\n if (!mapping) {\n // Event type doesn't affect report status\n return { nextStatus: null, activity: null }\n }\n\n validateTransition(currentStatus, mapping.status)\n\n return {\n nextStatus: mapping.status,\n activity: {\n activityType: mapping.activityType,\n previousStatus: currentStatus,\n },\n }\n}\n\nfunction handleQueueAction(currentStatus: string): ReportUpdateResult {\n // Queue routing only transitions open → queued\n if (currentStatus !== 'open') {\n return { nextStatus: null, activity: null }\n }\n\n return {\n nextStatus: 'queued',\n activity: { activityType: 'queueActivity', previousStatus: currentStatus },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Shared validation\n// ---------------------------------------------------------------------------\n\nfunction validateTransition(fromStatus: string, toStatus: string): void {\n if (fromStatus === toStatus) {\n throw new AlreadyInTargetState(fromStatus, toStatus)\n }\n const allowed = VALID_TRANSITIONS[fromStatus] ?? []\n if (!allowed.includes(toStatus)) {\n throw new InvalidStateTransition(fromStatus, toStatus)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"handle-report-update.js","sourceRoot":"","sources":["../../src/report/handle-report-update.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, synchronous state-transition logic for reports.\n *\n * Every code path that changes a report's status or creates a report activity\n * should call `handleReportUpdate` to determine the next status and the\n * activity record to insert. This keeps the state machine in one place and\n * decouples it from DB operations so it works for both single-row transactions\n * and bulk updates.\n */\n\n// ---------------------------------------------------------------------------\n// Error types — callers decide how to surface these (throw, skip, etc.)\n// ---------------------------------------------------------------------------\n\nexport class AlreadyInTargetState extends Error {\n constructor(\n public currentStatus: string,\n public targetStatus: string,\n ) {\n super(`Report is already in '${targetStatus}' status`)\n this.name = 'AlreadyInTargetState'\n }\n}\n\nexport class InvalidStateTransition extends Error {\n constructor(\n public fromStatus: string,\n public toStatus: string,\n ) {\n super(`Cannot transition report from '${fromStatus}' to '${toStatus}'`)\n this.name = 'InvalidStateTransition'\n }\n}\n\n// ---------------------------------------------------------------------------\n// State machine tables\n// ---------------------------------------------------------------------------\n\n/** Valid state transitions: key = fromState, value = allowed toStates */\nexport const VALID_TRANSITIONS: Record<string, string[]> = {\n open: ['closed', 'escalated', 'queued', 'assigned'],\n closed: ['open'],\n escalated: ['open', 'closed'],\n queued: ['assigned', 'open'],\n assigned: ['open', 'closed', 'escalated', 'queued'],\n}\n\n/** Activity types that map to a specific target status */\nconst ACTIVITY_TO_STATE: Record<string, string> = {\n queueActivity: 'queued',\n assignmentActivity: 'assigned',\n escalationActivity: 'escalated',\n closeActivity: 'closed',\n reopenActivity: 'open',\n}\n\n/** Activity types that are only valid from specific source states */\nconst ACTIVITY_VALID_FROM_STATES: Record<string, string[]> = {\n reopenActivity: ['closed'],\n}\n\n/** Moderation event types → target status (+ activity type) */\nconst EVENT_TYPE_MAP: Record<string, { status: string; activityType: string }> =\n {\n 'tools.ozone.moderation.defs#modEventAcknowledge': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventTakedown': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventLabel': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventComment': {\n status: 'closed',\n activityType: 'closeActivity',\n },\n 'tools.ozone.moderation.defs#modEventEscalate': {\n status: 'escalated',\n activityType: 'escalationActivity',\n },\n }\n\n// ---------------------------------------------------------------------------\n// Action types — the three ways a report's status can change\n// ---------------------------------------------------------------------------\n\nexport type ReportUpdateAction =\n | { type: 'activity'; activityType: string }\n | { type: 'event'; eventType: string }\n | { type: 'queue' }\n\n// ---------------------------------------------------------------------------\n// Result type\n// ---------------------------------------------------------------------------\n\nexport type ActivityRecord = {\n activityType: string\n previousStatus: string\n}\n\nexport type ReportUpdateResult = {\n nextStatus: string | null\n activity: ActivityRecord | null\n}\n\n// ---------------------------------------------------------------------------\n// Core function\n// ---------------------------------------------------------------------------\n\n/**\n * Determines the next status and activity record for a report update.\n *\n * @throws AlreadyInTargetState if the report is already in the target status\n * @throws InvalidStateTransition if the transition is not allowed\n * @returns nextStatus (null = no change) and activity (null = nothing to record)\n */\nexport function handleReportUpdate(\n currentStatus: string,\n action: ReportUpdateAction,\n): ReportUpdateResult {\n switch (action.type) {\n case 'activity':\n return handleActivityAction(currentStatus, action.activityType)\n case 'event':\n return handleEventAction(currentStatus, action.eventType)\n case 'queue':\n return handleQueueAction(currentStatus)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Action handlers\n// ---------------------------------------------------------------------------\n\nfunction handleActivityAction(\n currentStatus: string,\n activityType: string,\n): ReportUpdateResult {\n const toState = ACTIVITY_TO_STATE[activityType] ?? null\n\n // Note-type activities — no state change, but still produce an activity record\n if (toState === null) {\n return { nextStatus: null, activity: null }\n }\n\n // Check activity-specific source-state constraints\n const validFromStates = ACTIVITY_VALID_FROM_STATES[activityType]\n if (validFromStates && !validFromStates.includes(currentStatus)) {\n throw new InvalidStateTransition(currentStatus, toState)\n }\n\n validateTransition(currentStatus, toState)\n\n return {\n nextStatus: toState,\n activity: { activityType, previousStatus: currentStatus },\n }\n}\n\nfunction handleEventAction(\n currentStatus: string,\n eventType: string,\n): ReportUpdateResult {\n const mapping = EVENT_TYPE_MAP[eventType]\n if (!mapping) {\n // Event type doesn't affect report status\n return { nextStatus: null, activity: null }\n }\n\n validateTransition(currentStatus, mapping.status)\n\n return {\n nextStatus: mapping.status,\n activity: {\n activityType: mapping.activityType,\n previousStatus: currentStatus,\n },\n }\n}\n\nfunction handleQueueAction(currentStatus: string): ReportUpdateResult {\n // Queue routing only transitions open → queued\n if (currentStatus !== 'open') {\n return { nextStatus: null, activity: null }\n }\n\n return {\n nextStatus: 'queued',\n activity: { activityType: 'queueActivity', previousStatus: currentStatus },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Shared validation\n// ---------------------------------------------------------------------------\n\nfunction validateTransition(fromStatus: string, toStatus: string): void {\n if (fromStatus === toStatus) {\n throw new AlreadyInTargetState(fromStatus, toStatus)\n }\n const allowed = VALID_TRANSITIONS[fromStatus] ?? []\n if (!allowed.includes(toStatus)) {\n throw new InvalidStateTransition(fromStatus, toStatus)\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/report/stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAO,MAAM,QAAQ,CAAA;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAIxD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAqEvD,CAAA;AAID,MAAM,MAAM,yBAAyB,GAAG,CAAC,EAAE,EAAE,QAAQ,KAAK,kBAAkB,CAAA;AAE5E,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAC7B,CAAA;AACD,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AACD,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AACD,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AACD,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AACD,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,mBAAmB,GACnB,mBAAmB,GACnB,oBAAoB,CAAA;AAwDxB,qBAAa,kBAAkB;IACV,EAAE,EAAE,QAAQ;
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/report/stats.ts"],"names":[],"mappings":"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"}
|