Files
llmapikey/lib/db/postgres-client.js
T
tiennm99 02fa52ccf9 feat: scaffold OpenRouter key giveaway site (gated, code-only)
- Next.js 15 App Router (JS+JSDoc): landing, auth-gated dashboard, docs
- GitHub OAuth via Supabase; identity anchored on numeric provider_id
- key provisioning: reserve-then-mint-persist-compensate, one key per account
- api_keys in unexposed llmapikey schema via direct Postgres; RLS deny-all
- live minting gated behind PROVISIONING_ENABLED; Vercel auto-deploy disabled
- unit tests (mask, request-body), RLS deny-all test, reconcile script
2026-06-13 14:18:52 +07:00

42 lines
1.3 KiB
JavaScript

import "server-only";
import postgres from "postgres";
/**
* Direct Postgres client for the unexposed `llmapikey` schema.
*
* Why direct PG (not supabase-js): the `llmapikey` schema is intentionally NOT
* added to PostgREST's exposed schemas, so the REST API (and therefore the anon
* role) cannot reach `api_keys` at all. supabase-js cannot query an unexposed
* schema. A direct Postgres connection sidesteps PostgREST entirely.
*
* This module is `server-only`; DATABASE_URL must never reach the client bundle.
*
* Connection: use Supabase's pooler connection string. In transaction-pooling
* mode (port 6543) prepared statements are unsupported, so `prepare: false`.
*
* @type {import('postgres').Sql}
*/
let sql;
/**
* Lazily create the singleton sql client. Lazy so importing this module never
* throws at build time when DATABASE_URL is absent (e.g. CI without secrets).
*
* @returns {import('postgres').Sql}
*/
export function getSql() {
if (sql) return sql;
const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
throw new Error("Missing required environment variable: DATABASE_URL");
}
sql = postgres(connectionString, {
prepare: false,
max: 5,
idle_timeout: 20,
connect_timeout: 10,
});
return sql;
}