feat(analytics): add support for selected analytics guild and channel in App component

fix(redis): enhance Redis connection handling with fallback to in-memory storage
chore(sql): create missing messages and attachments tables with necessary constraints and indexes
This commit is contained in:
MythEclipse
2026-05-31 17:19:24 +07:00
parent 30ce607d88
commit 4bb90153b0
4 changed files with 264 additions and 90 deletions
+153
View File
@@ -0,0 +1,153 @@
-- Fix: missing messages and attachments tables on VPS
-- Run: PGPASSWORD=hunterz psql -h 100.108.1.124 -U asephs -d hub -f scripts/fix-missing-tables.sql
BEGIN;
-- 1. Create messages table if not exists
CREATE TABLE IF NOT EXISTS "messages" (
"id" text PRIMARY KEY NOT NULL,
"guild_id" text NOT NULL,
"channel_id" text NOT NULL,
"thread_id" text,
"user_id" text NOT NULL,
"username" text NOT NULL,
"avatar_url" text,
"content" text NOT NULL,
"edited_content" text,
"created_at" bigint NOT NULL,
"edited_at" bigint,
"deleted_at" bigint,
"type" text DEFAULT 'text' NOT NULL,
"metadata" text,
"ai_status" text DEFAULT 'pending' NOT NULL,
"ai_moderation_flags" text,
"ai_moderation_score" real,
"ai_moderation_raw" text,
"ai_analysis" text,
"ai_analyzed_at" bigint,
"ai_error" text
);
-- 2. Create attachments table if not exists
CREATE TABLE IF NOT EXISTS "attachments" (
"id" text PRIMARY KEY NOT NULL,
"message_id" text NOT NULL,
"guild_id" text NOT NULL,
"channel_id" text NOT NULL,
"thread_id" text,
"user_id" text NOT NULL,
"filename" text NOT NULL,
"size" integer NOT NULL,
"type" text NOT NULL,
"discord_url" text NOT NULL,
"uploaded_url" text,
"upload_status" text DEFAULT 'pending' NOT NULL,
"upload_error" text,
"created_at" bigint NOT NULL,
"uploaded_at" bigint
);
-- 3. Foreign key
ALTER TABLE "attachments" DROP CONSTRAINT IF EXISTS "fk_attachments_message_id";
ALTER TABLE "attachments" ADD CONSTRAINT "fk_attachments_message_id"
FOREIGN KEY ("message_id") REFERENCES "public"."messages"("id")
ON DELETE cascade ON UPDATE no action;
-- 4. Indexes from migration 0000
CREATE INDEX IF NOT EXISTS "idx_attachments_channel" ON "attachments" USING btree ("channel_id");
CREATE INDEX IF NOT EXISTS "idx_attachments_message" ON "attachments" USING btree ("message_id");
CREATE INDEX IF NOT EXISTS "idx_attachments_status" ON "attachments" USING btree ("upload_status");
CREATE INDEX IF NOT EXISTS "idx_messages_channel" ON "messages" USING btree ("channel_id");
CREATE INDEX IF NOT EXISTS "idx_messages_user" ON "messages" USING btree ("user_id");
CREATE INDEX IF NOT EXISTS "idx_messages_created" ON "messages" USING btree ("created_at");
CREATE INDEX IF NOT EXISTS "idx_messages_thread" ON "messages" USING btree ("thread_id");
-- 5. Indexes from migration 0001
CREATE INDEX IF NOT EXISTS "idx_attachments_channel_created" ON "attachments" ("channel_id","created_at","id");
CREATE INDEX IF NOT EXISTS "idx_attachments_thread_created" ON "attachments" ("thread_id","created_at","id");
CREATE INDEX IF NOT EXISTS "idx_messages_channel_created" ON "messages" ("channel_id","created_at","id");
CREATE INDEX IF NOT EXISTS "idx_messages_thread_created" ON "messages" ("thread_id","created_at","id");
CREATE INDEX IF NOT EXISTS "idx_messages_ai_status_created" ON "messages" ("ai_status","created_at","id");
CREATE INDEX IF NOT EXISTS "idx_messages_guild_ai_status_created" ON "messages" ("guild_id","ai_status","created_at","id");
-- 6. Columns from migration 0003
ALTER TABLE "messages" ADD COLUMN IF NOT EXISTS "ai_categories" text;
ALTER TABLE "messages" ADD COLUMN IF NOT EXISTS "ai_severity" text;
ALTER TABLE "messages" ADD COLUMN IF NOT EXISTS "ai_confidence" real;
ALTER TABLE "messages" ADD COLUMN IF NOT EXISTS "ai_recommended_action" text;
ALTER TABLE "messages" ADD COLUMN IF NOT EXISTS "ai_policy_version" text;
ALTER TABLE "messages" ADD COLUMN IF NOT EXISTS "ai_evidence" text;
-- 7. message_reviews, moderation_actions, retention_policies (from 0003 — should already exist, but IF NOT EXISTS safe)
CREATE TABLE IF NOT EXISTS "message_reviews" (
"id" text PRIMARY KEY NOT NULL,
"message_id" text NOT NULL,
"guild_id" text NOT NULL,
"channel_id" text NOT NULL,
"reviewer_id" text,
"status" text DEFAULT 'pending' NOT NULL,
"notes" text,
"created_at" bigint NOT NULL,
"reviewed_at" bigint
);
CREATE INDEX IF NOT EXISTS "idx_message_reviews_message_id" ON "message_reviews" USING btree ("message_id");
CREATE INDEX IF NOT EXISTS "idx_message_reviews_guild_status" ON "message_reviews" USING btree ("guild_id", "status", "created_at");
CREATE TABLE IF NOT EXISTS "moderation_actions" (
"id" text PRIMARY KEY NOT NULL,
"message_id" text,
"user_id" text,
"guild_id" text NOT NULL,
"action_type" text NOT NULL,
"reason" text,
"executed_by" text,
"status" text DEFAULT 'pending' NOT NULL,
"error" text,
"created_at" bigint NOT NULL,
"executed_at" bigint
);
CREATE INDEX IF NOT EXISTS "idx_moderation_actions_message_id" ON "moderation_actions" USING btree ("message_id");
CREATE INDEX IF NOT EXISTS "idx_moderation_actions_user_id" ON "moderation_actions" USING btree ("user_id");
CREATE INDEX IF NOT EXISTS "idx_moderation_actions_status" ON "moderation_actions" USING btree ("status");
CREATE INDEX IF NOT EXISTS "idx_moderation_actions_guild_status" ON "moderation_actions" USING btree ("guild_id", "status", "created_at");
CREATE TABLE IF NOT EXISTS "retention_policies" (
"id" text PRIMARY KEY NOT NULL,
"guild_id" text NOT NULL,
"channel_id" text,
"retention_days" integer DEFAULT 90 NOT NULL,
"apply_to_media" boolean DEFAULT true NOT NULL,
"apply_to_voice" boolean DEFAULT true NOT NULL,
"enabled" boolean DEFAULT true NOT NULL,
"created_at" bigint NOT NULL,
"updated_at" bigint NOT NULL
);
CREATE INDEX IF NOT EXISTS "idx_retention_policies_guild_id" ON "retention_policies" USING btree ("guild_id");
CREATE INDEX IF NOT EXISTS "idx_retention_policies_enabled" ON "retention_policies" USING btree ("enabled");
-- 8. Indexes from migration 0005
CREATE INDEX IF NOT EXISTS "idx_messages_guild_created_deleted" ON "messages" USING btree ("guild_id","created_at","deleted_at","id");
CREATE INDEX IF NOT EXISTS "idx_messages_channel_ai_status_created" ON "messages" USING btree ("channel_id","ai_status","created_at","id");
CREATE INDEX IF NOT EXISTS "idx_messages_thread_ai_status_created" ON "messages" USING btree ("thread_id","ai_status","created_at","id");
-- 9. Drizzle migration tracking table (so future drizzle-kit migrate works)
CREATE TABLE IF NOT EXISTS "__drizzle_migrations" (
"id" serial PRIMARY KEY,
"hash" text NOT NULL,
"created_at" bigint NOT NULL
);
-- Seed migration tracking so drizzle-kit doesn't try to re-apply
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM "__drizzle_migrations" WHERE hash = '0000_rare_kitty_pryde') THEN
INSERT INTO "__drizzle_migrations" (hash, created_at) VALUES
('0000_rare_kitty_pryde', 1778750697764),
('0001_curious_zodiak', 1778764447718),
('0002_dark_omega_flight', 1779109619461),
('0003_ai_moderation_review_guardrails', 1780079000000),
('0005_optimize-message-index', 1780218363790);
END IF;
END $$;
COMMIT;