Files
group_xinghuo_jinrong/app/api/products.py
T
zhanghongyu_0626 2b4eaa9725 feat(nav): Implement historical NAV tracking and enhance product API
- 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.
2026-09-11 20:47:18 +08:00

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()