← 返回宏观 DAG

Operations Management Sub-DAG

运营管理子图 | Scheduling / Payroll / Reports / AI Insights
2026-03-22 | Spec 098-business-dag-audit

健康度总览

9
总边数
7
已连通
2
部分连通
0
断裂

运营管理 DAG

已连通 (端到端代码链路验证)
部分连通 (后端存在但链路有缺口)
断裂 (未实现)
graph TD
  subgraph DataSources ["数据源层"]
    TXN["Transactions (交易记录)"]
    COMM["Commission Records (佣金记录)"]
    TIPS["Tip Distributions (小费分配)"]
    TC["Time Cards (工时卡)"]
    SCHED_TPL["Schedule Templates (排班模板)"]
    BIZ["Business Data (综合业务数据)"]
  end

  subgraph Operations ["运营管理层"]
    PAYROLL["Payroll Service (薪资报表)"]
    REPORTS["Report Engine (报表引擎)"]
    AI["AI Insight Pipeline (AI 洞察)"]
    SCHED_APPLY["Schedule Apply (排班生成)"]
  end

  subgraph Output ["输出层"]
    CSV_EXP["Payroll CSV Export (Gusto/ADP)"]
    RPT_EXP["Report Export (Excel/PDF)"]
  end

  TXN -->|"O1 交易数据聚合"| REPORTS
  COMM -->|"O2 佣金计算结果"| PAYROLL
  TIPS -->|"O3 小费间接读取"| PAYROLL
  TC -->|"O4 工时卡汇总"| PAYROLL
  SCHED_TPL -->|"O5 模板应用生成排班"| SCHED_APPLY
  PAYROLL -->|"O6 导出 CSV"| CSV_EXP
  REPORTS -->|"O7 导出 Excel/PDF"| RPT_EXP
  BIZ -->|"O8 多维指标采集"| AI
  BIZ -->|"O9 30+ 报表覆盖"| REPORTS

  style TXN fill:#1a2332,stroke:#3b82f6,color:#e0e0e0
  style COMM fill:#1a2332,stroke:#3b82f6,color:#e0e0e0
  style TIPS fill:#1a2332,stroke:#3b82f6,color:#e0e0e0
  style TC fill:#1a2332,stroke:#3b82f6,color:#e0e0e0
  style SCHED_TPL fill:#1a2332,stroke:#3b82f6,color:#e0e0e0
  style BIZ fill:#1a2332,stroke:#8b5cf6,color:#e0e0e0

  style PAYROLL fill:#1a2332,stroke:#22c55e,color:#e0e0e0
  style REPORTS fill:#1a2332,stroke:#22c55e,color:#e0e0e0
  style AI fill:#1a2332,stroke:#f59e0b,color:#e0e0e0
  style SCHED_APPLY fill:#1a2332,stroke:#22c55e,color:#e0e0e0

  style CSV_EXP fill:#0d2818,stroke:#22c55e,color:#22c55e,stroke-dasharray:5
  style RPT_EXP fill:#0d2818,stroke:#22c55e,color:#22c55e,stroke-dasharray:5

  linkStyle 0 stroke:#22c55e,stroke-width:2px
  linkStyle 1 stroke:#22c55e,stroke-width:2px
  linkStyle 2 stroke:#f59e0b,stroke-width:2px,stroke-dasharray:5
  linkStyle 3 stroke:#22c55e,stroke-width:2px
  linkStyle 4 stroke:#22c55e,stroke-width:2px
  linkStyle 5 stroke:#22c55e,stroke-width:2px
  linkStyle 6 stroke:#22c55e,stroke-width:2px
  linkStyle 7 stroke:#f59e0b,stroke-width:2px,stroke-dasharray:5
  linkStyle 8 stroke:#22c55e,stroke-width:2px
    

边审计表

