import { asc, eq } from "drizzle-orm";
import { db } from "../db";
import { siteAdmins, systemFlags, users } from "../db/schema";
export async function isSiteAdmin(
userId: string | null | undefined
): Promise<boolean> {
if (!userId) return false;
try {
const [row] = await db
.select({ userId: siteAdmins.userId })
.from(siteAdmins)
.where(eq(siteAdmins.userId, userId))
.limit(1);
if (row) return true;
const [anyAdmin] = await db.select().from(siteAdmins).limit(1);
if (anyAdmin) return false;
const [first] = await db
.select({ id: users.id })
.from(users)
.orderBy(asc(users.createdAt))
.limit(1);
return !!first && first.id === userId;
} catch {
return false;
}
}
export async function listSiteAdmins() {
try {
return await db
.select({
userId: siteAdmins.userId,
username: users.username,
grantedAt: siteAdmins.grantedAt,
grantedBy: siteAdmins.grantedBy,
})
.from(siteAdmins)
.innerJoin(users, eq(siteAdmins.userId, users.id));
} catch {
return [];
}
}
export async function grantSiteAdmin(
userId: string,
grantedBy: string | null
): Promise<boolean> {
try {
await db
.insert(siteAdmins)
.values({ userId, grantedBy: grantedBy || null })
.onConflictDoNothing();
return true;
} catch {
return false;
}
}
export async function revokeSiteAdmin(userId: string): Promise<boolean> {
try {
const res = await db
.delete(siteAdmins)
.where(eq(siteAdmins.userId, userId))
.returning({ userId: siteAdmins.userId });
return res.length > 0;
} catch {
return false;
}
}
export async function getFlag(key: string): Promise<string | null> {
try {
const [row] = await db
.select({ value: systemFlags.value })
.from(systemFlags)
.where(eq(systemFlags.key, key))
.limit(1);
return row?.value ?? null;
} catch {
return null;
}
}
export async function setFlag(
key: string,
value: string,
updatedBy: string | null
): Promise<boolean> {
try {
await db
.insert(systemFlags)
.values({ key, value, updatedBy: updatedBy || null })
.onConflictDoUpdate({
target: systemFlags.key,
set: { value, updatedBy: updatedBy || null, updatedAt: new Date() },
});
return true;
} catch (err) {
console.error("[admin] setFlag:", err);
return false;
}
}
export async function listFlags() {
try {
return await db.select().from(systemFlags);
} catch {
return [];
}
}
export const KNOWN_FLAGS = {
registration_locked: "0",
site_banner_text: "",
site_banner_level: "info",
read_only_mode: "0",
} as const;
export type FlagKey = keyof typeof KNOWN_FLAGS;
|