MySQL · 1127 bytes Raw Blame History
1 -- SPDX-License-Identifier: AGPL-3.0-or-later
2 --
3 -- PAYMENTS PRO08 — record Stripe's event.created timestamp on each
4 -- billing-state row so the webhook handler can refuse stale events.
5 --
6 -- Stripe does not guarantee delivery order for retries — a reverse-
7 -- ordered pair (subscription.updated[canceled] then
8 -- subscription.updated[active]) would re-activate a canceled
9 -- subscription if the handler applies them in arrival order. The
10 -- guard compares event.Created against the persisted last_event_at
11 -- and refuses the apply when the incoming event is older.
12 --
13 -- Nullable by design:
14 -- - Legacy rows (pre-PRO08) have no observed events — NULL means
15 -- "no prior event; accept anything."
16 -- - Rows for subjects that haven't received any Stripe event yet
17 -- also stay NULL until the first apply.
18
19 -- +goose Up
20 ALTER TABLE org_billing_states
21 ADD COLUMN last_event_at timestamptz;
22 ALTER TABLE user_billing_states
23 ADD COLUMN last_event_at timestamptz;
24
25 -- +goose Down
26 ALTER TABLE user_billing_states DROP COLUMN IF EXISTS last_event_at;
27 ALTER TABLE org_billing_states DROP COLUMN IF EXISTS last_event_at;
28