SPRINT-2 Gate C Report — Deploy + OAuth Smoke (S2-C)¶
Status: STOP — Ryan manual OAuth loop verification required before Gate D
Date: 2026-08-28
Target: VM 116 (192.168.1.99:5000) parallel stack only
Production: Railway realoutcomes.app unchanged
Gate A note (localhost redirect URI)¶
Question: Is http://localhost:5000/auth/callback on the production OIDC client a concern?
Answer: Low risk in current pre-user / parallel-stack phase. It is a common pattern for dev convenience on system apps. The secret is server-side only; PKCE still required. Cleanup target: remove localhost (and possibly LAN URI) from app_clients.redirect_uris after SPRINT-3 tunnel + prod cutover, when dev uses a dedicated staging client or localhost-only row. Not blocking now; track under post-SPRINT-3 hardening.
Gate B merge¶
PR #1 merged to main after Gate B approval (source of truth for deploy).
Deploy (VM 116)¶
| Step | Result |
|---|---|
Rsync sprint-2-last1id-auth / merged main → /opt/realoutcomes/src |
Done |
Render .env from BWS (37 keys incl. LAST1_*, VITE_LAST1_*) |
Done |
deploy-realoutcomes-app.sh Docker build + run |
Done |
Container realoutcomes-app |
Up on 192.168.1.99:5000 |
Env highlights (values in BWS, not repeated here):
LAST1_ID_ISSUER=https://auth.last1.idLAST1_OAUTH_CLIENT_ID=realoutcomesLAST1_OAUTH_REDIRECT_URI=http://192.168.1.99:5000/auth/callbackVITE_*mirrored for client bundle
Automated smoke (Cursor)¶
| Check | Result |
|---|---|
GET / |
200 |
GET /api/auth/user (no bearer) |
401 (expected) |
GET /api/directory?limit=1 |
200 |
Client bundle contains Sign in with Last1 ID + auth.last1.id |
Pass |
POST /api/auth/last1/callback {} |
400 (route mounted) |
POST /api/auth/last1/callback invalid code |
401 (exchange path live) |
Container → https://auth.last1.id/.well-known/jwks.json |
Pass |
VM 117 GoTrue (supabase-auth on .98) |
Still running (rollback path intact) |
Ryan Gate C — manual OAuth loop¶
URL: http://192.168.1.99:5000/login
Recommended test account for Gate C¶
Use ryan@last1.org for the first full loop before Gate D.
| Account | Gate C full login? | Why |
|---|---|---|
ryan@last1.org |
Yes (recommended) | No last1.id identity yet; callback upserts new public.users row with id = sub. No FK data to lose. |
ryan@last1.enterprises |
Wait for Gate D | Existing RO row d1034389… vs last1.id identity 52ce85f9…. Callback upsert by sub will conflict on unique email until FK remap. |
rydaunicorn@gmail.com |
N/A | Deleted in S2-A |
Steps¶
- Open http://192.168.1.99:5000/login
- Click Sign in with Last1 ID
- Confirm redirect to
https://auth.last1.id/oauth/authorize?client_id=realoutcomes&... - Sign in at auth.last1.id (Google or email)
- Approve consent if prompted
- Land on
/auth/callback→ redirect to/ - Confirm authenticated UI (watchlists/profile if applicable)
- DevTools:
sessionStoragekeyrealoutcomes_last1_session_v1present - Optional:
GET /api/auth/userwith bearer returns user row
Reply Gate C pass or report failure symptoms.
Blocked until Gate C pass¶
| Gate | Work |
|---|---|
| D | Mandatory pg_dump; FK remap ryan@last1.enterprises only (d1034389… → 52ce85f9…); verify ryan@last1.enterprises + ryan@last1.org logins |
| E | Retire VM 117 GoTrue |
| F | SPRINT-2 closeout → SPRINT-3 |
Rollback (Gate C)¶
Revert VM 116 to prior image/rsync; Supabase auth path on VM 117 still works until S2-E.