WebhookEvent (src/common/entities/webhook-event.entity.ts) has only deliveryId uniquely indexed (implicitly, via unique: true) — there is no @Index on eventType, status, or receivedAt, despite this being an append-only, ever-growing audit table by design (every inbound webhook, verified or not, gets a row per the entity's own doc comment: "Audit log of every inbound webhook ... for replay/debugging").
Any future operational tooling — an admin view listing recent FAILED events for triage, a metrics job counting events by type/day, or simply an engineer debugging "did webhook X for repo Y ever arrive" by filtering on eventType/receivedAt — will full-scan this table, which by its very nature never stops growing (nothing deletes old rows, unlike IdempotencyKey's TTL-based cleanup).
Fix: add a composite index on (eventType, status) and a separate index on receivedAt (or a composite covering common "recent failures" queries like (status, receivedAt)).
WebhookEvent(src/common/entities/webhook-event.entity.ts) has onlydeliveryIduniquely indexed (implicitly, viaunique: true) — there is no@IndexoneventType,status, orreceivedAt, despite this being an append-only, ever-growing audit table by design (every inbound webhook, verified or not, gets a row per the entity's own doc comment: "Audit log of every inbound webhook ... for replay/debugging").Any future operational tooling — an admin view listing recent
FAILEDevents for triage, a metrics job counting events by type/day, or simply an engineer debugging "did webhook X for repo Y ever arrive" by filtering oneventType/receivedAt— will full-scan this table, which by its very nature never stops growing (nothing deletes old rows, unlikeIdempotencyKey's TTL-based cleanup).Fix: add a composite index on
(eventType, status)and a separate index onreceivedAt(or a composite covering common "recent failures" queries like(status, receivedAt)).