From ca18d68e56eca9bafa27a43df702532c05d3ef5b Mon Sep 17 00:00:00 2001 From: Patrick Toal Date: Wed, 15 Apr 2026 22:35:33 -0400 Subject: [PATCH] docs: Update CLAUDE docs --- .../handoff-2026-04-15-supabase-migration.md | 0 ...-2026-04-15-supabase-vault-provisioning.md | 81 +++++++++++++++++++ 2 files changed, 81 insertions(+) rename docs/{summaries => archive/handoffs}/handoff-2026-04-15-supabase-migration.md (100%) create mode 100644 docs/summaries/handoff-2026-04-15-supabase-vault-provisioning.md diff --git a/docs/summaries/handoff-2026-04-15-supabase-migration.md b/docs/archive/handoffs/handoff-2026-04-15-supabase-migration.md similarity index 100% rename from docs/summaries/handoff-2026-04-15-supabase-migration.md rename to docs/archive/handoffs/handoff-2026-04-15-supabase-migration.md diff --git a/docs/summaries/handoff-2026-04-15-supabase-vault-provisioning.md b/docs/summaries/handoff-2026-04-15-supabase-vault-provisioning.md new file mode 100644 index 0000000..a46d220 --- /dev/null +++ b/docs/summaries/handoff-2026-04-15-supabase-vault-provisioning.md @@ -0,0 +1,81 @@ +# Session Handoff: Supabase Vault Provisioning & Inventory Secret Migration +**Date:** 2026-04-15 +**Session Focus:** Create provision_supabase_project.yml; move all vault lookups from playbooks into inventory +**Context Usage at Handoff:** ~50% + +## What Was Accomplished + +1. Created `playbooks/provision_supabase_project.yml` — reads admin secrets from `kv/data/toallab/supabase` (using `vault_kv2_get`), asserts required keys present, then writes `url`, `anon_key`, `service_key`, and `postgres_url` to per-environment vault path (using `vault_kv2_write`) +2. Updated `inventories/bab-inventory/host_vars/supabase-dev/main.yml` — added 5 provisioning vars: `supabase_admin_vault_path`, `supabase_api_url`, `supabase_db_host`, `supabase_db_port`, `supabase_db_name` +3. Updated `inventories/bab-inventory/host_vars/supabase-prod/main.yml` — same vars; prod marked OPEN (may need different admin instance) +4. Created `inventories/bab-inventory/host_vars/supabase-dev/vault.yml` — `supabase` var backed by hashi_vault lookup on `supabase_vault_path` +5. Created `inventories/bab-inventory/host_vars/supabase-prod/vault.yml` — same pattern +6. Created `inventories/bab-inventory/group_vars/all/vault.yml` — `gitea_token` var backed by hashi_vault lookup on `kv/data/oys/shared/infra/gitea_token` +7. Updated `playbooks/backup_supabase.yml` — removed inline vault lookup task; pg_dump now uses `supabase.postgres_url` from inventory +8. Updated `playbooks/sync_gitea_secrets.yml` — removed both vault lookup tasks; uses `supabase.url`, `supabase.anon_key`, `gitea_token.token`; added idempotent GET→POST/PUT pattern for Gitea variable API + +## Exact State of Work in Progress + +- `provision_supabase_project.yml` written but not yet run against prod; dev run is next step +- `kv/data/oys/dev/supabase` currently only contains `postgres_url` — `url`, `anon_key`, `service_key` are missing until provision playbook runs +- `kv/data/oys/prod/supabase` state unknown — assume same gap + +## Decisions Made This Session + +- Vault lookups moved to inventory (`host_vars/*/vault.yml` and `group_vars/all/vault.yml`) BECAUSE playbooks should reference clean variable names, not embed vault paths — STATUS: confirmed +- Self-hosted Supabase has no project management API — "create project" scope was abandoned BECAUSE the Studio `/api/v1/projects` endpoint is not exposed on self-hosted; there is one project per deployment — STATUS: confirmed +- Gitea variable API requires GET-then-POST/PUT (not PUT alone) BECAUSE PUT returns 404 when variable does not yet exist — STATUS: confirmed, tested + +## Key Numbers Generated or Discovered This Session + +- `kv/toallab/supabase` confirmed keys: `anon_key`, `service_key`, `db_password`, `jwt_secret`, `dashboard_username`, `dashboard_password`, plus analytics/realtime tokens +- `kv/oys/shared/infra/gitea_token` confirmed key: `token` (NOT `value` — old code was wrong) +- `kv/data/oys/dev/supabase` has exactly 1 key: `postgres_url` = `postgresql://postgres:mr8CQASBOwwxploV9nxoPFSVkhCzXOZA@db-supabase.apps.openshift.toal.ca:30432/postgres` +- Supabase Studio URL: `https://supabase.apps.openshift.toal.ca` (Kong gateway + Studio, same hostname) +- Supabase DB external NodePort: `30432` + +## Conditional Logic Established + +- IF `kv/data/oys/dev/supabase` does not have `url`/`anon_key` THEN `sync_gitea_secrets.yml` will fail with `'dict object' has no attribute 'url'` — run `provision_supabase_project.yml --limit supabase-dev` first +- IF Gitea variable does not exist THEN POST (status 201); IF it exists THEN PUT (status 204) — GET check drives the branch +- IF targeting `supabase-dev` THEN vault reads from `kv/data/oys/dev/supabase`; IF targeting `supabase-prod` THEN `kv/data/oys/prod/supabase` + +## Files Created or Modified + +| File Path | Action | Description | +|-----------|--------|-------------| +| `playbooks/provision_supabase_project.yml` | Created | Reads `kv/toallab/supabase`, writes url/anon_key/service_key/postgres_url to per-env vault path | +| `inventories/bab-inventory/host_vars/supabase-dev/main.yml` | Modified | Added supabase_admin_vault_path, supabase_api_url, supabase_db_host/port/name | +| `inventories/bab-inventory/host_vars/supabase-prod/main.yml` | Modified | Same vars; prod OPEN for different admin instance | +| `inventories/bab-inventory/host_vars/supabase-dev/vault.yml` | Created | `supabase` hashi_vault lookup var | +| `inventories/bab-inventory/host_vars/supabase-prod/vault.yml` | Created | `supabase` hashi_vault lookup var | +| `inventories/bab-inventory/group_vars/all/vault.yml` | Created | `gitea_token` hashi_vault lookup var | +| `playbooks/backup_supabase.yml` | Modified | Removed vault lookup task; uses `supabase.postgres_url` | +| `playbooks/sync_gitea_secrets.yml` | Modified | Removed vault lookups; uses inventory vars; GET→POST/PUT idempotency | + +## What the NEXT Session Should Do + +1. **First**: Run `ansible-navigator run playbooks/provision_supabase_project.yml --mode stdout --limit supabase-dev` to populate `kv/data/oys/dev/supabase` with `url`, `anon_key`, `service_key` +2. **Then**: Run `ansible-navigator run playbooks/sync_gitea_secrets.yml --mode stdout --limit supabase-dev` to verify end-to-end success +3. **Then**: Confirm `supabase_api_url` value for prod (`supabase-prod` currently ASSUMED same as dev — `https://supabase.apps.openshift.toal.ca`) +4. **Then**: Run provision + sync for prod + +## Open Questions Requiring User Input + +- [ ] `supabase-prod` admin instance — is it the same toallab Supabase as dev, or a different production instance? Impacts `supabase_admin_vault_path` and `supabase_api_url` in `host_vars/supabase-prod/main.yml` + +## Assumptions That Need Validation + +- ASSUMED: `supabase_api_url: https://supabase.apps.openshift.toal.ca` is the correct Kong/PostgREST API URL that the BAB app should use — validate by checking what URL the Vue app should call +- ASSUMED: prod uses the same admin vault path and API URL as dev — validate before running provision against prod + +## What NOT to Re-Read + +- `docs/archive/handoffs/handoff-2026-04-15-supabase-migration.md` — superseded by this handoff; all open questions from it are resolved or carried forward here + +## Files to Load Next Session + +- `playbooks/provision_supabase_project.yml` — if running or debugging provision +- `playbooks/sync_gitea_secrets.yml` — if running or debugging sync +- `inventories/bab-inventory/host_vars/supabase-dev/main.yml` — if adjusting provisioning vars +- `inventories/bab-inventory/host_vars/supabase-prod/main.yml` — when addressing prod OPEN question