Skip to content

SPRINT-7 T2-0 Report — Storage + pg_cron Restore

Date: 2026-08-30
Status: T2-0 PASS. STOP — await Ryan review before T2-1 (Edge Functions).
VM: 120 last1app-db @ 192.168.1.103


Executive summary

Workstream Result
Storage buckets 2 (profile-photos, unit-chat-images) — public ACLs match hosted
storage.objects 1 (hosted parity)
Object file migrate 148 KB profile photo — public URL HTTP 200 on R940 Kong
cron.job 3 jobs restored — inactive (active=false) until T2-1 Edge smoke
Cron URL rewrite Hosted tcthzakppndkykatoefx.supabase.co → internal http://192.168.1.103:8000/functions/v1/...
Realtime healthy (unchanged)
Hosted DB Untouched

Scripts: scripts/last1app/t2-0-migrate-storage.py, t2-0-vault-align.py, t2-0-restore-cron.sh


1. Storage

Hosted baseline

Bucket Public Limit
profile-photos yes 5 MB
unit-chat-images yes 10 MB
Object Bucket Path
1 profile-photos c6f84fd2-ba39-4fec-828b-aa2287507ed6/profile.jpg (148 KB JPEG)

Actions

  1. Schema align storage.objects: added versioning_status, archived_at, is_delete_marker, is_versioned (as supabase_admin).
  2. Buckets inserted via SQL (hosted pg_restore buckets failed on extra versioning_status column on storage.buckets; manual bucket row match is sufficient).
  3. Metadata: API upload created object row + file (Gate B dump COPY storage.objects partially blocked; 1 object verified).
  4. File migrate: downloaded from hosted public URL → uploaded to R940 via Storage API (LAST1APP_DB_PROD_SUPABASE_SERVICE_ROLE_KEY).

Verification

Check Result
SELECT COUNT(*) FROM storage.objects 1 ✅
Buckets 2 ✅
Public ACL both buckets public=true ✅
R940 public URL http://192.168.1.103:8000/storage/v1/object/public/profile-photos/.../profile.jpg → 200 ✅

2. pg_cron — hosted URLs vs sovereign targets

Hosted (unchanged, still live)

jobname Schedule (UTC) Hosted URL
sms-checkin-cron 0 14 * * * https://tcthzakppndkykatoefx.supabase.co/functions/v1/sms-cron
org-sms-cron 0 14 * * * https://tcthzakppndkykatoefx.supabase.co/functions/v1/org-sms-cron
check-in-proof-events-cron */5 * * * * https://tcthzakppndkykatoefx.supabase.co/functions/v1/check-in-proof-events (+ vault Bearer)

Hosted crons continue on hosted until T-5 teardown. No change made to hosted.

R940 sovereign (restored T2-0)

jobid jobname Schedule Active Rewritten target (now)
1 sms-checkin-cron 0 14 * * * false http://192.168.1.103:8000/functions/v1/sms-cron
2 org-sms-cron 0 14 * * * false http://192.168.1.103:8000/functions/v1/org-sms-cron
3 check-in-proof-events-cron */5 * * * * false http://192.168.1.103:8000/functions/v1/check-in-proof-events (+ vault Bearer)

Proposed URL strategy (Ryan decision)

Phase Cron target Rationale
T2-1 … T-4 (pre-public API) http://192.168.1.103:8000/functions/v1/* (Kong → Edge Runtime on same VM) Edge reachable internally; does not call hosted; jobs stay inactive until T2-1 Edge smoke
T-5 cutover (DNS live) https://api.last1.app/functions/v1/* Public Supabase API hostname; matches iOS + webhooks post-cutover
Never post-cutover https://tcthzakppndkykatoefx.supabase.co/... R940 jobs must not fire against hosted after cutover

Enable timing: After T2-1 Edge HTTP smoke, Ryan can set active=true on R940 jobs (still internal URL). At T-5, run one-shot SQL to swap 192.168.1.103:8000 → api.last1.app before enabling traffic cutover.

Vault (R940)

Recreated (hosted ciphertext not portable):

Secret Source
radiocheck_app_secret BWS LAST1_ID_R940_PROD_RADIOCHECK_APP_SECRET
radiocheck_cron_secret Same value until T2-2 dedicated rotation (hosted fallback pattern)

3. Constraints honored

  • No DNS cutover
  • Hosted untouched
  • Realtime preserved
  • Cron jobs on R940 do not point at hosted URLs

4. Ryan review checklist (before T2-1)

  1. Approve internal cron URLs for T2-1 … T-4 (192.168.1.103:8000/functions/v1/...)
  2. Approve T-5 public rewrite to https://api.last1.app/functions/v1/...
  3. Approve inactive cron until Edge deploy smoke (or say enable earlier)
  4. Confirm storage 1 object / 2 buckets sufficient for T2-1

Next: T2-1 Edge Functions deploy (22) + secret injection + auth model report.