-- Run in YOUR application's database, never in the Stampwing service database. -- Namespace by endpoint/provider: identifiers from different sources may overlap. CREATE TABLE email_webhook_inbox ( source text NOT NULL, event_id text NOT NULL, payload jsonb NOT NULL, received_at timestamptz NOT NULL DEFAULT now(), processed_at timestamptz, PRIMARY KEY (source, event_id) ); -- A worker should claim unprocessed rows, append events, and mark processed_at -- in one transaction. External side effects need their own idempotent outbox.