diff --git a/apps/discord-bot/src/index.ts b/apps/discord-bot/src/index.ts index 7cb1555..558ea61 100644 --- a/apps/discord-bot/src/index.ts +++ b/apps/discord-bot/src/index.ts @@ -3,6 +3,10 @@ import { Client, GatewayIntentBits, Partials } from "discord.js"; import { setupBotMode } from "~/modes/bot"; import { setupUserMode } from "~/modes/user"; import { parseArgs } from "~/utils/cli"; +import { runMigrations } from "@lbf-bot/database"; + +console.log("Running database migrations..."); +await runMigrations(); const mode = parseArgs(process.argv.slice(2)); diff --git a/packages/database/drizzle/0000_tan_justin_hammer.sql b/packages/database/drizzle/0000_tan_justin_hammer.sql new file mode 100644 index 0000000..3c077ea --- /dev/null +++ b/packages/database/drizzle/0000_tan_justin_hammer.sql @@ -0,0 +1,21 @@ +CREATE TABLE "accounts" ( + "player_id" uuid PRIMARY KEY NOT NULL, + "balance" integer DEFAULT 0 NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "tracked_players" ( + "player_id" uuid PRIMARY KEY NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "username_history" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "player_id" uuid NOT NULL, + "username" text NOT NULL, + "first_seen_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "username_history" ADD CONSTRAINT "username_history_player_id_tracked_players_player_id_fk" FOREIGN KEY ("player_id") REFERENCES "public"."tracked_players"("player_id") ON DELETE cascade ON UPDATE no action; \ No newline at end of file diff --git a/packages/database/drizzle/meta/0000_snapshot.json b/packages/database/drizzle/meta/0000_snapshot.json new file mode 100644 index 0000000..ea05e94 --- /dev/null +++ b/packages/database/drizzle/meta/0000_snapshot.json @@ -0,0 +1,141 @@ +{ + "id": "80475ee2-c581-462e-8075-13b1ae696df5", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.accounts": { + "name": "accounts", + "schema": "", + "columns": { + "player_id": { + "name": "player_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "balance": { + "name": "balance", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tracked_players": { + "name": "tracked_players", + "schema": "", + "columns": { + "player_id": { + "name": "player_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.username_history": { + "name": "username_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "player_id": { + "name": "player_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "username_history_player_id_tracked_players_player_id_fk": { + "name": "username_history_player_id_tracked_players_player_id_fk", + "tableFrom": "username_history", + "tableTo": "tracked_players", + "columnsFrom": ["player_id"], + "columnsTo": ["player_id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/packages/database/drizzle/meta/_journal.json b/packages/database/drizzle/meta/_journal.json new file mode 100644 index 0000000..d3d4571 --- /dev/null +++ b/packages/database/drizzle/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1764882945878, + "tag": "0000_tan_justin_hammer", + "breakpoints": true + } + ] +} diff --git a/packages/database/package.json b/packages/database/package.json index 53ef024..7209255 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -12,10 +12,12 @@ } }, "files": [ - "dist" + "dist", + "drizzle" ], "scripts": { "build": "rm -rf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json", + "db:generate": "drizzle-kit generate", "db:push": "drizzle-kit push", "db:studio": "drizzle-kit studio" }, diff --git a/packages/database/src/index.ts b/packages/database/src/index.ts index df9ab83..2a72d52 100644 --- a/packages/database/src/index.ts +++ b/packages/database/src/index.ts @@ -10,4 +10,5 @@ export const db = drizzle(env.DATABASE_URL, { }); export { redis } from "~/redis"; +export { runMigrations } from "~/migrate"; export * from "drizzle-orm"; diff --git a/packages/database/src/migrate.ts b/packages/database/src/migrate.ts new file mode 100644 index 0000000..5e69f8c --- /dev/null +++ b/packages/database/src/migrate.ts @@ -0,0 +1,11 @@ +import { drizzle } from "drizzle-orm/node-postgres"; +import { migrate } from "drizzle-orm/node-postgres/migrator"; +import { env } from "~/env"; + +export async function runMigrations() { + const db = drizzle(env.DATABASE_URL); + + await migrate(db, { migrationsFolder: "./drizzle" }); + + console.log("✅ Database migrations completed"); +}