Read the measured Soniox line from spend_daily when it has rows
What changed and why
The Omi TV Soniox line now reads the day's measured stt_soniox row from the settled spend ledger (omi_finops.spend_daily) whenever that row exists. The balance series and usage summary stay as the labelled fallback, and the Soniox-console constant stays the last labelled fallback. A spend_daily table that is not created yet reads as no rows, not an error. The line says "no data yet" only when spend_daily has no stt_soniox row and no balance series exists.
Display only: the cost stack and all-in totals are unchanged.
Stacked. This branch is on top of #24876 (spend reader, not merged yet) and includes the commit for #24944 (vendor-balance dark state, not merged yet). Review the last commit only (2e165153c2) for this change. Re-base onto main once #24876 and #24944 merge.
Product invariants affected
none
How it was verified
Run from web/admin on this branch:
node node_modules/vitest/vitest.mjs run(full admin suite): 89 files passed, 5 skipped; 1189 tests passed, 10 skipped.npx --no-install prettier --checkandeslinton the touched files: clean.npx --no-install tsc --noEmit -p .: exit 0.scripts/pr-preflight --pr-body-file: 17 checks passed.
Not verified: a rendered board showing the spend-ledger text. That needs the MacBook render session, and the settled table must be populated first.
Tests
web/admin/lib/__tests__/wall-spend.test.ts: soniox_usd is read as null, not 0, for missing days; sonioxSpendByDay maps only days with a row; the query filters on the stt_soniox line on the variable basis.
UI evidence
UI-Evidence: none -- dashboard label text only; the rendered board check is noted above as pending.
Failure class (fixes)
Failure-Class: none
Generated by Claude Code