chore(infra): auth fast-path, pg pool tuning, react-doctor devdep

Three coordinated changes that improve CI/build ergonomics and dev-mode
performance. None change database schema; all are reversible by env var.

src/lib/auth.ts
  Wrap Neon Auth getSession() with a fast-path that returns null when
  NEON_AUTH_BASE_URL is unset/placeholder (CI build-time value) OR when
  the dev_session cookie is set with a recognized role. The real
  getSession() does a network fetch and pays a 30s DNS timeout when the
  env var is unset. Admin pages each call getSession (directly or via
  getAdminUser()) — paying that tax per page load is unacceptable.

src/lib/db.ts + db/client.ts
  Raise PG_POOL_MAX default 10 -> 50 (Vercel function concurrency can
  exceed 10 with parallel RPCs). Lower PG_POOL_CONN_TIMEOUT_MS default
  30s -> 5s in src/lib/db.ts and 10s -> 5s in db/client.ts so a bad
  Neon branch fails fast instead of hanging requests.

src/lib/admin-permissions.ts + src/proxy.ts
  Add PERF_TEST_AUTH=1 env var that lets dev_session cookies bypass
  Neon Auth in production mode. Used by Playwright perf benchmarks
  against authenticated admin pages. NEVER set this in real production —
  the dev_session cookie then grants platform_admin / brand_admin /
  store_employee with no password check. The middleware guard in
  proxy.ts and getAdminUser() both honor the flag; the flag is the
  only toggle needed.

package.json
  Add react-doctor ^0.5.8 to devDependencies (used to drive the lint
  cleanup that landed in the 38 commits already on this branch).
This commit is contained in:
Nora
2026-06-26 17:08:22 -06:00
parent bb349e42f5
commit 826f554ae1
6 changed files with 70 additions and 11 deletions
+4 -2
View File
@@ -29,8 +29,10 @@ import type { AdminRole, AdminUser, TenantContext } from "@/lib/admin-permission
* shows "Access Denied" — correct behavior.
*/
export async function getAdminUser(): Promise<AdminUser | null> {
// Check for dev_session cookie in development mode
if (process.env.NODE_ENV !== "production") {
// Check for dev_session cookie in development mode, or when
// PERF_TEST_AUTH=1 (for production-mode perf benchmarks against
// authenticated admin pages — never enable in real production).
if (process.env.NODE_ENV !== "production" || process.env.PERF_TEST_AUTH === "1") {
const cookieStore = await cookies();
const devSession = cookieStore.get("dev_session")?.value;
if (devSession === "platform_admin" || devSession === "brand_admin" || devSession === "store_employee") {
+55 -2
View File
@@ -19,14 +19,67 @@ import "server-only";
import { createNeonAuth } from "@neondatabase/auth/next/server";
import { getNeonAuthConfig } from "@/auth.config";
import { cookies } from "next/headers";
const auth = createNeonAuth({
baseUrl: getNeonAuthConfig().baseUrl,
cookies: { secret: getNeonAuthConfig().cookieSecret },
});
export const { getSession, signIn, signOut, resetPassword, requestPasswordReset } = auth;
export const { listUsers, createUser, setRole, setUserPassword, updateUser } = auth.admin;
const { getSession: _realGetSession, signIn, signOut, resetPassword, requestPasswordReset } = auth;
const { listUsers, createUser, setRole, setUserPassword, updateUser } = auth.admin;
export { signIn, signOut, resetPassword, requestPasswordReset };
export { listUsers, createUser, setRole, setUserPassword, updateUser };
/**
* Fast-path wrapper around Neon Auth's `getSession()`.
*
* Neon Auth's real `getSession()` does a network fetch to the configured
* Auth base URL. When the env var is unset (or set to the CI build-time
* `placeholder.local`), every call hits a 30s DNS timeout before
* returning `null`. Admin pages each call `getSession()` (directly or
* via `getAdminUser()`) — paying that 30s tax on every page load is
* unacceptable.
*
* Short-circuits when:
* 1. `NEON_AUTH_BASE_URL` is unset / placeholder — Neon Auth can't
* resolve anything useful; return `null` immediately.
* 2. The `dev_session` cookie is set with a recognized role — we
* trust it as a development bypass and skip the network fetch.
*
* In production with a real `NEON_AUTH_BASE_URL` and no dev_session,
* falls through to the real Neon Auth lookup unchanged.
*/
function isAuthConfigured(): boolean {
const url = process.env.NEON_AUTH_BASE_URL;
if (!url || url === "placeholder" || url === "https://placeholder.local") return false;
return true;
}
async function isDevSession(): Promise<boolean> {
if (process.env.NODE_ENV === "production" && process.env.PERF_TEST_AUTH !== "1") return false;
try {
const store = await cookies();
const v = store.get("dev_session")?.value;
return v === "platform_admin" || v === "brand_admin" || v === "store_employee";
} catch {
return false;
}
}
export async function getSession(): Promise<Awaited<ReturnType<typeof _realGetSession>>> {
if (!isAuthConfigured()) {
if (process.env.PERF_TEST_AUTH === "1") console.log("[auth] getSession short-circuit: not configured");
return { data: null, error: null } as Awaited<ReturnType<typeof _realGetSession>>;
}
if (await isDevSession()) {
if (process.env.PERF_TEST_AUTH === "1") console.log("[auth] getSession short-circuit: dev_session");
return { data: null, error: null } as Awaited<ReturnType<typeof _realGetSession>>;
}
if (process.env.PERF_TEST_AUTH === "1") console.log("[auth] getSession calling real Neon Auth");
return _realGetSession();
}
/**
* Re-exported for the API route handler compatibility.
+2 -2
View File
@@ -48,10 +48,10 @@ function buildPool(): Pool {
// PG_POOL_MAX (default 10)
// PG_POOL_IDLE_MS (default 30s)
// PG_POOL_CONN_TIMEOUT_MS (default 10s)
max: parseInt(process.env.PG_POOL_MAX ?? "10", 10),
max: parseInt(process.env.PG_POOL_MAX ?? "50", 10),
idleTimeoutMillis: parseInt(process.env.PG_POOL_IDLE_MS ?? "30000", 10),
connectionTimeoutMillis: parseInt(
process.env.PG_POOL_CONN_TIMEOUT_MS ?? "30000",
process.env.PG_POOL_CONN_TIMEOUT_MS ?? "5000",
10,
),
// Vercel/serverless recycling: keep the pool hot for warm invocations.
+6 -3
View File
@@ -104,14 +104,17 @@ function hasNeonAuthSession(request: NextRequest): boolean {
}
// Development bypass: allow dev_session cookie for local testing
// This bypass only works when NODE_ENV is not "production"
if (process.env.NODE_ENV !== "production") {
// This bypass works when NODE_ENV is not "production", OR when
// PERF_TEST_AUTH=1 is set (for production-mode perf benchmarks against
// authenticated admin pages — never enable in real production).
const perfTestAuth = process.env.PERF_TEST_AUTH === "1";
if (process.env.NODE_ENV !== "production" || perfTestAuth) {
const devSession = cookies.get("dev_session")?.value;
if (devSession === "platform_admin" || devSession === "brand_admin" || devSession === "store_employee") {
return true;
}
}
return false;
}