fix: use static SQL for user column migration
This commit is contained in:
@@ -83,30 +83,33 @@ async function ensureToolRelationsTable(): Promise<void> {
|
|||||||
|
|
||||||
async function ensureUserColumns(): Promise<void> {
|
async function ensureUserColumns(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const cols = await db.execute(
|
const rows = (await db.execute(
|
||||||
sql`SELECT column_name FROM information_schema.columns WHERE table_name = 'users'`,
|
sql`SELECT column_name, is_nullable FROM information_schema.columns WHERE table_name = 'users'`,
|
||||||
);
|
)).rows as { column_name: string; is_nullable: string }[];
|
||||||
const existing = new Set((cols.rows as [{ column_name: string }]).map((r) => r.column_name));
|
const existing = new Map(rows.map((r) => [r.column_name, r.is_nullable]));
|
||||||
const toAdd: { name: string; def: string }[] = [];
|
|
||||||
if (!existing.has("tier")) toAdd.push({ name: "tier", def: "text NOT NULL DEFAULT 'free'" });
|
if (!existing.has("tier")) {
|
||||||
if (!existing.has("auth_provider")) toAdd.push({ name: "auth_provider", def: "text NOT NULL DEFAULT 'local'" });
|
await db.execute(sql`ALTER TABLE "users" ADD COLUMN "tier" text NOT NULL DEFAULT 'free'`);
|
||||||
if (!existing.has("auth_provider_id")) toAdd.push({ name: "auth_provider_id", def: "text" });
|
logger.info("Added column: tier");
|
||||||
if (!existing.has("display_name")) toAdd.push({ name: "display_name", def: "text" });
|
|
||||||
if (!existing.has("password_hash")) {
|
|
||||||
toAdd.push({ name: "password_hash", def: "text" });
|
|
||||||
} else {
|
|
||||||
const [ph] = await db.execute(
|
|
||||||
sql`SELECT is_nullable FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'password_hash'`,
|
|
||||||
);
|
|
||||||
const nullable = (ph.rows as [{ is_nullable: string }])[0]?.is_nullable;
|
|
||||||
if (nullable === "NO") {
|
|
||||||
await db.execute(sql`ALTER TABLE "users" ALTER COLUMN "password_hash" DROP NOT NULL`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (const col of toAdd) {
|
if (!existing.has("auth_provider")) {
|
||||||
const stmt = `ALTER TABLE "users" ADD COLUMN "${col.name}" ${col.def}`;
|
await db.execute(sql`ALTER TABLE "users" ADD COLUMN "auth_provider" text NOT NULL DEFAULT 'local'`);
|
||||||
await db.execute(sql.raw(stmt));
|
logger.info("Added column: auth_provider");
|
||||||
logger.info({ column: col.name }, "Added column to users table");
|
}
|
||||||
|
if (!existing.has("auth_provider_id")) {
|
||||||
|
await db.execute(sql`ALTER TABLE "users" ADD COLUMN "auth_provider_id" text`);
|
||||||
|
logger.info("Added column: auth_provider_id");
|
||||||
|
}
|
||||||
|
if (!existing.has("display_name")) {
|
||||||
|
await db.execute(sql`ALTER TABLE "users" ADD COLUMN "display_name" text`);
|
||||||
|
logger.info("Added column: display_name");
|
||||||
|
}
|
||||||
|
if (!existing.has("password_hash")) {
|
||||||
|
await db.execute(sql`ALTER TABLE "users" ADD COLUMN "password_hash" text`);
|
||||||
|
logger.info("Added column: password_hash");
|
||||||
|
} else if (existing.get("password_hash") === "NO") {
|
||||||
|
await db.execute(sql`ALTER TABLE "users" ALTER COLUMN "password_hash" DROP NOT NULL`);
|
||||||
|
logger.info("Made password_hash nullable");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error({ err }, "Failed to ensure user columns");
|
logger.error({ err }, "Failed to ensure user columns");
|
||||||
@@ -166,6 +169,7 @@ async function start(): Promise<void> {
|
|||||||
await ensureToolRelationsTable();
|
await ensureToolRelationsTable();
|
||||||
await ensureToolCostsTable();
|
await ensureToolCostsTable();
|
||||||
await ensureVoterTokenColumn();
|
await ensureVoterTokenColumn();
|
||||||
|
await ensureUserColumns();
|
||||||
await seedAdminUser();
|
await seedAdminUser();
|
||||||
await ensureAdminTier();
|
await ensureAdminTier();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user