fix(billing): key the usage email claim on the exact period start and anchor shared sums to their start

Merged
WA
1mo ago
+89-23

Summary

  • The usage-threshold email claim keyed creditsPeriod on the period start's UTC day. Two distinct periods starting the same day with the same limit (a subscription replaced the day it began) shared one key, so the new period's email was suppressed. It now keys on the exact period start in epoch seconds, bound as bigint in both the pre-check SELECT and the claim UPDATE, which share one SQL builder. This has to land before v0.9.4 reaches main, because changing the key later would re-arm every current claim
  • The shared reporting-usage cache wrote SET … PX TTL NX after the sum finished, so a sum that ran long, or a SET resent after a reconnect, got a full fresh TTL on an older total. The write now anchors expiry to when the sum began: PX max(sumStartedAt + TTL + jitter − now, 5s) NX. The 5s floor keeps a slow sum briefly shared instead of re-run by every process. TSDoc states the resulting bound
  • Responds to review threads on #8356

Type of Change

  • Bug fix

Testing

  • usage-threshold-email.integration.ts: a period and its same-day replacement each deliver their own warning; it fails on staging's day key
  • reporting-usage-cache.integration.ts (real Redis):
    • a sum that began 20s ago expires ~TTL−20s after the write, not a full TTL
    • a sum that began 31s ago is stored with the 5s floor
    • both fail on staging's relative write, and the second fails with the floor removed
  • Billing and logs integration (66) and unit (1,059) suites, type-check, lint, and check:audits pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)