migrate: replace Supabase REST with Drizzle/pg in water-log/time-tracking/reports/etc (wave 4)

This commit is contained in:
2026-06-07 03:05:00 +00:00
parent 01198111ea
commit b8317a200e
16 changed files with 346 additions and 545 deletions
+16 -37
View File
@@ -1,7 +1,7 @@
import "server-only";
import { getAdminUser } from "@/lib/admin-permissions";
import { svcHeaders } from "@/lib/svc-headers";
import { pool } from "@/lib/db";
export type BrandListItem = {
id: string;
@@ -16,49 +16,28 @@ export type BrandListItem = {
* - platform_admin: all brands (queried directly from the `brands` table)
* - everyone else: brands in `adminUser.brand_ids`
* - empty array for unauthenticated / no-access admins
*
* This is a plain async function (not a server action) so it can be called
* from server components and server actions without the "use server" wrapper.
* The BrandSelector client component receives the result as a prop.
*/
export async function listBrandsForAdmin(): Promise<BrandListItem[]> {
const adminUser = await getAdminUser();
if (!adminUser) return [];
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
if (!supabaseUrl || !serviceKey) return [];
if (adminUser.role === "platform_admin") {
try {
const res = await fetch(
`${supabaseUrl}/rest/v1/brands?select=id,name,slug,logo_url&order=name`,
{ headers: svcHeaders(serviceKey), cache: "no-store" }
);
if (!res.ok) return [];
const data = await res.json();
return Array.isArray(data) ? data : [];
} catch {
return [];
}
}
if (adminUser.brand_ids.length === 0) return [];
// Use PostgREST `in` filter. The brand_ids are UUIDs, so the quoting
// pattern in the spec is safe; the inner quotes are required by PostgREST
// for UUID literals.
const filter = `id=in.(${adminUser.brand_ids
.map((id) => `"${id}"`)
.join(",")})`;
try {
const res = await fetch(
`${supabaseUrl}/rest/v1/brands?${filter}&select=id,name,slug,logo_url&order=name`,
{ headers: svcHeaders(serviceKey), cache: "no-store" }
if (adminUser.role === "platform_admin") {
const { rows } = await pool.query<BrandListItem>(
`SELECT id, name, slug, logo_url FROM brands ORDER BY name`,
);
return rows;
}
if (adminUser.brand_ids.length === 0) return [];
const { rows } = await pool.query<BrandListItem>(
`SELECT id, name, slug, logo_url FROM brands
WHERE id = ANY($1::uuid[])
ORDER BY name`,
[adminUser.brand_ids],
);
if (!res.ok) return [];
const data = await res.json();
return Array.isArray(data) ? data : [];
return rows;
} catch {
return [];
}