Separate moderation case status from decisions
CI / checks (push) Failing after 7m24s

This commit is contained in:
2026-10-17 21:30:43 -04:00
parent 48653af3dc
commit a7f1c65d17
22 changed files with 357 additions and 222 deletions
+5 -7
View File
@@ -11,6 +11,7 @@ import {
canRevokeModerationRestriction,
isModerationCaseOpen,
moderationCaseOutcomes,
moderationCaseStatuses,
moderationCaseStatusLabels,
type ModerationCaseStatus,
type ModerationCasePriority,
@@ -438,13 +439,9 @@ function updateCase(actor: AuthUser, input: Record<string, unknown>, now: string
const status = input.status === undefined ? row.status : input.status;
if (
input.status !== undefined &&
status !== 'open' &&
status !== 'in_review' &&
status !== 'escalated'
!moderationCaseStatuses.includes(status as ModerationCaseStatus)
)
throw new AuthError('Choose an active case status, or close the case with an outcome.');
if (input.status !== undefined && !isModerationCaseOpen(row.status))
throw new AuthError('Use reopen to reactivate a closed case.', 409);
throw new AuthError('Choose Open, In progress, or Closed.');
const reason = textField(input.reason, 'Status change reason', 4000, status === row.status);
const changes: Record<string, unknown> = {};
if (title !== row.title) changes.title = { from: row.title, to: title };
@@ -585,6 +582,7 @@ export function mutateModeration(actorId: string, input: Record<string, unknown>
notifyCase(actor.id, row.id, 'evidence', now);
return { id: row.id };
}
// Older clients may still record decisions, but every closure now stores only Closed.
if (input.op === 'resolve-case') {
const row = caseRow(input.id);
if (row.revision !== input.revision || !isModerationCaseOpen(row.status))
@@ -620,7 +618,7 @@ export function mutateModeration(actorId: string, input: Record<string, unknown>
.prepare(
'UPDATE moderation_cases SET status=?,updated_at=?,revision=revision+1 WHERE id=?'
)
.run(outcome, now, row.id);
.run('closed', now, row.id);
moderationEvent(
actor,
`case.${outcome}`,