- New Express + TypeScript backend (server/) with pg, Better Auth, local file storage - De-Supabased Postgres schema (server/db) and TS reimplementations of DB functions - Frontend data layer rewired to REST (rest-client + backend-client compat shim) - Removed all Supabase references (code, config, deps, docs) - New brand assets: gradient favicon/app icons + dark/white wordmark logos Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
30 lines
996 B
TypeScript
30 lines
996 B
TypeScript
import { one } from '../db.js';
|
|
|
|
export type AppRole = 'admin' | 'moderator' | 'user';
|
|
|
|
/** Reimplements public.has_role(uuid, app_role). */
|
|
export async function hasRole(userId: string, role: AppRole): Promise<boolean> {
|
|
const row = await one<{ exists: boolean }>(
|
|
`SELECT EXISTS (SELECT 1 FROM public.user_roles WHERE user_id = $1 AND role = $2) AS exists`,
|
|
[userId, role]
|
|
);
|
|
return !!row?.exists;
|
|
}
|
|
|
|
/** Reimplements public.get_user_role(uuid). Returns null if none. */
|
|
export async function getUserRole(userId: string): Promise<AppRole | null> {
|
|
const row = await one<{ role: AppRole }>(
|
|
`SELECT role FROM public.user_roles WHERE user_id = $1 LIMIT 1`,
|
|
[userId]
|
|
);
|
|
return row?.role ?? null;
|
|
}
|
|
|
|
/** Reimplements public.no_admin_exists(). */
|
|
export async function noAdminExists(): Promise<boolean> {
|
|
const row = await one<{ exists: boolean }>(
|
|
`SELECT NOT EXISTS (SELECT 1 FROM public.user_roles WHERE role = 'admin') AS exists`
|
|
);
|
|
return !!row?.exists;
|
|
}
|