tenseleyflow/shithub / 11bf3d9

Browse files

migrations: add subject audit columns to billing_webhook_events

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
11bf3d9b2b5d02f003c5b35be035398213ab8796
Parents
7cfe69b
Tree
e3bfe23

1 changed file

StatusFile+-
A internal/migrationsfs/migrations/0075_billing_webhook_events_polymorphic.sql 44 0
internal/migrationsfs/migrations/0075_billing_webhook_events_polymorphic.sqladded
@@ -0,0 +1,44 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+--
3
+-- PAYMENTS PRO03 — add subject audit columns to billing_webhook_events.
4
+--
5
+-- The webhook idempotency table is already subject-agnostic at the
6
+-- data-model level: it dedupes by (provider, provider_event_id) and
7
+-- has no org FK. This migration only adds (subject_kind, subject_id)
8
+-- audit columns so future operator queries can answer "which user/org
9
+-- did this event apply to?" without re-parsing the payload.
10
+--
11
+-- Nullable by design:
12
+-- - Legacy rows (pre-PRO04) have no resolved subject — they predate
13
+--   the metadata convention.
14
+-- - Webhook events that fail to resolve a subject (corrupted
15
+--   metadata, customer-id not found on either side) still get a
16
+--   receipt row so they aren't replayed forever. Such rows carry
17
+--   NULL subject and a non-empty process_error.
18
+
19
+-- +goose Up
20
+
21
+ALTER TABLE billing_webhook_events
22
+    ADD COLUMN subject_kind billing_subject_kind,
23
+    ADD COLUMN subject_id   bigint;
24
+
25
+-- Both-or-neither: a receipt row either has a resolved subject (both
26
+-- columns populated) or doesn't (both NULL). Mixed state means a bug
27
+-- in the resolver.
28
+ALTER TABLE billing_webhook_events
29
+    ADD CONSTRAINT billing_webhook_events_subject_both_or_neither CHECK (
30
+        (subject_kind IS NULL AND subject_id IS NULL)
31
+        OR (subject_kind IS NOT NULL AND subject_id IS NOT NULL)
32
+    );
33
+
34
+-- Operator-query index for "events that did resolve a subject."
35
+CREATE INDEX billing_webhook_events_subject_idx
36
+    ON billing_webhook_events (subject_kind, subject_id, received_at DESC)
37
+    WHERE subject_kind IS NOT NULL;
38
+
39
+-- +goose Down
40
+
41
+DROP INDEX IF EXISTS billing_webhook_events_subject_idx;
42
+ALTER TABLE billing_webhook_events DROP CONSTRAINT IF EXISTS billing_webhook_events_subject_both_or_neither;
43
+ALTER TABLE billing_webhook_events DROP COLUMN IF EXISTS subject_id;
44
+ALTER TABLE billing_webhook_events DROP COLUMN IF EXISTS subject_kind;