feat(db): phase 4 group 1 — lib/ settings + notifications to Drizzle

Convert lib/settings.ts, lib/notifications/{in-app,email,capa-escalation,
effectiveness-recheck}.ts from Supabase PostgREST to Drizzle asAdmin queries.
Drop supabase arg from all call sites in app/api/ and cron routes. Rewrite
notification unit tests to mock @/lib/db/with-user instead of SupabaseClient.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 16:37:51 +08:00
co-authored by Claude Sonnet 4.6
parent d18d29168a
commit 25f923f530
19 changed files with 296 additions and 300 deletions
+18 -16
View File
@@ -1,4 +1,6 @@
import type { SupabaseClient } from '@supabase/supabase-js'
import 'server-only'
import { asAdmin } from '@/lib/db/with-user'
import { notificationsLog } from '@/lib/db/schema'
export interface InAppNotification {
userId: string
@@ -8,11 +10,7 @@ export interface InAppNotification {
capaId?: string
}
// Inserts go through the create_in_app_notification SECURITY DEFINER RPC:
// notifications_log INSERT is RLS-restricted to elevated roles, but reporters
// must still be able to trigger alerts to supervisors/HSE.
export async function createInAppNotifications(
supabase: SupabaseClient,
notifications: InAppNotification[],
): Promise<{ created: number }> {
const seen = new Set<string>()
@@ -24,18 +22,22 @@ export async function createInAppNotifications(
if (seen.has(key)) continue
seen.add(key)
const { error } = await supabase.rpc('create_in_app_notification', {
p_recipient: n.userId,
p_title: n.title,
p_link: n.link ?? null,
p_incident_id: n.incidentId ?? null,
p_capa_id: n.capaId ?? null,
})
if (error) {
console.error('in-app notification error:', error)
continue
try {
await asAdmin(db =>
db.insert(notificationsLog).values({
channel: 'in_app',
recipient: n.userId,
recipientUserId: n.userId,
title: n.title,
link: n.link ?? null,
incidentId: n.incidentId ?? null,
capaId: n.capaId ?? null,
})
)
created++
} catch (e) {
console.error('in-app notification error:', e)
}
created++
}
return { created }