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
+39
View File
@@ -235,3 +235,42 @@ export function migrateModerationCaseReferenceIndexes(handle: Database.Database)
ON moderation_case_notifications(case_id);
`);
}
/** Normalize lifecycle state while retaining every prior decision and child record. */
export function migrateModerationCaseStates(handle: Database.Database): void {
if (handle.pragma('foreign_keys', { simple: true }))
throw new Error('The case status migration requires foreign keys to be disabled');
const objects = handle
.prepare(
`SELECT sql FROM sqlite_master
WHERE tbl_name='moderation_cases' AND type IN ('index','trigger') AND sql IS NOT NULL`
)
.all() as { sql: string }[];
// Capture old statuses even for imported cases without a corresponding decision event.
handle.exec(`INSERT INTO moderation_events(game,guid,actor,action,subject_id,detail,created_at)
SELECT game,guid,'Maxis','case.status_migrated',id,
json_object('from',status,'to',CASE WHEN status='escalated' THEN 'in_review' ELSE 'closed' END),
strftime('%Y-%m-%dT%H:%M:%fZ','now') FROM moderation_cases
WHERE status NOT IN ('open','in_review');
CREATE TABLE moderation_cases_state (
id TEXT PRIMARY KEY, game TEXT NOT NULL, guid TEXT NOT NULL, title TEXT NOT NULL,
status TEXT NOT NULL CHECK(status IN ('open','in_review','closed')),
actor_id TEXT NOT NULL, actor TEXT NOT NULL,
created_at TEXT NOT NULL, updated_at TEXT NOT NULL, revision INTEGER NOT NULL DEFAULT 1,
priority TEXT NOT NULL DEFAULT 'normal' CHECK(priority IN ('low','normal','high','urgent')),
assignee_id TEXT REFERENCES auth_users(id) ON DELETE SET NULL,
review_at TEXT, review_reason TEXT NOT NULL DEFAULT '',
review_sanction_id TEXT REFERENCES moderation_sanctions(id) ON DELETE SET NULL
);
INSERT INTO moderation_cases_state
SELECT id,game,guid,title,
CASE WHEN status IN ('open','in_review') THEN status
WHEN status='escalated' THEN 'in_review' ELSE 'closed' END,
actor_id,actor,created_at,updated_at,
revision+CASE WHEN status IN ('open','in_review') THEN 0 ELSE 1 END,
priority,assignee_id,review_at,review_reason,review_sanction_id FROM moderation_cases;
DROP TABLE moderation_cases;
ALTER TABLE moderation_cases_state RENAME TO moderation_cases;
`);
for (const object of objects) handle.exec(object.sql);
}