- Added `list_nav_history` method in `CoreReadOnlyRepository` to retrieve historical NAV data for products over a specified number of days. - Introduced `get_nav_history` endpoint in `product_service` to return historical NAV sequences, improving product data accessibility. - Updated `products.py` to include new API endpoint for fetching NAV history, ensuring compliance with access control. - Enhanced `ready.py` to include a health check for the new functionality, ensuring system readiness. - Updated documentation to reflect the new testing baseline of 833 passed tests, indicating improved stability and functionality across the application. This update significantly enhances the product API by providing access to historical NAV data, improving user insights into product performance.
83 lines
2.7 KiB
Python
83 lines
2.7 KiB
Python
"""代销平台 · 产品货架 / 详情 / 净值。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends, Query, Request
|
|
|
|
from app.api.deps import AuthContext, assert_platform_product_read, get_platform_auth_context
|
|
from app.repository.core_ro import CoreReadOnlyRepository
|
|
from app.service.platform import product_service
|
|
from app.utils.exceptions import ApiError
|
|
from app.utils.response import ok
|
|
|
|
router = APIRouter(prefix="/api/products", tags=["platform-products"])
|
|
|
|
|
|
def _trace_id(request: Request) -> str:
|
|
return getattr(request.state, "trace_id", "unknown")
|
|
|
|
|
|
@router.get("")
|
|
def list_products_api(
|
|
request: Request,
|
|
limit: int = Query(50, ge=1, le=200),
|
|
offset: int = Query(0, ge=0),
|
|
auth: AuthContext = Depends(get_platform_auth_context),
|
|
) -> dict:
|
|
from app.api.deps import RiskRepository as RR
|
|
|
|
assert_platform_product_read(auth, RR())
|
|
data = product_service.list_products(limit=limit, offset=offset)
|
|
return ok(data, _trace_id(request)).model_dump()
|
|
|
|
|
|
@router.get("/{product_id}")
|
|
def get_product_api(
|
|
product_id: str,
|
|
request: Request,
|
|
auth: AuthContext = Depends(get_platform_auth_context),
|
|
) -> dict:
|
|
from app.api.deps import RiskRepository as RR
|
|
|
|
assert_platform_product_read(auth, RR())
|
|
row = product_service.get_product(product_id)
|
|
if row is None:
|
|
raise ApiError(404, "NOT_FOUND", f"product not found: {product_id}")
|
|
return ok(row, _trace_id(request)).model_dump()
|
|
|
|
|
|
@router.get("/{product_id}/nav/history")
|
|
def get_product_nav_history_api(
|
|
product_id: str,
|
|
request: Request,
|
|
days: int = Query(365, ge=1, le=730),
|
|
auth: AuthContext = Depends(get_platform_auth_context),
|
|
) -> dict:
|
|
from app.api.deps import RiskRepository as RR
|
|
|
|
repo = RR()
|
|
assert_platform_product_read(auth, repo)
|
|
core = CoreReadOnlyRepository()
|
|
data = product_service.get_nav_history(product_id, days=days, core_ro=core)
|
|
if data is None:
|
|
raise ApiError(404, "NOT_FOUND", f"product not found: {product_id}")
|
|
return ok(data, _trace_id(request)).model_dump()
|
|
|
|
|
|
@router.get("/{product_id}/nav")
|
|
def get_product_nav_api(
|
|
product_id: str,
|
|
request: Request,
|
|
auth: AuthContext = Depends(get_platform_auth_context),
|
|
) -> dict:
|
|
from app.api.deps import RiskRepository as RR
|
|
|
|
assert_platform_product_read(auth, RR())
|
|
core = CoreReadOnlyRepository()
|
|
if core.get_product(product_id) is None:
|
|
raise ApiError(404, "NOT_FOUND", f"product not found: {product_id}")
|
|
nav = product_service.get_latest_nav(product_id, core_ro=core)
|
|
if nav is None:
|
|
raise ApiError(404, "NOT_FOUND", f"nav not found for product: {product_id}")
|
|
return ok(nav, _trace_id(request)).model_dump()
|