Skip to content

SPRINT-2 Gate D Report — User ID Remap (S2-D)

Status: STOP — Ryan manual login verification required before Gate E
Date: 2026-08-28
Prerequisite: Gate C pass (ryan@last1.org OAuth loop clean)


Summary

Pre-remap backup captured. FK remap for ryan@last1.enterprises completed on the hosted Supabase Postgres used by VM 116 realoutcomes-app (authoritative app DB). Legacy user data (admin profile, Veterans watchlist, search history, feature usage) preserved.

Corrective note: The execution plan listed target id 52ce85f9… from an auth.identities row. OAuth id_token.sub uses public.identities.id, which is 396e95ce… for ryan@last1.enterprises. An initial remap to 52ce85f9 was corrected in the same session to 396e95ce… before Ryan login verification.


1. Pre-remap backup

Item Value
Path /var/backups/realoutcomes/pre-sprint2-user-remap-20260828T205228Z.dump (VM 116)
Size 133 MB (custom format, public + auth schemas)
SHA-256 25cbef2e5edb22c3a9f00748d735472f47f796215ffca547adf554c90bd5081f
Sidecar .dump.sha256, .manifest.json
Gitignored Yes (/var/backups/ outside repo)

Rollback: pg_restore -Fc --clean --if-exists --no-owner --no-acl -d "$DATABASE_URL" pre-sprint2-user-remap-20260828T205228Z.dump


2. FK remap transaction

UUID
Email ryan@last1.enterprises
Legacy RO public.users.id d1034389-14ef-4ea5-98f2-f7b453132edb
OAuth id_token.sub (public.identities) 396e95ce-abac-42e2-9980-c08f19a1af1d
Removed orphan RO row empty duplicate at 396e95ce… (pre-remap OAuth upsert)

Child rows updated (17 total)

Table Column Rows
user_search_history user_id 12
feature_usage user_id 3
user_profiles user_id 1
watchlists user_id 1
(8 other FK columns) 0

Post-remap verification (automated)

Check Result
Single ryan@last1.enterprises user row PASS — id 396e95ce…
Admin profile preserved PASS — role admin
Veterans watchlist preserved PASS
Zero orphan FK rows PASS
Legacy ids gone (d1034389…, wrong 52ce85f9…) PASS
ryan@last1.org rows untouched by remap PASS — see §4

3. Identity alignment (last1.id ↔ RealOutcomes)

Queried via https://auth.last1.id/rest/v1/identities (service role):

Email public.identities.id (OAuth sub) RO public.users.id after Gate D
ryan@last1.enterprises 396e95ce-abac-42e2-9980-c08f19a1af1d 396e95ce… aligned
ryan@last1.org 536a1797-d111-4717-8e2c-4814016dccad 536a1797… aligned (Gate C session)

Legacy pre-OAuth row 5e76069d… remains in DB but is not the OAuth sub; callback upserts by sub so login binds to 536a1797….


4. Login verification

Automated (agent)

Test Result
GET http://192.168.1.99:5000/ 200
GET /login 200
POST /api/auth/last1/start Returns auth.last1.id/oauth/authorize?client_id=realoutcomes…
GET https://auth.last1.id/.well-known/openid-configuration 200

Manual (Ryan required)

# Account Steps Expected
D-1 ryan@last1.enterprises Sign out → /login → Last1 ID → Google (Workspace) → Allow Authenticated home; /api/auth/user id = 396e95ce…; admin badge; Veterans watchlist visible
D-2 ryan@last1.org Sign out → full OAuth loop (Gate C repeat) Authenticated home; id = 536a1797…; no data loss from enterprises remap

Reply when both pass: Gate D pass
If either fails: do not proceed to Gate E; restore from pre-remap dump above.


5. DB scope note

Gate D ran against hosted Supabase (DATABASE_URL on VM 116 realoutcomes-app). VM 117 local Postgres has only 2 legacy users and is not the live app DB until T3 migration cutover completes.


6. Blocked until Gate D Ryan sign-off

Gate Work
E Retire VM 117 GoTrue
F SPRINT-2 closeout → SPRINT-3 (realoutcomes-edge)

Do not stop GoTrue until Ryan confirms D-1 and D-2.


END Gate D report