fix(auto-migrate): tenant_categories on-the-fly erstellung + migrate.js fail-fast
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 10m41s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 10m41s
This commit is contained in:
104
src/lib/auto-migrate.ts
Normal file
104
src/lib/auto-migrate.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Auto-migrate helper: ensures critical tables exist on-the-fly.
|
||||
* Called from API endpoints when a table-missing error is detected.
|
||||
*/
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export async function ensureTenantCategoriesTable() {
|
||||
try {
|
||||
await prisma.$executeRawUnsafe(`
|
||||
CREATE TABLE IF NOT EXISTS tenant_categories (
|
||||
id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"tenantId" TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE
|
||||
)
|
||||
`)
|
||||
console.log('[auto-migrate] tenant_categories ensured')
|
||||
} catch (e: any) {
|
||||
if (e.message?.includes('already exists')) return
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureTenantSymbolsTable() {
|
||||
try {
|
||||
await prisma.$executeRawUnsafe(`
|
||||
CREATE TABLE IF NOT EXISTS tenant_symbols (
|
||||
id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"tenantId" TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
"iconId" TEXT REFERENCES icon_assets(id) ON DELETE SET NULL,
|
||||
UNIQUE("tenantId", "iconId")
|
||||
)
|
||||
`)
|
||||
console.log('[auto-migrate] tenant_symbols ensured')
|
||||
} catch (e: any) {
|
||||
if (e.message?.includes('already exists')) return
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureTenantSymbolsColumns() {
|
||||
const columns = [
|
||||
`ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "name" TEXT`,
|
||||
`ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "svgPath" TEXT`,
|
||||
`ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "isUploaded" BOOLEAN NOT NULL DEFAULT false`,
|
||||
`ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "categoryId" TEXT`,
|
||||
`ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "migratedFromIconId" TEXT`,
|
||||
`ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP`,
|
||||
`ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP`,
|
||||
]
|
||||
for (const sql of columns) {
|
||||
try { await prisma.$executeRawUnsafe(sql) } catch (e) { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureTenantSymbolsCategoryFk() {
|
||||
try {
|
||||
await prisma.$executeRawUnsafe(`
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.table_constraints
|
||||
WHERE constraint_name = 'tenant_symbols_categoryId_fkey'
|
||||
AND table_name = 'tenant_symbols'
|
||||
) THEN
|
||||
ALTER TABLE tenant_symbols
|
||||
ADD CONSTRAINT "tenant_symbols_categoryId_fkey"
|
||||
FOREIGN KEY ("categoryId") REFERENCES tenant_categories(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RAISE NOTICE 'categoryId FK skipped: %', SQLERRM;
|
||||
END $$;
|
||||
`)
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
export async function ensureSymbolTemplatesTable() {
|
||||
try {
|
||||
await prisma.$executeRawUnsafe(`
|
||||
CREATE TABLE IF NOT EXISTS symbol_templates (
|
||||
id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"fileKey" TEXT NOT NULL,
|
||||
"originalFilename" TEXT NOT NULL,
|
||||
"displayName" TEXT,
|
||||
"categoryName" TEXT,
|
||||
"svgPath" TEXT,
|
||||
"metadata" JSONB NOT NULL DEFAULT '{}',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE("fileKey")
|
||||
)
|
||||
`)
|
||||
console.log('[auto-migrate] symbol_templates ensured')
|
||||
} catch (e: any) {
|
||||
if (e.message?.includes('already exists')) return
|
||||
throw e
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user