Expand moderation case workflows
CI / checks (push) Successful in 6m49s

This commit is contained in:
2026-10-17 16:19:33 -04:00
parent 4501eba873
commit 7f2205e9c4
22 changed files with 2815 additions and 167 deletions
+33 -4
View File
@@ -3,6 +3,7 @@ import { moderationActor, moderationNow, policyRevision } from './core.js';
import { runtimeFreshMs } from './actions.js';
import { refreshActionStates } from './runtime.js';
import {
moderationCaseStatuses,
moderationGuid,
type ModerationOverview,
type ModerationQuery,
@@ -19,12 +20,21 @@ export function moderationQuery(params: URLSearchParams): ModerationQuery {
const game = params.get('game');
const guid = (params.get('guid') ?? '').slice(0, 128);
const offset = Number(params.get('offset') ?? 0);
const caseStatus = params.get('caseStatus') ?? '';
const priority = params.get('priority') ?? '';
return {
view: view === 'restrictions' || view === 'cases' || view === 'history' ? view : 'players',
q: (params.get('q') ?? '').trim().slice(0, 200),
game: game === 't5' || game === 't6' ? game : '',
guid: game === 't5' || game === 't6' ? moderationGuid(game, guid) : guid,
offset: Number.isSafeInteger(offset) && offset >= 0 ? offset : 0
offset: Number.isSafeInteger(offset) && offset >= 0 ? offset : 0,
caseStatus: ['active', 'closed', ...moderationCaseStatuses].includes(caseStatus)
? (caseStatus as ModerationQuery['caseStatus'])
: '',
priority: ['low', 'normal', 'high', 'urgent'].includes(priority)
? (priority as ModerationQuery['priority'])
: '',
assignedTo: (params.get('assignedTo') ?? '').slice(0, 128)
};
}
export function moderationOverview(actorId: string, query: ModerationQuery): ModerationOverview {
@@ -93,6 +103,25 @@ export function moderationOverview(actorId: string, query: ModerationQuery): Mod
where.push('p.guid=?');
values.push(query.guid);
}
if (query.view === 'cases') {
if (query.caseStatus === 'active' || query.caseStatus === 'closed') {
where.push(
`p.status ${query.caseStatus === 'closed' ? 'NOT ' : ''}IN ('open','in_review','escalated')`
);
} else if (query.caseStatus) {
where.push('p.status=?');
values.push(query.caseStatus);
}
if (query.priority) {
where.push('p.priority=?');
values.push(query.priority);
}
if (query.assignedTo === 'unassigned') where.push('p.assignee_id IS NULL');
else if (query.assignedTo) {
where.push('p.assignee_id=?');
values.push(query.assignedTo === 'me' ? actorId : query.assignedTo);
}
}
if (query.q) {
const extra =
query.view === 'restrictions'
@@ -161,14 +190,14 @@ export function moderationOverview(actorId: string, query: ModerationQuery): Mod
} else if (query.view === 'restrictions') {
result.sanctions = rows<Omit<ModerationSanction, 'active'>>(
'moderation_sanctions',
'p.id,p.game,p.guid,p.kind,p.scope,p.server,p.reason,p.note,p.created_at AS createdAt,p.expires_at AS expiresAt,p.revoked_at AS revokedAt,p.actor_id AS actorId,p.actor,p.revision',
'p.id,p.game,p.guid,p.kind,p.scope,p.server,p.reason,p.note,p.created_at AS createdAt,p.expires_at AS expiresAt,p.revoked_at AS revokedAt,p.actor_id AS actorId,p.actor,p.revision,p.case_id AS caseId',
'p.created_at DESC,p.id'
).map((s) => ({ ...s, active: !s.revokedAt && (!s.expiresAt || s.expiresAt > now) }));
} else if (query.view === 'cases') {
result.cases = rows<Omit<ModerationCase, 'evidence'>>(
'moderation_cases',
'p.id,p.game,p.guid,p.title,p.status,p.actor,p.created_at AS createdAt,p.updated_at AS updatedAt,p.revision',
'p.updated_at DESC,p.id'
'p.id,p.game,p.guid,p.title,p.status,p.priority,p.assignee_id AS assigneeId,(SELECT username FROM auth_users WHERE id=p.assignee_id) AS assignee,p.actor,p.created_at AS createdAt,p.updated_at AS updatedAt,p.revision',
"CASE WHEN p.status IN ('open','in_review','escalated') THEN 0 ELSE 1 END,CASE p.priority WHEN 'urgent' THEN 0 WHEN 'high' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END,p.updated_at DESC,p.id"
).map((c) => ({
...c,
evidence: handle