Webhook receivers
Inbound events from connected providers land at /api/webhooks/[provider]. Signatures are verified per-provider; replays are deduplicated by payload hash.
Each connector that supports webhooks declares its signature-verification logic. The universal receiver at /api/webhooks/[provider] does:
(1) Look up the connector by key. (2) Run the connector's verifyWebhook against the raw body + headers. (3) Hash the payload (sha-256) and persist a webhook_events row. (4) Hand off to the connector's handleWebhook for reconcile.
Replays are returned as 200 fast (the unique constraint on (provider, payload_sha) catches them). Failed verifications are returned as 400 — providers will retry, and the failure is recorded for forensics.
Set the per-provider webhook secret env var (e.g. MERGE_WEBHOOK_SECRET, SLACK_SIGNING_SECRET) to activate verification. Without it, the connector returns false and rejects everything — safer than a permissive default.