状态 涉及端口 代码路径 备注
O1 Transactions → Reports API, Web services/reports/queries/revenue.js getDailyRevenue() / getTotalRevenue()
services/reports/queries/sales-summary.js getSalesByService() / getSalesByCategory()
services/reports/queries/sales-detail.js getSalesDetail()
services/reports/queries/profit.js getProfitSellCardMethod()
services/reports/queries/payment-methods.js
services/reports/queries/tips.js
services/reports/queries/refunds.js
表: transactions, transaction_items
Report Engine (report-engine.js) 注册 35+ 报表查询映射 (REPORT_QUERY_MAP), 多数读 transactions 表的 payment_status = 'completed' 记录。
Revenue、Sales Summary、Sales Detail、Profit、Payment Methods、Tips、Refunds 等模块均直接 SELECT FROM transactions
链路完整:交易数据 → 各查询模块 → Report Engine 调度 → API 返回。
O2 Commission → Payroll API services/commission/commissionEngine.js calculateRuleAmount()
services/commission/commissionRecorder.js recordCommissionForPayment()
services/payrollService.js getCommissionFromRecords() (L270)
表: commission_records WHERE status = 'confirmed'
写入路径commissionRecorder 在支付完成 (checkout/intent) 后触发, 按三级联级规则 (employee → job_title → tenant_default) 计算佣金比例, 写入 commission_records 表。
读取路径payrollService.getCommissionFromRecords() 汇总 commission_records WHERE status = 'confirmed',拆分 service/product commission。
链路完整:commissionEngine 计算 → commissionRecorder 持久化 → payrollService 聚合。
O3 Tip Data → Payroll API services/tipDistributionService.js commitDistribution()
services/commission/commissionRecorder.js (tip 记录)
services/payrollService.js getTipsTotal() (L179)
表: tip_distributions, commission_records WHERE commission_type = 'tip'
两套 tip 存储并行
(a) tipDistributionService 写入 tip_distributions 表(包含按员工分配明细);
(b) commissionRecorder 不写 tip 类型记录(无 commission_type = 'tip' INSERT)。
Payroll 读取路径getTipsTotal()commission_records WHERE commission_type = 'tip' 读取, 但 tip 数据实际存储在 tip_distributions 中。
桥接者dayEndCloseoutService 在日结时检测"有 tip 但无 commission_records tip 条目"的发票, 但没有自动创建 commission_records 的逻辑 -- 仅标记检查清单项。
缺口:tip 从分配到 payroll 聚合的自动化链路存在断层, 依赖日结流程或手动干预将 tip_distributions 数据同步到 commission_records。
O4 Working Hours → Payroll API services/timeClockService.js getEffectiveSettings() / getEmployeeScheduleForDate()
services/timeCardService.js getOrCreateTimeCard() / recordPunch()
services/payrollService.js getTimeCardsForPayroll() (L121) / getTotalHours() (L242)
表: time_cards, time_clock_settings, employee_schedules
写入路径timeCardService.recordPunch() 管理 clock in/out/break, 计算 total_hours 存入 time_cards
读取路径payrollService.getTimeCardsForPayroll() 按周期查询 time_cards WHERE status != 'voided'calculateHoursFromTimeCards() 计算 regular/overtime hours 拆分(40 小时分界线)。
链路完整:打卡 → time_cards → payrollService 聚合 → 薪资计算。
O5 Schedule Template → Apply API, Web services/scheduling/templateService.js generateSchedules() (L516)
services/scheduling/holidayService.js getHolidaysInRange()
services/scheduling/scheduleSync.js syncSchedule()
表: schedule_templates, employee_schedules
generateSchedules(templateId, startDate, endDate) 从模板读取 days_of_weekstart_time/end_time/break_*, 遍历日期范围,跳过节假日(holidayService), INSERT/UPDATE employee_schedules,并通过 scheduleSync 推送更新。
链路完整:模板定义 → 日期展开 → 节假日排除 → 排班写入 → 同步推送。
O6 Payroll → CSV Export API services/commission/csvExporter.js exportToGusto() / exportToADP()
api/payroll.js GET /reports/:id/export (L673)
Gusto 格式:一行一员工,字段含 Regular Hours, OT Hours, Commission, Tips, Deductions。
ADP 格式:一行一收入类型,UTF-8 BOM,Batch ID = "PAY-{periodEnd}"。
两种格式均将 payrollData.employees[] 序列化为 CSV 字符串。
链路完整:payrollService 计算 → csvExporter 格式化 → API 返回下载。
O7 Reports → Export API services/reports/export-service.js ExportService
services/reports/export-worker.js
依赖: ExcelJS (Excel 导出), pdfmake (PDF 导出, 注释中)
表: report_exports
ExportService 管理导出任务生命周期: createExportTask() → 状态更新 → Excel 文件生成。
支持 S3 上传 (s3Service 可选注入) 和链接有效期配置 (expiryMinutes)。
PDF 导出代码已注释(pdfmake 导入被注释),实际仅 Excel 可用。
链路基本完整,PDF 导出功能未完成。
O8 Business Data → AI Insights API services/ai/insight-pipeline.js executeRun()
services/ai/anomaly-engine.js detectStrategyAnomalies()
services/reports/index.js createInsightsQueryToolkit() (L87)
services/ai/insight-llm-service.js generateInsightNarrative()
createInsightsQueryToolkit() 暴露 7 个指标采集器:
average_ticket, revenue_total (revenue.js); retention_rate (retention.js); utilization_rate, service_count (working-hours.js); service_performance (service-performance.js); designated_booking_rate (designated-rate.js)。
缺口:30+ 报表模块中仅 7 个被接入 Insight Toolkit, 缺少 commission、payroll、tips、membership、points、giftcards、churn 等维度。 anomaly-engine 仅做 period-over-period 对比异常检测,无预测或趋势分析。
O9 30+ 报表覆盖 API, Web services/reports/report-engine.js REPORT_QUERY_MAP
services/reports/queries/*.js (31 个查询模块文件)
services/reports/index.js queries 导出
Report Engine 注册 35 个报表查询端点(见下方覆盖率矩阵)。
另有 14 个查询模块通过 reports/index.js 导出但不在 Engine 映射中 (revenue, tips, refunds, payment-methods 等通过独立 API 路由直接使用)。
31 个查询模块文件覆盖 17 个业务域,详见下方矩阵。

报表覆盖率矩阵

基于 backend/services/reports/queries/ 目录下 31 个查询模块文件的审计结果。 "Engine 注册"表示在 report-engine.jsREPORT_QUERY_MAP 中有映射; "直接使用"表示通过 reports/index.js 导出由独立 API 路由调用。

# 业务域 查询模块文件 Engine 注册 AI Insight 包含的报表类型
1 Sales (销售) sales-summary.js
sales-detail.js
consumption.js
✓ 9 端点 按服务/分类销售汇总、明细、按员工、趋势、客户消费、消费汇总
2 Revenue (营收) revenue.js 直接使用 ✓ 2 指标 日营收、总营收、交易数、平均客单价
3 Profit (利润) profit.js
income-expense.js
✓ 7 端点 售卡法/消耗法利润、趋势、对比、收支明细/分类/趋势
4 Tips (小费) tips.js 直接使用 小费汇总、按员工分配、按支付方式
5 Payment Methods (支付方式) payment-methods.js 直接使用 支付方式分布、趋势
6 Refunds (退款) refunds.js 直接使用 退款汇总、明细、原因分析
7 Commission (佣金) commission.js ✓ 2 端点 佣金汇总、明细(含 tip commission 拆分)
8 Payroll (薪资) payroll.js ✓ 2 端点 薪资汇总、按日明细
9 Working Hours (工时) working-hours.js
attendance.js
✓ 5 端点 ✓ 2 指标 工时汇总、按员工、趋势、按星期几、出勤报表
10 Entitlements (卡项权益) entitlements.js ✓ 4 端点 权益汇总、客户列表、按层级、到期预警
11 Retention (留存) retention.js 直接使用 ✓ 1 指标 留存率、回访率、新客/老客分布
12 Churn (流失) churn.js 直接使用 流失分析、流失客户列表
13 Appointments (预约) appointments.js
cancellations.js
直接使用 预约汇总、取消分析
14 Employee (员工) employee.js
ranking.js
designated-rate.js
✓ 1 端点 ✓ 1 指标 员工业绩、排名、指定率
15 Leaderboard (排行榜) leaderboard.js ✓ 3 端点 排名、目标、目标进度
16 Membership/Loyalty (会员/积分) membership.js
points.js
giftcards.js
直接使用 会员分析、积分统计、礼品卡统计
17 Service Performance (服务表现) service-performance.js ✓ 1 端点 ✓ 1 指标 服务维度营收、预约量、热门服务
18 Benchmark (行业基准) benchmark.js ✓ 2 端点 行业百分位对标、趋势
19 Platform (平台级) platform.js 直接使用 跨租户平台统计
20 Utilization (利用率) utilization.js 直接使用 资源利用率分析
21 Traffic (流量) traffic.js Legacy 客流量统计(legacy 模块,可能不可用)

覆盖率统计

31
查询模块文件
21
业务域覆盖
35
Engine 注册端点
7/21
AI Insight 接入率

未覆盖的业务域

业务域 报表覆盖 说明
Inventory (库存) ✗ 无 产品库存无独立报表查询模块。产品销售数据包含在 Sales 报表中,但库存水位、进销存无报表。
Marketing Campaigns (营销活动) ✗ 无 邮件/SMS 营销活动效果无报表模块。Campaign 数据存在(marketing_campaigns 表),但无查询聚合。
Cash Drawer (收银台) ✗ 无 收银台现金管理(cash_drawer_sessions)无独立报表。日结报表(dayEndReportGenerator)包含部分现金数据,但不在报表引擎体系内。
Acquisition (获客) ✗ 无 Google Business Profile 同步、Review Solicitation、Content Pipeline 等获客 Agent 数据无运营报表。

松散点汇总

1. Tip 数据双写且链路断层

tipDistributionService 将小费分配结果写入 tip_distributions 表, 而 payrollService.getTipsTotal()commission_records WHERE commission_type = 'tip' 读取。 commissionRecorder 在记录佣金时不写 tip 类型记录。

影响:若未通过日结流程手动将 tip 数据同步到 commission_records, payroll 计算中的 tip 金额可能为 0。dayEndCloseoutService 检测差异但不自动修复。

2. AI Insight 指标覆盖率低

createInsightsQueryToolkit() 仅暴露 7 个指标采集器 (average_ticket, revenue_total, retention_rate, utilization_rate, service_count, service_performance, designated_booking_rate), 而报表系统覆盖 21 个业务域。

缺失维度:commission、payroll、tips、membership、points、giftcards、 churn、cancellations、appointments、refunds、profit 等高价值运营指标未接入 AI 异常检测。 anomaly-engine 仅做 period-over-period 百分比对比,缺少趋势预测和多维关联分析。

3. PDF 导出未实现

export-service.jspdfmake 导入被注释掉, 仅 Excel (ExcelJS) 导出可用。createExportTask() 接受 format: 'pdf' 参数, 但实际生成逻辑未实现。

影响:API 层面接受 PDF 导出请求但无法生成文件,需要前端做格式限制或后端补齐实现。

4. 库存/营销/获客/收银台报表缺失

四个业务域(Inventory、Marketing Campaigns、Cash Drawer、Acquisition Agent) 在报表引擎体系中无对应查询模块。 日结报表 (dayEndReportGenerator) 覆盖部分 cash drawer 数据, 但这是独立于 Report Engine 的系统。

交叉引用

关联子图
核心文件索引