diff --git a/apps/core/server/db/migrate.ts b/apps/core/server/db/migrate.ts index c7cc7d8..87e00f3 100644 --- a/apps/core/server/db/migrate.ts +++ b/apps/core/server/db/migrate.ts @@ -30,18 +30,24 @@ if (!process.env.DATABASE_URL) { } // Log migration info for debugging +const sanitizedDbUrl = (() => { + try { + const url = new URL(process.env.DATABASE_URL!); + url.password = "****"; + return url.toString(); + } catch { + return process.env.DATABASE_URL!.replace(/:[^:@]+@/, ":****@"); + } +})(); // Hide password + +console.log("[Migrations] Starting migration process"); +console.log("[Migrations] Migrations folder:", migrationsFolder); +console.log("[Migrations] Database URL:", sanitizedDbUrl); + logger.info( { migrationsFolder, - databaseUrl: (() => { - try { - const url = new URL(process.env.DATABASE_URL!); - url.password = "****"; - return url.toString(); - } catch { - return process.env.DATABASE_URL!.replace(/:[^:@]+@/, ":****@"); - } - })(), // Hide password + databaseUrl: sanitizedDbUrl, }, "[Migrations] Starting migration process", ); @@ -55,11 +61,102 @@ const db = drizzle(migrationClient); // Run migrations async function main() { + // Verify migrations folder exists and has files + try { + const fs = await import("node:fs/promises"); + const migrationFiles = await fs.readdir(migrationsFolder); + const sqlFiles = migrationFiles.filter((f) => f.endsWith(".sql")); + + logger.info( + { + migrationsFolder, + totalFiles: migrationFiles.length, + sqlFiles: sqlFiles.length, + }, + "[Migrations] Found migration files", + ); + + if (sqlFiles.length === 0) { + const errorMsg = `No SQL migration files found in ${migrationsFolder}`; + console.error(`[Migrations] ERROR: ${errorMsg}`); + logger.error({}, errorMsg); + process.exit(1); + } + } catch (error: any) { + const errorMsg = `Failed to read migrations folder: ${error.message}`; + console.error(`[Migrations] ERROR: ${errorMsg}`); + console.error(`[Migrations] Stack: ${error.stack}`); + logger.error({ err: error }, errorMsg); + process.exit(1); + } + + // Test database connection before running migrations + console.log("[Migrations] Testing database connection..."); + try { + const result = await migrationClient`SELECT 1 as test`; + console.log("[Migrations] ✓ Database connection successful"); + logger.info({}, "[Migrations] Database connection test passed"); + } catch (error: any) { + const errorMsg = `Database connection failed: ${error.message}`; + console.error("[Migrations] ✗ DATABASE CONNECTION FAILED"); + console.error("Error Code:", error?.code); + console.error("Error Message:", error?.message); + console.error("Database URL:", sanitizedDbUrl); + console.error("Full Error:", JSON.stringify(error, null, 2)); + + logger.error( + { + err: error, + code: error?.code, + databaseUrl: sanitizedDbUrl, + }, + errorMsg, + ); + await migrationClient.end(); + process.exit(1); + } + + // Check for existing migrations (helps diagnose state) + try { + const existingMigrations = await migrationClient` + SELECT table_name + FROM information_schema.tables + WHERE table_schema = 'drizzle' + AND table_name = '__drizzle_migrations' + `; + + if (existingMigrations.length > 0) { + const appliedMigrations = await migrationClient` + SELECT id, hash, created_at + FROM drizzle.__drizzle_migrations + ORDER BY created_at DESC + LIMIT 5 + `; + console.log( + `[Migrations] Found ${appliedMigrations.length} previously applied migrations`, + ); + logger.info( + { count: appliedMigrations.length }, + "[Migrations] Previous migrations detected", + ); + } else { + console.log("[Migrations] No previous migrations found (fresh database)"); + logger.info({}, "[Migrations] Fresh database detected"); + } + } catch (error: any) { + // Ignore errors here - schema might not exist yet + console.log( + "[Migrations] Could not check migration history (expected on first run)", + ); + } + + console.log("[Migrations] Running migrations..."); logger.info({}, "[Migrations] Running migrations..."); try { await migrate(db, { migrationsFolder }); logger.info({}, "[Migrations] ✓ Migrations completed successfully"); + console.log("[Migrations] ✓ Migrations completed successfully"); // Ensure visibility in Railway } catch (error: any) { // Check if it's a "relation already exists" error (PostgreSQL code 42P07) // Drizzle wraps PostgreSQL errors, so check the cause as well @@ -72,16 +169,29 @@ async function main() { if (isAlreadyExistsError) { logger.warn({}, "[Migrations] ⚠️ Some tables already exist - skipping"); logger.info({}, "[Migrations] ✓ Database schema is up to date"); - } else { - logger.error( - { - err: error, - code: errorCode, - message: errorMessage, - migrationsFolder, - }, - "[Migrations] ✗ Migration failed", + console.log( + "[Migrations] ✓ Database schema is up to date (some tables already exist)", ); + } else { + // Log error details to both logger and console for maximum visibility + const errorDetails = { + code: errorCode, + message: errorMessage, + stack: error?.stack, + cause: error?.cause, + migrationsFolder, + }; + + console.error("[Migrations] ✗ MIGRATION FAILED - ERROR DETAILS:"); + console.error("Error Code:", errorCode); + console.error("Error Message:", errorMessage); + console.error("Full Error:", JSON.stringify(error, null, 2)); + console.error("Error Stack:", error?.stack); + if (error?.cause) { + console.error("Error Cause:", JSON.stringify(error.cause, null, 2)); + } + + logger.error(errorDetails, "[Migrations] ✗ Migration failed"); process.exit(1); } } diff --git a/apps/core/server/db/migrations/0031_stormy_black_panther.sql b/apps/core/server/db/migrations/0031_stormy_black_panther.sql index 163bd67..1de2c25 100644 --- a/apps/core/server/db/migrations/0031_stormy_black_panther.sql +++ b/apps/core/server/db/migrations/0031_stormy_black_panther.sql @@ -1,116 +1,116 @@ -DROP INDEX "idx_dialogues_deleted_at";--> statement-breakpoint -DROP INDEX "idx_dialogues_is_public";--> statement-breakpoint -DROP INDEX "idx_dialogues_view_count";--> statement-breakpoint -DROP INDEX "idx_dialogues_created_by_date";--> statement-breakpoint -DROP INDEX "idx_locations_deleted_at";--> statement-breakpoint -DROP INDEX "idx_locations_is_public";--> statement-breakpoint -DROP INDEX "idx_locations_view_count";--> statement-breakpoint -DROP INDEX "idx_lores_deleted_at";--> statement-breakpoint -DROP INDEX "idx_lores_is_public";--> statement-breakpoint -DROP INDEX "idx_lores_view_count";--> statement-breakpoint -DROP INDEX "idx_lores_created_by_date";--> statement-breakpoint -DROP INDEX "idx_music_deleted_at";--> statement-breakpoint -DROP INDEX "idx_music_is_public";--> statement-breakpoint -DROP INDEX "idx_music_view_count";--> statement-breakpoint -DROP INDEX "idx_music_mood_public";--> statement-breakpoint -DROP INDEX "idx_npcs_deleted_at";--> statement-breakpoint -DROP INDEX "idx_npcs_is_public";--> statement-breakpoint -DROP INDEX "idx_npcs_view_count";--> statement-breakpoint -DROP INDEX "idx_npcs_created_by_date";--> statement-breakpoint -DROP INDEX "idx_quests_deleted_at";--> statement-breakpoint -DROP INDEX "idx_quests_is_public";--> statement-breakpoint -DROP INDEX "idx_quests_view_count";--> statement-breakpoint -DROP INDEX "idx_quests_created_by_date";--> statement-breakpoint -DROP INDEX "idx_worlds_deleted_at";--> statement-breakpoint -DROP INDEX "idx_worlds_is_public";--> statement-breakpoint -DROP INDEX "idx_worlds_view_count";--> statement-breakpoint -DROP INDEX "idx_worlds_created_by_date";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_dialogues_deleted_at";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_dialogues_is_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_dialogues_view_count";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_dialogues_created_by_date";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_locations_deleted_at";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_locations_is_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_locations_view_count";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_lores_deleted_at";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_lores_is_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_lores_view_count";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_lores_created_by_date";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_music_deleted_at";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_music_is_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_music_view_count";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_music_mood_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_npcs_deleted_at";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_npcs_is_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_npcs_view_count";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_npcs_created_by_date";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_quests_deleted_at";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_quests_is_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_quests_view_count";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_quests_created_by_date";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_worlds_deleted_at";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_worlds_is_public";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_worlds_view_count";--> statement-breakpoint +DROP INDEX IF EXISTS "idx_worlds_created_by_date";--> statement-breakpoint ALTER TABLE "projects" ALTER COLUMN "owner_id" DROP NOT NULL;--> statement-breakpoint ALTER TABLE "projects" ALTER COLUMN "is_public" SET DEFAULT true;--> statement-breakpoint ALTER TABLE "users" ALTER COLUMN "privy_user_id" DROP NOT NULL;--> statement-breakpoint ALTER TABLE "users" ALTER COLUMN "role" SET DEFAULT 'admin';--> statement-breakpoint ALTER TABLE "assets" ALTER COLUMN "visibility" SET DEFAULT 'public';--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "deleted_at";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "deleted_by";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "view_count";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "favorite_count";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "last_viewed_at";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "is_public";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "is_featured";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "version";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "parent_id";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "is_template";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "quality_score";--> statement-breakpoint -ALTER TABLE "dialogues" DROP COLUMN "is_verified";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "deleted_at";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "deleted_by";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "view_count";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "favorite_count";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "last_viewed_at";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "is_public";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "is_featured";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "version";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "parent_id";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "is_template";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "quality_score";--> statement-breakpoint -ALTER TABLE "locations" DROP COLUMN "is_verified";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "deleted_at";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "deleted_by";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "view_count";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "favorite_count";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "last_viewed_at";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "is_public";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "is_featured";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "version";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "parent_id";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "is_template";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "quality_score";--> statement-breakpoint -ALTER TABLE "lores" DROP COLUMN "is_verified";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "deleted_at";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "deleted_by";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "view_count";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "favorite_count";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "last_viewed_at";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "is_public";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "is_featured";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "version";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "parent_id";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "is_template";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "quality_score";--> statement-breakpoint -ALTER TABLE "music_tracks" DROP COLUMN "is_verified";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "deleted_at";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "deleted_by";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "view_count";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "favorite_count";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "last_viewed_at";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "is_public";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "is_featured";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "version";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "parent_id";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "is_template";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "quality_score";--> statement-breakpoint -ALTER TABLE "npcs" DROP COLUMN "is_verified";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "deleted_at";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "deleted_by";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "view_count";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "favorite_count";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "last_viewed_at";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "is_public";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "is_featured";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "version";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "parent_id";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "is_template";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "quality_score";--> statement-breakpoint -ALTER TABLE "quests" DROP COLUMN "is_verified";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "deleted_at";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "deleted_by";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "view_count";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "favorite_count";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "last_viewed_at";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "is_public";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "is_featured";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "version";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "parent_id";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "is_template";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "quality_score";--> statement-breakpoint -ALTER TABLE "worlds" DROP COLUMN "is_verified"; \ No newline at end of file +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "deleted_at";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "deleted_by";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "view_count";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "favorite_count";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "last_viewed_at";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "is_public";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "is_featured";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "version";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "parent_id";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "is_template";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "quality_score";--> statement-breakpoint +ALTER TABLE "dialogues" DROP COLUMN IF EXISTS "is_verified";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "deleted_at";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "deleted_by";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "view_count";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "favorite_count";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "last_viewed_at";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "is_public";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "is_featured";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "version";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "parent_id";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "is_template";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "quality_score";--> statement-breakpoint +ALTER TABLE "locations" DROP COLUMN IF EXISTS "is_verified";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "deleted_at";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "deleted_by";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "view_count";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "favorite_count";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "last_viewed_at";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "is_public";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "is_featured";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "version";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "parent_id";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "is_template";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "quality_score";--> statement-breakpoint +ALTER TABLE "lores" DROP COLUMN IF EXISTS "is_verified";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "deleted_at";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "deleted_by";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "view_count";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "favorite_count";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "last_viewed_at";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "is_public";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "is_featured";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "version";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "parent_id";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "is_template";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "quality_score";--> statement-breakpoint +ALTER TABLE "music_tracks" DROP COLUMN IF EXISTS "is_verified";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "deleted_at";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "deleted_by";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "view_count";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "favorite_count";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "last_viewed_at";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "is_public";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "is_featured";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "version";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "parent_id";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "is_template";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "quality_score";--> statement-breakpoint +ALTER TABLE "npcs" DROP COLUMN IF EXISTS "is_verified";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "deleted_at";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "deleted_by";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "view_count";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "favorite_count";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "last_viewed_at";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "is_public";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "is_featured";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "version";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "parent_id";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "is_template";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "quality_score";--> statement-breakpoint +ALTER TABLE "quests" DROP COLUMN IF EXISTS "is_verified";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "deleted_at";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "deleted_by";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "view_count";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "favorite_count";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "last_viewed_at";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "is_public";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "is_featured";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "version";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "parent_id";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "is_template";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "quality_score";--> statement-breakpoint +ALTER TABLE "worlds" DROP COLUMN IF EXISTS "is_verified"; \ No newline at end of file