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
+1 -1
View File
@@ -28,7 +28,7 @@ export async function POST(
if ((recentCount ?? 0) > 0)
return NextResponse.json({ error: 'Rate limited — please wait 60 seconds' }, { status: 429 })
const deepseekKey = await getApiKey(supabase, 'DEEPSEEK_API_KEY')
const deepseekKey = await getApiKey('DEEPSEEK_API_KEY')
const client = createDeepSeekClient(deepseekKey)
const { data: incident } = await supabase
@@ -28,7 +28,7 @@ export async function POST(
if ((recentCount ?? 0) > 0)
return NextResponse.json({ error: 'Rate limited — please wait 60 seconds' }, { status: 429 })
const deepseekKey = await getApiKey(supabase, 'DEEPSEEK_API_KEY')
const deepseekKey = await getApiKey('DEEPSEEK_API_KEY')
const client = createDeepSeekClient(deepseekKey)
const { data: incident } = await supabase
+1 -1
View File
@@ -51,7 +51,7 @@ export async function POST(
})
if (incident.reported_by) {
await createInAppNotifications(supabase, [{
await createInAppNotifications([{
userId: incident.reported_by,
title: `Your incident report ${incident.reference_no ?? ''} has been closed`,
link: '/reporter',
+1 -1
View File
@@ -18,7 +18,7 @@ export async function GET(
const supabase = await createClient()
const googleAiKey = await getApiKey(supabase, 'GOOGLE_AI_API_KEY')
const googleAiKey = await getApiKey('GOOGLE_AI_API_KEY')
const { data: incident } = await supabase
.from('incidents')