diff --git a/drizzle.config.ts b/drizzle.config.ts new file mode 100644 index 0000000..5ed4f59 --- /dev/null +++ b/drizzle.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "drizzle-kit"; +import { config } from "./src/config"; + +export default defineConfig({ + schema: "./src/database/schema.ts", + out: "./drizzle/migrations", + dialect: config.DATABASE_TYPE === "postgres" ? "postgresql" : "sqlite", + dbCredentials: + config.DATABASE_TYPE === "postgres" + ? { + host: config.POSTGRES_HOST, + port: config.POSTGRES_PORT, + user: config.POSTGRES_USER || "postgres", + password: config.POSTGRES_PASSWORD || "", + database: config.POSTGRES_DB || "moderation_bot", + } + : { + url: "./.muxer-queue.db", + }, +}); diff --git a/drizzle/migrations/0000_windy_victor_mancha.sql b/drizzle/migrations/0000_windy_victor_mancha.sql new file mode 100644 index 0000000..9952c08 --- /dev/null +++ b/drizzle/migrations/0000_windy_victor_mancha.sql @@ -0,0 +1,67 @@ +CREATE TABLE `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` integer NOT NULL, + `uploaded_at` integer +); +--> statement-breakpoint +CREATE INDEX `idx_attachments_channel` ON `attachments` (`channel_id`);--> statement-breakpoint +CREATE INDEX `idx_attachments_message` ON `attachments` (`message_id`);--> statement-breakpoint +CREATE INDEX `idx_attachments_status` ON `attachments` (`upload_status`);--> statement-breakpoint +CREATE TABLE `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` integer NOT NULL, + `edited_at` integer, + `deleted_at` integer, + `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` integer, + `ai_error` text +); +--> statement-breakpoint +CREATE INDEX `idx_messages_channel` ON `messages` (`channel_id`);--> statement-breakpoint +CREATE INDEX `idx_messages_user` ON `messages` (`user_id`);--> statement-breakpoint +CREATE INDEX `idx_messages_created` ON `messages` (`created_at`);--> statement-breakpoint +CREATE INDEX `idx_messages_thread` ON `messages` (`thread_id`);--> statement-breakpoint +CREATE TABLE `muxer_jobs` ( + `id` text PRIMARY KEY NOT NULL, + `data` text NOT NULL, + `status` text DEFAULT 'pending' NOT NULL, + `attempts` integer DEFAULT 0 NOT NULL, + `maxAttempts` integer DEFAULT 3 NOT NULL, + `createdAt` integer NOT NULL, + `updatedAt` integer NOT NULL, + `error` text +); +--> statement-breakpoint +CREATE INDEX `idx_muxer_jobs_status` ON `muxer_jobs` (`status`);--> statement-breakpoint +CREATE INDEX `idx_muxer_jobs_createdAt` ON `muxer_jobs` (`createdAt`);--> statement-breakpoint +CREATE TABLE `ui_state` ( + `key` text PRIMARY KEY NOT NULL, + `value` text NOT NULL, + `updated_at` integer NOT NULL +); diff --git a/drizzle/migrations/meta/0000_snapshot.json b/drizzle/migrations/meta/0000_snapshot.json new file mode 100644 index 0000000..b0d83c3 --- /dev/null +++ b/drizzle/migrations/meta/0000_snapshot.json @@ -0,0 +1,459 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "0f1b703a-dee9-40f5-807c-776649af94d9", + "prevId": "00000000-0000-0000-0000-000000000000", + "tables": { + "attachments": { + "name": "attachments", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "guild_id": { + "name": "guild_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "thread_id": { + "name": "thread_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "discord_url": { + "name": "discord_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "uploaded_url": { + "name": "uploaded_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "upload_status": { + "name": "upload_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "upload_error": { + "name": "upload_error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "uploaded_at": { + "name": "uploaded_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_attachments_channel": { + "name": "idx_attachments_channel", + "columns": [ + "channel_id" + ], + "isUnique": false + }, + "idx_attachments_message": { + "name": "idx_attachments_message", + "columns": [ + "message_id" + ], + "isUnique": false + }, + "idx_attachments_status": { + "name": "idx_attachments_status", + "columns": [ + "upload_status" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "messages": { + "name": "messages", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "guild_id": { + "name": "guild_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "thread_id": { + "name": "thread_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "edited_content": { + "name": "edited_content", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "edited_at": { + "name": "edited_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'text'" + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_status": { + "name": "ai_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "ai_moderation_flags": { + "name": "ai_moderation_flags", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_moderation_score": { + "name": "ai_moderation_score", + "type": "real", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_moderation_raw": { + "name": "ai_moderation_raw", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_analysis": { + "name": "ai_analysis", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_analyzed_at": { + "name": "ai_analyzed_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ai_error": { + "name": "ai_error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_messages_channel": { + "name": "idx_messages_channel", + "columns": [ + "channel_id" + ], + "isUnique": false + }, + "idx_messages_user": { + "name": "idx_messages_user", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_messages_created": { + "name": "idx_messages_created", + "columns": [ + "created_at" + ], + "isUnique": false + }, + "idx_messages_thread": { + "name": "idx_messages_thread", + "columns": [ + "thread_id" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "muxer_jobs": { + "name": "muxer_jobs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "maxAttempts": { + "name": "maxAttempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 3 + }, + "createdAt": { + "name": "createdAt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_muxer_jobs_status": { + "name": "idx_muxer_jobs_status", + "columns": [ + "status" + ], + "isUnique": false + }, + "idx_muxer_jobs_createdAt": { + "name": "idx_muxer_jobs_createdAt", + "columns": [ + "createdAt" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "ui_state": { + "name": "ui_state", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/drizzle/migrations/meta/_journal.json b/drizzle/migrations/meta/_journal.json new file mode 100644 index 0000000..ed98ae8 --- /dev/null +++ b/drizzle/migrations/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "sqlite", + "entries": [ + { + "idx": 0, + "version": "6", + "when": 1778747576917, + "tag": "0000_windy_victor_mancha", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index 439a4d8..71c3ce2 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,10 @@ "typecheck": "tsc --noEmit", "lint": "biome check --diagnostic-level=error .", "format": "biome format --write .", - "test": "vitest run" + "test": "vitest run", + "db:generate": "drizzle-kit generate", + "db:migrate": "drizzle-kit migrate", + "db:studio": "drizzle-kit studio" }, "dependencies": { "@discordjs/opus": "^0.10.0",