mirror of
https://github.com/tiennm99/bsk.git
synced 2026-06-17 20:47:46 +00:00
10a3693f1b
- env: cross-check VERCEL_ENV against NEXT_PUBLIC_APP_ENV at boot so prod credentials cannot silently write into a dev keyspace - upstash: tighten cache-key regex (kebab + colon only); split SCAN patterns into their own validator so glob '*' is allowed only there - eslint: forbid raw @upstash/redis, @upstash/ratelimit, @supabase/supabase-js imports outside the named factory files - supabase/admin: harmonize 'use cache' guidance with CONTRIBUTING.md (safe inside cache; partition key on identity for user-specific reads) - app/layout: clarify global-error.tsx vs error.tsx shell requirements given the passthrough root layout - readme: Next.js 15 -> 16 (matches scaffolded version)
25 lines
1005 B
TypeScript
25 lines
1005 B
TypeScript
import "server-only";
|
|
import { createClient } from "@supabase/supabase-js";
|
|
import { serverEnv, SUPABASE_SCHEMA } from "@/lib/env/server";
|
|
|
|
/**
|
|
* Privileged Supabase client (uses the secret key, bypasses RLS on behalf of no user).
|
|
* Use only for admin tasks: invites, cron sweeps, system writes.
|
|
* NEVER expose this client to the browser.
|
|
*
|
|
* `'use cache'` interaction: this factory does NOT read cookies, so it is safe
|
|
* to call inside a cached scope. But if the result depends on a caller's identity
|
|
* (user / role / tenant), the cache key MUST partition on that identity — otherwise
|
|
* one user sees another user's data. For genuinely user-agnostic reads (e.g.
|
|
* clinic settings, services list), no key partitioning is needed.
|
|
*/
|
|
export function createSupabaseAdminClient() {
|
|
return createClient(serverEnv.NEXT_PUBLIC_SUPABASE_URL, serverEnv.SUPABASE_SECRET_KEY, {
|
|
db: { schema: SUPABASE_SCHEMA },
|
|
auth: {
|
|
persistSession: false,
|
|
autoRefreshToken: false,
|
|
},
|
|
});
|
|
}
|