Every production SaaS needs a single place to answer the question “is everything actually running?” without SSHing into a server or digging through logs. Oolvay ships with this page preconfigured, giving super admins immediate visibility into deployment state, runtime configuration, and live infrastructure health without any additional setup.
The System page exposes deployment metadata, Node.js runtime details, database and cache health checks, and Vercel deployment information in a single operational dashboard. All data is generated server-side on every request with revalidate = 0, so what you see always reflects the current state of the running application.
Unlike the rest of the administrative interface, this route is restricted to super admins.
| Section | Purpose |
|---|---|
| Environment | Runtime and deployment metadata |
| Infrastructure | Real-time health checks and latency monitoring |
The Environment section displays metadata about the currently running deployment, assembled at render time and presented in a two-column layout via EnvInfo.
| Field | Source |
|---|---|
| Environment | process.env.NODE_ENV |
| Node.js Version | process.version |
| Platform | process.platform |
| App Version | package.json version field |
| App URL | siteConfig.brand.url |
| Auth URL | process.env.BETTER_AUTH_URL |
| Deployment Environment | process.env.VERCEL_ENV |
| Region | process.env.VERCEL_REGION |
| Git Branch | process.env.VERCEL_GIT_COMMIT_REF |
| Commit SHA | process.env.VERCEL_GIT_COMMIT_SHA (first 7 characters) |
| Commit Message | process.env.VERCEL_GIT_COMMIT_MESSAGE |
| Deployment ID | process.env.VERCEL_DEPLOYMENT_ID |
Vercel-specific fields display unknown or local when running outside of a Vercel deployment.
0 / 2,000 characters
const envItems = [
{ label: "Environment", value: process.env.NODE_ENV ?? "unknown" },
{ label: "Node.js Version", value: process.version },
{ label: "Platform", value: process.platform },
{ label: "App Version", value: packageJson.version },
{ label: "App URL", value: siteConfig.brand.url },
{ label: "Auth URL", value: process.env.BETTER_AUTH_URL ?? "not set" },
{ label: "Deployment Environment", value: process.env.VERCEL_ENV ?? "local" },
{ label: "Region", value: process.env.VERCEL_REGION ?? "unknown" },
{
label: "Git Branch",
value: process.env.VERCEL_GIT_COMMIT_REF ?? "unknown",
},
{ label: "Commit SHA", value: commitSha ? commitSha.slice(0, 7) : "unknown" },
{
label: "Commit Message",
value: process.env.VERCEL_GIT_COMMIT_MESSAGE ?? "unknown",
},
{
label: "Deployment ID",
value: process.env.VERCEL_DEPLOYMENT_ID ?? "unknown",
},
]The Infrastructure section runs live health checks against the database and cache on every page load. Each service is represented by a HealthCard showing operational status, measured latency in milliseconds, and a latency grade badge.
async function checkDatabase() {
const start = Date.now()
await db.execute(sql`SELECT 1`)
return { healthy: true, latencyMs: Date.now() - start }
}async function checkRedis() {
if (!redis) {
return { healthy: false, latencyMs: null, error: "Not configured" }
}
const start = Date.now()
await redis.ping()
return { healthy: true, latencyMs: Date.now() - start }
}Both checks run in parallel.
const [dbHealth, cacheHealth] = await Promise.all([
checkDatabase(),
checkRedis(),
])If Redis is not configured, checkRedis() returns healthy: false with the
error "Not configured". The Cache card displays an outage state. This does
not indicate an application failure.
HealthCard derives an OperationalStatus from the health result and the configured thresholds.
function getOperationalStatus(
healthy: boolean,
latencyMs: number | null,
thresholds: { good: number; degraded: number }
): OperationalStatus {
if (!healthy) return "outage"
if (latencyMs === null) return "outage"
const grade = getLatencyGrade(latencyMs, thresholds)
if (grade === "good") return "operational"
return "degraded"
}Thresholds are defined as constants in infrastructure-health.tsx and passed into each HealthCard.
const DB_THRESHOLDS = { good: 200, degraded: 500 }
const CACHE_THRESHOLDS = { good: 50, degraded: 150 }| Status | Database | Cache |
|---|---|---|
| Operational | under 200 ms | under 50 ms |
| Degraded | 200 to 500 ms | 50 to 150 ms |
| Outage | unreachable | unreachable |
The health dashboard validates connectivity and round-trip latency only. It does not measure query throughput, cache hit rates, memory consumption, or CPU usage.
Health checks run on page load and can be refreshed manually without a full reload. InfrastructureHealth is a client component that holds db and cache state initialised from the server-rendered props.
The Refresh button calls /api/admin/health, updates both health states, and records the time of the last check.
const res = await fetch("/api/admin/health")
const data = await res.json()
setDb(data.db)
setCache(data.cache)
setCheckedAt(new Date(data.checkedAt))The transition is managed with useTransition(), which keeps the button in a disabled spinning state while the fetch is in progress. Errors during refresh are captured to Sentry.
A Super Admin visits /admin/system. The page sets revalidate = 0, so
Next.js never serves a cached version.
getServerSession() retrieves the current session. No session redirects to
/login.
The user role is checked against ROLES.SUPER_ADMIN. Any other role calls
unauthorized().
checkDatabase() and checkRedis() run in parallel via Promise.all. Each
measures its own round-trip latency.
Environment metadata is assembled from process.env, process.version,
process.platform, siteConfig, and package.json.
EnvInfo renders the environment table and InfrastructureHealth receives
the health results as initial props. The page is fully server-rendered on
first load.
Clicking Refresh invokes GET /api/admin/health, which re-runs both health
checks and returns fresh results. InfrastructureHealth updates its local
state without a page reload.
Add a new health check function in app/(protected)/admin/system/page.tsx following the existing shape.
async function checkNewService(): Promise<{
healthy: boolean
latencyMs: number | null
error?: string
}> {
const start = Date.now()
await newServiceClient.ping()
return { healthy: true, latencyMs: Date.now() - start }
}Add it to the Promise.all call alongside the existing checks.
const [dbHealth, cacheHealth, newServiceHealth] = await Promise.all([
checkDatabase(),
checkRedis(),
checkNewService(),
])Define thresholds and pass the result into InfrastructureHealth as a new prop.
const NEW_SERVICE_THRESHOLDS = { good: 100, degraded: 300 }Render a new HealthCard inside InfrastructureHealth using the result and thresholds.
Update /api/admin/health to include the new service in its response so the Refresh button stays in sync with the initial page load.
<HealthCard
name="New Service"
{...newService}
thresholds={NEW_SERVICE_THRESHOLDS}
/>