Database
operatorMarketplace Postgres (Neon) + Drizzle: schema overview, migrations, rollback notes, and the no-DB degradation path.
Provider
Production uses Postgres provisioned through the Vercel Marketplace Neon integration, connected to the hiss-web project. Vercel's first-party Postgres is no longer available for new projects (existing databases were migrated to Neon) — Marketplace integrations such as Neon, Prisma Postgres, or Supabase are the supported path, and they inject connection env vars automatically.
vercel integration add neon # provision + connect to the linked project
vercel env pull .env.local # local dev credentials (gitignored)ORM and migrations
The schema lives in apps/web/lib/db/schema.ts (Drizzle ORM, postgres-js driver, pooler-safe settings). Migration SQL is generated and committed under apps/web/drizzle/.
pnpm --filter @hiss/web db:generate # schema → SQL migration
pnpm --filter @hiss/web db:migrate # apply (reads DATABASE_URL)
pnpm --filter @hiss/web db:studio # inspect locallyWhat the schema holds
| Table | Holds |
|---|---|
users | Normalized wallet address, chain ID, first/last seen. No keys, no balances. |
wallet_sessions | SIWE-style session nonces with issue/expiry/revocation timestamps. |
coils / coil_versions | User-authored Coils and immutable manifest/fuse/allocation snapshots. |
autonomy_receipts | Deterministic autonomy receipts. live_order_sent is CHECK-pinned to false. |
live_readiness_acks | Live-autonomy acknowledgment hashes and boolean flags — never credentials. |
bankrbot_command_packs | Compiled Bankrbot command packs, keyed to receipts. |
robinhood_mcp_instruction_packs | Compiled Robinhood MCP instruction packs, keyed to receipts. |
x402_call_receipts | Request/response hashes for paid x402 calls. |
post_run_audits | Post-run audit reports with ok/violations status. |
audit_events / rate_limit_events | Operational audit trail. No secrets, redacted by construction. |
Nothing in this schema stores Robinhood credentials, brokerage account data, balances, API keys, or private keys — there are no columns for them, and requests carrying credential-looking fields are rejected before any handler runs.
Degradation without a database
Every persistence adapter returns { persisted: false, reason: "database not configured" }when DATABASE_URL is absent. Compilation, validation, receipts, and audits all still work — they are deterministic pure computations — and the response says plainly that nothing was stored. See Environment variables for the gating flags.