fix(ai-moderation): resolve race conditions and implement processing state

Introduces a `processing` state to the AI analysis lifecycle to prevent
duplicate processing of the same messages.

- Implements row-level locking using `FOR UPDATE SKIP LOCKED` in
  `messageStore.ts` to ensure atomic message acquisition.
- Adds a `processing` status to the `AIStatus` type and database schema.
- Fixes a TOCTOU race condition in `aiAnalyzer.ts` by synchronizing
  the conversation processing lock before async database operations.
- Implements `revertStuckProcessingMessages` to recover messages stuck
  in the `processing` state due to worker crashes or timeouts.
- Updates `processBatch` and scheduling logic to correctly manage and
  release conversation-level locks.
This commit is contained in:
MythEclipse
2026-06-05 16:36:14 +07:00
parent 399919ded0
commit 09f6e80ddd
4 changed files with 98 additions and 14 deletions
@@ -62,7 +62,7 @@ export const pgMessagesTable = pgTable(
.default("text"),
metadata: pgText("metadata"),
ai_status: pgText("ai_status", {
enum: ["pending", "clean", "warn", "flagged", "error"],
enum: ["pending", "processing", "clean", "warn", "flagged", "error"],
})
.notNull()
.default("pending"),