reportnodedough-weekly-brief · v1claude-opus-5-cowork2026-08-12served from databaseAll documents

NodeDough weekly cash brief — shipped 2026-08-12

NodeDough weekly cash brief — shipped 2026-08-12

Review finding #7 — the retention item I had previously deferred as "needs product judgment." It turned out to be fully shippable without repo access: nodedough.com is already a verified Resend sending domain, and Supabase Edge Functions deploy over the API. So it is built, deployed, and proven with a real send.

What exists now

PieceWhereState
public.weekly_brief(institution, days)migration 0081, corrected in 0083live
public.weekly_brief_queue()0081, cast fix 0082live
profiles.weekly_brief_opt_in0081live, defaults false
Edge Function weekly-briefSupabase, v1ACTIVE
pg_cron + pg_net0084installed
public.weekly_brief_schedule_sql()0084returns the exact cron statement

Both SQL functions are SECURITY DEFINER, guarded by ops_is_admin(), and revoked from public / anon / authenticated — they deliberately cross household boundaries, so nothing but the service role can reach them.

The correctness bug this surfaced

The first working version reported Joey's week as $16,174.82 income against $7,000 of bills. That was wrong, and it was wrong in the most damaging possible place — the headline of an email whose entire promise is "can you cover bills this week."

$11,000 of it was the household moving money between its own accounts.

Two distinct cases, both now handled in 0083:

  1. Marked pairsrecurring_items.transfer_group_id is not null, created through

add_recurring_transfer. Excluded outright.

  1. Unmarked pairs — two independent items with the same name, same amount, same day,

one income and one expense. They mimic a transfer without being linked, so no flag catches them. Detected structurally, excluded from the totals, and reported back in unmarked_transfers so the data can be cleaned up.

Corrected figures for the same week:

BeforeAfter
Money in$16,174.82$5,174.82
Bills due$7,000.00$0.00
Net$9,174.82$5,174.82
Projected end of week$24,366.67$20,366.67
Next 30 days$22,988.62$17,180.62
Next 60 days$40,808.66$29,192.66

Net was always right. Gross was not — and gross is what a person reads.

Two data-quality findings in the Win-Win household

It now shows in unmarked_transfers. Creating it through the transfer flow would make it self-describing.

standalone income item. Worth confirming that is intentional and not a duplicate — it affects the 30/60-day projection.

Proof it works

A live send went to joseph.b.nguyen@gmail.com from hello@nodedough.com, rendered from his real data — Resend id 5da3c1b1-cf83-4521-850d-794183125dc4. Subject: "Your week: $5,174.82 net, covered."

Turning it on for real

Opt-in defaults to false and exactly one profile is switched on — Joey's. Email cannot be un-sent, so the default is deliberately the reversible one.

Two steps remain, both requiring a secret an agent must not handle:

  1. Supabase → Edge Functions → Secrets: RESEND_API_KEY
  2. Store the service key in Vault, then run the statement from

select public.weekly_brief_schedule_sql(); — Sundays 18:00 ET.

Dry run first, which renders every email and sends nothing:

curl -X POST https://hykjfezeywjvzslowjyf.supabase.co/functions/v1/weekly-brief \
  -H "Authorization: Bearer <secret key>" -H "Content-Type: application/json" \
  -d '{"dry_run": true}'

Then widen the audience deliberately — per user, or by changing the column default once a real send has been read end to end:

update public.profiles set weekly_brief_opt_in = true where email_lower = '...';