Skip to content

Tier 3 Pre-Migration Audit — last1-admin (T3-0)

Status: Audit complete. Awaiting Ryan review before Tier 3 Week 1 execution.
Date: 2026-08-27
Scope: Planning only (T3-0). No migration work executed.
Product: admin.last1.enterprises — Last 1 internal ops portal
Repo: Last-1-Enterprises/last1-admin
Muster item: migrate-last1-admin-compute-to-r940


Executive summary

Tier 3 is a compute-only migration: move the last1-admin Node monolith off Railway onto R940 while keeping Supabase Auth and admin metadata on hosted project tcthzakppndkykatoefx until Tier 6.

This is materially simpler than Tier 2 (no Postgres migration, no GoTrue, no Kong ingress gap for a public IdP). It is more complex than Tier 1 n8n because last1-admin is a multi-product BFF holding service-role keys and HMAC gateway secrets for six business units.

Sovereignty / revenue framing (Ryan, 2026-08-27): Completing Tiers 3–6 removes remaining Railway and Supabase dependencies from the Last 1 portfolio, strengthening the sovereignty narrative used in SBIR and pitch conversations. Tier 3 alone removes one Railway surface but leaves the shared Supabase auth dependency visible until Tier 6. Still worth doing now: it is low user-risk, unlocks the next full-stack rehearsals (RealOutcomes, Onset), and puts the internal ops hub on the same metal as auth.last1.id and api.last.vet.

Recommended calendar: 2–4 days compressed execution (n8n-style runbook), not an 8-week Tier 2 pattern. Pre-work before Week 1 is more important than week count.

Top pre-flight risks:

  1. LAST1_ID_API_BASE may still point at https://last1.id (code and .env.example default) while sovereign issuer is https://auth.last1.id.
  2. Tier 0 muster blockers (infra-consolidation-playbook-approve, infra-bw-naming-r940-products-approve) unless Ryan explicitly waives for kickoff.
  3. Tier 2 lesson: verify every unit switcher and at least one write path per product in a browser, not only curl/smoke scripts.

1. Current architecture

1.1 Deployment

Layer Current state
Compute Railway — Dockerfile Node 22 Alpine, port 5000, node dist/index.cjs
Domain https://admin.last1.enterprises (Tier 3 compute; not Cloudflare Pages)
Build Vite 7 client + Express 5 server monolith; Railway build args: VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY, VITE_LAST1_API_BASE
Last push 2026-08-18 (main)
Memory / replicas / Railway cost Unknown (no Railway API audit in T3-0)

Target posture (from consolidation plan): dedicated small R940 app VM (or share ops VM initially); ingress via Cloudflare tunnel on lastvet-edge (same pattern as n8n Tier 1).

1.2 Repo and tech stack

Field Value
Repo Last-1-Enterprises/last1-admin (private)
Branch main
Pattern Same monolith shape as pre-L2-7 last1.id: Express BFF + React SPA in one process
Runtime Node 22 (Dockerfile comment: Supabase Realtime needs native WebSocket)
UI React 18, Wouter, Radix, Tailwind, TanStack Query
Auth client @supabase/supabase-js v2.93
Optional legacy pg pool for LastVet direct DB (local dev only; prod uses API proxy)

Code volume (GitHub tree audit):

Metric Count
Total blobs ~160
TypeScript / TSX files ~137
TypeScript LOC (GitHub language stats) ~1.18 MB source
SQL docs in repo 2 (docs/ADMIN_TELEMETRY_TABLE.sql, docs/LASTVET_OPS_DIGEST_SENT.sql)
Checked-in Supabase migrations None (schema lives in shared project history)

Business-unit surface (client pages under client/src/pages/):

Unit Admin modules
last1.app metrics, governance, check-ins, reports
last1.id identities, issuers, app-clients, audit, abuse
RealOutcomes dashboard, users
RadioCheck units, users, messaging, org-admins
Onset dashboard, clinics, users, sync-diagnostics, support
LastVet veterans, providers, consent, Part 2 monitor, privacy notices, ops digest
Angel dashboard, invites, users, health
Marketing subscribers, broadcasts, sequences (SendGrid + shared Supabase marketing_*)

