From f92f2d98f313bd2626fdecb3efdfd30d9ed4b558 Mon Sep 17 00:00:00 2001 From: Neo Date: Tue, 5 May 2026 00:30:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(tools):=20=E6=81=A2=E5=A4=8D=20OpenAPI=20?= =?UTF-8?q?=E6=8A=93=E5=8F=96=E8=84=9A=E6=9C=AC=20+=20=E9=87=8D=E6=8A=93?= =?UTF-8?q?=20backend-api.json=20(W1=20/=20F2-1A)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 历史: 2026-04-06 commit 779b2f6 大批量清理时被 Claude Opus 4.6 误归档到 _DEL/_DEL/scripts/ops/_export_openapi.py, 28 天 stale。 恢复: - cp _DEL/_DEL/scripts/ops/_export_openapi.py scripts/ops/ - 跑脚本重抓: 137 -> 167 paths (新增 30) / 194 -> 234 schemas - 0 个 removed (后端无废弃) 新增 30 端点分布: admin-ai 5 + runtime-context 3 + task-engine 7 + triggers 1 + db-health 1 + execution/internal/trigger-jobs 5 + xcx 5 附 F3-2B prompt 文件清单 (本地 8 个 + App1 缺本地副本): docs/_overview/wave1-findings/F3-2-prompt-files-list.md Neo 决策 B 云端权威, 用清单对照云端 prompt 检查/更新本地副本。 详细 diff 见审计: docs/audit/changes/2026-05-04__wave1_f2_1_openapi_script_restored.md --- .../wave1-findings/F3-2-prompt-files-list.md | 79 + ...-04__wave1_f2_1_openapi_script_restored.md | 131 + docs/contracts/openapi/backend-api.json | 4283 ++++++++++++++++- scripts/ops/_export_openapi.py | 12 + 4 files changed, 4334 insertions(+), 171 deletions(-) create mode 100644 docs/_overview/wave1-findings/F3-2-prompt-files-list.md create mode 100644 docs/audit/changes/2026-05-04__wave1_f2_1_openapi_script_restored.md create mode 100644 scripts/ops/_export_openapi.py diff --git a/docs/_overview/wave1-findings/F3-2-prompt-files-list.md b/docs/_overview/wave1-findings/F3-2-prompt-files-list.md new file mode 100644 index 0000000..58ecbc6 --- /dev/null +++ b/docs/_overview/wave1-findings/F3-2-prompt-files-list.md @@ -0,0 +1,79 @@ +# F3-2B 本地 Prompt 文件清单 — 待 Neo 核对更新 + +> 日期:2026-05-04 / 触发:Neo F3-2B 反馈"给我本地的 Prompt 保存地址,我去检查并更新" +> 决策:**B 云端权威 + git 备份**,SDK 调用方式不改(继续用百炼 APP 调用) +> 用法:Neo 用本清单逐个对照百炼控制台 prompt,本地过期则更新 + +## 一、本地 prompt 文件清单(8 个) + +目录:`apps/backend/app/ai/prompts/` + +| # | APP | 文件 | 用途 | +|---|---|---|---| +| 1 | App2 | [`app2_finance_prompt.py`](../../../apps/backend/app/ai/prompts/app2_finance_prompt.py) | 财务洞察(总览,area=all)| +| 2 | App2a | [`app2a_finance_area_prompt.py`](../../../apps/backend/app/ai/prompts/app2a_finance_area_prompt.py) | 财务洞察(区域,area≠all)| +| 3 | App3 | [`app3_clue_prompt.py`](../../../apps/backend/app/ai/prompts/app3_clue_prompt.py) | 维客线索分析 | +| 4 | App4 | [`app4_analysis_prompt.py`](../../../apps/backend/app/ai/prompts/app4_analysis_prompt.py) | 关系分析 / 任务建议 | +| 5 | App5 | [`app5_tactics_prompt.py`](../../../apps/backend/app/ai/prompts/app5_tactics_prompt.py) | 话术建议 | +| 6 | App6 | [`app6_note_prompt.py`](../../../apps/backend/app/ai/prompts/app6_note_prompt.py) | 备注分析 | +| 7 | App7 | [`app7_customer_prompt.py`](../../../apps/backend/app/ai/prompts/app7_customer_prompt.py) | 客户洞察 | +| 8 | App8 | [`app8_consolidation_prompt.py`](../../../apps/backend/app/ai/prompts/app8_consolidation_prompt.py) | 整合去重落库 | + +## 二、关键缺失:App1 + +**`app1_chat_prompt.py` 不存在**。 + +App1(通用对话/SSE 流式)的 prompt **没有本地副本**,完全在百炼控制台。原因可能是: +- App1 是 SSE 流式,prompt 改动频率高,主要在百炼调试 +- 历史上没有"本地存 prompt"的设计 + +**建议**: +- Neo 从百炼控制台导出 App1 prompt → 创建 `app1_chat_prompt.py` 入仓作为备份 +- 或者:接受 App1 prompt 仅在云端(SSE 场景特殊) + +## 三、对照核查方法(给 Neo) + +对每个 APP: + +1. 打开百炼控制台 → 进入对应 APP 设置 → 找到 system prompt +2. 打开本仓库对应文件(上面表格链接) +3. **diff** 两边内容 +4. **如果云端 = git** → 一致,无需更新 +5. **如果云端 ≠ git** → 云端为权威,**用云端版本覆盖 git 文件**(对齐 Neo 决策"云端权威") +6. 在本文件末尾标"已对照 / 已更新 / 一致" + 日期 + +## 四、对照状态记录(Neo 自填) + +| APP | 对照日期 | 状态 | 备注 | +|---|---|---|---| +| App1 | — | **缺本地副本,需从云端导出** | — | +| App2 | — | 待对照 | — | +| App2a | — | 待对照 | — | +| App3 | — | 待对照 | — | +| App4 | — | 待对照 | — | +| App5 | — | 待对照 | — | +| App6 | — | 待对照 | — | +| App7 | — | 待对照 | — | +| App8 | — | 待对照 | — | + +## 五、SDK 调用方式(已确认不改) + +Neo 反馈:**"SDK 调用不要改,我坚持使用 APP 调用的方式"**。 + +后端继续走百炼 APP 调用(SDK 携带 app_id,云端 prompt 生效),git 文件**仅作备份用**,不通过 SDK 传 prompt_template。 + +## 六、风险提示 + +云端权威方案的已知风险(P2-6 / F3-2B 已讨论): +- 不可 git diff / blame +- 多 AI 调优时云端可能漂移,git 可能滞后(本对照机制是唯一的同步触发) + +**缓解**: +- 每月定期对照(本文件 § 四 记录) +- 重大 prompt 调整后立即同步 git + +## 七、关联 + +- 决策来源:[`01-W1-findings-response.md`](01-W1-findings-response.md) §10.4 +- P2-6 原讨论:[`docs/_overview/04c-feedback/P2-6-and-P2-9-design.md`](../04c-feedback/P2-6-and-P2-9-design.md) +- F3-2A SCD2 配置表:Wave 2 实施(`biz.cfg_ai_token_price`) diff --git a/docs/audit/changes/2026-05-04__wave1_f2_1_openapi_script_restored.md b/docs/audit/changes/2026-05-04__wave1_f2_1_openapi_script_restored.md new file mode 100644 index 0000000..50209dc --- /dev/null +++ b/docs/audit/changes/2026-05-04__wave1_f2_1_openapi_script_restored.md @@ -0,0 +1,131 @@ +# Wave 1 F2-1 — 恢复 OpenAPI 抓取脚本 + 重抓 backend-api.json + +| 字段 | 值 | +|---|---| +| 日期 | 2026-05-04 | +| Wave | 1 / Wave 2 前(立即处理) | +| 范围 | F2-1A 恢复 `_export_openapi.py` + 重抓 backend-api.json + diff 核对 | +| 文件改动 | 2 文件(脚本恢复 + JSON 重抓)| + +## 一、恢复操作 + +### 1.1 从 _DEL/ 恢复脚本 + +```bash +cp _DEL/_DEL/scripts/ops/_export_openapi.py scripts/ops/_export_openapi.py +``` + +文件内容(13 行): +```python +"""从运行中的 FastAPI app 导出 OpenAPI spec 到 docs/contracts/openapi/backend-api.json""" +import json +import pathlib +import sys + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "apps" / "backend")) +from app.main import app + +spec = app.openapi() +out = pathlib.Path(r"C:\Project\NeoZQYY\docs\contracts\openapi\backend-api.json") +out.write_text(json.dumps(spec, ensure_ascii=False, indent=2), encoding="utf-8") +print(f"Done: {len(spec['paths'])} paths, {len(spec['components']['schemas'])} schemas") +``` + +**未做改动**(脚本本身无 bug,仅是被误归档)。 + +### 1.2 立即重抓 + +```bash +.venv/Scripts/python.exe scripts/ops/_export_openapi.py +# Done: 167 paths, 234 schemas +``` + +## 二、Diff 核对(Neo 反馈"看下 json 内容是否和当前情况相一致") + +| 维度 | git HEAD(2026-04-06)| 重抓(2026-05-04)| 差异 | +|---|---|---|---| +| paths | 137 | **167** | **+30** | +| schemas | 194 | **234** | +40 | +| removed | 0 | 0 | 后端无废弃 | + +### 30 个新增端点(28 天积累) + +按业务模块分组: + +**admin-ai 系列**(5): +- `/api/admin/ai/prewarm/progress` +- `/api/admin/ai/run/{app_type}` +- `/api/admin/ai/trigger-event` +- `/api/admin/ai/triggers`(GET&PATCH) +- `/api/admin/ai/triggers/{trigger_id}` + +**admin-runtime-context 系列**(3): +- `/api/admin/runtime-context` +- `/api/admin/runtime-context/sites` +- `/api/config/runtime-context` + +**admin-task-engine 系列**(7): +- `/api/admin/task-engine/clear-all-tasks`(P0-6 高危) +- `/api/admin/task-engine/config`、`/config/{param_id}` +- `/api/admin/task-engine/pending-review`、`/pending-review/{task_id}/close`、`/reassign` +- `/api/admin/task-engine/transfer-log`、`/transfer-log/{member_id}/history` + +**admin-triggers**(1): +- `/api/admin/triggers/unified`(P1-6 三 API 之一) + +**admin-db-health**(1): +- `/api/admin/db-health` + +**execution / internal / trigger-jobs**(5): +- `/api/execution/cleanup-output` +- `/api/internal/etl-completed` +- `/api/internal/run-job` +- `/api/trigger-jobs`、`/trigger-jobs/{job_id}/config`、`/{job_id}/run` + +**xcx 系列**(5): +- `/api/xcx/avatar/upload`、`/avatar/{user_id}` +- `/api/xcx/coaches/{coach_id}/banner` +- `/api/xcx/customers/{customer_id}/consumption-records` +- `/api/xcx/runtime/clock` +- `/api/xcx/tasks/by-member/{member_id}` + +**结论**:30 个新增端点全部为 28 天内合理迭代,**0 个 removed**(无废弃),与代码完全一致。 + +## 三、修正 W1-T7 批 1 PRD 总览的端点数 + +之前 `docs/_overview/admin-api-prd/00-overview.md` 写"151 端点 / 34 标签",来源是旧 backend-api.json。**正确数字应为 167 端点**。 + +W1-T7 批 1 内的 23 端点中,Wave 0 标记"OpenAPI 缺 10 个" — 现已全部出现在新 spec 中(本次重抓覆盖到了)。 + +## 四、风险与回滚 + +| 项 | 风险 | 回滚 | +|---|---|---| +| 脚本恢复 | 低 — 13 行简单逻辑 | `git rm scripts/ops/_export_openapi.py` | +| backend-api.json 重抓 | 低 — 内容反映真实 router | `git checkout HEAD -- docs/contracts/openapi/backend-api.json` | + +## 五、F2-1B(后续):防御机制 + +**留 Wave 2-3 实施**: +1. 加 PostToolUse hook 匹配 `apps/backend/app/routers/*.py`,提醒"router 已改,记得跑 `python scripts/ops/_export_openapi.py`" +2. 在 `.claude/commands/spec-close.md` L45 补脚本调用命令(从"手工同步"升级为"具体命令") +3. (可选)CI 加一步:对比 `/openapi.json` vs `backend-api.json`,不一致则失败 + +## 六、commit 建议 + +``` +fix(tools): 恢复 OpenAPI 抓取脚本 + 重抓 backend-api.json (W1 / F2-1A) + +历史: 2026-04-06 commit 779b2f6 大批量清理时被 Claude Opus 4.6 误归档 + 到 _DEL/_DEL/scripts/ops/_export_openapi.py, 28 天 stale。 + +恢复: +- cp _DEL/_DEL/scripts/ops/_export_openapi.py scripts/ops/ +- 跑脚本重抓: 137 -> 167 paths (新增 30) / 194 -> 234 schemas +- 0 个 removed (后端无废弃) + +新增 30 端点分布: admin-ai 5 + runtime-context 3 + task-engine 7 + +triggers 1 + db-health 1 + execution/internal/trigger-jobs 5 + xcx 5 + +详细 diff 见审计文档。 +``` diff --git a/docs/contracts/openapi/backend-api.json b/docs/contracts/openapi/backend-api.json index 68d1050..c402a66 100644 --- a/docs/contracts/openapi/backend-api.json +++ b/docs/contracts/openapi/backend-api.json @@ -668,6 +668,35 @@ } } }, + "/api/execution/cleanup-output": { + "post": { + "tags": [ + "任务执行" + ], + "summary": "Cleanup Output", + "description": "清理 EXPORT_ROOT 下每个任务文件夹的旧运行记录,只保留最近 10 个。", + "operationId": "cleanup_output_api_execution_cleanup_output_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "additionalProperties": true, + "type": "object", + "title": "Response Cleanup Output Api Execution Cleanup Output Post" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, "/api/schedules": { "get": { "tags": [ @@ -1280,7 +1309,7 @@ "数据库查看器" ], "summary": "Execute Query", - "description": "只读 SQL 执行。\n\n安全措施:\n1. 拦截写操作关键词(INSERT / UPDATE / DELETE / DROP / TRUNCATE)\n2. 限制返回行数上限 1000 行\n3. 设置查询超时 30 秒", + "description": "只读 SQL 执行。\n\n安全措施(P0-8 修复 2026-05-04):\n1. 白名单:SQL 必须以 SELECT / WITH / EXPLAIN / SHOW 开头(去注释/空白后)\n2. 黑名单:深度防御,语句含 DML/DDL/DCL 关键词一律拒绝(覆盖 INSERT/UPDATE/DELETE/DROP/\n TRUNCATE/ALTER/CREATE/GRANT/REVOKE/COPY/CALL/COMMENT/VACUUM/REINDEX/CLUSTER/REFRESH/LOCK)\n3. 限制返回行数上限 1000 行\n4. 设置查询超时 30 秒\n5. 数据库连接为只读账号(get_etl_readonly_connection,默认 read-only 事务)", "operationId": "execute_query_api_db_query_post", "requestBody": { "content": { @@ -2225,7 +2254,7 @@ "小程序认证" ], "summary": "Refresh Token", - "description": "刷新令牌。\n\n解码 refresh_token → 根据用户当前状态签发新的令牌对。\n- 受限 refresh_token(limited=True)→ 签发新的受限令牌对\n- 完整 refresh_token → 签发新的完整令牌对(保持原 site_id)", + "description": "刷新令牌。\n\n解码 refresh_token → 根据用户当前数据库状态签发新的令牌对。\n- approved 用户 → 签发完整令牌(即使旧 token 是受限的,也自动升级)\n- 其他状态 → 签发受限令牌", "operationId": "refresh_token_api_xcx_refresh_post", "requestBody": { "content": { @@ -2469,6 +2498,94 @@ ] } }, + "/api/xcx/avatar/upload": { + "post": { + "tags": [ + "小程序头像" + ], + "summary": "Upload Avatar", + "description": "接收小程序 chooseAvatar 上传的头像文件。\n\n流程:\n1. 读取上传文件内容\n2. 保存到 AVATAR_EXPORT_PATH/{user_id}.jpg(覆盖式,幂等)\n3. 更新 auth.users.avatar_url\n4. 返回相对路径", + "operationId": "upload_avatar_api_xcx_avatar_upload_post", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_upload_avatar_api_xcx_avatar_upload_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AvatarUploadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/xcx/avatar/{user_id}": { + "get": { + "tags": [ + "小程序头像" + ], + "summary": "Get Avatar", + "description": "获取用户头像文件。\n\n无需鉴权(头像为公开资源,通过 user_id 访问)。\n文件不存在时返回 404。", + "operationId": "get_avatar_api_xcx_avatar__user_id__get", + "parameters": [ + { + "name": "user_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "User Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, "/api/admin/applications": { "get": { "tags": [ @@ -2754,7 +2871,7 @@ "required": false, "schema": { "type": "integer", - "maximum": 100, + "maximum": 200, "minimum": 1, "default": 20, "title": "Page Size" @@ -2785,6 +2902,54 @@ } } }, + "/api/xcx/tasks/by-member/{member_id}": { + "get": { + "tags": [ + "小程序任务" + ], + "summary": "Get Task By Member", + "description": "按 member_id 查询当前助教的最高优先级 active 任务详情。", + "operationId": "get_task_by_member_api_xcx_tasks_by_member__member_id__get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "member_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Member Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskDetailResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, "/api/xcx/tasks/{task_id}": { "get": { "tags": [ @@ -3614,7 +3779,7 @@ "小程序绩效" ], "summary": "Get Performance Records", - "description": "绩效明细(PERF-2)。", + "description": "绩效明细(PERF-2)。\n\n权限分流(请求路径):\n- 不带 coach_id(查自己):要求 view_tasks 权限,assistant_id 由 user 绑定决定\n- 带 coach_id(查他人):要求 view_board_coach 权限(manager/head_coach/staff),\n assistant_id 直接用传入值;同 site 由 user.site_id 隐式约束", "operationId": "get_performance_records_api_xcx_performance_records_get", "security": [ { @@ -3664,6 +3829,24 @@ "default": 20, "title": "Page Size" } + }, + { + "name": "coach_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "目标助教 ID(仅管理员可用)", + "title": "Coach Id" + }, + "description": "目标助教 ID(仅管理员可用)" } ], "responses": { @@ -3845,6 +4028,122 @@ } } }, + "/api/xcx/customers/{customer_id}/consumption-records": { + "get": { + "tags": [ + "小程序客户" + ], + "summary": "Get Customer Consumption Records", + "description": "客户消费记录(CUST-3)。", + "operationId": "get_customer_consumption_records_api_xcx_customers__customer_id__consumption_records_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "customer_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Customer Id" + } + }, + { + "name": "year", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "title": "Year" + } + }, + { + "name": "month", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "maximum": 12, + "minimum": 1, + "title": "Month" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomerConsumptionRecordsResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/xcx/coaches/{coach_id}/banner": { + "get": { + "tags": [ + "小程序助教" + ], + "summary": "Get Coach Banner", + "description": "助教 banner 轻量信息(仅 name / level / store_name)。\n\n比 /{coach_id} 快一个数量级,供 PERF-2 等只需 banner 的页面调用。", + "operationId": "get_coach_banner_api_xcx_coaches__coach_id__banner_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "coach_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Coach Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CoachBannerResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, "/api/xcx/coaches/{coach_id}": { "get": { "tags": [ @@ -3933,6 +4232,29 @@ "$ref": "#/components/schemas/BoardTimeEnum", "default": "month" } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "default": 1, + "title": "Page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 20, + "title": "Page Size" + } } ], "responses": { @@ -4139,6 +4461,26 @@ ] } }, + "/api/xcx/runtime/clock": { + "get": { + "tags": [ + "小程序业务时钟" + ], + "summary": "Get Business Clock", + "description": "返回当前门店的业务时钟。\n\n返回示例(live)::\n\n {\n \"mode\": \"live\",\n \"business_date\": \"2026-05-02\",\n \"business_year\": 2026,\n \"business_month\": 5,\n \"business_year_month\": \"2026-05\",\n \"is_sandbox\": false,\n \"sandbox_date\": null\n }\n\nsandbox 模式下 ``business_date`` 等于配置的 ``sandbox_date``。\n小程序页面应使用本接口结果替代 ``new Date()``,以确保 sandbox 模式下\n展示和请求都对齐到 sandbox_date。", + "operationId": "get_business_clock_api_xcx_runtime_clock_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, "/api/tenant/auth/login": { "post": { "tags": [ @@ -4721,7 +5063,7 @@ "租户用户管理" ], "summary": "Edit User", - "description": "编辑用户角色/门店/状态。site_id 超出管辖范围返回 403。", + "description": "编辑用户角色/门店 + 绑定(合并接口)。\n\n- 角色与绑定互斥:coach 只能绑 assistant_id,其他角色只能绑 staff_id\n- 换角色时自动清除旧绑定\n- site_id 超出管辖范围返回 403", "operationId": "edit_user_api_tenant_users__user_id__patch", "security": [ { @@ -4775,7 +5117,7 @@ "租户用户管理" ], "summary": "Remove User", - "description": "从当前租户管辖的店铺中移除用户。\n\nCHANGE 2026-03-23 | 租户\"移除\"替代\"禁用\"\n- 删除 auth.user_site_roles 中该用户在管辖 site 下的记录\n- 若用户不再绑定任何 site,将 auth.users.status 改为 'new'(可重新申请)\n- 不影响用户的微信身份(第一层),只解除店铺关系(第二层)", + "description": "从当前租户管辖的店铺中移除用户(软删除)。\n\nCHANGE 2026-03-23 | 租户\"移除\"替代\"禁用\"\nCHANGE 2026-03-24 | 物理删除改软删除:标记 is_removed + removed_at,同步标记 user_assistant_binding\n- 标记 auth.user_site_roles 中该用户在管辖 site 下的记录为已移除\n- 标记 auth.user_assistant_binding 中对应记录为已移除\n- 若用户不再有任何活跃 site 绑定,将 auth.users.status 改为 'new'(可重新申请)\n- 不影响用户的微信身份(第一层),只解除店铺关系(第二层)", "operationId": "remove_user_api_tenant_users__user_id__delete", "security": [ { @@ -6305,13 +6647,119 @@ } } }, + "/api/internal/etl-completed": { + "post": { + "tags": [ + "internal-events" + ], + "summary": "Etl Completed Endpoint", + "description": "ETL pipeline 完成后的统一编排入口。\n\nCHANGE 2026-04-07 | Fix-12:ETL 完成后自动触发。\n编排顺序:recall_detector.run() → task_generator.run()", + "operationId": "etl_completed_endpoint_api_internal_etl_completed_post", + "parameters": [ + { + "name": "authorization", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "Authorization" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EtlCompletedRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EtlCompletedResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/internal/run-job": { + "post": { + "tags": [ + "internal-events" + ], + "summary": "Run Job By Name Endpoint", + "description": "按 job_name 查找并执行 biz.trigger_jobs 中的任务。\n\nETL DWS_TASK_ENGINE 任务通过此端点按顺序执行后端任务引擎的各个步骤。", + "operationId": "run_job_by_name_endpoint_api_internal_run_job_post", + "parameters": [ + { + "name": "authorization", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "Authorization" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunJobByNameRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunJobByNameResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, "/api/admin/ai/dashboard": { "get": { "tags": [ "admin-ai" ], "summary": "Get Dashboard", - "description": "总览统计(支持 site_id 筛选)。", + "description": "总览统计(支持 site_id + 时间范围筛选)。", "operationId": "get_dashboard_api_admin_ai_dashboard_get", "security": [ { @@ -6336,6 +6784,62 @@ "title": "Site Id" }, "description": "门店 ID 筛选" + }, + { + "name": "range_days", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer", + "maximum": 365, + "minimum": 1 + }, + { + "type": "null" + } + ], + "description": "回溯天数:1=今日 / 3 / 7 / 10", + "title": "Range Days" + }, + "description": "回溯天数:1=今日 / 3 / 7 / 10" + }, + { + "name": "date_from", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "起始日期 YYYY-MM-DD(与 date_to 成对使用)", + "title": "Date From" + }, + "description": "起始日期 YYYY-MM-DD(与 date_to 成对使用)" + }, + { + "name": "date_to", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "结束日期 YYYY-MM-DD", + "title": "Date To" + }, + "description": "结束日期 YYYY-MM-DD" } ], "responses": { @@ -7174,6 +7678,250 @@ } } }, + "/api/admin/ai/run/{app_type}": { + "post": { + "tags": [ + "admin-ai" + ], + "summary": "Run Single App", + "description": "按需执行单个 App,跳过链路编排。\n\n使用场景:admin-web 缓存详情页 / 告警页的\"重新生成\"按钮。\n熔断/限流/预算检查由 dispatcher._run_step 自动执行。\n结果写入 ai_cache,失败不抛异常,通过 success=False 返回。", + "operationId": "run_single_app_api_admin_ai_run__app_type__post", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "app_type", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "App Type" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunAppRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunAppResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/ai/triggers": { + "get": { + "tags": [ + "admin-ai" + ], + "summary": "List Triggers", + "description": "列出所有 AI 相关触发器(job_type=ai_* 或 task_generator)。", + "operationId": "list_triggers_api_admin_ai_triggers_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/TriggerItem" + }, + "type": "array", + "title": "Response List Triggers Api Admin Ai Triggers Get" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/admin/ai/triggers/{trigger_id}": { + "patch": { + "tags": [ + "admin-ai" + ], + "summary": "Update Trigger", + "description": "更新触发器:启用/禁用、修改 cron 表达式、修改描述。", + "operationId": "update_trigger_api_admin_ai_triggers__trigger_id__patch", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "trigger_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Trigger Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TriggerUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TriggerItem" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/ai/prewarm/progress": { + "get": { + "tags": [ + "admin-ai" + ], + "summary": "Get Prewarm Progress", + "description": "查询 app2_finance 72 组合预热进度(done / missing)。", + "operationId": "get_prewarm_progress_api_admin_ai_prewarm_progress_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "site_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "description": "门店 ID", + "title": "Site Id" + }, + "description": "门店 ID" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrewarmProgressResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/ai/trigger-event": { + "post": { + "tags": [ + "admin-ai" + ], + "summary": "Manual Trigger Event", + "description": "手动触发 AI 事件链,默认 is_forced=True 跳过去重。\n\n事件类型:consumption / dws_completed / note_created / task_assigned", + "operationId": "manual_trigger_event_api_admin_ai_trigger_event_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ManualTriggerRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ManualTriggerResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, "/api/admin/dev-trace/dates": { "get": { "tags": [ @@ -7682,6 +8430,977 @@ ] } }, + "/api/trigger-jobs": { + "get": { + "tags": [ + "定时任务" + ], + "summary": "Get Trigger Jobs", + "description": "返回所有定时任务列表。", + "operationId": "get_trigger_jobs_api_trigger_jobs_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/app__schemas__trigger_jobs__TriggerJobItem" + }, + "type": "array", + "title": "Response Get Trigger Jobs Api Trigger Jobs Get" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/trigger-jobs/{job_id}/run": { + "post": { + "tags": [ + "定时任务" + ], + "summary": "Run Trigger Job", + "description": "手动执行指定定时任务。", + "operationId": "run_trigger_job_api_trigger_jobs__job_id__run_post", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Job Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunJobResult" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/trigger-jobs/{job_id}/config": { + "patch": { + "tags": [ + "定时任务" + ], + "summary": "Update Trigger Config", + "description": "编辑触发器的 cron_expression 或 interval_seconds。\n\n仅 merge 请求中非 None 的字段到 trigger_config JSONB,\n不覆盖其他已有字段。更新后重新计算 next_run_at。", + "operationId": "update_trigger_config_api_trigger_jobs__job_id__config_patch", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Job Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateTriggerConfigRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/app__schemas__trigger_jobs__TriggerJobItem" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/transfer-log": { + "get": { + "tags": [ + "任务引擎管理" + ], + "summary": "List Transfer Logs", + "description": "转移日志分页列表。", + "operationId": "list_transfer_logs_api_admin_task_engine_transfer_log_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "site_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "门店 ID", + "title": "Site Id" + }, + "description": "门店 ID" + }, + { + "name": "from_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "description": "起始日期", + "title": "From Date" + }, + "description": "起始日期" + }, + { + "name": "to_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "description": "截止日期", + "title": "To Date" + }, + "description": "截止日期" + }, + { + "name": "assistant_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "助教 ID", + "title": "Assistant Id" + }, + "description": "助教 ID" + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "default": 1, + "title": "Page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 20, + "title": "Page Size" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransferLogPage" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/transfer-log/{member_id}/history": { + "get": { + "tags": [ + "任务引擎管理" + ], + "summary": "Get Member Transfer History", + "description": "某客户全部转移历史。", + "operationId": "get_member_transfer_history_api_admin_task_engine_transfer_log__member_id__history_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "member_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Member Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TransferLogItem" + }, + "title": "Response Get Member Transfer History Api Admin Task Engine Transfer Log Member Id History Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/pending-review": { + "get": { + "tags": [ + "任务引擎管理" + ], + "summary": "List Pending Reviews", + "description": "待审核任务列表。", + "operationId": "list_pending_reviews_api_admin_task_engine_pending_review_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "site_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "门店 ID", + "title": "Site Id" + }, + "description": "门店 ID" + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "default": 1, + "title": "Page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 20, + "title": "Page Size" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PendingReviewPage" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/pending-review/{task_id}/reassign": { + "post": { + "tags": [ + "任务引擎管理" + ], + "summary": "Reassign Task", + "description": "重新分配待审核任务(仅超级管理员)。\n\n逻辑:原任务 status → 'transferred',新建 active 任务,写 transfer_log。", + "operationId": "reassign_task_api_admin_task_engine_pending_review__task_id__reassign_post", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Task Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReassignRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReassignResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/pending-review/{task_id}/close": { + "post": { + "tags": [ + "任务引擎管理" + ], + "summary": "Close Task", + "description": "关闭待审核任务(仅超级管理员)。\n\n逻辑:任务 status → 'inactive',记录 abandon_reason。", + "operationId": "close_task_api_admin_task_engine_pending_review__task_id__close_post", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Task Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CloseResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/config": { + "get": { + "tags": [ + "任务引擎管理" + ], + "summary": "List Config Params", + "description": "参数列表。", + "operationId": "list_config_params_api_admin_task_engine_config_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "site_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "门店 ID(不传则返回全部)", + "title": "Site Id" + }, + "description": "门店 ID(不传则返回全部)" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigParamList" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "任务引擎管理" + ], + "summary": "Create Config Param", + "description": "新增门店覆盖参数(仅超级管理员)。", + "operationId": "create_config_param_api_admin_task_engine_config_post", + "security": [ + { + "HTTPBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigParamCreate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigParamResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/config/{param_id}": { + "put": { + "tags": [ + "任务引擎管理" + ], + "summary": "Update Config Param", + "description": "更新参数值(仅超级管理员)。\n\n权重参数(w_rs / w_ms / w_ml)更新后会校验三者之和是否为 1.0。", + "operationId": "update_config_param_api_admin_task_engine_config__param_id__put", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "param_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Param Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigParamUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigParamResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "任务引擎管理" + ], + "summary": "Delete Config Param", + "description": "删除门店覆盖参数(仅超级管理员)。\n\n不允许删除 site_id IS NULL 的全局默认参数。", + "operationId": "delete_config_param_api_admin_task_engine_config__param_id__delete", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "param_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Param Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigParamResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/task-engine/clear-all-tasks": { + "delete": { + "tags": [ + "任务引擎管理" + ], + "summary": "Clear All Tasks", + "description": "【测试用】清空所有 coach_tasks 及关联数据(仅超级管理员)。\n\n用于开发/测试阶段重置任务数据,让 task_generator 重新生成。\n按外键依赖顺序删除:transfer_log → notes → history → tasks。", + "operationId": "clear_all_tasks_api_admin_task_engine_clear_all_tasks_delete", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "additionalProperties": true, + "type": "object", + "title": "Response Clear All Tasks Api Admin Task Engine Clear All Tasks Delete" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/admin/db-health": { + "get": { + "tags": [ + "系统管理" + ], + "summary": "Get Db Health", + "description": "返回 4 个数据库的健康状态。\n\n遍历 DB_CONFIGS 中的 4 个库,逐一执行诊断 SQL。\n连接失败时返回 disconnected 状态,不抛出 HTTP 错误。\n即使所有库都连接失败,仍返回 HTTP 200。", + "operationId": "get_db_health_api_admin_db_health_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DbHealthItem" + }, + "type": "array", + "title": "Response Get Db Health Api Admin Db Health Get" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/admin/triggers/unified": { + "get": { + "tags": [ + "系统管理" + ], + "summary": "Get Unified Triggers", + "description": "聚合三张表的触发器数据。\n\n依次查询 biz.trigger_jobs、biz.ai_trigger_jobs、scheduled_tasks,\n某数据源查询失败时记录日志并跳过,返回其他数据源的数据。", + "operationId": "get_unified_triggers_api_admin_triggers_unified_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/UnifiedTriggerItem" + }, + "type": "array", + "title": "Response Get Unified Triggers Api Admin Triggers Unified Get" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/admin/runtime-context": { + "get": { + "tags": [ + "业务运行上下文" + ], + "summary": "Get Admin Runtime Context", + "description": "系统管理端按门店查看业务运行上下文。", + "operationId": "get_admin_runtime_context_api_admin_runtime_context_get", + "security": [ + { + "HTTPBearer": [] + } + ], + "parameters": [ + { + "name": "site_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "minimum": 1, + "title": "Site Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuntimeContextResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "业务运行上下文" + ], + "summary": "Switch Runtime Context", + "description": "切换门店业务运行上下文。\n\n切换前会终止当前运行中的 ETL、取消未完成 AI 触发记录。\n`biz.trigger_jobs` 是全局调度表(无 site_id 列),不随单门店沙箱切换暂停;\n多门店隔离完全通过 runtime_mode + sandbox_instance_id 实现。", + "operationId": "switch_runtime_context_api_admin_runtime_context_patch", + "security": [ + { + "HTTPBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuntimeSwitchRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuntimeSwitchResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/admin/runtime-context/sites": { + "get": { + "tags": [ + "业务运行上下文" + ], + "summary": "List Runtime Sites", + "description": "列出可配置门店及其当前运行上下文。", + "operationId": "list_runtime_sites_api_admin_runtime_context_sites_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Response List Runtime Sites Api Admin Runtime Context Sites Get" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, + "/api/config/runtime-context": { + "get": { + "tags": [ + "业务配置" + ], + "summary": "Get Current Runtime Context", + "description": "返回当前登录用户门店的业务运行上下文。", + "operationId": "get_current_runtime_context_api_config_runtime_context_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuntimeContextResponse" + } + } + } + } + }, + "security": [ + { + "HTTPBearer": [] + } + ] + } + }, "/health": { "get": { "tags": [ @@ -8105,12 +9824,28 @@ "hallA", "hallB", "hallC", + "vip", + "snooker", "mahjong", - "teamBuilding" + "ktv" ], "title": "AreaFilterEnum", "description": "BOARD-3 区域筛选。" }, + "AvatarUploadResponse": { + "properties": { + "avatarUrl": { + "type": "string", + "title": "Avatarurl" + } + }, + "type": "object", + "required": [ + "avatarUrl" + ], + "title": "AvatarUploadResponse", + "description": "头像上传响应。" + }, "BatchRunConfirm": { "properties": { "batch_id": { @@ -8206,6 +9941,20 @@ "title": "BoardTimeEnum", "description": "BOARD-1 时间范围。" }, + "Body_upload_avatar_api_xcx_avatar_upload_post": { + "properties": { + "file": { + "type": "string", + "format": "binary", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_avatar_api_xcx_avatar_upload_post" + }, "Body_upload_excel_api_tenant_excel_upload_post": { "properties": { "file": { @@ -8414,9 +10163,42 @@ "type": "string", "title": "Label" }, + "desc": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desc" + }, "amount": { "type": "number", "title": "Amount" + }, + "compare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Compare" + }, + "down": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Down" } }, "type": "object", @@ -8445,6 +10227,39 @@ "total": { "type": "number", "title": "Total" + }, + "totalCompare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Totalcompare" + }, + "totalDown": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Totaldown" + }, + "totalFlat": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Totalflat" } }, "type": "object", @@ -8461,9 +10276,31 @@ "type": "string", "title": "Label" }, + "desc": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desc" + }, "amount": { "type": "number", "title": "Amount" + }, + "compare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Compare" } }, "type": "object", @@ -8693,6 +10530,34 @@ "title": "CleanupRequest", "description": "手动清理请求体。" }, + "CloseRequest": { + "properties": { + "reason": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Reason" + } + }, + "type": "object", + "required": [ + "reason" + ], + "title": "CloseRequest" + }, + "CloseResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + } + }, + "type": "object", + "required": [ + "success" + ], + "title": "CloseResponse" + }, "ClueCategory-Output": { "type": "string", "enum": [ @@ -8972,6 +10837,35 @@ ], "title": "CoachAnalysisTable" }, + "CoachBannerResponse": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "level": { + "type": "string", + "title": "Level", + "default": "" + }, + "storeName": { + "type": "string", + "title": "Storename", + "default": "" + } + }, + "type": "object", + "required": [ + "id", + "name" + ], + "title": "CoachBannerResponse", + "description": "助教 banner 轻量响应(仅 name / level / store_name),用于 PERF-2 等只需 banner 的页面。" + }, "CoachBoardItem": { "properties": { "id": { @@ -9109,6 +11003,18 @@ "type": "array", "title": "Items" }, + "total": { + "type": "integer", + "title": "Total" + }, + "page": { + "type": "integer", + "title": "Page" + }, + "pageSize": { + "type": "integer", + "title": "Pagesize" + }, "dimType": { "type": "string", "title": "Dimtype" @@ -9117,6 +11023,9 @@ "type": "object", "required": [ "items", + "total", + "page", + "pageSize", "dimType" ], "title": "CoachBoardResponse" @@ -9139,6 +11048,11 @@ "type": "string", "title": "Level" }, + "storeName": { + "type": "string", + "title": "Storename", + "default": "" + }, "skills": { "items": { "type": "string" @@ -9182,6 +11096,13 @@ "title": "Tiernodes", "default": [] }, + "taskStats": { + "$ref": "#/components/schemas/CoachTaskStats", + "default": { + "callback": 0, + "recall": 0 + } + }, "visibleTasks": { "items": { "$ref": "#/components/schemas/CoachTaskItem" @@ -9319,7 +11240,7 @@ "title": "Coursetype" }, "hours": { - "type": "number", + "type": "string", "title": "Hours" }, "perfHours": { @@ -9398,7 +11319,7 @@ "title": "Duration" }, "income": { - "type": "string", + "type": "number", "title": "Income" }, "date": { @@ -9415,6 +11336,11 @@ } ], "title": "Perfhours" + }, + "isScattered": { + "type": "boolean", + "title": "Isscattered", + "default": false } }, "type": "object", @@ -9475,6 +11401,11 @@ "type": "string", "title": "Levelcolor" }, + "heartScore": { + "type": "number", + "title": "Heartscore", + "default": 0.0 + }, "taskType": { "type": "string", "title": "Tasktype" @@ -9582,6 +11513,23 @@ ], "title": "CoachTaskItem" }, + "CoachTaskStats": { + "properties": { + "callback": { + "type": "integer", + "title": "Callback", + "default": 0 + }, + "recall": { + "type": "integer", + "title": "Recall", + "default": 0 + } + }, + "type": "object", + "title": "CoachTaskStats", + "description": "当月任务完成统计(回访/召回分类)。" + }, "ColumnInfo": { "properties": { "name": { @@ -9617,6 +11565,145 @@ "title": "ColumnInfo", "description": "列定义。" }, + "ConfigParam": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "site_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Site Id" + }, + "site_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Site Name" + }, + "param_key": { + "type": "string", + "title": "Param Key" + }, + "param_value": { + "type": "number", + "title": "Param Value" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "param_key", + "param_value", + "updated_at" + ], + "title": "ConfigParam" + }, + "ConfigParamCreate": { + "properties": { + "site_id": { + "type": "integer", + "title": "Site Id" + }, + "param_key": { + "type": "string", + "maxLength": 64, + "title": "Param Key" + }, + "param_value": { + "type": "number", + "title": "Param Value" + } + }, + "type": "object", + "required": [ + "site_id", + "param_key", + "param_value" + ], + "title": "ConfigParamCreate" + }, + "ConfigParamList": { + "properties": { + "params": { + "items": { + "$ref": "#/components/schemas/ConfigParam" + }, + "type": "array", + "title": "Params" + } + }, + "type": "object", + "required": [ + "params" + ], + "title": "ConfigParamList" + }, + "ConfigParamResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Id" + } + }, + "type": "object", + "required": [ + "success" + ], + "title": "ConfigParamResponse" + }, + "ConfigParamUpdate": { + "properties": { + "param_value": { + "type": "number", + "title": "Param Value" + } + }, + "type": "object", + "required": [ + "param_value" + ], + "title": "ConfigParamUpdate" + }, "ConfirmRequest": { "properties": { "uploadId": { @@ -9690,7 +11777,7 @@ "duration": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" @@ -9750,16 +11837,41 @@ ], "title": "Foodorigprice" }, + "foodDetail": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fooddetail" + }, "totalAmount": { "type": "number", "title": "Totalamount" }, "totalOrigPrice": { - "type": "number", + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], "title": "Totalorigprice" }, "payMethod": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Paymethod" }, "rechargeAmount": { @@ -9779,9 +11891,7 @@ "id", "type", "date", - "totalAmount", - "totalOrigPrice", - "payMethod" + "totalAmount" ], "title": "ConsumptionRecord" }, @@ -9825,6 +11935,14 @@ ], "title": "Min Run Interval Unit", "default": "minutes" + }, + "min_run_intervals": { + "additionalProperties": { + "$ref": "#/components/schemas/MinRunIntervalItem" + }, + "type": "object", + "title": "Min Run Intervals", + "default": {} } }, "type": "object", @@ -9878,7 +11996,7 @@ "type": "string", "title": "Task Code" }, - "last_fetch_time": { + "last_start": { "anyOf": [ { "type": "string" @@ -9887,18 +12005,18 @@ "type": "null" } ], - "title": "Last Fetch Time" + "title": "Last Start" }, - "record_count": { + "last_end": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "title": "Record Count" + "title": "Last End" } }, "type": "object", @@ -9940,6 +12058,102 @@ ], "title": "CustomerBoardResponse" }, + "CustomerConsumptionRecordsResponse": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "phone": { + "type": "string", + "title": "Phone" + }, + "phoneFull": { + "type": "string", + "title": "Phonefull" + }, + "balance": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Balance" + }, + "consumption60D": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Consumption60D" + }, + "idealInterval": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Idealinterval" + }, + "daysSinceVisit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Dayssincevisit" + }, + "visitCount": { + "type": "integer", + "title": "Visitcount", + "default": 0 + }, + "consumeTotal": { + "type": "number", + "title": "Consumetotal", + "default": 0.0 + }, + "rechargeTotal": { + "type": "number", + "title": "Rechargetotal", + "default": 0.0 + }, + "records": { + "items": { + "$ref": "#/components/schemas/ConsumptionRecord" + }, + "type": "array", + "title": "Records", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "name", + "phone", + "phoneFull" + ], + "title": "CustomerConsumptionRecordsResponse", + "description": "CUST-3 响应:客户消费记录(按月)。" + }, "CustomerDetailResponse": { "properties": { "id": { @@ -10108,6 +12322,16 @@ "type": "string", "title": "Taglabel" }, + "creatorName": { + "type": "string", + "title": "Creatorname", + "default": "" + }, + "creatorRole": { + "type": "string", + "title": "Creatorrole", + "default": "" + }, "createdAt": { "type": "string", "title": "Createdat" @@ -10165,6 +12389,11 @@ "type": "number", "title": "Monthhours" }, + "monthIncome": { + "type": "number", + "title": "Monthincome", + "default": 0.0 + }, "records": { "items": { "$ref": "#/components/schemas/ServiceRecordItem" @@ -10319,6 +12548,17 @@ "type": "string", "title": "Customername" }, + "memberId": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Memberid" + }, "avatarChar": { "anyOf": [ { @@ -10330,16 +12570,21 @@ ], "title": "Avatarchar" }, - "avatarColor": { + "heartScore": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "title": "Avatarcolor" + "title": "Heartscore" + }, + "isScattered": { + "type": "boolean", + "title": "Isscattered", + "default": false }, "timeRange": { "type": "string", @@ -10353,10 +12598,6 @@ "type": "string", "title": "Coursetype" }, - "courseTypeClass": { - "type": "string", - "title": "Coursetypeclass" - }, "location": { "type": "string", "title": "Location" @@ -10372,13 +12613,79 @@ "timeRange", "hours", "courseType", - "courseTypeClass", "location", "income" ], "title": "DateGroupRecord", "description": "按日期分组的单条服务记录。" }, + "DbHealthItem": { + "properties": { + "db_name": { + "type": "string", + "title": "Db Name" + }, + "status": { + "type": "string", + "enum": [ + "connected", + "disconnected" + ], + "title": "Status" + }, + "active_connections": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Active Connections" + }, + "idle_connections": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Idle Connections" + }, + "db_size_mb": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Db Size Mb" + }, + "slow_query_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Slow Query Count" + } + }, + "type": "object", + "required": [ + "db_name", + "status" + ], + "title": "DbHealthItem", + "description": "单个数据库健康状态" + }, "DevContextResponse": { "properties": { "userId": { @@ -10682,6 +12989,74 @@ "title": "EnvEntry", "description": "单条环境变量键值对。" }, + "EtlCompletedRequest": { + "properties": { + "pipeline": { + "type": "string", + "title": "Pipeline", + "description": "完成的 pipeline 名称", + "default": "api_full" + }, + "site_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Site Id", + "description": "门店 ID(可选)" + } + }, + "type": "object", + "title": "EtlCompletedRequest", + "description": "ETL 完成通知请求体。" + }, + "EtlCompletedResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "recall_result": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Recall Result" + }, + "task_gen_result": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Task Gen Result" + }, + "message": { + "type": "string", + "title": "Message", + "default": "" + } + }, + "type": "object", + "required": [ + "success" + ], + "title": "EtlCompletedResponse", + "description": "ETL 完成编排结果。" + }, "ExecutionHistoryItem": { "properties": { "id": { @@ -10982,6 +13357,16 @@ "type": "string", "title": "Name" }, + "heartScore": { + "type": "number", + "title": "Heartscore", + "default": 0.0 + }, + "level": { + "type": "string", + "title": "Level", + "default": "" + }, "relationIndex": { "type": "string", "title": "Relationindex" @@ -11032,10 +13417,24 @@ "$ref": "#/components/schemas/RevenuePanel" }, "cashflow": { - "$ref": "#/components/schemas/CashflowPanel" + "anyOf": [ + { + "$ref": "#/components/schemas/CashflowPanel" + }, + { + "type": "null" + } + ] }, "expense": { - "$ref": "#/components/schemas/ExpensePanel" + "anyOf": [ + { + "$ref": "#/components/schemas/ExpensePanel" + }, + { + "type": "null" + } + ] }, "coachAnalysis": { "$ref": "#/components/schemas/CoachAnalysisPanel" @@ -11280,15 +13679,15 @@ "title": "Estimated" }, "customers": { - "type": "string", + "type": "integer", "title": "Customers" }, "hours": { - "type": "string", + "type": "number", "title": "Hours" }, "salary": { - "type": "string", + "type": "number", "title": "Salary" }, "callbackDone": { @@ -11430,6 +13829,83 @@ "title": "LoginRequest", "description": "登录请求。" }, + "ManualTriggerRequest": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "site_id": { + "type": "integer", + "title": "Site Id" + }, + "member_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Member Id" + }, + "assistant_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Assistant Id" + }, + "payload": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Payload" + }, + "is_forced": { + "type": "boolean", + "title": "Is Forced", + "default": true + } + }, + "type": "object", + "required": [ + "event_type", + "site_id" + ], + "title": "ManualTriggerRequest", + "description": "手动触发 AI 事件请求。" + }, + "ManualTriggerResponse": { + "properties": { + "trigger_job_id": { + "type": "integer", + "title": "Trigger Job Id" + }, + "status": { + "type": "string", + "title": "Status", + "default": "pending" + } + }, + "type": "object", + "required": [ + "trigger_job_id" + ], + "title": "ManualTriggerResponse", + "description": "手动事件触发响应。" + }, "MessageBrief": { "properties": { "id": { @@ -11483,19 +13959,59 @@ ], "title": "MetricItem" }, + "MinRunIntervalItem": { + "properties": { + "value": { + "type": "integer", + "title": "Value", + "default": 0 + }, + "unit": { + "type": "string", + "enum": [ + "minutes", + "hours", + "days" + ], + "title": "Unit", + "default": "minutes" + } + }, + "type": "object", + "title": "MinRunIntervalItem", + "description": "单个任务的最小执行间隔" + }, "NewCustomer": { "properties": { "name": { "type": "string", "title": "Name" }, + "memberId": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Memberid" + }, "avatarChar": { "type": "string", "title": "Avatarchar" }, - "avatarColor": { - "type": "string", - "title": "Avatarcolor" + "heartScore": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Heartscore" }, "lastService": { "type": "string", @@ -11510,7 +14026,6 @@ "required": [ "name", "avatarChar", - "avatarColor", "lastService", "count" ], @@ -11765,19 +14280,47 @@ "title": "Confirmedrevenue" }, "cashIn": { - "type": "number", + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], "title": "Cashin" }, "cashOut": { - "type": "number", + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], "title": "Cashout" }, "cashBalance": { - "type": "number", + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], "title": "Cashbalance" }, "balanceRate": { - "type": "number", + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], "title": "Balancerate" }, "occurrenceCompare": { @@ -12050,52 +14593,211 @@ "occurrence", "discount", "discountRate", - "confirmedRevenue", - "cashIn", - "cashOut", - "cashBalance", - "balanceRate" + "confirmedRevenue" ], "title": "OverviewPanel", "description": "经营一览:8 项核心指标 + 各 3 个环比字段(Optional,compare=0 时为 None)。" }, - "PerformanceMetrics": { + "PendingReviewItem": { "properties": { - "monthlyHours": { - "type": "number", - "title": "Monthlyhours" - }, - "monthlySalary": { - "type": "number", - "title": "Monthlysalary" - }, - "customerBalance": { - "type": "number", - "title": "Customerbalance" - }, - "tasksCompleted": { + "id": { "type": "integer", - "title": "Taskscompleted" + "title": "Id" }, - "perfCurrent": { - "type": "number", - "title": "Perfcurrent" + "site_id": { + "type": "integer", + "title": "Site Id" }, - "perfTarget": { - "type": "number", - "title": "Perftarget" + "site_name": { + "type": "string", + "title": "Site Name", + "default": "" + }, + "member_id": { + "type": "integer", + "title": "Member Id" + }, + "member_name": { + "type": "string", + "title": "Member Name", + "default": "" + }, + "assistant_id": { + "type": "integer", + "title": "Assistant Id" + }, + "assistant_name": { + "type": "string", + "title": "Assistant Name", + "default": "" + }, + "task_type": { + "type": "string", + "title": "Task Type" + }, + "task_type_label": { + "type": "string", + "title": "Task Type Label", + "default": "" + }, + "transfer_count": { + "type": "integer", + "title": "Transfer Count", + "default": 0 + }, + "priority_score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Priority Score" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" } }, "type": "object", "required": [ - "monthlyHours", - "monthlySalary", - "customerBalance", - "tasksCompleted", - "perfCurrent", - "perfTarget" + "id", + "site_id", + "member_id", + "assistant_id", + "task_type", + "created_at" ], - "title": "PerformanceMetrics" + "title": "PendingReviewItem" + }, + "PendingReviewPage": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/PendingReviewItem" + }, + "type": "array", + "title": "Items" + }, + "total": { + "type": "integer", + "title": "Total" + } + }, + "type": "object", + "required": [ + "items", + "total" + ], + "title": "PendingReviewPage" + }, + "PerformanceMetrics": { + "properties": { + "totalHours": { + "type": "number", + "title": "Totalhours", + "default": 0 + }, + "totalIncome": { + "type": "number", + "title": "Totalincome", + "default": 0 + }, + "totalCustomers": { + "type": "integer", + "title": "Totalcustomers", + "default": 0 + }, + "monthLabel": { + "type": "string", + "title": "Monthlabel", + "default": "" + }, + "tierNodes": { + "items": { + "type": "number" + }, + "type": "array", + "title": "Tiernodes", + "default": [] + }, + "basicHours": { + "type": "number", + "title": "Basichours", + "default": 0 + }, + "bonusHours": { + "type": "number", + "title": "Bonushours", + "default": 0 + }, + "currentTier": { + "type": "integer", + "title": "Currenttier", + "default": 0 + }, + "nextTierHours": { + "type": "number", + "title": "Nexttierhours", + "default": 0 + }, + "tierCompleted": { + "type": "boolean", + "title": "Tiercompleted", + "default": false + }, + "bonusMoney": { + "type": "number", + "title": "Bonusmoney", + "default": 0 + }, + "incomeTrend": { + "type": "string", + "title": "Incometrend", + "default": "" + }, + "incomeTrendDir": { + "type": "string", + "title": "Incometrenddir", + "default": "up" + }, + "prevMonth": { + "type": "string", + "title": "Prevmonth", + "default": "" + }, + "currentTierLabel": { + "type": "string", + "title": "Currenttierlabel", + "default": "" + }, + "customerBalance": { + "type": "number", + "title": "Customerbalance", + "default": 0 + }, + "tasksCompleted": { + "type": "integer", + "title": "Taskscompleted", + "default": 0 + }, + "monthlyHours": { + "type": "number", + "title": "Monthlyhours", + "default": 0 + }, + "monthlySalary": { + "type": "number", + "title": "Monthlysalary", + "default": 0 + } + }, + "type": "object", + "title": "PerformanceMetrics", + "description": "绩效概览 -- 与任务页 PerformanceSummary 统一数据源(monthly_summary 实时值)。" }, "PerformanceOverviewResponse": { "properties": { @@ -12299,6 +15001,68 @@ "title": "PerformanceSummary", "description": "绩效概览(附带在任务列表响应中)。" }, + "PrewarmMissingItem": { + "properties": { + "target_id": { + "type": "string", + "title": "Target Id" + }, + "time_dimension": { + "type": "string", + "title": "Time Dimension" + }, + "area": { + "type": "string", + "title": "Area" + } + }, + "type": "object", + "required": [ + "target_id", + "time_dimension", + "area" + ], + "title": "PrewarmMissingItem", + "description": "缺失的预热组合项。" + }, + "PrewarmProgressResponse": { + "properties": { + "total": { + "type": "integer", + "title": "Total" + }, + "done": { + "type": "integer", + "title": "Done" + }, + "missing": { + "items": { + "$ref": "#/components/schemas/PrewarmMissingItem" + }, + "type": "array", + "title": "Missing" + }, + "last_updated": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Updated" + } + }, + "type": "object", + "required": [ + "total", + "done", + "missing" + ], + "title": "PrewarmProgressResponse", + "description": "app2_finance 预热进度响应。" + }, "ProcessingModeDefinition": { "properties": { "id": { @@ -12473,6 +15237,43 @@ "title": "QueueTaskResponse", "description": "队列任务响应" }, + "ReassignRequest": { + "properties": { + "to_assistant_id": { + "type": "integer", + "title": "To Assistant Id" + } + }, + "type": "object", + "required": [ + "to_assistant_id" + ], + "title": "ReassignRequest" + }, + "ReassignResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "new_task_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "New Task Id" + } + }, + "type": "object", + "required": [ + "success" + ], + "title": "ReassignResponse" + }, "RecentRun": { "properties": { "id": { @@ -12735,6 +15536,39 @@ } ], "title": "Cardbalanceflat" + }, + "allCardBalanceCompare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Allcardbalancecompare" + }, + "allCardBalanceDown": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Allcardbalancedown" + }, + "allCardBalanceFlat": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Allcardbalanceflat" } }, "type": "object", @@ -12849,13 +15683,31 @@ "type": "string", "title": "Name" }, + "memberId": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Memberid" + }, "avatarChar": { "type": "string", "title": "Avatarchar" }, - "avatarColor": { - "type": "string", - "title": "Avatarcolor" + "heartScore": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Heartscore" }, "hours": { "type": "number", @@ -12874,7 +15726,6 @@ "required": [ "name", "avatarChar", - "avatarColor", "hours", "income", "count" @@ -13115,9 +15966,31 @@ "type": "string", "title": "Label" }, + "desc": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desc" + }, "amount": { "type": "number", "title": "Amount" + }, + "compare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Compare" } }, "type": "object", @@ -13147,6 +16020,39 @@ "type": "number", "title": "Totaloccurrence" }, + "totalOccurrenceCompare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Totaloccurrencecompare" + }, + "totalOccurrenceDown": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Totaloccurrencedown" + }, + "totalOccurrenceFlat": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Totaloccurrenceflat" + }, "discountItems": { "items": { "$ref": "#/components/schemas/RevenueItem" @@ -13154,10 +16060,81 @@ "type": "array", "title": "Discountitems" }, + "discountTotal": { + "type": "number", + "title": "Discounttotal", + "default": 0.0 + }, + "discountTotalCompare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Discounttotalcompare" + }, + "discountTotalDown": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Discounttotaldown" + }, + "discountTotalFlat": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Discounttotalflat" + }, "confirmedTotal": { "type": "number", "title": "Confirmedtotal" }, + "confirmedTotalCompare": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Confirmedtotalcompare" + }, + "confirmedTotalDown": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Confirmedtotaldown" + }, + "confirmedTotalFlat": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Confirmedtotalflat" + }, "channelItems": { "items": { "$ref": "#/components/schemas/ChannelItem" @@ -13237,6 +16214,197 @@ ], "title": "RevenueStructureRow" }, + "RunAppRequest": { + "properties": { + "site_id": { + "type": "integer", + "title": "Site Id" + }, + "member_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Member Id" + }, + "assistant_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Assistant Id" + }, + "time_dimension": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Time Dimension" + }, + "area": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Area" + }, + "note_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Content" + }, + "noted_by_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Noted By Name" + }, + "noted_by_created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Noted By Created At" + } + }, + "type": "object", + "required": [ + "site_id" + ], + "title": "RunAppRequest", + "description": "按需执行单个 App 请求体。\n\ncontext 字段根据 app_type 不同有不同约束:\n- app2_finance: site_id + time_dimension + area(area 默认 all)\n- app3_clue / app7_customer: site_id + member_id\n- app4_analysis / app5_tactics: site_id + member_id + assistant_id\n- app6_note: site_id + member_id + note_content + noted_by_name\n- app8_consolidation: site_id + member_id" + }, + "RunAppResponse": { + "properties": { + "app_type": { + "type": "string", + "title": "App Type" + }, + "success": { + "type": "boolean", + "title": "Success" + }, + "result": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Result" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error" + } + }, + "type": "object", + "required": [ + "app_type", + "success" + ], + "title": "RunAppResponse", + "description": "按需执行单个 App 响应。" + }, + "RunJobByNameRequest": { + "properties": { + "job_name": { + "type": "string", + "title": "Job Name", + "description": "任务名称,如 recall_completion_check" + } + }, + "type": "object", + "required": [ + "job_name" + ], + "title": "RunJobByNameRequest", + "description": "按 job_name 执行任务的请求体。" + }, + "RunJobByNameResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "job_name": { + "type": "string", + "title": "Job Name" + } + }, + "type": "object", + "required": [ + "success", + "message", + "job_name" + ], + "title": "RunJobByNameResponse", + "description": "执行结果。" + }, + "RunJobResult": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "RunJobResult", + "description": "手动执行结果" + }, "RunLogDetailResponse": { "properties": { "id": { @@ -13465,6 +16633,195 @@ "title": "RunLogListResponse", "description": "调用记录分页列表响应。" }, + "RuntimeContextResponse": { + "properties": { + "site_id": { + "type": "integer", + "title": "Site Id" + }, + "mode": { + "type": "string", + "enum": [ + "live", + "sandbox" + ], + "title": "Mode" + }, + "business_day_start_hour": { + "type": "integer", + "title": "Business Day Start Hour" + }, + "business_date": { + "type": "string", + "format": "date", + "title": "Business Date" + }, + "business_now": { + "type": "string", + "format": "date-time", + "title": "Business Now" + }, + "sandbox_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Sandbox Date" + }, + "sandbox_instance_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sandbox Instance Id" + }, + "ai_mode": { + "type": "string", + "const": "live", + "title": "Ai Mode", + "default": "live" + }, + "status": { + "type": "string", + "title": "Status", + "default": "active" + }, + "is_sandbox": { + "type": "boolean", + "title": "Is Sandbox", + "default": false + } + }, + "type": "object", + "required": [ + "site_id", + "mode", + "business_day_start_hour", + "business_date", + "business_now" + ], + "title": "RuntimeContextResponse" + }, + "RuntimeSwitchRequest": { + "properties": { + "site_id": { + "type": "integer", + "minimum": 1.0, + "title": "Site Id" + }, + "mode": { + "type": "string", + "enum": [ + "live", + "sandbox" + ], + "title": "Mode" + }, + "sandbox_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Sandbox Date" + }, + "reset_sandbox": { + "type": "boolean", + "title": "Reset Sandbox", + "default": true + }, + "reason": { + "anyOf": [ + { + "type": "string", + "maxLength": 500 + }, + { + "type": "null" + } + ], + "title": "Reason" + } + }, + "type": "object", + "required": [ + "site_id", + "mode" + ], + "title": "RuntimeSwitchRequest" + }, + "RuntimeSwitchResponse": { + "properties": { + "context": { + "$ref": "#/components/schemas/RuntimeContextResponse" + }, + "steps": { + "items": { + "$ref": "#/components/schemas/RuntimeTransitionStep" + }, + "type": "array", + "title": "Steps" + } + }, + "type": "object", + "required": [ + "context", + "steps" + ], + "title": "RuntimeSwitchResponse" + }, + "RuntimeTransitionStep": { + "properties": { + "key": { + "type": "string", + "title": "Key" + }, + "title": { + "type": "string", + "title": "Title" + }, + "status": { + "type": "string", + "enum": [ + "success", + "skipped", + "warning", + "failed" + ], + "title": "Status" + }, + "detail": { + "type": "string", + "title": "Detail", + "default": "" + }, + "count": { + "type": "integer", + "title": "Count", + "default": 0 + } + }, + "type": "object", + "required": [ + "key", + "title", + "status" + ], + "title": "RuntimeTransitionStep" + }, "ScheduleConfigSchema": { "properties": { "schedule_type": { @@ -13649,6 +17006,12 @@ ], "title": "Last Success At" }, + "min_run_intervals": { + "additionalProperties": true, + "type": "object", + "title": "Min Run Intervals", + "default": {} + }, "created_at": { "type": "string", "format": "date-time", @@ -14735,6 +18098,17 @@ "type": "string", "title": "Customername" }, + "customerPhone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Customerphone" + }, "customerAvatar": { "type": "string", "title": "Customeravatar" @@ -14785,6 +18159,17 @@ "type": "integer", "title": "Customerid" }, + "balance": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Balance" + }, "retentionClues": { "items": { "$ref": "#/components/schemas/app__schemas__xcx_tasks__RetentionClue" @@ -15196,12 +18581,17 @@ "title": "Servicecount" }, "balance": { - "type": "string", + "type": "number", "title": "Balance" }, "consume": { - "type": "string", + "type": "number", "title": "Consume" + }, + "isScattered": { + "type": "boolean", + "title": "Isscattered", + "default": false } }, "type": "object", @@ -15219,6 +18609,204 @@ ], "title": "TopCustomer" }, + "TransferLogItem": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "site_id": { + "type": "integer", + "title": "Site Id" + }, + "site_name": { + "type": "string", + "title": "Site Name", + "default": "" + }, + "member_id": { + "type": "integer", + "title": "Member Id" + }, + "member_name": { + "type": "string", + "title": "Member Name", + "default": "" + }, + "from_assistant_id": { + "type": "integer", + "title": "From Assistant Id" + }, + "from_assistant_name": { + "type": "string", + "title": "From Assistant Name", + "default": "" + }, + "to_assistant_id": { + "type": "integer", + "title": "To Assistant Id" + }, + "to_assistant_name": { + "type": "string", + "title": "To Assistant Name", + "default": "" + }, + "transfer_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transfer Reason" + }, + "transfer_score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Transfer Score" + }, + "guard_checks": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Guard Checks" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "site_id", + "member_id", + "from_assistant_id", + "to_assistant_id", + "created_at" + ], + "title": "TransferLogItem" + }, + "TransferLogPage": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/TransferLogItem" + }, + "type": "array", + "title": "Items" + }, + "total": { + "type": "integer", + "title": "Total" + } + }, + "type": "object", + "required": [ + "items", + "total" + ], + "title": "TransferLogPage" + }, + "TriggerItem": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "job_name": { + "type": "string", + "title": "Job Name" + }, + "job_type": { + "type": "string", + "title": "Job Type" + }, + "trigger_condition": { + "type": "string", + "title": "Trigger Condition" + }, + "trigger_config": { + "additionalProperties": true, + "type": "object", + "title": "Trigger Config" + }, + "status": { + "type": "string", + "title": "Status" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "last_run_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Run At" + }, + "next_run_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Run At" + }, + "last_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error" + } + }, + "type": "object", + "required": [ + "id", + "job_name", + "job_type", + "trigger_condition", + "trigger_config", + "status" + ], + "title": "TriggerItem", + "description": "触发器单条记录。" + }, "TriggerJobDetailResponse": { "properties": { "id": { @@ -15336,98 +18924,11 @@ "title": "TriggerJobDetailResponse", "description": "调度任务详情响应(含 payload、error_message)。" }, - "TriggerJobItem": { - "properties": { - "id": { - "type": "integer", - "title": "Id" - }, - "event_type": { - "type": "string", - "title": "Event Type" - }, - "member_id": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Member Id" - }, - "status": { - "type": "string", - "title": "Status" - }, - "app_chain": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "App Chain" - }, - "is_forced": { - "type": "boolean", - "title": "Is Forced" - }, - "site_id": { - "type": "integer", - "title": "Site Id" - }, - "started_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Started At" - }, - "finished_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Finished At" - }, - "created_at": { - "type": "string", - "title": "Created At" - } - }, - "type": "object", - "required": [ - "id", - "event_type", - "member_id", - "status", - "app_chain", - "is_forced", - "site_id", - "started_at", - "finished_at", - "created_at" - ], - "title": "TriggerJobItem", - "description": "调度任务列表项。" - }, "TriggerJobListResponse": { "properties": { "items": { "items": { - "$ref": "#/components/schemas/TriggerJobItem" + "$ref": "#/components/schemas/app__schemas__admin_ai__TriggerJobItem" }, "type": "array", "title": "Items" @@ -15537,6 +19038,118 @@ "title": "TriggerResponse", "description": "触发响应。" }, + "TriggerUpdateRequest": { + "properties": { + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "cron_expression": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Cron Expression" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + } + }, + "type": "object", + "title": "TriggerUpdateRequest", + "description": "触发器更新请求(3 个字段至少填一个)。" + }, + "UnifiedTriggerItem": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source": { + "type": "string", + "enum": [ + "biz", + "ai", + "etl" + ], + "title": "Source" + }, + "trigger_condition": { + "type": "string", + "title": "Trigger Condition" + }, + "status": { + "type": "string", + "title": "Status" + }, + "last_run_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Run At" + }, + "next_run_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Run At" + }, + "last_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source", + "trigger_condition", + "status" + ], + "title": "UnifiedTriggerItem", + "description": "统一触发器视图项" + }, "UpdateScheduleRequest": { "properties": { "name": { @@ -15612,6 +19225,20 @@ } ], "title": "Min Run Interval Unit" + }, + "min_run_intervals": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/MinRunIntervalItem" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Min Run Intervals" } }, "type": "object", @@ -15632,6 +19259,35 @@ "title": "UpdateSiteCodeRequest", "description": "设置/修改店铺简写ID 请求。" }, + "UpdateTriggerConfigRequest": { + "properties": { + "cron_expression": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Cron Expression" + }, + "interval_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Interval Seconds" + } + }, + "type": "object", + "title": "UpdateTriggerConfigRequest", + "description": "触发器配置编辑请求(部分更新)" + }, "UserBindingRequest": { "properties": { "assistantId": { @@ -15675,7 +19331,7 @@ } ], "title": "Role", - "description": "新角色" + "description": "新角色 code(coach/staff/head_coach/manager)" }, "siteId": { "anyOf": [ @@ -15688,11 +19344,35 @@ ], "title": "Siteid", "description": "新门店 ID" + }, + "assistantId": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Assistantid", + "description": "关联助教 ID(仅 coach 角色)" + }, + "staffId": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Staffid", + "description": "关联员工 ID(仅非 coach 角色)" } }, "type": "object", "title": "UserEditRequest", - "description": "用户编辑请求。" + "description": "用户编辑请求(合并角色+绑定)。\n\n角色与绑定互斥:coach 只能绑 assistant_id,其他角色只能绑 staff_id。\n换角色时后端自动清除旧绑定。staffBinding=\"none\" 表示解绑。" }, "UserStatusResponse": { "properties": { @@ -15715,6 +19395,17 @@ ], "title": "Nickname" }, + "avatarUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Avatarurl" + }, "role": { "anyOf": [ { @@ -15726,6 +19417,36 @@ ], "title": "Role" }, + "permissions": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Permissions", + "default": [] + }, + "storeName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Storename" + }, + "coachLevel": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Coachlevel" + }, "applications": { "items": { "$ref": "#/components/schemas/ApplicationResponse" @@ -15960,6 +19681,93 @@ ], "title": "TaskItem" }, + "app__schemas__admin_ai__TriggerJobItem": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "member_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Member Id" + }, + "status": { + "type": "string", + "title": "Status" + }, + "app_chain": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "App Chain" + }, + "is_forced": { + "type": "boolean", + "title": "Is Forced" + }, + "site_id": { + "type": "integer", + "title": "Site Id" + }, + "started_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "member_id", + "status", + "app_chain", + "is_forced", + "site_id", + "started_at", + "finished_at", + "created_at" + ], + "title": "TriggerJobItem", + "description": "调度任务列表项。" + }, "app__schemas__member_retention_clue__ClueCategory": { "type": "string", "enum": [ @@ -16042,6 +19850,107 @@ "title": "RejectRequest", "description": "审核拒绝请求。" }, + "app__schemas__trigger_jobs__TriggerJobItem": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "job_type": { + "type": "string", + "title": "Job Type" + }, + "job_name": { + "type": "string", + "title": "Job Name" + }, + "trigger_condition": { + "type": "string", + "title": "Trigger Condition" + }, + "trigger_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Trigger Config" + }, + "last_run_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Run At" + }, + "next_run_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Next Run At" + }, + "status": { + "type": "string", + "title": "Status" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "last_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "job_type", + "job_name", + "trigger_condition", + "status" + ], + "title": "TriggerJobItem", + "description": "单个定时任务信息" + }, "app__schemas__xcx_auth__ApproveRequest": { "properties": { "roleId": { @@ -16298,6 +20207,38 @@ } ], "title": "Aisuggestion" + }, + "expectedDays": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Expecteddays" + }, + "idealIntervalDays": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Idealintervaldays" + }, + "recent60DHours": { + "type": "number", + "title": "Recent60Dhours", + "default": 0.0 + }, + "recent60DIncome": { + "type": "number", + "title": "Recent60Dincome", + "default": 0.0 } }, "type": "object", diff --git a/scripts/ops/_export_openapi.py b/scripts/ops/_export_openapi.py new file mode 100644 index 0000000..45407e8 --- /dev/null +++ b/scripts/ops/_export_openapi.py @@ -0,0 +1,12 @@ +"""从运行中的 FastAPI app 导出 OpenAPI spec 到 docs/contracts/openapi/backend-api.json""" +import json +import pathlib +import sys + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "apps" / "backend")) +from app.main import app + +spec = app.openapi() +out = pathlib.Path(r"C:\Project\NeoZQYY\docs\contracts\openapi\backend-api.json") +out.write_text(json.dumps(spec, ensure_ascii=False, indent=2), encoding="utf-8") +print(f"Done: {len(spec['paths'])} paths, {len(spec['components']['schemas'])} schemas")