Legal-i commited on
Commit
8f1492f
·
verified ·
1 Parent(s): 059729c

Stage 239: per-delivery retry (infra/api/app.py)

Browse files
Files changed (1) hide show
  1. infra/api/app.py +50 -0
infra/api/app.py CHANGED
@@ -3533,6 +3533,56 @@ def create_app(db_path: Optional[str] = None,
3533
  # Stage 168 — delivery log for a single webhook. Read-only,
3534
  # any tenant role can see it (debugging "why didn't I get the
3535
  # Slack ping" needs analyst-tier access, not operator).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3536
  @app.get("/webhooks/{webhook_id}/deliveries", tags=["webhooks"])
3537
  async def list_webhook_deliveries_route(
3538
  webhook_id: str,
 
3533
  # Stage 168 — delivery log for a single webhook. Read-only,
3534
  # any tenant role can see it (debugging "why didn't I get the
3535
  # Slack ping" needs analyst-tier access, not operator).
3536
+ # Stage 239 — tenant-wide delivery list (cross-webhook). Used
3537
+ # by the Webhooks page "failed deliveries" section.
3538
+ @app.get("/tenants/{tenant_id}/webhook_deliveries",
3539
+ tags=["webhooks"])
3540
+ async def list_tenant_webhook_deliveries_route(
3541
+ tenant_id: str,
3542
+ status: Optional[str] = Query(default=None),
3543
+ limit: int = Query(100, ge=1, le=500),
3544
+ key: ApiKey = Depends(auth_dep),
3545
+ ):
3546
+ require_tenant_access(key, tenant_id)
3547
+ require_role(key, ROLE_READONLY)
3548
+ try:
3549
+ return {
3550
+ "deliveries": svc.list_tenant_webhook_deliveries(
3551
+ tenant_id, status=status, limit=limit,
3552
+ ),
3553
+ }
3554
+ except ValueError as e:
3555
+ raise ApiError("bad_request", str(e), status=400) from e
3556
+
3557
+ # Stage 239 — manual retry of one specific delivery.
3558
+ @app.post("/webhook_deliveries/{delivery_id}/retry",
3559
+ tags=["webhooks"])
3560
+ async def retry_one_delivery_route(
3561
+ delivery_id: str,
3562
+ authorization: Optional[str] = Header(default=None),
3563
+ ):
3564
+ # Resolve the delivery's tenant before auth so a
3565
+ # forged delivery_id doesn't sneak through.
3566
+ delivery = svc.webhook_deliveries.get(delivery_id)
3567
+ if delivery is None:
3568
+ raise ApiError(
3569
+ "not_found",
3570
+ f"unknown delivery {delivery_id!r}", status=404,
3571
+ )
3572
+ key = require_tenant_or_admin(
3573
+ svc, authorization, delivery["tenant_id"],
3574
+ )
3575
+ if key is not None:
3576
+ require_role(key, ROLE_OPERATOR)
3577
+ actor = (key.key_id if key is not None
3578
+ else _admin_actor(authorization))
3579
+ try:
3580
+ return svc.retry_one_delivery(delivery_id, actor=actor)
3581
+ except KeyError as e:
3582
+ raise ApiError("not_found", str(e), status=404) from e
3583
+ except ValueError as e:
3584
+ raise ApiError("bad_request", str(e), status=400) from e
3585
+
3586
  @app.get("/webhooks/{webhook_id}/deliveries", tags=["webhooks"])
3587
  async def list_webhook_deliveries_route(
3588
  webhook_id: str,