fix(v2): m002 — rename dca_commission_splits.wallet_id → target

The collapsed m001 introduced commit (2886dd7) renamed wallet_id → target
on dca_commission_splits, but a real-world install caught a subtle
LNbits-side wrinkle: the sqlite file persists across extension
uninstall+reinstall. LNbits' uninstall wipes the dbversions tracker
(so m001 re-runs), but NOT the satoshimachine.sqlite3 file. With
`CREATE TABLE IF NOT EXISTS` in m001, the pre-existing
dca_commission_splits table (created by an earlier partial m005 with
the old `wallet_id` column) survived unchanged. m001 marked itself
complete, then runtime queries blew up because the model expected
`target` but the DB still had `wallet_id`:

  ERROR | distribution.process_settlement:389
  unexpected: 1 validation error for CommissionSplit
  target
    field required (type=value_error.missing)

m002 fixes it idempotently:
  - Probes for the wallet_id column via SELECT
  - If it exists (stale install): ALTER TABLE … RENAME COLUMN
  - If the SELECT errors (fresh install or already renamed): no-op

ALTER TABLE … RENAME COLUMN is portable across SQLite 3.25+ and
PostgreSQL. Both backends preserve row data on rename.

Refs: aiolabs/satmachineadmin#9, found while validating cash-in flow
end-to-end (LNURL-withdraw redemption on the regtest stack).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-15 07:55:57 +02:00
commit 47916bdddd

View file

@ -302,3 +302,33 @@ async def m001_satmachine_v2_initial(db):
);
"""
)
async def m002_rename_commission_split_wallet_id_to_target(db):
"""One-off correction for installs whose `dca_commission_splits` table
pre-exists from an earlier partial v2 migration run (where the column
was named `wallet_id`). The collapsed m001 uses `CREATE TABLE IF NOT
EXISTS`, which is a no-op when the table already exists so the
schema drift survives the documented uninstall + reinstall workflow
because LNbits' uninstall wipes the dbversions tracker but NOT the
satoshimachine.sqlite3 file on disk.
Idempotent: probes for the `wallet_id` column via a SELECT. If the
probe succeeds the column still exists and we RENAME it; otherwise
the rename is already done (or the table was fresh) and we no-op.
Fresh installs from m001 onward already have `target` directly for
them this migration is a no-op.
"""
try:
await db.fetchone(
"SELECT wallet_id FROM satoshimachine.dca_commission_splits LIMIT 1"
)
except Exception:
# wallet_id column doesn't exist; either m001 produced the correct
# schema on a fresh install or the rename already landed.
return
await db.execute(
"ALTER TABLE satoshimachine.dca_commission_splits "
"RENAME COLUMN wallet_id TO target"
)