From 3b3e7da2a383eb4c603b61d5ef7ee2cb6c6259ce Mon Sep 17 00:00:00 2001 From: bernatsampera Date: Sun, 9 Aug 2026 12:30:31 +0200 Subject: [PATCH] Add publish endpoint to re-approve rejected workflows Co-Authored-By: Claude Opus 4.6 (1M context) --- api/app/routes_admin.py | 17 ++++++++++++++++- api/tests/test_api.py | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/api/app/routes_admin.py b/api/app/routes_admin.py index b0b9db6..66f9fc5 100644 --- a/api/app/routes_admin.py +++ b/api/app/routes_admin.py @@ -1,9 +1,11 @@ +from datetime import datetime, timezone + from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.orm import Session, selectinload from .db import get_session -from .models import Template +from .models import APPROVED, REJECTED, Template from .routes_moderation import require_admin from .schemas import AdminUpdateIn, AdminWorkflowOut @@ -55,6 +57,19 @@ def update_metadata( return _to_out(template) +@router.post("/workflows/{workflow_id}/publish") +def publish_workflow(workflow_id: str, session: Session = Depends(get_session)): + template = session.scalars( + select(Template).where(Template.id == workflow_id, Template.status == REJECTED) + ).first() + if template is None: + raise HTTPException(status_code=404, detail="no rejected workflow with this id") + template.status = APPROVED + template.reviewed_at = datetime.now(timezone.utc) + session.commit() + return {"id": workflow_id, "status": APPROVED} + + @router.delete("/workflows/{workflow_id}") def delete_workflow(workflow_id: str, session: Session = Depends(get_session)): template = session.scalars( diff --git a/api/tests/test_api.py b/api/tests/test_api.py index b90a6a0..7e8c2cb 100644 --- a/api/tests/test_api.py +++ b/api/tests/test_api.py @@ -231,6 +231,26 @@ def test_admin_delete_not_found(client, admin): assert resp.status_code == 404 +def test_admin_publish_rejected(client, admin): + submit(client) + client.post("/api/moderation/workflows/demo-flow/reject", headers=admin) + + resp = client.post("/api/admin/workflows/demo-flow/publish", headers=admin) + assert resp.status_code == 200 + assert resp.json()["status"] == "approved" + + public = client.get("/api/workflows/demo-flow") + assert public.status_code == 200 + assert public.json()["name"] == "Demo Flow" + + +def test_admin_publish_not_rejected_404(client, admin): + submit(client) + client.post("/api/moderation/workflows/demo-flow/approve", headers=admin) + resp = client.post("/api/admin/workflows/demo-flow/publish", headers=admin) + assert resp.status_code == 404 + + def test_admin_delete_requires_token(client): assert client.delete("/api/admin/workflows/x").status_code == 401