Files
electric-cherry/src/lib/server/moderation/assessments.ts
T

64 lines
2.8 KiB
TypeScript

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 };
}