Files
Neo-ZQYY/apps/backend/app/routers/xcx_performance.py
Neo 2a7a5d68aa feat: 2026-04-15~04-20 累积变更基线 — 多主线合流
主线 1: rns1-customer-coach-api + 04-miniapp-core-business 后端实施
  - 新增 GET /xcx/coaches/{id}/banner 轻量接口
  - performance/records 加 coach_id 参数 + view_board_coach 权限分流
  - coach/customer/performance/board/task 服务层重构
  - fdw_queries 结算单粒度聚合 + consumption_summary 视图统一
  - task_generator 回访宽限 72h + UPSERT 替代策略 + Step 5 保底清理
  - recall_detector settle_type=3 双重限制 + 门店级 resolved

主线 2: 小程序权限分流 + 新增 coach-service-records 管理者视角业绩明细页
  - perf-progress 共享模块去重 task-list/coach-detail 动画逻辑
  - isScattered 散客标记端到端
  - foodDetail/phoneFull/creator* 字段透传

主线 3: P19 指数回测框架 Phase 1+2
  - 3 个指数表 stat_date 日快照模式
  - 新增 DWS_INDEX_BACKFILL / DWS_TASK_SIMULATION 工具任务
  - task_engine 升级 HTTP 实时 + 推演回测双模式

主线 4: Core 维度层启用
  - 新增 CORE_DIM_SYNC 任务(DWD → core 4 维度表)
  - 修复 app 视图空查询问题

主线 5: member_project_tag 改为 LAST_30_VISITS 消费次数窗口

主线 6: 2 个迁移 SQL 已执行(stat_date + member_project_tag 新窗口)
  - schema 基线与 DDL 快照同步

主线 7: 开发机路径迁移 C:\NeoZQYY → C:\Project\NeoZQYY(约 95% 改动量)

附带: 新建运维脚本(churned_customer_report / simulate_historical_tasks /
      backfill_index_snapshots)+ tools/task-analysis/ 任务分析工具

合计 157 文件。未包含中间产物(tmp/ .playwright-mcp/ inspect-* excel/sheet 分析 txt)。
审计记录见下一个 commit。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 06:32:07 +08:00

76 lines
2.7 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.
# -*- coding: utf-8 -*-
"""
小程序绩效路由 —— 绩效概览、绩效明细。
端点清单:
- GET /api/xcx/performance — 绩效概览PERF-1
- GET /api/xcx/performance/records — 绩效明细PERF-2
所有端点均需 JWTapproved 状态)。
"""
from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, Query
from app.auth.dependencies import CurrentUser
from app.middleware.permission import require_approved, require_permission
from app.schemas.xcx_performance import (
PerformanceOverviewResponse,
PerformanceRecordsResponse,
)
from app.services import performance_service
from app.services.role import get_user_permissions
from app.trace.decorators import trace_service
router = APIRouter(prefix="/api/xcx/performance", tags=["小程序绩效"])
@router.get("", response_model=PerformanceOverviewResponse)
@trace_service("获取绩效概览", "Get performance overview")
async def get_performance_overview(
year: int = Query(...),
month: int = Query(..., ge=1, le=12),
# CHANGE 2026-03-27 | 权限改造 W4绩效跟任务走
user: CurrentUser = Depends(require_permission("view_tasks")),
):
"""绩效概览PERF-1"""
return await performance_service.get_overview(
user.user_id, user.site_id, year, month
)
@router.get("/records", response_model=PerformanceRecordsResponse)
@trace_service("获取绩效明细", "Get performance records")
async def get_performance_records(
year: int = Query(...),
month: int = Query(..., ge=1, le=12),
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=100),
coach_id: int | None = Query(None, description="目标助教 ID仅管理员可用"),
user: CurrentUser = Depends(require_approved()),
):
"""
绩效明细PERF-2
权限分流(请求路径):
- 不带 coach_id查自己要求 view_tasks 权限assistant_id 由 user 绑定决定
- 带 coach_id查他人要求 view_board_coach 权限manager/head_coach/staff
assistant_id 直接用传入值;同 site 由 user.site_id 隐式约束
"""
user_perms = await get_user_permissions(user.user_id, user.site_id)
if coach_id is None:
if "view_tasks" not in user_perms:
raise HTTPException(status_code=403, detail="权限不足")
return await performance_service.get_records(
user.user_id, user.site_id, year, month, page, page_size,
)
if "view_board_coach" not in user_perms:
raise HTTPException(status_code=403, detail="权限不足")
return await performance_service.get_records(
user.user_id, user.site_id, year, month, page, page_size,
assistant_id_override=coach_id,
)