diff --git a/CHANGELOG.md b/CHANGELOG.md index aee2129..06bd0fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). LLM-backed condition in Watchflow; adds ~1-3s latency. Gracefully skips (no violation) if the LLM is unavailable. +### Fixed + +- **Duplicate tags on Swagger docs** -- Swagger docs should now display all methods only once without repeating them in different tags. + ## [2026-03-01] -- PR #59 ### Added diff --git a/src/api/auth.py b/src/api/auth.py index a6f391f..175f0d5 100644 --- a/src/api/auth.py +++ b/src/api/auth.py @@ -9,7 +9,7 @@ logger = structlog.get_logger() # Use prefix to keep URLs clean: /auth/validate-token -router = APIRouter(prefix="/auth", tags=["Authentication"]) +router = APIRouter(prefix="/auth") class ValidateTokenRequest(BaseModel): diff --git a/src/api/recommendations.py b/src/api/recommendations.py index 35d30c0..a39c434 100644 --- a/src/api/recommendations.py +++ b/src/api/recommendations.py @@ -16,7 +16,7 @@ logger = structlog.get_logger() -router = APIRouter(prefix="/rules", tags=["Recommendations"]) +router = APIRouter(prefix="/rules") # --- Models --- # API schema—keep in sync with frontend expectations. diff --git a/src/api/repos.py b/src/api/repos.py index bdad1ba..a42ff1e 100644 --- a/src/api/repos.py +++ b/src/api/repos.py @@ -10,7 +10,7 @@ logger = structlog.get_logger() -router = APIRouter(prefix="/repos", tags=["Repositories"]) +router = APIRouter(prefix="/repos") @router.get( diff --git a/src/main.py b/src/main.py index 6752547..2481314 100644 --- a/src/main.py +++ b/src/main.py @@ -122,20 +122,20 @@ async def lifespan(_app: FastAPI) -> Any: app.include_router(webhook_router, prefix="/webhooks", tags=["GitHub Webhooks"]) -app.include_router(rules_api_router, prefix="/api/v1", tags=["Public API"]) -app.include_router(recommendations_api_router, prefix="/api/v1", tags=["Recommendations API"]) -app.include_router(auth_api_router, prefix="/api/v1", tags=["Authentication API"]) -app.include_router(repos_api_router, prefix="/api/v1", tags=["Repositories API"]) -app.include_router(scheduler_api_router, prefix="/api/v1/scheduler", tags=["Scheduler API"]) +app.include_router(rules_api_router, prefix="/api/v1", tags=["Public"]) +app.include_router(recommendations_api_router, prefix="/api/v1", tags=["Recommendations"]) +app.include_router(auth_api_router, prefix="/api/v1", tags=["Authentication"]) +app.include_router(repos_api_router, prefix="/api/v1", tags=["Repositories"]) +app.include_router(scheduler_api_router, prefix="/api/v1/scheduler", tags=["Scheduler"]) -@app.get("/", tags=["Health Check"]) +@app.get("/", tags=["Health"]) async def read_root() -> dict[str, str]: """A simple health check endpoint to confirm the service is running.""" return {"status": "ok", "message": "Watchflow agents are running."} -@app.get("/health/tasks", tags=["Health Check"]) +@app.get("/health/tasks", tags=["Health"]) async def health_tasks() -> dict[str, Any]: """Check the status of the task queue.""" stats = task_queue.get_stats() @@ -150,7 +150,7 @@ async def health_tasks() -> dict[str, Any]: } -@app.get("/health/scheduler", tags=["Health Check"]) +@app.get("/health/scheduler", tags=["Health"]) async def health_scheduler() -> dict[str, Any]: """Check the status of the deployment scheduler.""" return get_deployment_scheduler().get_status()