Files
group_xinghuo_jinrong/app/api/customers.py
T
zhanghongyu_0626 ef56c56435 feat(api): 实现代销平台 API v0.1,包括客户、产品、理财师、合规及员工接口
- 新增多个 API 路由:`/api/customers`, `/api/products`, `/api/advisors`, `/api/compliance`, `/api/staff`,支持客户信息、产品详情、理财师客户列表、合规判定及员工上下文查询。
- 引入平台服务层,封装核心只读操作,支持数据脱敏功能。
- 更新依赖注入,确保各 API 路由的权限控制与数据访问一致性。
- 添加相应的单元测试,确保新接口的功能完整性与稳定性。

此更新为代销平台提供了基础的 REST API 支持,增强了系统的可扩展性与可维护性。
2026-09-08 21:01:07 +08:00

91 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""代销平台 · 客户 L0 与资产读 API(canonical · 不要求 X-Agent-Type)。"""
from __future__ import annotations
from fastapi import APIRouter, Depends, Query, Request
from app.api.deps import (
AuthContext,
assert_platform_customer_access,
get_platform_auth_context,
)
from app.repository.core_ro import CoreReadOnlyRepository
from app.repository.risk_repository import RiskRepository
from app.service.platform import customer_service
from app.utils.exceptions import ApiError
from app.utils.response import ok
router = APIRouter(prefix="/api/customers", tags=["platform-customers"])
def _core_ro() -> CoreReadOnlyRepository:
return CoreReadOnlyRepository()
def _risk_repo() -> RiskRepository:
return RiskRepository()
def _trace_id(request: Request) -> str:
return getattr(request.state, "trace_id", "unknown")
@router.get("/{customer_id}")
def get_customer_api(
customer_id: str,
request: Request,
auth: AuthContext = Depends(get_platform_auth_context),
) -> dict:
core = _core_ro()
repo = _risk_repo()
assert_platform_customer_access(auth, customer_id, core_ro=core, risk_repo=repo)
row = customer_service.get_customer_l0(customer_id, core_ro=core)
if row is None:
raise ApiError(404, "NOT_FOUND", f"customer not found: {customer_id}")
return ok(row, _trace_id(request)).model_dump()
@router.get("/{customer_id}/holdings")
def list_holdings_api(
customer_id: str,
request: Request,
limit: int = Query(500, ge=1, le=500),
auth: AuthContext = Depends(get_platform_auth_context),
) -> dict:
core = _core_ro()
repo = _risk_repo()
assert_platform_customer_access(auth, customer_id, core_ro=core, risk_repo=repo)
data = customer_service.list_holdings(customer_id, limit=limit, core_ro=core)
return ok(data, _trace_id(request)).model_dump()
@router.get("/{customer_id}/trades")
def list_trades_api(
customer_id: str,
request: Request,
limit: int = Query(50, ge=1, le=200),
offset: int = Query(0, ge=0),
auth: AuthContext = Depends(get_platform_auth_context),
) -> dict:
core = _core_ro()
repo = _risk_repo()
assert_platform_customer_access(auth, customer_id, core_ro=core, risk_repo=repo)
data = customer_service.list_trades(
customer_id, limit=limit, offset=offset, core_ro=core
)
return ok(data, _trace_id(request)).model_dump()
@router.get("/{customer_id}/products")
def list_customer_products_api(
customer_id: str,
request: Request,
limit: int = Query(50, ge=1, le=200),
auth: AuthContext = Depends(get_platform_auth_context),
) -> dict:
core = _core_ro()
repo = _risk_repo()
assert_platform_customer_access(auth, customer_id, core_ro=core, risk_repo=repo)
data = customer_service.list_customer_products(customer_id, limit=limit, core_ro=core)
return ok(data, _trace_id(request)).model_dump()