Files
info-share-spot/supabase
adminandClaude Opus 5 85d87d1c62 Charge tuition automatically from attendance
Adds a per-student daily rate (students.daily_tuition_cents) and a trigger
that writes a tuition charge when a student is marked present or late.

Idempotency is the crux. The attendance UI upserts on (student_id, date)
and teachers toggle a status freely — present, absent, present again. A
naive "insert a charge on attendance" trigger bills the family once per
click. So each auto-charge is bound to the attendance row that caused it
via ledger_entries.attendance_id (UNIQUE), which turns the write into an
upsert, lets a change back to absent delete the charge, and cascades the
charge away if the attendance record is deleted.

Manual entries keep attendance_id NULL — Postgres allows unlimited NULLs
in a unique index — so hand-entered charges are untouched and the UI can
tell auto from manual.

A NULL rate (the default) means never auto-charge, so nothing begins
billing until a rate is deliberately set on a student. Existing
attendance is not backfilled: retroactively generating charges against
families' balances should be an explicit decision, not a side effect of
deploying a migration.

The trigger is SECURITY DEFINER because the writer is a teacher marking
attendance while ledger_entries is admin-write under RLS; teachers gain
no general ledger access, only this fixed attendance-derived write.

Verified against the live schema across all eight paths: charge on
present, reversal on absent, no duplicate on re-mark, late billable,
excused free, no rate means no charge, rate change on re-save, and
cascade on attendance delete.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 09:45:30 -04:00
..