| 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 |