Files

75 lines
2.8 KiB
Python
Raw Permalink Normal View History

"""Recommendation generation and reviewed publication endpoints."""
from typing import Any
from fastapi import APIRouter, Depends, Header, Path
from app.api.dependencies.auth import build_request_context
from app.api.dependencies.rate_limit import enforce_rate_limit
from app.core.contracts import RequestContext
from app.core.product_recommendation_contracts import ProductRecommendationQuery
from app.service.advisor_rollout_service import enforce_advisor_rollout
from app.service.product_recommendation_service import ProductRecommendationService
advisor_router = APIRouter(
prefix="/api/v1/advisor",
tags=["advisor-recommendations"],
dependencies=[Depends(enforce_rate_limit), Depends(enforce_advisor_rollout)],
)
admin_router = APIRouter(
prefix="/api/v1/admin",
tags=["platform-admin"],
dependencies=[Depends(enforce_rate_limit)],
)
@advisor_router.post("/recommendations")
async def generate_recommendation(
payload: ProductRecommendationQuery,
context: RequestContext = Depends(build_request_context), # noqa: B008
key: str | None = Header(default=None, alias="Idempotency-Key"),
) -> dict[str, object]:
2026-09-11 16:42:31 +08:00
return await ProductRecommendationService(enforce_profile_governance=True).generate(
payload, context, key
)
@advisor_router.get("/recommendations/published")
async def published_recommendations(
context: RequestContext = Depends(build_request_context), # noqa: B008
) -> dict[str, object]:
return await ProductRecommendationService().published(context)
@admin_router.post(
"/advisor/recommendations/{content_id}/reviews",
dependencies=[Depends(enforce_advisor_rollout)],
)
async def review_recommendation(
payload: dict[str, Any],
content_id: int = Path(gt=0),
context: RequestContext = Depends(build_request_context), # noqa: B008
key: str | None = Header(default=None, alias="Idempotency-Key"),
) -> dict[str, object]:
decision = payload.get("decision")
if decision not in {"approved", "rejected"}:
from app.core.errors import ValidationAgentError
raise ValidationAgentError("decision 必须为 approved 或 rejected")
comment = payload.get("comment", "")
if not isinstance(comment, str):
raise ValueError("comment must be a string")
return await ProductRecommendationService().review(content_id, decision, comment, context, key)
@admin_router.post(
"/advisor/recommendations/{content_id}/publications",
dependencies=[Depends(enforce_advisor_rollout)],
)
async def publish_recommendation(
content_id: int = Path(gt=0),
context: RequestContext = Depends(build_request_context), # noqa: B008
key: str | None = Header(default=None, alias="Idempotency-Key"),
) -> dict[str, object]:
return await ProductRecommendationService().publish(content_id, context, key)