Migra banco de dados de SQLite para PostgreSQL
- Muda provider Prisma de sqlite para postgresql - Remove dependencias SQLite (better-sqlite3, adapter) - Atualiza Better Auth para provider postgresql - Simplifica prisma.ts removendo adapter SQLite - Atualiza stack.yml para usar PostgreSQL existente com 2 replicas - Remove logica de rebuild better-sqlite3 do start-web.sh - Adiciona script de migracao de dados SQLite -> PostgreSQL - Atualiza healthcheck para testar PostgreSQL via Prisma - Habilita start-first deploy para zero-downtime Melhoria: permite multiplas replicas e deploys sem downtime. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
fb97d9bec8
commit
33a59634e7
10 changed files with 362 additions and 223 deletions
|
|
@ -18,27 +18,13 @@ export async function GET() {
|
|||
},
|
||||
}
|
||||
|
||||
// Test SQLite binding
|
||||
try {
|
||||
const Database = (await import("better-sqlite3")).default
|
||||
const testDb = new Database(":memory:")
|
||||
testDb.exec("SELECT 1")
|
||||
testDb.close()
|
||||
diagnostics.sqlite = { status: "ok", message: "better-sqlite3 binding works" }
|
||||
} catch (error) {
|
||||
diagnostics.sqlite = {
|
||||
status: "error",
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
}
|
||||
}
|
||||
|
||||
// Test Prisma connection
|
||||
// Test PostgreSQL connection via Prisma
|
||||
try {
|
||||
const { prisma } = await import("@/lib/prisma")
|
||||
await prisma.$queryRaw`SELECT 1`
|
||||
diagnostics.prisma = { status: "ok", message: "Prisma connection works" }
|
||||
diagnostics.postgres = { status: "ok", message: "PostgreSQL connection works" }
|
||||
} catch (error) {
|
||||
diagnostics.prisma = {
|
||||
diagnostics.postgres = {
|
||||
status: "error",
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export const auth = betterAuth({
|
|||
)
|
||||
),
|
||||
database: prismaAdapter(prisma, {
|
||||
provider: "sqlite",
|
||||
provider: "postgresql",
|
||||
}),
|
||||
user: {
|
||||
// Use the exact Prisma client property names (lower camel case)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
import path from "node:path"
|
||||
|
||||
import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3"
|
||||
import { PrismaClient } from "@/generated/prisma/client"
|
||||
|
||||
type PrismaClientInstance = InstanceType<typeof PrismaClient>
|
||||
|
|
@ -17,69 +14,18 @@ declare global {
|
|||
var prisma: PrismaClientInstance | undefined
|
||||
}
|
||||
|
||||
// Resolve a robust DATABASE_URL for all runtimes (prod/dev)
|
||||
const PROJECT_ROOT = process.cwd()
|
||||
const PRISMA_DIR = path.join(PROJECT_ROOT, "prisma")
|
||||
// PostgreSQL connection - requires DATABASE_URL environment variable
|
||||
const databaseUrl = process.env.DATABASE_URL
|
||||
|
||||
function resolveFileUrl(url: string) {
|
||||
if (!url.startsWith("file:")) {
|
||||
return url
|
||||
}
|
||||
|
||||
const filePath = url.slice("file:".length)
|
||||
|
||||
if (filePath.startsWith("//")) {
|
||||
return url
|
||||
}
|
||||
|
||||
if (path.isAbsolute(filePath)) {
|
||||
return `file:${path.normalize(filePath)}`
|
||||
}
|
||||
|
||||
const normalized = path.normalize(filePath)
|
||||
const prismaPrefix = `prisma${path.sep}`
|
||||
const relativeToPrisma = normalized.startsWith(prismaPrefix)
|
||||
? normalized.slice(prismaPrefix.length)
|
||||
: normalized
|
||||
|
||||
const absolutePath = path.resolve(PRISMA_DIR, relativeToPrisma)
|
||||
|
||||
if (!absolutePath.startsWith(PROJECT_ROOT)) {
|
||||
throw new Error(`DATABASE_URL path escapes project directory: ${filePath}`)
|
||||
}
|
||||
|
||||
return `file:${absolutePath}`
|
||||
if (!databaseUrl) {
|
||||
throw new Error("DATABASE_URL environment variable is required for PostgreSQL connection")
|
||||
}
|
||||
|
||||
function normalizeDatasourceUrl(envUrl?: string | null) {
|
||||
const trimmed = envUrl?.trim()
|
||||
if (trimmed) {
|
||||
return resolveFileUrl(trimmed)
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
return "file:/app/data/db.sqlite"
|
||||
}
|
||||
|
||||
return resolveFileUrl("file:./db.dev.sqlite")
|
||||
}
|
||||
|
||||
const resolvedDatabaseUrl = normalizeDatasourceUrl(process.env.DATABASE_URL)
|
||||
process.env.DATABASE_URL = resolvedDatabaseUrl
|
||||
|
||||
const sqliteAdapter = new PrismaBetterSqlite3({
|
||||
url: resolvedDatabaseUrl,
|
||||
})
|
||||
|
||||
export const prisma = global.prisma ?? new PrismaClient({ adapter: sqliteAdapter })
|
||||
export const prisma = global.prisma ?? new PrismaClient()
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
global.prisma = prisma
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
// Helps detect mismatched DB path during dev server bootstrap
|
||||
console.log("[prisma] Using database:", resolvedDatabaseUrl)
|
||||
console.log("[prisma] Using PostgreSQL database")
|
||||
}
|
||||
|
||||
export * from "@/generated/prisma/client"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue