37494a7192
将 web/routes.py 拆分为模块化 router + service 架构
- 新增 web/app_factory.py 集中注册 7 个域名 router
- 新增 web/routers/ 薄壳路由层(auth/city/system/scan/ops/payments/analytics)
- 新增 web/services/ 业务函数下沉(每域独立 service 文件)
- web/routes.py 缩减为 city_runtime 的兼容重导出 facade
- analysis_service.py/app.py 适配新入口并清理冗余导入
Scope-risk: LOW — 全量 170 测试通过,router 注册顺序与原路由一致
Tested: python -m pytest -q (170 passed), ruff check . (All checks passed)
@
80 lines
2.0 KiB
Python
80 lines
2.0 KiB
Python
"""Operations/admin API routes."""
|
|
|
|
from fastapi import APIRouter, Request
|
|
|
|
from web.core import GrantPointsRequest
|
|
from web.services.ops_api import (
|
|
get_ops_analytics_funnel,
|
|
get_ops_truth_history,
|
|
get_ops_weekly_leaderboard,
|
|
grant_ops_points,
|
|
list_ops_memberships,
|
|
list_ops_payment_incidents,
|
|
resolve_ops_payment_incident,
|
|
search_ops_users,
|
|
)
|
|
|
|
router = APIRouter(tags=["ops"])
|
|
|
|
|
|
@router.get("/api/ops/users")
|
|
async def ops_search_users(request: Request, q: str = "", limit: int = 20):
|
|
return search_ops_users(request, q=q, limit=limit)
|
|
|
|
|
|
@router.get("/api/ops/leaderboard/weekly")
|
|
async def ops_weekly_leaderboard(request: Request, limit: int = 20):
|
|
return get_ops_weekly_leaderboard(request, limit=limit)
|
|
|
|
|
|
@router.get("/api/ops/memberships")
|
|
async def ops_memberships(request: Request, limit: int = 200):
|
|
return list_ops_memberships(request, limit=limit)
|
|
|
|
|
|
@router.get("/api/ops/payments/incidents")
|
|
async def ops_payment_incidents(
|
|
request: Request,
|
|
limit: int = 50,
|
|
reason: str = "",
|
|
include_resolved: bool = False,
|
|
):
|
|
return list_ops_payment_incidents(
|
|
request,
|
|
limit=limit,
|
|
reason=reason,
|
|
include_resolved=include_resolved,
|
|
)
|
|
|
|
|
|
@router.post("/api/ops/payments/incidents/{event_id}/resolve")
|
|
async def ops_resolve_payment_incident(request: Request, event_id: int):
|
|
return resolve_ops_payment_incident(request, event_id)
|
|
|
|
|
|
@router.post("/api/ops/users/grant-points")
|
|
async def ops_grant_points(request: Request, body: GrantPointsRequest):
|
|
return grant_ops_points(request, body)
|
|
|
|
|
|
@router.get("/api/ops/analytics/funnel")
|
|
async def ops_analytics_funnel(request: Request, days: int = 30):
|
|
return get_ops_analytics_funnel(request, days=days)
|
|
|
|
|
|
@router.get("/api/ops/truth-history")
|
|
async def ops_truth_history(
|
|
request: Request,
|
|
city: str = "",
|
|
date_from: str = "",
|
|
date_to: str = "",
|
|
limit: int = 200,
|
|
):
|
|
return get_ops_truth_history(
|
|
request,
|
|
city=city,
|
|
date_from=date_from,
|
|
date_to=date_to,
|
|
limit=limit,
|
|
)
|