perf(ux): request-cached permission checks (dedupe RPC fan-out)

New React cache()-wrapped hasPermission(uid,sid,perm): identical checks
resolve once per server render, so the (app) layout's nav-permission
resolution and a page's checks for the same perm (door.manage,
forms.manage) no longer double-round-trip user_has_permission. Pure
dedupe -- semantics unchanged, permission logic stays in SQL/RLS.
Adopted in the layout + members page.
This commit is contained in:
Moheeb Zara
2026-05-17 01:36:54 -07:00
parent ca498d5163
commit b8440e9c9e
3 changed files with 27 additions and 19 deletions
+16
View File
@@ -0,0 +1,16 @@
import { cache } from 'react'
import { createClient } from '@/lib/supabase/server'
// Request-scoped memoized permission check. The same (uid, sid, perm) is
// resolved at most once per server render, so the layout and the page it
// renders no longer double-round-trip the `user_has_permission` RPC for
// overlapping permissions (e.g. door.manage / forms.manage). Semantics are
// identical to calling the RPC directly -- this only dedupes, it does NOT
// reimplement permission logic (that stays in the SQL function + RLS).
export const hasPermission = cache(
async (uid: string, sid: string, perm: string): Promise<boolean> => {
const supabase = await createClient()
const { data } = await supabase.rpc('user_has_permission', { uid, sid, perm })
return !!data
},
)