docs: define actionable workbench

This commit is contained in:
malei 2026-08-01 23:47:58 +08:00
parent fe92fab4dd
commit 05f7c9c7ec
9 changed files with 63 additions and 54 deletions

View File

@ -3,7 +3,7 @@
> 本体条目 ↔ 文档章节 ↔ 代码路径 ↔ 测试用例 三方对齐审计。 > 本体条目 ↔ 文档章节 ↔ 代码路径 ↔ 测试用例 三方对齐审计。
> 证据强度:`anchored`(三处对齐)/ `documented`(仅文档)/ `implemented`(仅代码)/ `gap`(缺失)。 > 证据强度:`anchored`(三处对齐)/ `documented`(仅文档)/ `implemented`(仅代码)/ `gap`(缺失)。
> >
> **刷新时间**2026-08-01BusinessEvent 落库、工作台事件漏斗、StoreCustomer 主档与身份语义收口后刷新) > **刷新时间**2026-08-01BusinessEvent、StoreCustomer、身份语义与工作台行动聚合收口后刷新)
## 审计方法 ## 审计方法
@ -125,7 +125,7 @@ python3 docs/graph/audit_drift.py
| ID | 类型 | 用途 | | ID | 类型 | 用途 |
|----|------|------| |----|------|------|
| `entity:admin_console` | Entity | Web 管理端壳 | | `entity:admin_console` | Entity | Web 管理端壳 |
| `entity:workbench` / `workbench_todo_item` | Entity | 今日工作台与待办;报告事件漏斗已 anchored | | `entity:workbench` / `workbench_todo_item` | Entity | 服务端准确行动聚合、低敏预览与报告事件漏斗均 anchored |
| `entity:store_customer` | Entity | 门店客户稳定主档(非会员卡) | | `entity:store_customer` | Entity | 门店客户稳定主档(非会员卡) |
| `action:view_workbench` 等 8 个 admin_* | Action | 工作台/列表/设置/排班 | | `action:view_workbench` 等 8 个 admin_* | Action | 工作台/列表/设置/排班 |
| `rule:BR-ADMIN-001`…`004` | Rule | 角色、店范围、内部字段、范围闸门 | | `rule:BR-ADMIN-001`…`004` | Rule | 角色、店范围、内部字段、范围闸门 |

View File

