This commit was merged in pull request #71.
This commit is contained in:
@@ -134,7 +134,7 @@ export class ModerationService {
|
||||
/**
|
||||
* Review a single pending event with Claude.
|
||||
* Returns "approve" (event is injected into strfry + status → auto_approved)
|
||||
* or "flag" (status stays pending — admin must decide).
|
||||
* or "flag" (status → flagged — admin must decide).
|
||||
*/
|
||||
async autoReview(eventId: string): Promise<ModerationDecision> {
|
||||
const rows = await db
|
||||
@@ -176,10 +176,10 @@ export class ModerationService {
|
||||
if (result.decision === "approve") {
|
||||
await this.decide(eventId, "auto_approved", result.reason, "timmy_ai");
|
||||
} else {
|
||||
// Update reason but leave status as "pending" for admin
|
||||
// Transition to "flagged" so processPending() won't re-review this event
|
||||
await db
|
||||
.update(relayEventQueue)
|
||||
.set({ reviewReason: result.reason, reviewedBy: "timmy_ai" })
|
||||
.set({ status: "flagged", reviewReason: result.reason, reviewedBy: "timmy_ai" })
|
||||
.where(eq(relayEventQueue.eventId, eventId));
|
||||
|
||||
logger.info("moderation: event flagged for admin review", {
|
||||
|
||||
@@ -106,6 +106,7 @@ router.get("/admin/relay/stats", requireAdmin, async (_req: Request, res: Respon
|
||||
|
||||
res.json({
|
||||
pending: statusMap["pending"] ?? 0,
|
||||
flagged: statusMap["flagged"] ?? 0,
|
||||
approved: statusMap["approved"] ?? 0,
|
||||
autoApproved: statusMap["auto_approved"] ?? 0,
|
||||
rejected: statusMap["rejected"] ?? 0,
|
||||
|
||||
9
lib/db/migrations/0007_moderation_flagged_status.sql
Normal file
9
lib/db/migrations/0007_moderation_flagged_status.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- Migration: Add 'flagged' status to relay_event_queue
|
||||
-- Fixes infinite re-review loop (#27): AI-flagged events now transition to
|
||||
-- status='flagged' instead of staying 'pending', so processPending() skips them.
|
||||
--
|
||||
-- The status column is plain TEXT (not a Postgres enum), so no ALTER TYPE is
|
||||
-- needed. This migration adds an index for admin queries on flagged events.
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_relay_event_queue_status
|
||||
ON relay_event_queue(status);
|
||||
@@ -3,7 +3,7 @@ import { nostrIdentities } from "./nostr-identities";
|
||||
|
||||
// ── Status + reviewer types ───────────────────────────────────────────────────
|
||||
|
||||
export const QUEUE_STATUSES = ["pending", "approved", "rejected", "auto_approved"] as const;
|
||||
export const QUEUE_STATUSES = ["pending", "approved", "rejected", "auto_approved", "flagged"] as const;
|
||||
export type QueueStatus = (typeof QUEUE_STATUSES)[number];
|
||||
|
||||
export const QUEUE_REVIEWERS = ["timmy_ai", "admin"] as const;
|
||||
|
||||
Reference in New Issue
Block a user