feat(content): add catalogue review metadata

Add reversible review states, audit history, and super-admin controls for catalogue entities without changing current client visibility.

Stage 30 high-risk production packs for archival review, cap generated content at non-explicit language, and preserve a checksummed pre-change production catalogue snapshot.
This commit is contained in:
jjbrunton committed 2026-08-28 11:32:55 +01:00
1 parent b43804d8fd
commit 94c76535a4
30 files changed
+46906 -128

No files matched your search

@@ -0,0 +1,46 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { CONTENT_STATUS_LABELS } from '@/lib/contentReviewStatus';
const { update } = vi.hoisted(() => ({ update: vi.fn() }));
vi.mock('@/hooks/useAuditedSupabase', () => ({
auditedSupabase: { update },
}));
import { updateContentReviewStatus } from './contentReviews';
describe('catalogue review labels', () => {
it('uses archive language for reversible removals', () => {
expect(CONTENT_STATUS_LABELS).toEqual({
unreviewed: 'Needs review',
allowed: 'Allowed',
archived: 'Archived',
});
});
beforeEach(() => {
update.mockReset();
update.mockResolvedValue({ data: null, error: null });
});
it('writes a trimmed, audited review decision', async () => {
await updateContentReviewStatus(
'question_packs',
'pack-1',
'archived',
' Store compliance review ',
);
expect(update).toHaveBeenCalledWith('question_packs', 'pack-1', {
content_status: 'archived',
content_review_reason: 'Store compliance review',
});
});
it('rejects an empty reason before writing', async () => {
await expect(
updateContentReviewStatus('questions', 'question-1', 'allowed', ' '),
).rejects.toThrow('A review reason is required');
expect(update).not.toHaveBeenCalled();
});
});