Phase 2.3 chat 上下文捕获链路从未真正激活到完整工作: - 14 处 ai-float-button 补 sourcePage,chat.ts 三分支同步设 pageFilters.contextId - 后端 page_context 4 层 BUG 修(列名错位 + RLS site_id 未重设) - xcx_chat filters.pop 破坏 body.page_context 引用 — dict() 浅拷贝隔离 - chat 流式 markdown 实时解析(表格/标题/列表/加粗 + KPI 富卡) - reference_card KPI 富卡接入 SSE 路径,db 真写入 - 维客线索 source 显示规则:AI 来源用机器人 icon 替代长文字 数据库: - public.member_retention_clue 加 emoji + runtime_mode + sandbox_instance_id - biz.ai_run_logs 加 assistant_id + 复合索引 - chk_ai_cache_type CHECK 约束 8 类应用名 - cache_type / app_type 命名统一(app6_note / app7_customer / app8_consolidation) - 历史 emoji 抽取脚本 44/44 成功 后端 silent failure 修: - cleanup_service WHERE app_type → cache_type(90 天清理 + 20K 上限重新生效) - _build_ai_insight 字段错位修复(app4 → app7 + 字段对齐 prompt schema) - task_manager talkingPoints 改 app5_tactics + tactics 字段 - task_manager aiSuggestion 改取 one_line_summary - cache_service.CACHE_EXPIRY_DAYS 加 app2a_finance_area - WS /ws/ai-cache 加 token + JWT + site_id 校验(P0 信息泄露漏洞) - internal_ai token 改 hmac.compare_digest 工具/文档: - main.py 加 RotatingFileHandler logs/backend.log + uvicorn /health 过滤 - 新建 utils/clue_category.py(VI 6 类配色 + emoji fallback + source 显示规则) - 新建 utils/markdown.ts(轻量 md 转 rich-text 解析 + streaming 容错) - audit + 数据库变更说明 + backlog §七 #14 收口 + #15-#38 残余子任务 - backlog 追加 §十一 App1 参数/MCP/沙箱审计 + §十二 百炼/SQL MCP 主任务线 实地 MCP 走查:14 入口数据层 + 5 代表入口 sourcePage 注入 + customer-detail 全模块 + chat md 渲染 + reference_card 富卡 都已验证。9 项预先 BUG/UX 登记 §七 #29-#38 后续修复。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
189 lines
4.4 KiB
Python
189 lines
4.4 KiB
Python
"""
|
||
小程序任务相关 Pydantic 模型。
|
||
|
||
覆盖:任务列表项、任务详情、绩效概览、放弃请求等场景。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pydantic import Field
|
||
|
||
from app.schemas.base import CamelModel
|
||
|
||
|
||
class TaskListItem(CamelModel):
|
||
"""任务列表项(含客户信息 + RS 指数 + 爱心 icon)。"""
|
||
|
||
id: int
|
||
task_type: str
|
||
status: str
|
||
priority_score: float | None
|
||
is_pinned: bool
|
||
expires_at: str | None
|
||
created_at: str
|
||
# 客户信息(FDW 读取)
|
||
member_id: int
|
||
member_name: str | None
|
||
member_phone: str | None
|
||
# RS 指数 + 爱心 icon
|
||
rs_score: float | None
|
||
heart_icon: str # 💖 / 🧡 / 💛 / 💙
|
||
# 放弃原因(仅 abandoned 任务有值)
|
||
abandon_reason: str | None = None
|
||
|
||
|
||
class AbandonRequest(CamelModel):
|
||
"""放弃任务请求(reason 必填)。"""
|
||
|
||
reason: str = Field(..., min_length=1, description="放弃原因(必填)")
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# RNS1.1 扩展模型
|
||
# ---------------------------------------------------------------------------
|
||
|
||
|
||
class PerformanceSummary(CamelModel):
|
||
"""绩效概览(附带在任务列表响应中)。"""
|
||
|
||
total_hours: float
|
||
total_income: float
|
||
total_customers: int
|
||
month_label: str
|
||
tier_nodes: list[float]
|
||
basic_hours: float
|
||
bonus_hours: float
|
||
current_tier: int
|
||
next_tier_hours: float
|
||
tier_completed: bool
|
||
bonus_money: float
|
||
income_trend: str
|
||
income_trend_dir: str # 'up' | 'down'
|
||
prev_month: str
|
||
current_tier_label: str
|
||
|
||
|
||
class TaskItem(CamelModel):
|
||
"""任务列表项(扩展版)。"""
|
||
|
||
id: int
|
||
customer_name: str
|
||
customer_avatar: str
|
||
task_type: str
|
||
task_type_label: str
|
||
deadline: str | None
|
||
heart_score: float
|
||
hobbies: list[str]
|
||
is_pinned: bool
|
||
has_note: bool
|
||
status: str
|
||
last_visit_days: int | None = None
|
||
balance: float | None = None
|
||
ai_suggestion: str | None = None
|
||
expected_days: int | None = None
|
||
ideal_interval_days: int | None = None
|
||
# CHANGE 2026-03-27 | 近60天服务汇总(口径同 task-detail serviceSummary)
|
||
recent60d_hours: float = 0.0
|
||
recent60d_income: float = 0.0
|
||
|
||
|
||
class TaskListResponse(CamelModel):
|
||
"""TASK-1 响应。"""
|
||
|
||
items: list[TaskItem]
|
||
total: int
|
||
page: int
|
||
page_size: int
|
||
performance: PerformanceSummary
|
||
|
||
|
||
class RetentionClue(CamelModel):
|
||
"""维客线索。"""
|
||
|
||
tag: str
|
||
tag_color: str
|
||
emoji: str
|
||
text: str
|
||
source: str # 'manual' | 'ai_consumption' | 'ai_note'
|
||
desc: str | None = None
|
||
|
||
|
||
class ServiceRecord(CamelModel):
|
||
"""服务记录。"""
|
||
|
||
table: str | None = None
|
||
type: str
|
||
type_class: str # 'basic' | 'vip' | 'tip' | 'recharge' | 'incentive'
|
||
record_type: str | None = None # 'course' | 'recharge'
|
||
duration: float
|
||
duration_raw: float | None = None
|
||
income: float
|
||
is_estimate: bool | None = None
|
||
drinks: str | None = None
|
||
date: str
|
||
|
||
|
||
class TacticItem(CamelModel):
|
||
"""App5 话术单条(场景 + 话术)。
|
||
|
||
W1-AI-CLOSURE 组 3 修正:talking_points 从 list[str] 改为 list[TacticItem],
|
||
对齐 App5Result.tactics(prompt schema 权威 — 之前查的 cache_type
|
||
'app5_talking_points' 与字段 'talking_points' 全是不存在的幽灵命名,P0-6)。
|
||
"""
|
||
|
||
scenario: str
|
||
script: str
|
||
|
||
|
||
class AiAnalysis(CamelModel):
|
||
"""AI 分析结果(对齐 App4Result one_line_summary + action_suggestions)。"""
|
||
|
||
summary: str
|
||
suggestions: list[str]
|
||
|
||
|
||
class NoteItem(CamelModel):
|
||
"""备注项。"""
|
||
|
||
id: int
|
||
content: str
|
||
tag_type: str
|
||
tag_label: str
|
||
created_at: str
|
||
score: int | None = None
|
||
|
||
|
||
class ServiceSummary(CamelModel):
|
||
"""服务记录摘要。"""
|
||
|
||
total_hours: float
|
||
total_income: float
|
||
avg_income: float
|
||
|
||
|
||
class TaskDetailResponse(CamelModel):
|
||
"""TASK-2 响应。"""
|
||
|
||
# 基础信息
|
||
id: int
|
||
customer_name: str
|
||
customer_phone: str | None = None
|
||
customer_avatar: str
|
||
task_type: str
|
||
task_type_label: str
|
||
deadline: str | None
|
||
heart_score: float
|
||
hobbies: list[str]
|
||
is_pinned: bool
|
||
has_note: bool
|
||
status: str
|
||
customer_id: int
|
||
balance: float | None = None
|
||
# 扩展模块
|
||
retention_clues: list[RetentionClue]
|
||
talking_points: list[TacticItem]
|
||
service_summary: ServiceSummary
|
||
service_records: list[ServiceRecord]
|
||
ai_analysis: AiAnalysis
|
||
notes: list[NoteItem]
|