Skip to content

auth-healthcheck.py

auth-healthcheck.py

Script: tools/auth-healthcheck.py
Config: tools/auth-healthcheck.env (copy from tools/auth-healthcheck.env.example)
Report: auth-healthcheck-YYYYMMDD-HHMMSS.json (repo root, gitignored)

End-to-end production auth diagnostic for the Better Auth / Bloqr stack. Validates the full authentication chain from sign-up through session validation, then checks every backing store (KV, D1, Neon) and captures wrangler tail logs in the background.


What It Checks

StepCheckWhat it verifies
1API healthGET /api/version responds, /api/auth/providers lists providers
2Sign-upPOST /api/auth/sign-up/email creates a new test user
3Sign-in + tokenPOST /api/auth/sign-in/email returns session.token, session.id, user object
4Session validationGET /api/auth/get-session with Bearer token returns the correct user
5Email verificationuser.emailVerified flag checked; warns if false
6Better Auth KVwrangler kv key list — verifies KV is accessible and shows key prefix distribution
7D1 databasesBoth DB (bloqr-backend-app-db) and ADMIN_DB (bloqr-backend-admin-db) — table list + row counts
8Neon / PostgreSQLDirect connection via psycopg2 — table row counts, test user row, session row
9Admin APIGET /api/auth/admin/list-users with API key (optional)
10Tail log summaryWorker exceptions and auth-related log events captured during the run

Prerequisites

Terminal window
# One-time setup (from repo root)
uv sync --directory tools

psycopg2-binary is a self-contained PostgreSQL client — no Homebrew Postgres install required.


Configuration

Terminal window
cp tools/auth-healthcheck.env.example tools/auth-healthcheck.env
# Edit tools/auth-healthcheck.env

Key variables

VariableRequiredDescription
NEON_URL✅ YesDirect Neon connection string. Get from Neon Console → Branch → “Direct connection”
BETTER_AUTH_API_KEYOptionalEnables admin API check (list-users). Leave blank to skip
TEST_EMAILOptionalFixed test email. Leave blank to auto-generate a unique email each run
API_BASEOptionalDefaults to https://api.bloqr.dev/api
KV_BINDINGOptionalDefaults to BETTER_AUTH_KV
D1_BINDINGOptionalDefaults to DB
D1_ADMIN_BINDINGOptionalDefaults to ADMIN_DB
ENABLE_TAILOptionalSet to false to skip wrangler tail. Defaults to true

Running

Terminal window
# Using the shell alias (recommended)
auth-check
# Or directly
uv run --directory tools python auth-healthcheck.py

The script will:

  1. Start wrangler tail in the background
  2. Run all checks sequentially
  3. Wait a few seconds for tail to flush
  4. Print a rich summary table to the terminal
  5. Write a JSON report to the repo root

Interpreting Results

All green ✅

Auth is fully working. Sign-up, sign-in, session validation, KV writes, and Neon rows all succeeded.

session.token present

The most critical failure. Means sign-in returned HTTP 200 but no token in the response body. Common causes:

  • storeSessionInDatabase conflict with KV binding (fixed in PR #1725)
  • Prisma field mapping error — displayName / name mismatch
  • Better Auth plugin (sentinel) crashing on init (fixed in PR #1724)

POST /auth/sign-in/email → HTTP 500 ❌

Worker is crashing during sign-in. Check tail logs section of the report for the exception.

emailVerified ⚠️

Normal for new sign-ups if requireEmailVerification=false. If sign-in is being blocked, this means requireEmailVerification=true is set and Resend is not delivering the verification email.

Session in Neon ⚠️ (not in Postgres)

Expected behaviour when storeSessionInDatabase=false (the default when KV is bound). Sessions live in KV only. This is correct and not a bug.

KV accessible ❌ or D1 execute

Wrangler binding is not resolving. Check wrangler.toml binding names match the KV_BINDING / D1_BINDING values in your env file.


JSON Report

The report is written to auth-healthcheck-YYYYMMDD-HHMMSS.json at the repo root. Structure:

{
"timestamp": "2026-05-02T10:00:00",
"api_base": "https://api.bloqr.dev/api",
"results": {
"POST /auth/sign-in/email": {
"status": "PASS",
"detail": "HTTP 200 OK",
"data": {}
}
},
"errors": [
{ "check": "session.token present", "detail": "missing — response keys: ['user']" }
],
"summary": {
"passed": 14,
"failed": 1,
"warnings": 2
}
}

Paste the contents of this file into a Copilot chat for instant root-cause analysis.


Wrangler Tail Logs

The script starts wrangler tail --format json in a background process and writes output to wrangler-tail.log (gitignored). The final section of the terminal output summarises:

  • Worker exceptions (unhandled errors)
  • Error-level log lines
  • Auth-related log events (sign-in, sign-up, session, Prisma, Better Auth)

To watch the tail live in a separate terminal while the script runs:

Terminal window
tail -f wrangler-tail.log | jq '.logs[].parts[]'

Relation to Other Docs