Problem
retry_job (app/api/v1/endpoints/jobs.py) has a webhook branch:
elif job.job_type == JobType.WEBHOOK_DISPATCH:
from app.tasks.webhook_tasks import dispatch_webhook_delivery
task_result = dispatch_webhook_delivery.delay(payload) # payload is the parsed JSON dict
dispatch_webhook_delivery(self, delivery_id: str) (app/tasks/webhook_tasks.py) expects a delivery UUID string and immediately calls UUID(delivery_id) — passing the payload dict raises TypeError inside the task, which then retries 5 times and dies.
Separately, JobType.WEBHOOK_DISPATCH is referenced nowhere else: no code path creates a job with that type (app/tasks/sla_tasks.py only creates SLA_COMPUTATION/BULK_SLA_COMPUTATION), so the branch is unreachable today.
Consequences:
- The branch is broken if ever reached: a manually-inserted or future webhook job retried through the API schedules a task that fails on
UUID({...}) — the retry is silently doomed, and the audit event job_retry_initiated records a success that will never happen.
- The dead branch is a trap for the webhook-dispatch work: when webhook dispatch jobs are introduced (the service already documents webhook delivery retry semantics), this path will mislead a contributor into thinking retry works.
- The branch's payload semantics are undefined: a webhook job's payload should carry a
delivery_id, not the raw event dict the SLA paths use — the two job types have different payload shapes and the retry code treats them the same.
Root cause
The retry branch was scaffolded to match the enum without the corresponding job-creating code path or a payload contract.
Why this is architecturally hard
- The fix requires defining what a WEBHOOK_DISPATCH job's payload is (the delivery id? the event?) and who creates such jobs — either remove the branch and the enum value, or implement the creator and a schema-validated retry.
- If kept, the branch must validate
payload is a string delivery id before .delay(), mirroring dispatch_delivery(db, UUID(delivery_id))'s expectations.
- A test must create a WEBHOOK_DISPATCH job (or assert the branch is unreachable) — today the enum value and branch are completely untested.
Proposed design
Either delete the WEBHOOK_DISPATCH retry branch (and the enum value) until webhook jobs exist, or implement job creation for webhook dispatch with a delivery_id payload and fix the .delay(payload) call to pass the id. Add a test covering whichever path remains.
Acceptance criteria
Service
Tests
Out of scope
The duplicate-row retry bug (tracked separately) and webhook delivery semantics.
Getting started
pytest tests/test_payment_retry_queue_backoff.py -q
make typecheck
Good first files to read: app/api/v1/endpoints/jobs.py, app/tasks/webhook_tasks.py, app/models/job.py.
Problem
retry_job(app/api/v1/endpoints/jobs.py) has a webhook branch:dispatch_webhook_delivery(self, delivery_id: str)(app/tasks/webhook_tasks.py) expects a delivery UUID string and immediately callsUUID(delivery_id)— passing the payload dict raisesTypeErrorinside the task, which then retries 5 times and dies.Separately,
JobType.WEBHOOK_DISPATCHis referenced nowhere else: no code path creates a job with that type (app/tasks/sla_tasks.pyonly createsSLA_COMPUTATION/BULK_SLA_COMPUTATION), so the branch is unreachable today.Consequences:
UUID({...})— the retry is silently doomed, and the audit eventjob_retry_initiatedrecords a success that will never happen.delivery_id, not the raw event dict the SLA paths use — the two job types have different payload shapes and the retry code treats them the same.Root cause
The retry branch was scaffolded to match the enum without the corresponding job-creating code path or a payload contract.
Why this is architecturally hard
payloadis a string delivery id before.delay(), mirroringdispatch_delivery(db, UUID(delivery_id))'s expectations.Proposed design
Either delete the WEBHOOK_DISPATCH retry branch (and the enum value) until webhook jobs exist, or implement job creation for webhook dispatch with a
delivery_idpayload and fix the.delay(payload)call to pass the id. Add a test covering whichever path remains.Acceptance criteria
Service
Tests
Out of scope
The duplicate-row retry bug (tracked separately) and webhook delivery semantics.
Getting started
Good first files to read:
app/api/v1/endpoints/jobs.py,app/tasks/webhook_tasks.py,app/models/job.py.