Add structured moderation assessments with revision history
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import {
|
||||
moderationConcernCategories,
|
||||
moderationFindingOutcomes,
|
||||
type ModerationCaseAssessment
|
||||
} from '../../moderation.js';
|
||||
import { AuthError } from '../auth/index.js';
|
||||
import { db } from '../db/index.js';
|
||||
import { textField } from './core.js';
|
||||
|
||||
type AssessmentDraft = Pick<ModerationCaseAssessment, 'summary' | 'rules' | 'findings'>;
|
||||
|
||||
export function assessmentDraft(input: Record<string, unknown>): AssessmentDraft {
|
||||
const summary = textField(input.summary, 'Assessment summary', 2000);
|
||||
if (!Array.isArray(input.rules) || input.rules.length > 20)
|
||||
throw new AuthError('Choose up to 20 applicable rules.');
|
||||
const rules = input.rules.map((rule) => textField(rule, 'Applicable rule', 160));
|
||||
if (
|
||||
!Array.isArray(input.findings) ||
|
||||
!input.findings.length ||
|
||||
input.findings.length > moderationConcernCategories.length
|
||||
)
|
||||
throw new AuthError('Record between 1 and 7 findings, one per concern category.');
|
||||
const categories = new Set<string>();
|
||||
const findings = input.findings.map((value): AssessmentDraft['findings'][number] => {
|
||||
if (!value || typeof value !== 'object')
|
||||
throw new AuthError('Choose a concern category and finding.');
|
||||
const category = moderationConcernCategories.find(
|
||||
(category) => category === value.category
|
||||
);
|
||||
const finding = moderationFindingOutcomes.find((finding) => finding === value.finding);
|
||||
if (!category || !finding)
|
||||
throw new AuthError('Choose a known concern category and finding.');
|
||||
if (categories.has(category))
|
||||
throw new AuthError('Record each concern category only once.');
|
||||
categories.add(category);
|
||||
return { category, finding, detail: textField(value.detail, 'Finding detail', 1000) };
|
||||
});
|
||||
return { summary, rules, findings };
|
||||
}
|
||||
|
||||
export function caseAssessmentHistory(caseId: string): ModerationCaseAssessment[] {
|
||||
return (
|
||||
db()
|
||||
.prepare(
|
||||
`SELECT revision,data,actor,created_at AS createdAt
|
||||
FROM moderation_case_assessments WHERE case_id=? ORDER BY revision DESC`
|
||||
)
|
||||
.all(caseId) as { revision: number; data: string; actor: string; createdAt: string }[]
|
||||
).map(({ data, ...revision }) => ({ ...JSON.parse(data), ...revision }));
|
||||
}
|
||||
|
||||
export function currentCaseAssessment(caseId: string): ModerationCaseAssessment | null {
|
||||
const row = db()
|
||||
.prepare(
|
||||
`SELECT revision,data,actor,created_at AS createdAt
|
||||
FROM moderation_case_assessments WHERE case_id=? ORDER BY revision DESC LIMIT 1`
|
||||
)
|
||||
.get(caseId) as
|
||||
{ revision: number; data: string; actor: string; createdAt: string } | undefined;
|
||||
if (!row) return null;
|
||||
const { data, ...revision } = row;
|
||||
return { ...JSON.parse(data), ...revision };
|
||||
}
|
||||
Reference in New Issue
Block a user