Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions apps/core/server/db/migrate.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
/**
* Database Migration Runner
* Runs pending migrations against the database
* Note: Bun auto-loads .env files, no dotenv needed
*/

import "dotenv/config";
import { drizzle } from "drizzle-orm/postgres-js";
import { logger } from "../utils/logger";
import { migrate } from "drizzle-orm/postgres-js/migrator";
import postgres from "postgres";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
import { logger } from "../utils/logger";

// Get absolute path to migrations folder
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const migrationsFolder = join(__dirname, "migrations");

// Validate environment
if (!process.env.DATABASE_URL) {
Expand All @@ -22,6 +29,15 @@ if (!process.env.DATABASE_URL) {
process.exit(1);
}

// Log migration info for debugging
logger.info(
{
migrationsFolder,
databaseUrl: process.env.DATABASE_URL?.replace(/:[^:@]+@/, ":****@"), // Hide password
Comment thread
Dexploarer marked this conversation as resolved.
Outdated
},
Comment on lines +35 to +45
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Remove redundant optional chaining operator

Suggested change
migrationsFolder,
databaseUrl: process.env.DATABASE_URL?.replace(/:[^:@]+@/, ":****@"), // Hide password
},
migrationsFolder,
databaseUrl: process.env.DATABASE_URL.replace(/:[^:@]+@/, ":****@"), // Hide password
},

"[Migrations] Starting migration process",
);

// Migration connection with NOTICE suppression
const migrationClient = postgres(process.env.DATABASE_URL, {
max: 1,
Expand All @@ -34,7 +50,7 @@ async function main() {
logger.info({}, "[Migrations] Running migrations...");

try {
await migrate(db, { migrationsFolder: "./server/db/migrations" });
await migrate(db, { migrationsFolder });
logger.info({}, "[Migrations] ✓ Migrations completed successfully");
} catch (error: any) {
// Check if it's a "relation already exists" error (PostgreSQL code 42P07)
Expand All @@ -49,7 +65,15 @@ async function main() {
logger.warn({}, "[Migrations] ⚠️ Some tables already exist - skipping");
logger.info({}, "[Migrations] ✓ Database schema is up to date");
} else {
logger.error({ err: error }, "[Migrations] ✗ Migration failed:");
logger.error(
{
err: error,
code: errorCode,
message: errorMessage,
migrationsFolder,
},
"[Migrations] ✗ Migration failed",
);
process.exit(1);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resource Management: Potential Unclosed Database Connection

If an error occurs before migrationClient.end() is called (for example, if an exception is thrown before or during the migration process), the database connection may remain open. To ensure proper resource cleanup, consider using a finally block to always close the connection, regardless of whether an error occurs:

try {
  await migrate(db, { migrationsFolder });
  logger.info({}, "[Migrations] ✓ Migrations completed successfully");
} catch (error: any) {
  // ... error handling ...
} finally {
  await migrationClient.end();
}

This guarantees that the connection is closed even if an error is thrown.

Expand Down
42 changes: 0 additions & 42 deletions apps/core/server/db/migrations/0030_fix_uuid_defaults.sql

This file was deleted.

194 changes: 0 additions & 194 deletions apps/core/server/db/migrations/0031_add_row_level_security.sql

This file was deleted.

Loading