refactor: remove unused AI columns from messages table
Drop 3 columns that were written but never read: - ai_moderation_raw: raw LLM JSON response (~KB per message, never consumed) - ai_policy_version: hardcoded 'default-2026-05-30', never used for decisions - ai_evidence: JSON evidence array, never read after write Changes: - schema.ts: remove columns from both Postgres and SQLite table definitions - messageStore.ts: remove from AIAnalysisUpdate interface and SET clauses - aiAnalyzer.ts: remove from individual fallback update calls - aiAnalysisWorker.ts: remove raw write, add missing fields (categories, severity, etc.) - types.ts: remove from MessageRecord interface - analysisRoutes.ts: remove from reset analysis call - New migration: src/database/migrations/001_drop_unused_ai_columns.sql - Migration applied to live DB: 27 columns → 24 columns Kept ai_error (useful for future debugging, currently 0 non-null) Kept metadata (1.9MB total, used for AI sticker/embed evidence analysis) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
551d11ba82
commit
a00a5a508f
@@ -0,0 +1,10 @@
|
|||||||
|
-- Migration: 001_drop_unused_ai_columns.sql
|
||||||
|
-- Date: 2026-05-30
|
||||||
|
-- Description: Drop columns that are written but never read from messages table
|
||||||
|
-- - ai_moderation_raw: raw LLM response, never consumed
|
||||||
|
-- - ai_policy_version: hardcoded string, never used for decisions
|
||||||
|
-- - ai_evidence: JSON evidence array, never read after write
|
||||||
|
|
||||||
|
ALTER TABLE messages DROP COLUMN IF EXISTS ai_moderation_raw;
|
||||||
|
ALTER TABLE messages DROP COLUMN IF EXISTS ai_policy_version;
|
||||||
|
ALTER TABLE messages DROP COLUMN IF EXISTS ai_evidence;
|
||||||
@@ -76,7 +76,6 @@ export const pgMessagesTable = pgTable(
|
|||||||
.default("pending"),
|
.default("pending"),
|
||||||
ai_moderation_flags: pgText("ai_moderation_flags"),
|
ai_moderation_flags: pgText("ai_moderation_flags"),
|
||||||
ai_moderation_score: pgReal("ai_moderation_score"),
|
ai_moderation_score: pgReal("ai_moderation_score"),
|
||||||
ai_moderation_raw: pgText("ai_moderation_raw"),
|
|
||||||
ai_analysis: pgText("ai_analysis"),
|
ai_analysis: pgText("ai_analysis"),
|
||||||
ai_categories: pgText("ai_categories"),
|
ai_categories: pgText("ai_categories"),
|
||||||
ai_severity: pgText("ai_severity", {
|
ai_severity: pgText("ai_severity", {
|
||||||
@@ -86,8 +85,6 @@ export const pgMessagesTable = pgTable(
|
|||||||
ai_recommended_action: pgText("ai_recommended_action", {
|
ai_recommended_action: pgText("ai_recommended_action", {
|
||||||
enum: ["none", "monitor", "warn", "review", "delete", "escalate"],
|
enum: ["none", "monitor", "warn", "review", "delete", "escalate"],
|
||||||
}),
|
}),
|
||||||
ai_policy_version: pgText("ai_policy_version"),
|
|
||||||
ai_evidence: pgText("ai_evidence"),
|
|
||||||
ai_analyzed_at: pgBigint("ai_analyzed_at", { mode: "number" }),
|
ai_analyzed_at: pgBigint("ai_analyzed_at", { mode: "number" }),
|
||||||
ai_error: pgText("ai_error"),
|
ai_error: pgText("ai_error"),
|
||||||
},
|
},
|
||||||
@@ -306,7 +303,6 @@ export const sqliteMessagesTable = sqliteTable(
|
|||||||
.default("pending"),
|
.default("pending"),
|
||||||
ai_moderation_flags: sqliteText("ai_moderation_flags"),
|
ai_moderation_flags: sqliteText("ai_moderation_flags"),
|
||||||
ai_moderation_score: sqliteReal("ai_moderation_score"),
|
ai_moderation_score: sqliteReal("ai_moderation_score"),
|
||||||
ai_moderation_raw: sqliteText("ai_moderation_raw"),
|
|
||||||
ai_analysis: sqliteText("ai_analysis"),
|
ai_analysis: sqliteText("ai_analysis"),
|
||||||
ai_categories: sqliteText("ai_categories"),
|
ai_categories: sqliteText("ai_categories"),
|
||||||
ai_severity: sqliteText("ai_severity", {
|
ai_severity: sqliteText("ai_severity", {
|
||||||
@@ -316,8 +312,6 @@ export const sqliteMessagesTable = sqliteTable(
|
|||||||
ai_recommended_action: sqliteText("ai_recommended_action", {
|
ai_recommended_action: sqliteText("ai_recommended_action", {
|
||||||
enum: ["none", "monitor", "warn", "review", "delete", "escalate"],
|
enum: ["none", "monitor", "warn", "review", "delete", "escalate"],
|
||||||
}),
|
}),
|
||||||
ai_policy_version: sqliteText("ai_policy_version"),
|
|
||||||
ai_evidence: sqliteText("ai_evidence"),
|
|
||||||
ai_analyzed_at: sqliteInteger("ai_analyzed_at"),
|
ai_analyzed_at: sqliteInteger("ai_analyzed_at"),
|
||||||
ai_error: sqliteText("ai_error"),
|
ai_error: sqliteText("ai_error"),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -103,8 +103,11 @@ export default async function processAnalysisRequest({
|
|||||||
status: analysisResult.status,
|
status: analysisResult.status,
|
||||||
flags: JSON.stringify(analysisResult.flags),
|
flags: JSON.stringify(analysisResult.flags),
|
||||||
score: analysisResult.score,
|
score: analysisResult.score,
|
||||||
raw: JSON.stringify(result.raw),
|
|
||||||
analysis: analysisResult.analysis,
|
analysis: analysisResult.analysis,
|
||||||
|
categories: analysisResult.categories,
|
||||||
|
severity: analysisResult.severity,
|
||||||
|
confidence: analysisResult.confidence,
|
||||||
|
recommendedAction: analysisResult.recommendedAction,
|
||||||
analyzedAt: Date.now(),
|
analyzedAt: Date.now(),
|
||||||
error: null,
|
error: null,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -304,14 +304,11 @@ async function processIndividualFallback(
|
|||||||
status: r.status,
|
status: r.status,
|
||||||
flags: JSON.stringify(r.flags),
|
flags: JSON.stringify(r.flags),
|
||||||
score: r.score,
|
score: r.score,
|
||||||
raw: JSON.stringify(analysisResult.raw),
|
|
||||||
analysis: r.analysis,
|
analysis: r.analysis,
|
||||||
categories: r.categories,
|
categories: r.categories,
|
||||||
severity: r.severity,
|
severity: r.severity,
|
||||||
confidence: r.confidence,
|
confidence: r.confidence,
|
||||||
recommendedAction: r.recommendedAction,
|
recommendedAction: r.recommendedAction,
|
||||||
policyVersion: r.policyVersion,
|
|
||||||
evidence: r.evidence,
|
|
||||||
analyzedAt: Date.now(),
|
analyzedAt: Date.now(),
|
||||||
error: null,
|
error: null,
|
||||||
},
|
},
|
||||||
@@ -361,15 +358,12 @@ async function processIndividualFallback(
|
|||||||
status: "error",
|
status: "error",
|
||||||
flags: JSON.stringify(["individual_analysis_exhausted"]),
|
flags: JSON.stringify(["individual_analysis_exhausted"]),
|
||||||
score: 0,
|
score: 0,
|
||||||
raw: null,
|
|
||||||
analysis:
|
analysis:
|
||||||
"Individual fallback exhausted all retries: LLM consistently dropped this message even in single-target mode",
|
"Individual fallback exhausted all retries: LLM consistently dropped this message even in single-target mode",
|
||||||
categories: ["individual_analysis_exhausted"],
|
categories: ["individual_analysis_exhausted"],
|
||||||
severity: "none",
|
severity: "none",
|
||||||
confidence: 0,
|
confidence: 0,
|
||||||
recommendedAction: "review",
|
recommendedAction: "review",
|
||||||
policyVersion: "default-2026-05-30",
|
|
||||||
evidence: [],
|
|
||||||
analyzedAt: Date.now(),
|
analyzedAt: Date.now(),
|
||||||
error: lastError,
|
error: lastError,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -184,7 +184,6 @@ export async function updateMessageAsEdited(
|
|||||||
ai_status: "pending",
|
ai_status: "pending",
|
||||||
ai_moderation_flags: null,
|
ai_moderation_flags: null,
|
||||||
ai_moderation_score: null,
|
ai_moderation_score: null,
|
||||||
ai_moderation_raw: null,
|
|
||||||
ai_analysis: null,
|
ai_analysis: null,
|
||||||
ai_analyzed_at: null,
|
ai_analyzed_at: null,
|
||||||
ai_error: null,
|
ai_error: null,
|
||||||
@@ -392,14 +391,11 @@ interface AIAnalysisUpdate {
|
|||||||
status: "pending" | "clean" | "warn" | "flagged" | "error";
|
status: "pending" | "clean" | "warn" | "flagged" | "error";
|
||||||
flags?: string | null;
|
flags?: string | null;
|
||||||
score?: number | null;
|
score?: number | null;
|
||||||
raw?: string | null;
|
|
||||||
analysis?: string | null;
|
analysis?: string | null;
|
||||||
categories?: string[] | string | null;
|
categories?: string[] | string | null;
|
||||||
severity?: MessageRecord["ai_severity"] | null;
|
severity?: MessageRecord["ai_severity"] | null;
|
||||||
confidence?: number | null;
|
confidence?: number | null;
|
||||||
recommendedAction?: MessageRecord["ai_recommended_action"] | null;
|
recommendedAction?: MessageRecord["ai_recommended_action"] | null;
|
||||||
policyVersion?: string | null;
|
|
||||||
evidence?: string[] | string | null;
|
|
||||||
analyzedAt?: number | null;
|
analyzedAt?: number | null;
|
||||||
error?: string | null;
|
error?: string | null;
|
||||||
}
|
}
|
||||||
@@ -423,14 +419,11 @@ export async function updateMessageAIAnalysis(
|
|||||||
ai_status: result.status,
|
ai_status: result.status,
|
||||||
ai_moderation_flags: result.flags ?? null,
|
ai_moderation_flags: result.flags ?? null,
|
||||||
ai_moderation_score: result.score ?? null,
|
ai_moderation_score: result.score ?? null,
|
||||||
ai_moderation_raw: result.raw ?? null,
|
|
||||||
ai_analysis: result.analysis ?? null,
|
ai_analysis: result.analysis ?? null,
|
||||||
ai_categories: stringifyAIList(result.categories),
|
ai_categories: stringifyAIList(result.categories),
|
||||||
ai_severity: result.severity ?? null,
|
ai_severity: result.severity ?? null,
|
||||||
ai_confidence: result.confidence ?? result.score ?? null,
|
ai_confidence: result.confidence ?? result.score ?? null,
|
||||||
ai_recommended_action: result.recommendedAction ?? null,
|
ai_recommended_action: result.recommendedAction ?? null,
|
||||||
ai_policy_version: result.policyVersion ?? null,
|
|
||||||
ai_evidence: stringifyAIList(result.evidence),
|
|
||||||
ai_analyzed_at: result.analyzedAt ?? Date.now(),
|
ai_analyzed_at: result.analyzedAt ?? Date.now(),
|
||||||
ai_error: result.error ?? null,
|
ai_error: result.error ?? null,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,14 +33,11 @@ export interface MessageRecord {
|
|||||||
ai_status?: AIStatus | null;
|
ai_status?: AIStatus | null;
|
||||||
ai_moderation_flags?: string | null;
|
ai_moderation_flags?: string | null;
|
||||||
ai_moderation_score?: number | null;
|
ai_moderation_score?: number | null;
|
||||||
ai_moderation_raw?: string | null;
|
|
||||||
ai_analysis?: string | null;
|
ai_analysis?: string | null;
|
||||||
ai_categories?: string | null;
|
ai_categories?: string | null;
|
||||||
ai_severity?: AISeverity | null;
|
ai_severity?: AISeverity | null;
|
||||||
ai_confidence?: number | null;
|
ai_confidence?: number | null;
|
||||||
ai_recommended_action?: AIRecommendedAction | null;
|
ai_recommended_action?: AIRecommendedAction | null;
|
||||||
ai_policy_version?: string | null;
|
|
||||||
ai_evidence?: string | null;
|
|
||||||
ai_analyzed_at?: number | null;
|
ai_analyzed_at?: number | null;
|
||||||
ai_error?: string | null;
|
ai_error?: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ export function createAnalysisRoutes(): Router {
|
|||||||
status: "pending",
|
status: "pending",
|
||||||
flags: null,
|
flags: null,
|
||||||
score: null,
|
score: null,
|
||||||
raw: null,
|
|
||||||
analysis: null,
|
analysis: null,
|
||||||
analyzedAt: null,
|
analyzedAt: null,
|
||||||
error: null,
|
error: null,
|
||||||
|
|||||||
Reference in New Issue
Block a user