@ -202,15 +202,15 @@
{"id":"rel:br_int_001_applies","type":"Relation","subject":"rule:BR-INT-001","predicate":"APPLIES_TO","object":"action:get_report_suggestion","domain":"service_type","evidence":"anchored"} {"id":"rel:br_int_001_applies","type":"Relation","subject":"rule:BR-INT-001","predicate":"APPLIES_TO","object":"action:get_report_suggestion","domain":"service_type","evidence":"anchored"}
{"id":"rel:br_store_003_applies","type":"Relation","subject":"rule:BR-STORE-003","predicate":"APPLIES_TO","object":"action:get_store","domain":"store","evidence":"anchored"} {"id":"rel:br_store_003_applies","type":"Relation","subject":"rule:BR-STORE-003","predicate":"APPLIES_TO","object":"action:get_store","domain":"store","evidence":"anchored"}
{"id":"entity:admin_console","type":"Entity","name":"AdminConsole","nameZh":"门店 Web 管理后台","domain":"admin","jpa":false,"fields":["surface","navModules","storeScope","roleGate"],"systems":["Store Admin FE","Backend Core"],"code":"","doc":"docs/ontology/objects.md#entity:admin_console","test":"","evidence":"documented","note":"Phase A 产品预录入;独立 Web 端,与 uni-app 小程序并存。对标宠老板「店铺概况」入口,不做收银/库存。详见 docs/门店管理后台升级方案-对标宠老板.md","status":"planned"} {"id":"entity:admin_console","type":"Entity","name":"AdminConsole","nameZh":"门店 Web 管理后台","domain":"admin","jpa":false,"fields":["surface","navModules","storeScope","roleGate"],"systems":["Store Admin FE","Backend Core"],"code":"","doc":"docs/ontology/objects.md#entity:admin_console","test":"","evidence":"documented","note":"Phase A 产品预录入;独立 Web 端,与 uni-app 小程序并存。对标宠老板「店铺概况」入口,不做收银/库存。详见 docs/门店管理后台升级方案-对标宠老板.md","status":"planned"}
{"id":"entity:workbench","type":"Entity","name":"Workbench","nameZh":"今日工作台","domain":"admin","jpa":false,"fields":["todayAppointmentCount","todayDoneCount","pendingLeadCount","highlightFailedCount","todoItems","reportFunnel","anomalyList"],"systems":["Store Admin FE","Backend Core","Report Media Backend"],"code":"admin/src/views/WorkbenchView.vue; backend/src/main/java/com/petstore/service/AdminBusinessEventService.java","doc":"docs/ontology/objects.md#entity:workbench","test":"AdminBusinessEventServiceTest","evidence":"anchored","note":"登录落点;待办复用现有接口,报告提交/打开/留资来自 BusinessEvent发送与转预约未跟踪时显示未知。","status":"implemented"} {"id":"entity:workbench","type":"Entity","name":"Workbench","nameZh":"今日行动工作台","domain":"admin","jpa":false,"fields":["todayAppointmentCount","todayDoneCount","overdueAppointmentCount","inServiceCount","upcomingTodayCount","highlightAnomalyCount","dueFollowUpCount","actionGroups","reportFunnel"],"systems":["Store Admin FE","Backend Core","Report Media Backend"],"code":"admin/src/views/WorkbenchView.vue; backend/src/main/java/com/petstore/service/AdminWorkbenchService.java; backend/src/main/java/com/petstore/service/AdminBusinessEventService.java","doc":"docs/ontology/objects.md#entity:workbench","test":"AdminWorkbenchServiceTest; AdminBusinessEventServiceTest","evidence":"anchored","note":"服务端按完整本店数据准确聚合行动;每组最多 3 条低敏预览;报告发送与转预约未跟踪时显示未知。","status":"implemented"}
{"id":"entity:workbench_todo_item","type":"Entity","name":"WorkbenchTodoItem","nameZh":"工作台待办项","domain":"admin","jpa":false,"fields":["kind","count","drilldownAction","filter"],"systems":["Store Admin FE"],"code":"","doc":"docs/ontology/objects.md#entity:workbench_todo_item","test":"","evidence":"documented","note":"kind: today_appointments | pending_report | highlight_anomaly | pending_lead","status":"planned"} {"id":"entity:workbench_todo_item","type":"Entity","name":"WorkbenchTodoItem","nameZh":"工作台行动组","domain":"admin","jpa":false,"fields":["kind","urgency","count","items","drilldownAction","filter"],"systems":["Store Admin FE","Backend Core"],"code":"backend/src/main/java/com/petstore/service/AdminWorkbenchService.java; admin/src/views/WorkbenchView.vue","doc":"docs/ontology/objects.md#entity:workbench_todo_item","test":"AdminWorkbenchServiceTest","evidence":"anchored","note":"kind: overdue_appointment | in_service | upcoming_today | highlight_anomaly | follow_up_dueitems 不含手机号/token/媒体 URL","status":"implemented"}
{"id":"entity:store_customer","type":"Entity","name":"StoreCustomer","nameZh":"门店客户主档(瘦身)","domain":"admin","jpa":true,"fields":["id","store_id","customer_user_id","phone","display_name","source","first_contact_at","last_contact_at","create_time","update_time","deleted"],"systems":["Store Admin FE","Backend Core","Report Media Backend"],"code":"backend/src/main/java/com/petstore/entity/StoreCustomer.java; backend/src/main/java/com/petstore/service/StoreCustomerService.java; backend/src/main/java/com/petstore/service/AdminServiceCustomerService.java","doc":"docs/ontology/objects.md#entity:store_customer; docs/架构决策-门店客户主档-2026-08-01.md","test":"StoreCustomerServiceTest; AdminServiceCustomerServiceTest; IdentityOwnershipQueryTest","evidence":"anchored","note":"门店与客户的稳定关系实体API 动态聚合宠物/到店/报告/留资,不含余额/次卡/积分。","status":"implemented"} {"id":"entity:store_customer","type":"Entity","name":"StoreCustomer","nameZh":"门店客户主档(瘦身)","domain":"admin","jpa":true,"fields":["id","store_id","customer_user_id","phone","display_name","source","first_contact_at","last_contact_at","create_time","update_time","deleted"],"systems":["Store Admin FE","Backend Core","Report Media Backend"],"code":"backend/src/main/java/com/petstore/entity/StoreCustomer.java; backend/src/main/java/com/petstore/service/StoreCustomerService.java; backend/src/main/java/com/petstore/service/AdminServiceCustomerService.java","doc":"docs/ontology/objects.md#entity:store_customer; docs/架构决策-门店客户主档-2026-08-01.md","test":"StoreCustomerServiceTest; AdminServiceCustomerServiceTest; IdentityOwnershipQueryTest","evidence":"anchored","note":"门店与客户的稳定关系实体API 动态聚合宠物/到店/报告/留资,不含余额/次卡/积分。","status":"implemented"}
{"id":"rule:BR-ADMIN-001","type":"Rule","name":"adminRoleGate","nameZh":"门店后台角色门禁boss/staff 可读写)","domain":"admin","appliesTo":["action:view_workbench","action:admin_list_appointments","action:admin_list_reports","action:admin_list_leads","action:admin_list_service_customers","action:admin_update_settings"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-001; docs/门店管理后台-PhaseA-页面清单PRD.md","test":"","evidence":"documented","note":"boss 与 staff 均可进入 admin_console 并编辑本店数据customer 禁止。删店/部分设置仍仅 bossBR-STORE-001/BR-USER-001。产品决策 2026-07-10。"} {"id":"rule:BR-ADMIN-001","type":"Rule","name":"adminRoleGate","nameZh":"门店后台角色门禁boss/staff 可读写)","domain":"admin","appliesTo":["action:view_workbench","action:admin_list_appointments","action:admin_list_reports","action:admin_list_leads","action:admin_list_service_customers","action:admin_update_settings"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-001; docs/门店管理后台-PhaseA-页面清单PRD.md","test":"","evidence":"documented","note":"boss 与 staff 均可进入 admin_console 并编辑本店数据customer 禁止。删店/部分设置仍仅 bossBR-STORE-001/BR-USER-001。产品决策 2026-07-10。"}
{"id":"rule:BR-ADMIN-002","type":"Rule","name":"adminStoreScope","nameZh":"后台数据仅本店 storeId","domain":"admin","appliesTo":["action:view_workbench","action:admin_list_appointments","action:admin_list_reports","action:admin_list_leads","action:admin_list_service_customers","action:admin_update_settings"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-002","test":"","evidence":"documented","note":"所有后台查询/写操作强制 current.storeId忽略跨店请求参数。连锁同步不在 Phase A。"} {"id":"rule:BR-ADMIN-002","type":"Rule","name":"adminStoreScope","nameZh":"后台数据仅本店 storeId","domain":"admin","appliesTo":["action:view_workbench","action:admin_list_appointments","action:admin_list_reports","action:admin_list_leads","action:admin_list_service_customers","action:admin_update_settings"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-002","test":"","evidence":"documented","note":"所有后台查询/写操作强制 current.storeId忽略跨店请求参数。连锁同步不在 Phase A。"}
{"id":"rule:BR-ADMIN-003","type":"Rule","name":"adminInternalFieldsAllowed","nameZh":"后台可看内部字段(与公开裁剪对称)","domain":"admin","appliesTo":["action:admin_list_reports","action:admin_update_settings","action:admin_list_service_customers"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-003","test":"","evidence":"documented","note":"经 BR-ADMIN-001 鉴权后,后台可返回 inviteCode、完整报告内部字段等公开 API 仍受 BR-STORE-003/BR-RPT-006 约束。手机号默认仍脱敏,明文需更高权限(预留)。"} {"id":"rule:BR-ADMIN-003","type":"Rule","name":"adminInternalFieldsAllowed","nameZh":"后台可看内部字段(与公开裁剪对称)","domain":"admin","appliesTo":["action:admin_list_reports","action:admin_update_settings","action:admin_list_service_customers"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-003","test":"","evidence":"documented","note":"经 BR-ADMIN-001 鉴权后,后台可返回 inviteCode、完整报告内部字段等公开 API 仍受 BR-STORE-003/BR-RPT-006 约束。手机号默认仍脱敏,明文需更高权限(预留)。"}
{"id":"rule:BR-ADMIN-004","type":"Rule","name":"adminPhaseAOutOfScope","nameZh":"Phase A 后台范围闸门","domain":"admin","appliesTo":["entity:admin_console","entity:workbench"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-004","test":"","evidence":"documented","note":"禁止将 membership/stored_value/service_package/收银/库存/寄养/押金/点餐/支付宝渠道 写入 Phase A 后台范围或设计稿。上述保持 evidence=gap。"} {"id":"rule:BR-ADMIN-004","type":"Rule","name":"adminPhaseAOutOfScope","nameZh":"Phase A 后台范围闸门","domain":"admin","appliesTo":["entity:admin_console","entity:workbench"],"code":"","doc":"docs/ontology/rules.md#rule:BR-ADMIN-004","test":"","evidence":"documented","note":"禁止将 membership/stored_value/service_package/收银/库存/寄养/押金/点餐/支付宝渠道 写入 Phase A 后台范围或设计稿。上述保持 evidence=gap。"}
{"id":"action:view_workbench","type":"Action","name":"viewWorkbench","nameZh":"查看今日工作台","domain":"admin","inputs":["date","entity:current_user"],"outputs":["entity:workbench","entity:workbench_todo_item"],"entrypoints":["GET /api/admin/workbench/report-funnel","Admin UI /workbench"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-ADMIN-004","rule:BR-BE-001"],"code":"backend/src/main/java/com/petstore/controller/AdminBusinessEventController.java#reportFunnel; backend/src/main/java/com/petstore/service/AdminBusinessEventService.java; admin/src/views/WorkbenchView.vue","doc":"docs/ontology/actions.md#action:view_workbench","test":"AdminBusinessEventControllerTest; AdminBusinessEventServiceTest","evidence":"anchored","note":"事件漏斗按会话 storeId 与日期汇总;待办继续复用现有 appointment/report/lead 接口。"} {"id":"action:view_workbench","type":"Action","name":"viewWorkbench","nameZh":"查看今日行动工作台","domain":"admin","inputs":["date","entity:current_user"],"outputs":["entity:workbench","entity:workbench_todo_item"],"entrypoints":["GET /api/admin/workbench/actions","GET /api/admin/workbench/report-funnel","Admin UI /workbench"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-ADMIN-004","rule:BR-BE-001"],"code":"backend/src/main/java/com/petstore/controller/AdminBusinessEventController.java#actions; #reportFunnel; backend/src/main/java/com/petstore/service/AdminWorkbenchService.java; backend/src/main/java/com/petstore/service/AdminBusinessEventService.java; admin/src/views/WorkbenchView.vue","doc":"docs/ontology/actions.md#action:view_workbench","test":"AdminBusinessEventControllerTest; AdminWorkbenchServiceTest; AdminBusinessEventServiceTest","evidence":"anchored","note":"按会话 storeId 聚合完整本店行动低敏预览;事件漏斗按日期汇总。"}
{"id":"action:drilldown_workbench_todo","type":"Action","name":"drilldownWorkbenchTodo","nameZh":"工作台待办下钻","domain":"admin","inputs":["entity:workbench_todo_item"],"outputs":[],"entrypoints":["Admin UI workbench todo click (planned)"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002"],"code":"","doc":"docs/ontology/actions.md#action:drilldown_workbench_todo","evidence":"documented","note":"按 kind 跳转 admin_list_appointments / reports / leads 并带筛选。"} {"id":"action:drilldown_workbench_todo","type":"Action","name":"drilldownWorkbenchTodo","nameZh":"工作台行动下钻","domain":"admin","inputs":["entity:workbench_todo_item"],"outputs":[],"entrypoints":["Admin UI workbench action click"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002"],"code":"admin/src/views/WorkbenchView.vue; admin/src/views/AppointmentsView.vue","doc":"docs/ontology/actions.md#action:drilldown_workbench_todo","evidence":"anchored","note":"按 kind 跳转 appointments/reports/leads 并带筛选;预约预览可按受保护 ID 详情打开。"}
{"id":"action:admin_list_appointments","type":"Action","name":"adminListAppointments","nameZh":"后台预约列表","domain":"admin","inputs":["status","dateFrom","dateTo","assignedUserId","page","pageSize"],"outputs":["entity:appointment"],"entrypoints":["Admin UI /appointments (planned)","reuses GET /api/appointment/list"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-APPT-001","rule:BR-APPT-002"],"code":"backend/.../AppointmentController.java#list (reuse)","doc":"docs/ontology/actions.md#action:admin_list_appointments","evidence":"documented","note":"Web 列表增强筛选;业务规则复用现有 Appointment*不另造状态机。Web 允许调用 start_service产品决策 2026-07-10"} {"id":"action:admin_list_appointments","type":"Action","name":"adminListAppointments","nameZh":"后台预约列表","domain":"admin","inputs":["status","dateFrom","dateTo","assignedUserId","page","pageSize"],"outputs":["entity:appointment"],"entrypoints":["Admin UI /appointments (planned)","reuses GET /api/appointment/list"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-APPT-001","rule:BR-APPT-002"],"code":"backend/.../AppointmentController.java#list (reuse)","doc":"docs/ontology/actions.md#action:admin_list_appointments","evidence":"documented","note":"Web 列表增强筛选;业务规则复用现有 Appointment*不另造状态机。Web 允许调用 start_service产品决策 2026-07-10"}
{"id":"action:admin_list_reports","type":"Action","name":"adminListReports","nameZh":"后台报告列表","domain":"admin","inputs":["dateFrom","dateTo","highlightStatus","page","pageSize"],"outputs":["entity:report","entity:highlight_video"],"entrypoints":["Admin UI /reports (planned)","reuses GET /api/report/list"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-ADMIN-003","rule:BR-RPT-005"],"code":"backend/.../ReportController.java#list (reuse)","doc":"docs/ontology/actions.md#action:admin_list_reports","evidence":"documented","note":"含成片三态、复制公开链接、触发重生成(复用 generate_highlight。"} {"id":"action:admin_list_reports","type":"Action","name":"adminListReports","nameZh":"后台报告列表","domain":"admin","inputs":["dateFrom","dateTo","highlightStatus","page","pageSize"],"outputs":["entity:report","entity:highlight_video"],"entrypoints":["Admin UI /reports (planned)","reuses GET /api/report/list"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-ADMIN-003","rule:BR-RPT-005"],"code":"backend/.../ReportController.java#list (reuse)","doc":"docs/ontology/actions.md#action:admin_list_reports","evidence":"documented","note":"含成片三态、复制公开链接、触发重生成(复用 generate_highlight。"}
{"id":"action:admin_list_leads","type":"Action","name":"adminListLeads","nameZh":"后台回访线索列表","domain":"admin","inputs":["remindStatus","remindDateTo","page","pageSize"],"outputs":["entity:report_lead"],"entrypoints":["Admin UI /leads (planned)","reuses GET /api/report/leads"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-LEAD-002","rule:BR-LEAD-003"],"code":"backend/.../ReportLeadController.java#leads (reuse)","doc":"docs/ontology/actions.md#action:admin_list_leads","evidence":"documented"} {"id":"action:admin_list_leads","type":"Action","name":"adminListLeads","nameZh":"后台回访线索列表","domain":"admin","inputs":["remindStatus","remindDateTo","page","pageSize"],"outputs":["entity:report_lead"],"entrypoints":["Admin UI /leads (planned)","reuses GET /api/report/leads"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-LEAD-002","rule:BR-LEAD-003"],"code":"backend/.../ReportLeadController.java#leads (reuse)","doc":"docs/ontology/actions.md#action:admin_list_leads","evidence":"documented"}
@ -219,7 +219,7 @@
{"id":"action:admin_manage_schedule","type":"Action","name":"adminManageSchedule","nameZh":"后台排班与占用","domain":"admin","inputs":["date","entity:schedule_block"],"outputs":["entity:schedule_block","entity:appointment"],"entrypoints":["Admin UI /schedule","GET /api/schedule/day","POST /api/schedule/block","DELETE /api/schedule/block"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-SCH-001","rule:BR-SCH-002","rule:BR-APPT-004"],"code":"","doc":"docs/ontology/actions.md#action:admin_manage_schedule","evidence":"anchored","note":"Web 排班日视图展示容量占用;增删带时长占用复用 ScheduleController。"} {"id":"action:admin_manage_schedule","type":"Action","name":"adminManageSchedule","nameZh":"后台排班与占用","domain":"admin","inputs":["date","entity:schedule_block"],"outputs":["entity:schedule_block","entity:appointment"],"entrypoints":["Admin UI /schedule","GET /api/schedule/day","POST /api/schedule/block","DELETE /api/schedule/block"],"appliesRules":["rule:BR-ADMIN-001","rule:BR-ADMIN-002","rule:BR-SCH-001","rule:BR-SCH-002","rule:BR-APPT-004"],"code":"","doc":"docs/ontology/actions.md#action:admin_manage_schedule","evidence":"anchored","note":"Web 排班日视图展示容量占用;增删带时长占用复用 ScheduleController。"}
{"id":"event:workbench_viewed","type":"Event","name":"workbenchViewed","nameZh":"工作台已打开","domain":"admin","emittedBy":["action:view_workbench"],"payload":["storeId","userId","ts"],"code":"","doc":"docs/ontology/events.md#event:workbench_viewed","evidence":"gap","note":"可选埋点A 期可不实现上报。"} {"id":"event:workbench_viewed","type":"Event","name":"workbenchViewed","nameZh":"工作台已打开","domain":"admin","emittedBy":["action:view_workbench"],"payload":["storeId","userId","ts"],"code":"","doc":"docs/ontology/events.md#event:workbench_viewed","evidence":"gap","note":"可选埋点A 期可不实现上报。"}
{"id":"rel:admin_console_has_workbench","type":"Relation","subject":"entity:admin_console","predicate":"HAS","object":"entity:workbench","domain":"admin","evidence":"documented","cardinality":"1—1","doc":"登录默认工作台"} {"id":"rel:admin_console_has_workbench","type":"Relation","subject":"entity:admin_console","predicate":"HAS","object":"entity:workbench","domain":"admin","evidence":"documented","cardinality":"1—1","doc":"登录默认工作台"}
{"id":"rel:workbench_has_todo_items","type":"Relation","subject":"entity:workbench","predicate":"HAS","object":"entity:workbench_todo_item","domain":"admin","evidence":"documented","cardinality":"1—N","doc":"今日待办卡片"} {"id":"rel:workbench_has_todo_items","type":"Relation","subject":"entity:workbench","predicate":"HAS","object":"entity:workbench_todo_item","domain":"admin","evidence":"anchored","cardinality":"1—N","doc":"按优先级排序的行动组"}
{"id":"rel:workbench_reads_appointments","type":"Relation","subject":"entity:workbench","predicate":"AGGREGATES","object":"entity:appointment","domain":"admin","evidence":"documented","cardinality":"1—N","doc":"今日预约指标"} {"id":"rel:workbench_reads_appointments","type":"Relation","subject":"entity:workbench","predicate":"AGGREGATES","object":"entity:appointment","domain":"admin","evidence":"documented","cardinality":"1—N","doc":"今日预约指标"}
{"id":"rel:workbench_reads_reports","type":"Relation","subject":"entity:workbench","predicate":"AGGREGATES","object":"entity:report","domain":"admin","evidence":"documented","cardinality":"1—N","doc":"待出报告/成片异常"} {"id":"rel:workbench_reads_reports","type":"Relation","subject":"entity:workbench","predicate":"AGGREGATES","object":"entity:report","domain":"admin","evidence":"documented","cardinality":"1—N","doc":"待出报告/成片异常"}
{"id":"rel:workbench_reads_leads","type":"Relation","subject":"entity:workbench","predicate":"AGGREGATES","object":"entity:report_lead","domain":"admin","evidence":"documented","cardinality":"1—N","doc":"待回访"} {"id":"rel:workbench_reads_leads","type":"Relation","subject":"entity:workbench","predicate":"AGGREGATES","object":"entity:report_lead","domain":"admin","evidence":"documented","cardinality":"1—N","doc":"待回访"}
@ -235,4 +235,4 @@
{"id":"rel:admin_list_reports_reads_report","type":"Relation","subject":"action:admin_list_reports","predicate":"READS","object":"entity:report","domain":"admin","evidence":"documented"} {"id":"rel:admin_list_reports_reads_report","type":"Relation","subject":"action:admin_list_reports","predicate":"READS","object":"entity:report","domain":"admin","evidence":"documented"}
{"id":"rel:admin_list_leads_reads_lead","type":"Relation","subject":"action:admin_list_leads","predicate":"READS","object":"entity:report_lead","domain":"admin","evidence":"documented"} {"id":"rel:admin_list_leads_reads_lead","type":"Relation","subject":"action:admin_list_leads","predicate":"READS","object":"entity:report_lead","domain":"admin","evidence":"documented"}
{"id":"rel:admin_list_customers_reads_sc","type":"Relation","subject":"action:admin_list_service_customers","predicate":"READS","object":"entity:store_customer","domain":"admin","evidence":"anchored"} {"id":"rel:admin_list_customers_reads_sc","type":"Relation","subject":"action:admin_list_service_customers","predicate":"READS","object":"entity:store_customer","domain":"admin","evidence":"anchored"}
{"id":"rel:drilldown_todo_to_list_appts","type":"Relation","subject":"action:drilldown_workbench_todo","predicate":"ROUTES_TO","object":"action:admin_list_appointments","domain":"admin","evidence":"documented","doc":"kind=today_appointments|pending_report 等"} {"id":"rel:drilldown_todo_to_list_appts","type":"Relation","subject":"action:drilldown_workbench_todo","predicate":"ROUTES_TO","object":"action:admin_list_appointments","domain":"admin","evidence":"anchored","doc":"kind=overdue_appointment|in_service|upcoming_today按 ID 或服务端口径筛选"}

View File

@ -588,23 +588,24 @@
### action:view_workbench ### action:view_workbench
查看今日工作台(登录落点;可弹今日待办)。报告提交、打开与留资三项通过服务端事件汇总,未建模的报告发送/转预约保持未知。 查看今日行动工作台(登录落点)。服务端按完整本店数据聚合逾期预约、服务中、今日待开始、成片异常和到期回访,返回准确总数与低敏预览;报告提交、打开与留资通过 BusinessEvent 汇总,未建模的报告发送/转预约保持未知。
- **入口**Admin UI `/workbench``GET /api/admin/workbench/report-funnel?date=yyyy-MM-dd` - **入口**Admin UI `/workbench``GET /api/admin/workbench/actions`;兼容 `GET /api/admin/workbench/report-funnel?date=yyyy-MM-dd`
- **输出**`entity:workbench`、`entity:workbench_todo_item` - **输出**`entity:workbench`、`entity:workbench_todo_item`
- **适用规则**`rule:BR-ADMIN-001`、`rule:BR-ADMIN-002`、`rule:BR-ADMIN-004`、`rule:BR-BE-001` - **适用规则**`rule:BR-ADMIN-001`、`rule:BR-ADMIN-002`、`rule:BR-ADMIN-004`、`rule:BR-BE-001`
- **触发事件**`event:workbench_viewed`可选gap - **触发事件**`event:workbench_viewed`可选gap
- **代码**`AdminBusinessEventController`、`AdminBusinessEventService`、`admin/src/views/WorkbenchView.vue` - **代码**`AdminBusinessEventController`、`AdminWorkbenchService`、`AdminBusinessEventService`、`admin/src/views/WorkbenchView.vue`
- **测试**`AdminBusinessEventControllerTest`、`AdminBusinessEventServiceTest` - **测试**`AdminBusinessEventControllerTest`、`AdminWorkbenchServiceTest`、`AdminBusinessEventServiceTest`
- **证据**`anchored`(事件漏斗已落地;其他待办仍复用现有接口聚合) - **证据**`anchored`
### action:drilldown_workbench_todo ### action:drilldown_workbench_todo
工作台待办卡片下钻到对应列表并带筛选 工作台行动组或具体预览下钻到对应列表并带筛选;预约预览可按 ID 直接打开受保护详情
- **入口**Admin UI workbench todo clickplanned - **入口**Admin UI workbench action click
- **适用规则**`rule:BR-ADMIN-001`、`rule:BR-ADMIN-002` - **适用规则**`rule:BR-ADMIN-001`、`rule:BR-ADMIN-002`
- **证据**`documented` - **代码**`admin/src/views/WorkbenchView.vue`、`AppointmentsView.vue`
- **证据**`anchored`
### action:admin_list_appointments ### action:admin_list_appointments

View File

@ -386,18 +386,19 @@
## entity:workbench ## entity:workbench
**今日工作台**(非 JPA 聚合视图)。指标卡 + 今日待办 + 报告漏斗摘要;待办来自 appointment/report/lead/highlight报告漏斗来自 BusinessEvent**无独立工作台表**。 **今日工作台**(非 JPA 聚合视图)。指标卡 + 按履约优先级排序的行动队列 + 报告漏斗摘要;行动来自 appointment/report/lead/highlight报告漏斗来自 BusinessEvent**无独立工作台表**。服务端按完整本店数据计算准确总数,不再由前端拉取前 200 条估算。
| 字段(概念) | 说明 | | 字段(概念) | 说明 |
|------|------| |------|------|
| todayAppointmentCount / todayDoneCount | 今日预约 / 今日完成 | | todayAppointmentCount / todayDoneCount | 今日预约 / 今日完成 |
| pendingLeadCount / highlightFailedCount | 待回访 / 成片失败 | | overdueAppointmentCount / inServiceCount / upcomingTodayCount | 逾期未开始 / 服务中 / 今日待开始 |
| todoItems | `entity:workbench_todo_item[]` | | dueFollowUpCount / highlightAnomalyCount | 到期回访 / 成片失败或处理超时 |
| actionGroups | `entity:workbench_todo_item[]`(每组最多 3 条低敏预览) |
| reportFunnel | 已提交/已打开/已留资/报告转预约;未跟踪的发送与转预约返回未知 | | reportFunnel | 已提交/已打开/已留资/报告转预约;未跟踪的发送与转预约返回未知 |
| anomalyList | 成片失败或待回访最近 N 条 | | anomalyList | 成片失败或待回访最近 N 条 |
- **代码**`admin/src/views/WorkbenchView.vue`、`AdminBusinessEventController`、`AdminBusinessEventService` - **代码**`admin/src/views/WorkbenchView.vue`、`AdminBusinessEventController`、`AdminWorkbenchService`、`AdminBusinessEventService`
- **测试**`AdminBusinessEventControllerTest`、`AdminBusinessEventServiceTest` - **测试**`AdminBusinessEventControllerTest`、`AdminWorkbenchServiceTest`、`AdminBusinessEventServiceTest`
- **证据**`anchored` - **证据**`anchored`
- **动作**`action:view_workbench` - **动作**`action:view_workbench`
@ -407,12 +408,15 @@
| 字段 | 说明 | | 字段 | 说明 |
|------|------| |------|------|
| kind | `today_appointments` / `pending_report` / `highlight_anomaly` / `pending_lead` | | kind | `overdue_appointment` / `in_service` / `upcoming_today` / `highlight_anomaly` / `follow_up_due` |
| urgency | critical / high / normal |
| count | 数量 | | count | 数量 |
| drilldownAction | 下钻到的 admin list action | | items | 最多 3 条 resource ID + 宠物/服务/时间低敏预览无手机号、token、媒体 URL |
| filter | 预置筛选 | | drilldownAction / filter | 下钻到的 admin list action 与预置筛选 |
- **证据**`documented` - **代码**`AdminWorkbenchService`、`admin/src/views/WorkbenchView.vue`
- **测试**`AdminWorkbenchServiceTest`
- **证据**`anchored`
## entity:store_customer ## entity:store_customer

View File

@ -154,7 +154,7 @@
| 关系 | 说明 | | 关系 | 说明 |
|------|------| |------|------|
| `admin_console` HAS `workbench` | 登录默认工作台 | | `admin_console` HAS `workbench` | 登录默认工作台 |
| `workbench` HAS `workbench_todo_item` | 今日待办 | | `workbench` HAS `workbench_todo_item` | 按优先级排序的行动组(准确总数 + 低敏预览) |
| `workbench` AGGREGATES `appointment` / `report` / `report_lead` | 指标与异常来源 | | `workbench` AGGREGATES `appointment` / `report` / `report_lead` | 指标与异常来源 |
| `store` HAS `store_customer` | 一店多个稳定客户关系 | | `store` HAS `store_customer` | 一店多个稳定客户关系 |
| `store_customer` LINKS `user` | 可选关联全局 customer 账号;留资客户可先不关联 | | `store_customer` LINKS `user` | 可选关联全局 customer 账号;留资客户可先不关联 |

View File

@ -23,7 +23,7 @@
## A1 工作台 ## A1 工作台
- [x] 静态:四指标下钻参数、待办弹层、「今日不再提醒」 - [x] 静态:四指标/行动组下钻、服务端完整计数、最多 3 条低敏预览;不再每日强弹
- [x] 静态:成片失败含 failed + processing 超 30 分钟 - [x] 静态:成片失败含 failed + processing 超 30 分钟
- [x] 静态:侧栏无收银/库存/会员 - [x] 静态:侧栏无收银/库存/会员
- [ ] 联机:数字与列表一致 - [ ] 联机:数字与列表一致

View File

@ -20,7 +20,7 @@
| 模块 | 状态 | 主要缺口 | | 模块 | 状态 | 主要缺口 |
|------|------|----------| |------|------|----------|
| A0 壳层登录 | ~95% | 生产微信登录策略另议 | | A0 壳层登录 | ~95% | 生产微信登录策略另议 |
| A1 工作台 | ~95% | 待办弹层已做;漏斗提交/打开/留资已接 BusinessEvent转预约仍待归因模型 | | A1 工作台 | ~98% | 服务端准确行动聚合 + 低敏预览已做;发送状态与转预约归因仍待后续模型,真实环境 smoke 待补 |
| A2 预约 | ~95% | 详情/筛选/待出报告/宠主脱敏已做 | | A2 预约 | ~95% | 详情/筛选/待出报告/宠主脱敏已做 |
| A6 排班 | ~90% | 与小程序对照验收 | | A6 排班 | ~90% | 与小程序对照验收 |
| A3 报告 | ~95% | 详情抽屉+失败文案+H5 | | A3 报告 | ~95% | 详情抽屉+失败文案+H5 |
@ -39,7 +39,7 @@
|--------|------|----------| |--------|------|----------|
| **S1** | 预约/工作台下钻闭环 | 待出报告过滤正确;预约详情;技师/日期筛选 | | **S1** | 预约/工作台下钻闭环 | 待出报告过滤正确;预约详情;技师/日期筛选 |
| **S2** | 报告/线索经营闭环 | 报告详情+失败文案;线索打开报告;到期筛 | | **S2** | 报告/线索经营闭环 | 报告详情+失败文案;线索打开报告;到期筛 |
| **S3** | 客户详情 + 体验打磨 | 客户详情;工作台待办弹层;文案/空态 | | **S3** | 客户详情 + 体验打磨 | 客户详情;工作台常驻行动队列;文案/空态 |
| **S4** | 验收冻结 | 冒烟全绿§11 剧本演示;文档/本体同步 | | **S4** | 验收冻结 | 冒烟全绿§11 剧本演示;文档/本体同步 |
每完成一个 Sprint更新本文件进度表 + 冒烟清单勾选状态。 每完成一个 Sprint更新本文件进度表 + 冒烟清单勾选状态。

View File

@ -33,23 +33,24 @@
## A1 工作台 `/workbench` ## A1 工作台 `/workbench`
**一句话**一眼看清今天要干啥,点卡片就能下钻 **一句话**先处理会卡住履约的事,再看报告转化;数字由服务端完整聚合
```text ```text
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│今日预约│ │今日完成│ │待回访│ │成片失败│ ← 可点下钻 │今日预约│ │逾期未开始│ │服务中│ │今日完成│ ← 可点下钻
└─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘
今日待办 [待开始 n] [服务中 n] [待出报告 n] [成片异常 n] [待回访 n] 行动队列
① 预约已过时间 n 最近 3 条 …………………… [全部处理]
② 服务中等待收尾 n 最近 3 条 …………………… [全部处理]
③ 今天接下来到店 n 最近 3 条 …………………… [全部处理]
④ 成片异常 n 最近 3 条 …………………… [全部处理]
⑤ 回访日期已到 n 最近 3 条 …………………… [全部处理]
报告漏斗 已提交 | 已打开 | 已留资 | 转预约— 报告漏斗 已提交 | 确认发送— | 已打开 | 已留资 | 转预约—
异常最近 5 条 …………………… [去处理]
右侧:门店卡片(店名 / 营业时段 / 员工数)
``` ```
**主操作**:点指标/待办下钻;关闭「今日待办」弹层(可勾今日不再提醒)。 **主操作**:点指标、行动组或具体低敏预览下钻;工作台常驻,不用先关弹窗。
**不做**:寄养/库存待办、经营 sparkline。 **不做**:寄养/库存待办、经营 sparkline。
--- ---

View File

@ -89,10 +89,10 @@ entity:admin_console
```text ```text
顶栏 4 指标卡 顶栏 4 指标卡
今日待办条(或登录弹层关闭后的常驻摘要 常驻行动队列(不再每日强弹
报告漏斗四格(提交/打开/留资已由 BusinessEvent 汇总;转预约仍为「—」) 报告漏斗四格(提交/打开/留资已由 BusinessEvent 汇总;转预约仍为「—」)
异常列表(成片失败 / 待回访 最近 5 条) 每组最多 3 条低敏预览 + 准确总数 + 列表下钻
右侧:门店卡片(店名、营业时段摘要、员工数)+ 帮助链接 报告漏斗(提交 / 发送未知 / 打开 / 留资 / 再预约未知)
``` ```
### 2.2 顶栏指标卡 ### 2.2 顶栏指标卡
@ -100,20 +100,21 @@ entity:admin_console
| 卡 | 口径 | 点击下钻 | | 卡 | 口径 | 点击下钻 |
|----|------|----------| |----|------|----------|
| 今日预约 | 今日 `appointmentTime` 落在当天的预约数(含各状态) | `/appointments?date=today` | | 今日预约 | 今日 `appointmentTime` 落在当天的预约数(含各状态) | `/appointments?date=today` |
| 今日完成 | 今日变为 `done` 的预约数 | `/appointments?status=done&date=today` | | 逾期未开始 | 所有 `status=new``appointmentTime<now` | `/appointments?status=new&overdue=1` |
| 待回访 | `remind_status=pending``remindDate≤今天` | `/leads?due=today` | | 服务中 | 所有 `status=doing` | `/appointments?status=doing&missingReport=1` |
| 成片失败 | 本店报告 `highlight_video_status=failed`(可限近 7 日) | `/reports?highlightStatus=failed` | | 今日完成 | 今日 `updateTime` 变为 `done` 的预约数 | `/appointments?status=done&completedToday=1` |
### 2.3 今日待办(弹层 + 常驻) ### 2.3 行动队列(常驻)
| kind | 文案 | count 口径 | 下钻 | | kind | 文案 | count 口径 | 下钻 |
|------|------|------------|------| |------|------|------------|------|
| `today_appointments` | 今日预约 | 同「今日预约」卡,可分子状态:待开始 / 服务中 | 预约列表 | | `overdue_appointment` | 预约已过时间 | 所有 `new` 且预约时间早于当前时刻 | 预约列表 `status=new&overdue=1` |
| `pending_report` | 待出报告 | `status=doing` 且尚无报告 | 预约列表 `status=doing&missingReport=1` | | `in_service` | 服务中,等待收尾 | 所有 `doing`;提交报告后自动退出 | 预约列表 `status=doing&missingReport=1` |
| `highlight_anomaly` | 成片异常 | `failed` + 可选 `processing` 超时(阈值产品定,默认 30min | 报告列表 | | `upcoming_today` | 今天接下来要到店 | 今日尚未到时刻的 `new` | 预约列表 `status=new&date=today` |
| `pending_lead` | 待回访 | 同「待回访」卡 | 线索列表 | | `highlight_anomaly` | 成片异常 | `failed` + `processing` 超过 30 分钟 | 报告列表 `highlightStatus=anomaly` |
| `follow_up_due` | 回访日期已到 | `pending``remindDate≤今天` 或日期缺失 | 线索列表 `due=today` |
弹层:首次进入当日可弹;勾选「今日不再提醒」写入 localStorage「确定」关闭 优先级固定为:逾期预约 → 服务中 → 今日待开始 → 成片异常 → 到期回访。每组只返回最多 3 条预览,预览不含手机号、报告 token、媒体 URL 或微信标识;准确总数由服务端按完整数据计算。工作台不再每日强弹,避免值班人员为了关弹窗而忽略真正行动
**不对标宠老板**:寄养、临期商品、库存、待发货、售后。 **不对标宠老板**:寄养、临期商品、库存、待发货、售后。
@ -128,14 +129,16 @@ entity:admin_console
### 2.5 API / 聚合 ### 2.5 API / 聚合
待办与异常仍复用现有接口;报告漏斗使用 `GET /api/admin/workbench/report-funnel?date=yyyy-MM-dd``storeId` 从会话派生 行动队列使用 `GET /api/admin/workbench/actions`,一次返回 `metrics + actions + reportFunnel``storeId` 只从会话派生,不接受 query storeId。报告漏斗原接口 `GET /api/admin/workbench/report-funnel?date=yyyy-MM-dd` 保留兼容
复用候选:`/api/appointment/list`、`/api/report/list`、`/api/report/leads`、`/api/store/get`(后台可用内部字段,`BR-ADMIN-003` `actions[].items` 只包含 resourceType/resourceId、宠物名、服务类型、计划时间、状态和是否逾期详细联系信息必须进入对应受保护列表后按权限读取
### 2.6 验收 ### 2.6 验收
- [ ] 老板登录后默认进入工作台 - [ ] 老板登录后默认进入工作台
- [ ] 四指标与待办数字与列表下钻一致 - [ ] 四指标与行动队列数字来自完整本店数据,不受列表前 200 条截断
- [ ] 今日完成按状态更新时间下钻,逾期预约按当前时刻下钻
- [ ] 行动预览不含手机号、report token、媒体 URL 或微信标识
- [ ] 待办不含库存/寄养类卡片 - [ ] 待办不含库存/寄养类卡片
- [ ] customer 无法打开 - [ ] customer 无法打开
- [ ] **staff 与 boss 均可进入并操作本店工作台** - [ ] **staff 与 boss 均可进入并操作本店工作台**
@ -431,7 +434,7 @@ API`user/staff-list`、`create-staff`、删除接口
## 11. 验收剧本(端到端) ## 11. 验收剧本(端到端)
1. 老板登录 → 默认工作台,见今日待办 1. 老板登录 → 默认工作台,见按履约优先级排序的行动队列
2. 点「待出报告」→ 预约列表仅 doing 且无报告 2. 点「待出报告」→ 预约列表仅 doing 且无报告
3. 打开某已完成单的报告 → 复制公开链接 → 无痕浏览器打开,字段符合公开裁剪 3. 打开某已完成单的报告 → 复制公开链接 → 无痕浏览器打开,字段符合公开裁剪
4. 线索页处理一条待回访(至少能打开关联报告) 4. 线索页处理一条待回访(至少能打开关联报告)