1.3 Database

Database Project ref Role for last1-admin
Shared "Last 1 App + Radio Check" tcthzakppndkykatoefx Primary: Supabase Auth login, system_admin_memberships, admin profiles, telemetry, marketing tables
Onset Supabase Separate project (ref not in admin repo) Read/write via ONSET_SUPABASE_* service role for clinic dashboards
RadioCheck Supabase Separate URL in env Direct queries + integration secret
RealOutcomes Supabase cpocwrygxlqhzvmlrpjv Not direct DB — HTTP proxy via REALOUTCOMES_API_BASE + gateway HMAC
LastVet clinical DB R940 Postgres behind api.last.vet Not in admin Supabase — BFF proxies to /api/internal/admin/*

Tier 3 constraint (locked): move compute only; do not migrate tcthzakppndkykatoefx in Tier 3. Auth DB moves with Tier 6 (last1.app + RadioCheck bundle).

Tables last1-admin is known to touch on shared Supabase:

  • system_admin_memberships, org_admin_memberships, user_profiles
  • admin_telemetry_events
  • marketing_* (Onset, LastVet, Last1.org brands)

1.4 Data sensitivity

Data class In admin DB? Notes
LastVet veteran ePHI at rest No Production proxies to api.last.vet; README forbids LASTVET_DATABASE_URL in prod
LastVet PHI displayed in UI Yes (via API) Veterans, providers, consent views fetch from LastVet internal admin API
42 CFR Part 2 records at rest in admin No Part 2 Monitor page reads metadata/aggregates through LastVet API, not stored in admin Supabase
Onset clinical / PHI-adjacent Possible Onset Supabase service-role access for clinic admin dashboards
Identity PII Yes last1.id admin module, RadioCheck user lists
Marketing subscriber PII Yes Email addresses across products
High-privilege secrets at runtime Yes Multiple service-role keys, gateway HMAC secrets, Angel/LastVet bearer tokens in one process

Phase 1 LastVet note: last1-admin is operator infrastructure, not the veteran-facing coordination layer. Clinical data flows are read/proxy paths for Ryan's ops work, not a new persistence plane for ePHI.

1.5 Who uses it

Audience Access
Internal operators only Consolidation plan posture; not a customer-facing product
Domain-gated RBAC Email domain maps to allowed units (last1.enterprises → all units; product domains scoped)
System roles super_admin, platform_admin, security_admin, support_admin, read_only_auditor
Known recipients Ops digest → ryan@last1.enterprises (.env.example)
Login entry Supabase Auth on shared project; company admin sign-in documented as https://auth.last1.id/login?entry=admin

User count: not measured in T3-0. Expect Ryan-primary with possible additional @last1.enterprises operators. Onset clinic staff use clinic.theonset.app, not admin directly, except via deep links to admin dashboards.


2. Dependencies (both directions)

2.1 Upstream (last1-admin consumes)

Service Mechanism Post–Tier 2 status
last1.id LAST1_ID_API_BASE + LAST1ID_ADMIN_GATEWAY_SECRET HMAC proxy Sovereign on R940 at auth.last1.id — verify Railway env matches
last1.app LAST1_API_BASE + gateway Still Railway
RealOutcomes REALOUTCOMES_API_BASE + ADMIN_GATEWAY_SECRET Still Railway + Supabase
Onset ONSET_SUPABASE_*, ONSET_ADMIN_METRICS_TOKEN Still Railway + Supabase
RadioCheck RADIOCHECK_SUPABASE_*, integration secret Tier 6 bundle
LastVet LASTVET_API_BASE, LASTVET_INTERNAL_ADMIN_SECRET Already R940 (api.last.vet)
Angel ANGEL_API_BASE, ANGEL_INTERNAL_ADMIN_SECRET Cloudflare Worker
SendGrid SENDGRID_API_KEY Marketing sends + LastVet ops digest
Shared Supabase auth VITE_SUPABASE_*, SUPABASE_SERVICE_ROLE_KEY Hosted until Tier 6

2.2 Downstream (others consume admin)

Admin is mostly terminal for data (nothing reads admin's DB for product runtime). Verified exceptions where other services depend on admin-initiated traffic or shared secrets:

Consumer Dependency
RealOutcomes Validates ADMIN_GATEWAY_SECRET on admin gateway routes
last1.id Admin gateway HMAC for privileged identity ops
LastVet API Provider approval and internal admin routes via LASTVET_INTERNAL_ADMIN_SECRET
Angel Worker Matching ANGEL_INTERNAL_ADMIN_SECRET
clinic.theonset.app Deep link / reference to admin.last1.enterprises
Muster MCP MUSTER_OAUTH_CONSENT_SECRET stored in last1-admin BWS project

Proxy route inventory (server/proxy.ts, server/index.ts):

  • POST /api/proxy/last1, /api/proxy/realoutcomes, /api/proxy/radiocheck, /api/proxy/last1id, /api/proxy/org-last1id
  • /api/lastvet/*, /api/angel/* (dedicated routers)
  • Onset metrics, support, sync-diagnostics, marketing routes
  • In-process LastVet ops digest scheduler (startLastVetOpsDigestScheduler())

Cutover implication: downtime affects Ryan's ops workflows, not end-user product login flows. Gateway secret mismatch during cutover would break admin → product writes, not product → product traffic.


3. Complexity vs Tier 2

Dimension Tier 2 (last1.id) Tier 3 (last1-admin)
Scope Full sovereign stack: compute + Postgres + GoTrue + Kong + DNS split Compute only
Calendar (actual/planned) ~3.5 days execution after planning (exceptional) / 5–8 weeks planned 2–4 days (planning estimate)
Database migration Yes — off Supabase nztgswcpnwggymncrnyx No — stays on tcthzakppndkykatoefx
Auth migration Self-hosted GoTrue on R940 Keeps Supabase Auth (hosted)
Ingress risk Kong SPA gap caught post-closeout (L3) Single monolith on one port; simpler than Kong multi-service
Code volume Large monolith + marketing (pre-L2-7) ~160 files; smaller than last1.id
Integration fan-out Partner OIDC, email, MinIO 7 product proxies + SendGrid + 3 Supabase URLs
Runbook maturity Full (LAST1_ID_MIGRATION_RUNBOOK.md, gate reports) Missing — generic consolidation plan + n8n precedent only
Closest precedent — Tier 1 n8n (compute + tunnel + soak)

Existing docs quality

Document Quality Gap
LAST1_INFRASTRUCTURE_CONSOLIDATION_PLAN.md §6 Strong product inventory No Tier 3 execution runbook
Repo README.md Strong env var catalog + smoke scripts Stale LastVet "AWS RDS" language; duplicate .env.example sections
N8N_MIGRATION_RUNBOOK.md Good compute-only template Not adapted for last1-admin
Dedicated LAST1_ADMIN_MIGRATION_PLAN.md Missing Should be T3-1 output after Ryan approves T3-0

Technical debt worth naming

  1. LAST1_ID_API_BASE default https://last1.id in code and .env.example — stale post–Tier 2.
  2. Gateway secret alias sprawl — ADMIN_GATEWAY_SECRET, LAST1_ADMIN_GATEWAY_SECRET, LAST1ID_ADMIN_GATEWAY_SECRET with fallback chains.
  3. Legacy lastvet-db.ts direct Postgres — disabled when API configured, but code remains.
  4. No checked-in Supabase migrations — schema coupling opaque until Tier 6.
  5. In-process ops digest scheduler — must survive VM restart policy (systemd vs in-app cron).
  6. BWS cross-project credential inference — Tier 2 Week 4 incident: stale GOOGLE_OAUTH_* in last1-admin BWS was wrongly used for last1.id. Never infer across BWS projects.

Cursor context already touched

  • Aug 2026: Tailscale API key placed in last1-admin BWS; ACL policy work for Ryan + Robert observability.
  • Tier 2 Week 4: last1-admin BWS incorrectly sourced for last1.id GCP OAuth credentials (Ryan corrected directly).
  • No prior Tier 3 migration execution in agent transcripts; Tier 2 closeout repeatedly deferred to "when Ryan schedules."

4. Risk assessment

Risk Severity Notes
Wrong LAST1_ID_API_BASE after cutover High last1.id admin module breaks; verify Railway prod env before deploy
Gateway secret mismatch High Breaks proxied writes to RealOutcomes / last1.id; do not rotate during cutover
Service-role key exposure on new VM Critical Multiple SRKs in one process; Tailscale-only + UFW + BWS LAST1ADMIN_R940_*
LastVet Part 2 admin outage High (compliance ops) Ryan loses Part 2 monitoring UI; run smoke:lastvet + browser probe
Ops digest scheduler gap Medium Daily/weekly LastVet digest emails may stop if scheduler not restarted
Supabase latency from R940 Low–Medium Acceptable for hybrid Tier 3; monitor proxy telemetry
Real user impact Low Internal-only; Ryan-primary
Business impact if briefly down Low–Medium Blocks ops (provider approval, marketing sends, dashboards), not customer login
Data loss risk Low for Tier 3 No DB migration; worst case is misconfigured env pointing at wrong upstream
Cursor autonomous execution Medium–high touch VM deploy is automatable (n8n pattern); secret sync and multi-unit browser E2E need Ryan checkpoints

Autonomy recommendation: Cursor can execute VM provision, Docker build, env render, curl smoke, soak monitoring autonomously with BWS + SSH access. Require Ryan browser sign-off on unit switcher matrix before Railway teardown (Tier 2 Kong lesson). Treat LastVet Part 2 and provider approval write paths as mandatory manual checks.


Not an 8-week Tier 2 pattern

Tier 3 does not need Weeks 1–4 build / 5 test / 6 cutover / 7 teardown / 8 docs. Use a compressed n8n-style phase model:

Phase Duration Deliverables
T3-0 1 session This audit (done)
T3-1 ~2 h LAST1_ADMIN_MIGRATION_PLAN.md + env audit checklist + smoke matrix
T3-2 ~4 h R940 VM (or ops VM slot), Docker deploy, BWS env render, tunnel/DNS staging
T3-3 ~4 h Parallel soak: Railway + R940; curl + smoke scripts
T3-4 ~2 h Ryan browser E2E (all units)
T3-5 ~1 h DNS cutover admin.last1.enterprises → R940
T3-6 24–48 h Soak (internal-only policy from consolidation plan)
T3-7 ~2 h Railway teardown, runbook, muster update

Total: 2–4 working days assuming Tier 0 approvals resolved and no env surprises.

Pre-work before Week 1 (T3-1) execution

Item Owner Blocker?
Approve or waive Tier 0 muster items (infra-consolidation-playbook-approve, infra-bw-naming-r940-products-approve) Ryan Yes (muster)
Railway prod env audit (~30 vars from README); confirm LAST1_ID_API_BASE=https://auth.last1.id Cursor + Ryan Strongly recommended
Approve BWS prefix LAST1ADMIN_R940_* per BITWARDEN_NAMING_CONVENTION.md Ryan Yes for clean secret layout
Choose VM target (new small VM vs share ops/sovereign-app) Ryan Yes
Define browser E2E matrix (7 units × login + 1 read + 1 write where safe) Cursor draft, Ryan approve Recommended
Update repo README LastVet section (R940 not AWS) Cursor (docs PR) Nice-to-have pre-cutover

6. Sequence recommendation (Tiers 3–6)

Locked order (consolidation plan, still valid)

Tier Product Sovereignty story weight
3 last1-admin compute Removes 1 Railway; partial (Supabase auth remains)
4 RealOutcomes (+ IRS cron) Full stack off Railway + Supabase — strong pitch anchor
5 Onset clinic + Supabase Clinical boundary; SOC 2 driver; highest care with PHI-adjacent data
6 last1.app + RadioCheck + angel.report app tier (+ admin auth DB) Largest Supabase bundle; completes shared tcthzakppndkykatoefx story

Should anything move earlier?

Question Recommendation
Stronger sovereignty anchor before admin? No. Tier 3 is the right warm-up: lowest blast radius, internal-only, validates R940 app deploy pattern before full-stack cuts. RealOutcomes (Tier 4) is a stronger narrative win but also higher coordination (Stripe, edge functions, IRS cron, marketing split). Do Tier 3 first to de-risk ops hub relocation.
Dependency chains forcing reorder? No change. Tier 2 (last1.id) unblocked identity-dependent paths. Tier 6 bundle constraint on shared Supabase is unchanged. RealOutcomes does not block admin compute move.
Parallel with Tier 3? Planning only: T4-0 audit can run while T3 executes. Do not parallel two cutovers. SendGrid → RealSend remains a separate track (do not interleave).

Sovereignty narrative progression (SBIR / pitch)

Use this sequencing in external conversations:

  1. Done: Universal identity sovereign on R940 (auth.last1.id) — Tier 2.
  2. Tier 3: Internal ops hub off Railway (hybrid auth OK to disclose honestly).
  3. Tier 4: First full product stack (app + DB) on R940 — RealOutcomes.
  4. Tier 5: Clinical-adjacent product on R940 — Onset (SOC 2 alignment).
  5. Tier 6: Shared consumer platform bundle off Supabase — completes "no hosted Postgres for Last 1 apps" claim.

Honesty point: until Tier 6, pitch language should say "compute sovereignty complete; database consolidation in progress" rather than implying zero Supabase dependency.


7. T3-0 verification matrix (for Week 1)

Execute before DNS cutover when Ryan authorizes T3-1:

Check Method Pass criteria
Login Browser Supabase auth → admin shell loads
Unit: last1.id Browser + proxy Identity list loads via auth.last1.id
Unit: LastVet smoke:lastvet + browser Stats + Part 2 monitor page
Unit: Angel smoke:angel + browser Dashboard stats
Unit: Onset Browser Clinics/users dashboard
Unit: RealOutcomes Browser Dashboard loads via gateway
Unit: RadioCheck Browser Users/units list
Unit: last1.app Browser Metrics/governance view
Ops digest Log check Scheduler tick after VM restart
Gateway write Ryan-approved safe action e.g. read-only audit export or test flag (no prod destructive ops)

8. Investigation limits (T3-0 honesty box)

  • No local clone of last1-admin; repo facts via GitHub API only.
  • Railway live env vars not read (prod LAST1_ID_API_BASE unknown until T3-1 audit).
  • Supabase row counts / admin MAU not measured.
  • BWS secret values not touched.
  • No VM provisioning or deploy performed in T3-0.

9. Recommended Ryan decisions (post-audit)

  1. Authorize T3-1 — create LAST1_ADMIN_MIGRATION_PLAN.md from this audit + n8n runbook template.
  2. Waive or complete Tier 0 muster blockers before execution.
  3. Confirm VM target (new VMID vs shared ops host).
  4. Confirm soak window (24–48 h internal-only, same as consolidation plan).
  5. Schedule browser E2E window with Ryan present for T3-4.


T3-0 verdict: Tier 3 is ready for planning sign-off. Scope is bounded, risks are manageable, and execution should follow the compressed n8n pattern, not Tier 2's week model. The highest-value pre-flight action is a Railway env audit confirming LAST1_ID_API_BASE=https://auth.last1.id before any R940 deploy.