This is the source code for Jingxiang Guo's academic website: https://jingxiangguo.com
The dashboard can run as static JSON or through Vercel Functions under api/dashboard/.
Required Vercel environment variables for hosted writes:
BLOB_READ_WRITE_TOKEN: Vercel Blob read/write token.DASHBOARD_WRITE_TOKEN: bootstrap token for the code-reservedjingxiangadministrator; it is the only credential with theadminrole.DASHBOARD_SESSION_SECRET: independent random secret used to sign HttpOnly dashboard sessions.DASHBOARD_PRIVATE_BLOB_PATH: private dashboard snapshot path; defaults todashboard-state-private/embodied-ai-dashboard.json.DASHBOARD_ACCESS_BLOB_PATH: private token registry path; defaults todashboard-access/access-control.json.DASHBOARD_PASSKEY_BLOB_PATH: private Passkey public-key/challenge registry path; defaults todashboard-access/passkeys.json.DASHBOARD_PASSKEY_RP_ID: optional WebAuthn relying-party ID; defaults tojingxiangguo.com.DASHBOARD_PASSKEY_ORIGIN: optional exact WebAuthn origin; defaults tohttps://jingxiangguo.com.DASHBOARD_WRITE_TOKEN_USERS: optional JSON map from private random tokens to viewer names; use this for Vercel-managed viewer credentials instead of standalone per-user variables.DASHBOARD_WRITE_TOKEN_<VIEWER>: legacy sensitive per-user token compatibility only. Do not create new standalone per-user variables.DASHBOARD_BLOB_PATH: legacy public snapshot path used only while migrating existing state.
Without those variables, /api/dashboard/state falls back to bundled JSON and the dashboard stays read-only.
Hosted dashboard reads and writes are token-gated. The jingxiang administrator receives the full state and can open
the Settings dialog to create, rotate, copy, delete, disable, and scope viewer tokens. Environment-managed viewer tokens
are copied only through an authenticated, non-cached administrator request that reads the Vercel Function runtime; their
values are never written to dashboard state or browser storage. Dashboard-managed tokens remain one-time values because
the private registry stores only salted hashes and fingerprints. Viewer names are unique across both credential sources.
Viewers can read and mutate only their visible cards: Research cards are visible by default, and per-card
includes/excludes are enforced on both state reads and every mutation.
The administrator can enroll multiple Passkeys from Settings after first signing in with the bootstrap token. WebAuthn
private keys remain in the device or synced password manager; the private Blob stores only credential IDs, public keys,
signature counters, device metadata, and short-lived one-time challenges. Passkey verification issues the same seven-day
HttpOnly session used by token login. Keep DASHBOARD_WRITE_TOKEN as the break-glass recovery method, especially until a
second Passkey has been enrolled on another device.
Production builds intentionally omit dashboard/state/**. The ?json=1 static fallback is restricted to localhost,
so production visibility cannot be bypassed through the bundled JSON mirror. The source repository still contains the
local mirror; do not treat cards committed to a public repository as confidential data.
DASHBOARD_WRITE_TOKEN_USERS credentials remain login-compatible and are scoped to the same Research-default visibility
as Settings-created viewers. Legacy DASHBOARD_WRITE_TOKEN_<VIEWER> variables are still accepted by the runtime only for
backward compatibility; prefer the administrator Settings dialog for new viewers, and use DASHBOARD_WRITE_TOKEN_USERS
if a Vercel environment credential is still needed.
Initial setup order:
- Create or link the Vercel project.
- Add a Vercel Blob store and expose
BLOB_READ_WRITE_TOKENto production and preview. - Add private
DASHBOARD_WRITE_TOKENandDASHBOARD_SESSION_SECRETvalues to production and preview, with no per-user token aliases for the administrator. - Seed the hosted dashboard snapshot once, only if no Blob snapshot exists yet:
BLOB_READ_WRITE_TOKEN=... npm run vercel:seed-blob:force- Deploy the site. Open
/dashboard/; use theUnlockfield withDASHBOARD_WRITE_TOKEN, then open Settings to provision viewer tokens and enroll the first administrator Passkey with the device's Face ID, Touch ID, PIN, or security key prompt.
Daily dashboard workflow is remote-first. Vercel Blob is the mutable source of truth; local JSON is a mirror for Git
history and static fallback. Before editing dashboard/state/*.json, pull the hosted snapshot:
npm run vercel:pull-blobDo not run npm run vercel:seed-blob for normal task/status/comment work. That command intentionally refuses to run
without --force/DASHBOARD_ALLOW_BLOB_SEED=1 because it overwrites the hosted Blob from local JSON. Hosted task edits
should go through /api/dashboard/* first, then pull Blob back into local files before committing.
Useful checks:
npm run test:dashboard
node --check scripts/dashboard-vercel-api.mjs
npm run vercel:pull-blob -- --dry-runSupported hosted mutations:
POST /api/dashboard/task-createPOST /api/dashboard/task-statusPOST /api/dashboard/task-commentPOST /api/dashboard/task-comment-deleteGET|POST|PATCH|DELETE /api/dashboard/access-users(administrator only)GET|POST /api/dashboard/passkeys?action=optionsPOST /api/dashboard/passkeys?action=verifyGET|PATCH|DELETE /api/dashboard/passkeys(administrator only)