logicspike/docs

Communication

Mailbox — activation runbook & diagnostics

Mailbox's code is complete; when it "doesn't work" it's almost always an activation gap (a worker not deployed, a secret unset, a migration or backfill not run, or a stale session), not a bug. This is the checklist to bring it live and to pinpoint a failure. Steps marked ⚙ run by you touch production (deploys / prod DB) and can't be run from the assistant sandbox.

How the pieces connect

Dashboard  →  /api/mailbox/* (Next proxy, attaches JWT)  →  gateway /mailbox/*
   (nav shows on the `mailbox` service)      (authorizes on `mailbox` OR `comms`)
        →  logicspike-mailbox worker (Neon)   ←  sends replies through  →  logicspike-communication
  • Nav appears when the tenant has the mailbox service enabled (+ a fresh login).
  • API now authorizes on mailbox OR comms (hardened — was comms-only).
  • Create/verify relies on comms (/internal/sending-domains + verified domains).
  • Inbox visibility = org-admin (system:owner / mailbox:accounts.manage) sees all; everyone else sees only mailboxes they hold a grant on.

Activation checklist

  1. ⚙ Deploy the workerpnpm --filter logicspike-mailbox deploy.
  2. ⚙ Set its secrets (Windows-safe, use secret bulk not piped secret put): MAILBOX_DATABASE_URL (the mailbox Neon URL — note the MAILBOX_ prefix, not DATABASE_URL), GATEWAY_SECRET, INTERNAL_KEY. Verify with wrangler secret list.
  3. ⚙ Apply the schema to the mailbox Neon (mailbox_accounts, mailbox_account_access, mailbox_threads, mailbox_messages) via drizzle-kit push.
  4. ⚙ Redeploy the edge: gateway (picks up the mailbox route/binding + the new 403-mapping and mailbox-or-comms authorization + /health reporting), comms (/internal/sending-domains), manager (new-signup provisioning already lists comms+mailbox).
  5. ⚙ Provision the tenant — ensure tenant_services has both comms and mailbox enabled for the workspace.
  6. ⚙ Backfill grants — run apps/mailbox/backfill-owner-access.mjs so the owner/members hold mailbox_account_access rows (otherwise non-admins see an empty inbox).
  7. Re-login in the dashboard — mints a fresh JWT carrying the updated services and mailbox:* / system:owner permissions. Without this, even a fully-deployed stack shows an empty inbox + "admin access required."
  8. Open Mailbox → Domains, verify a domain → Mailboxes → New mailbox on it, assign a teammate, send a reply, and confirm an inbound reply lands.

Diagnostics — which step is missing?

  • curl https://api.vlozi.app/health → look for "MAILBOX_SERVICE": true. Missing/false → step 1/4 (worker not deployed or gateway not redeployed).
  • wrangler tail logicspike-mailbox while loading the inbox → MAILBOX_DATABASE_URL errors ⇒ step 2/3; no requests arriving ⇒ gateway routing (step 4).
  • Signed-in, hit /api/mailbox/v1/accounts and read the status:
    • 403 {code:"SERVICE_DISABLED"} → entitlement (step 5) or stale session (step 7).
    • 5xx → worker/DB down (steps 1–3).
    • 200 with [] → deployed & entitled, but no mailboxes/grants (steps 6/8).
  • Check the DB: tenant_services has comms+mailbox enabled; mailbox_accounts / mailbox_account_access have rows for the tenant.

What the UI now tells you (post-hardening)

The dashboard no longer shows a bare "couldn't load." It distinguishes: 403 → "Mailbox isn't enabled here — an admin must enable it, or sign out/in"; 5xx → "Mailbox is unavailable"; empty + admin → "No mailboxes yet → Set up Mailbox"; empty + member → "No inboxes assigned to you — ask an admin." The Domains page says "couldn't reach the sending service" instead of a false "no domains yet."

Communication