fix: admin notification flood caps (C5) at every remaining insert site; gift-card expiry-sweep TOCTOU (M4)
- adminnotify: MaxUnacknowledgedCriticalLogs global cap exposed as CriticalLogsCapExceeded — a pre-check helper every insert site pairs with the atomic fold inside its INSERT (count-then-insert is atomic, closing the TOCTOU where concurrent inserts could both read a below-cap count). - jobs/cleanup.go ScanCriticalPaymentLogs: capped at the shared cap, pre-check skips the scan and logs the suppression. - scheduling: 1_week_no_pay, 1_month_no_pay, default_hours_changed, deposit_not_paid_by_deadline and the Square-erasure critical notification all flood-capped with pre-check + atomic fold (per-booking/per-user dedup kept). - time-blockers.go CleanupExpiredGiftCards (M4): the expiry SELECT now runs under FOR UPDATE row locks so the read-expired-then-zero window is atomic — a concurrent top-up either commits before the SELECT (refreshed last_used_at drops the card out of the predicate) or blocks until the sweep's tx ends and revives the zeroed card via its own expiry refresh; the top-up value can never be destroyed by the sweep. - flood-cap tests added for 1_week_no_pay; adminnotify unit coverage added.
This commit is contained in:
@@ -16,18 +16,13 @@
|
||||
// (dispute, booking, unknown-event, orphan-replay).
|
||||
// - handlers/user/account.go InsertSquareErasureCriticalNotification.
|
||||
//
|
||||
// Sites owned by OTHER agents that still need the fold (coordination notes):
|
||||
// Sites owned by OTHER agents (coordination notes):
|
||||
//
|
||||
// - handlers/payments/sweep.go:1556 insertCriticalPaymentNotification (money
|
||||
// agent) — its INSERT ... SELECT ... WHERE NOT EXISTS is the same
|
||||
// unbounded-across-accounts shape; fold `AND (SELECT COUNT(*) FROM
|
||||
// admin_notifications _an WHERE _an.reason = 'critical_payment_log' AND
|
||||
// _an.acknowledged_at IS NULL) < $N` (N = MaxUnacknowledgedCriticalLogs)
|
||||
// into its WHERE clause.
|
||||
// - handlers/scheduling/time-blockers.go:511 insertSquareCleanupCriticalNotification
|
||||
// and internal/jobs/cleanup.go:333 ScanCriticalPaymentLogs — the same
|
||||
// 'critical_payment_log' insert shape on the GDPR-cleanup and log-scan
|
||||
// paths (owner: the jobs/scheduling agent).
|
||||
// - handlers/payments/sweep.go insertCriticalPaymentNotification — NOW capped
|
||||
// (same atomic fold + pre-check as every other site).
|
||||
// - handlers/scheduling/time-blockers.go insertSquareCleanupCriticalNotification
|
||||
// and internal/jobs/cleanup.go ScanCriticalPaymentLogs — both NOW capped
|
||||
// (same atomic fold + pre-check as every other site).
|
||||
// - main.go has NO admin_notifications insert sites (it only mounts the
|
||||
// notification read/ack routes), so nothing to cap there.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user