timarai-dashboard-mcp 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,265 @@
1
+ /**
2
+ * 面向 Agent 的静态知识资源。
3
+ *
4
+ * 把这些「口径」固化成 Resource 而不是塞进每个 tool 的 description,
5
+ * 可以在不膨胀工具上下文的前提下,让 Agent 在拿不准时按需读取。
6
+ */
7
+ import { ENDPOINTS, DASHBOARD_ROUTE_PREFIX } from "./registry.js";
8
+ import { DATE_PRESETS, REPORT_TIME_ZONE } from "./date-range.js";
9
+ import { CHART_SPECS } from "./charts/specs.js";
10
+ import { REPORT_TEMPLATES } from "./reports/templates.js";
11
+ export const FIELD_GLOSSARY = `# 平台驾驶舱字段口径
12
+
13
+ ## 通用:Meta(数据新鲜度)
14
+ 每个数据响应都带 \`meta\`,**回答任何经营数据时都应先看它**:
15
+
16
+ | 字段 | 含义 | 使用建议 |
17
+ |------|------|----------|
18
+ | \`dataAsOf\` | 数据新鲜度时间戳 | **为 \`null\` 表示本区间内没有任何统计产出**,此时数据集为空 |
19
+ | \`lastRefreshTime\` | 最近一次刷新时刻 | \`isStale\` 的**判定基准**;与 \`dataAsOf\`(统计产出时刻)是两种不同的滞后,见下 |
20
+ | \`isStale\` | 刷新链路是否滞后 | 规则是 \`UtcNow - lastRefreshTime > 5min\`,⚠️ **基准是 \`lastRefreshTime\`,不是 \`dataAsOf\`**。\`true\` 只表示准实时刷新没跑,**不代表数据本身错** |
21
+ | \`coveredDates\` | 区间内**有**统计产出的日期 | 真正的口径边界:不在此列表中的日期没有数据 |
22
+ | \`missingDates\` | 区间内**无**统计产出的日期 | 这些日期**不会再补 0**,不要把「缺失」当成「那天为零」 |
23
+ | \`dataVersion\` | 本次使用的数据版本 | 同一批数据可比 |
24
+ | \`isFinal\` | 是否已封板为终值 | \`false\` 表示**未终值**,出正式财报前须确认。**窗口含今天时恒为 \`false\`**(当日不封板) |
25
+ | \`reportTimeZone\` | 固定为 ${REPORT_TIME_ZONE} | 所有"今天/昨天"以此为准 |
26
+ | \`appliedFilters\` | 本次实际生效的筛选维度 | 用于确认筛选被采纳 |
27
+ | \`ignoredFilters\` | 被忽略的筛选维度 | 非空说明该舱不支持此维度,**不要**据此宣称"已按 X 筛选" |
28
+
29
+ #### 「数据滞后」有两种,不要混为一谈
30
+
31
+ | 类型 | 看哪个字段 | 含义 | 能不能用 |
32
+ |------|-----------|------|----------|
33
+ | **统计产出滞后** | \`dataAsOf\` 远早于 \`coveredDates\` 的最后一天 | 日表还没产出(例如今天是 09-21,最新覆盖日只有 09-18) | ✅ 数字是对的,只是旧。**说明「数据截止 X」即可,不要说「数据有问题」** |
34
+ | **刷新链路滞后** | \`isStale=true\`(相对 \`lastRefreshTime\` 超 5 分钟) | 准实时刷新任务没跑 | ✅ 同样不代表数据错。两者**可以同时为真,也可以只有一个为真** |
35
+
36
+ 测试环境的刷新任务通常不常驻,\`isStale\` **恒为 \`true\` 是预期**,不是误判——
37
+ 生产有 5 分钟刷新任务时会正常跳动。
38
+
39
+ ### \`appliedFilters\` / \`ignoredFilters\` 维度对照
40
+
41
+ 两个字段列出的是**维度标识**,历史上出现过两种写法,本服务都能解码并直接给出中文:
42
+
43
+ | 可读名(现) | 单字母码(旧) | 维度 | 对应工具入参 |
44
+ |--------------|----------------|------|--------------|
45
+ | \`date\` | \`D\` | 日期范围 | \`startDate\` / \`endDate\` / \`preset\` |
46
+ | \`businessType\` | \`B\` | 业务类型 | \`businessTypes\` |
47
+ | \`merchant\` | \`M\` | 商户 | \`merchantId\` |
48
+ | \`channel\` | \`C\` | **渠道**(旧码 \`C\` 极易被误读成币种) | \`channelCodes\` |
49
+ | \`currency\` | \`Y\` | **币种**(旧码 \`Y\` 极易被误读成年份) | \`currencies\` |
50
+ | \`accountType\` | \`A\` | 账户类型 | \`accountTypes\` |
51
+ | \`realtimeOverlay\` | — | 实时覆盖(走了当日业务表而非日表) | — |
52
+
53
+ 各舱支持情况(与该舱支持的筛选入参一致):
54
+
55
+ | 舱 | 支持 | 不支持 |
56
+ |----|------|--------|
57
+ | CEO | 日期、业务类型、商户、币种 | **渠道、账户类型** |
58
+ | OPERATION | 日期、业务类型、商户、渠道、币种 | **账户类型** |
59
+ | FINANCE | 日期、业务类型、商户、币种、账户类型 | **渠道** |
60
+
61
+ 因此:不能在 CEO 舱按渠道或账户类型筛选,不能在运营舱按账户类型筛选,
62
+ 不能在财务舱按渠道筛选——传了会被静默忽略(体现在 \`ignoredFilters\`)。
63
+
64
+ ## 通用:金额与币种
65
+
66
+ 金额类字段旁都带 \`currency\`:
67
+
68
+ | \`currency\` 取值 | 含义 | 能否相加 |
69
+ |------------------|------|----------|
70
+ | 具体币种码(\`USDT\` 等) | 已用 \`currencies\` 收敛到单一币种 | ✅ 可以合计 |
71
+ | \`MIXED\` | 未收敛到单一币种 | ❌ **不可相加**(但形态有三种,见下) |
72
+ | \`null\` | 该行不是金额(笔数 / 成功率 / 商户数) | —— |
73
+
74
+ 这是**唯一**可靠的判断依据,不要靠字段名猜。要算合计就用 \`currencies\` 指定单一币种重查。
75
+
76
+ ### \`MIXED\` 只剩一种形态(2026-09-21 第九轮之后)
77
+
78
+ 接口侧已把**全部**金额路由改成「按币种拆行 + 带 \`currency\`」(排行类、渠道成本、
79
+ 失败原因金额、财务分布、对账分析均同此处理)。横扫 22 条数据路由实测:
80
+ **行级再无 \`MIXED\`,只剩 \`ceo/overview\` 的顶层 \`currency=MIXED\`**,
81
+ 而它恰恰是"已拆分"形态——不是错值:
82
+
83
+ | 形态 | 出现位置 | 实际内容 | 怎么办 |
84
+ |------|----------|----------|--------|
85
+ | **已拆分** | \`ceo/overview\` | 金额标量(\`gmv\`/\`revenue\`/\`grossProfit\`/\`aum\`)为 **null**,明细在 \`amountsByCurrency\` | ✅ 数值是对的,读分币种那一栏;**不要说「数据缺失」** |
86
+ | **行级币种** | 其余所有金额路由 | 每行自带 \`currency\` 币种码 | ✅ 直接按币种读;跨币种不可相加 |
87
+ | **笔数类** | \`TransactionCount\` 等计数指标 | 两币种笔数相加=总笔数 | ✅ 相加本身正确,**不需要警告** |
88
+
89
+ > 历史上还有过两种形态——财务分布类是跨币种加总值(🚨 曾是错值)、\`share\` 是组内占比,
90
+ > 第九轮已一并消失。旧文案仍留在检测逻辑里当兜底:**哪天行里又没了 \`currency\`,提示会自己回来**。
91
+
92
+ \`amountsByCurrency\` 是**数组**,每项形如
93
+ \`{currency, value, secondaryValue, tertiaryValue, aum}\`,映射为:
94
+ \`value\`=GMV、\`secondaryValue\`=收入、\`tertiaryValue\`=毛利、\`aum\`=管理资产。
95
+
96
+ ### 响应已按币种拆行
97
+
98
+ 金额类路由未指定 \`currencies\` 时会返回**多币种明细行**,
99
+ 同一主体(商户 / 渠道 / 失败原因)会在不同币种下**各占一行**,\`rank\` 在币种内重新编号。
100
+ 实测 \`ceo/top-merchants\` 不筛选 = 6 行(3 商户 × 2 币种),\`rank\` 为 USD 1,2,3 / USDT 1,2,3。
101
+ **这不是重复数据**,输出时会被明确标注;要单一币种合计请传 \`currencies\`。
102
+
103
+ ### \`filters\` 的币种清单
104
+
105
+ 第九轮已修:清单改为「字典配置 ∪ 日表 DISTINCT」,三个舱均返回 **11 个码**(含此前缺失的 EUR)。
106
+ 「按清单逐个币种查再相加」现在可以还原不筛选的总额——
107
+ \`ceo/top-merchants\` 实测 不筛选 752707.20 = USD 376353.60 + USDT 376353.60,正好相等。
108
+ 这一结论由 e2e 的覆盖度探针持续盯住,一旦出现新的清单外币种,差额会重新打出来。
109
+
110
+ ### \`share\` 已回到全局占比(2026-09-21 第九轮)
111
+
112
+ \`share\` 现在按**本次响应的全部金额项**归一:\`ceo/business-breakdown\` items=7 时
113
+ 各项 share 之和 = **1.0**,\`finance/*-distribution\`、\`finance/reconciliation-analysis\`、
114
+ \`operation/fail-reason-breakdown\` 同样。按 share 排序与按 \`value\` 排序结果一致
115
+ (实测同为 Exchange)。
116
+
117
+ > 第七轮时它曾变成「组内占比」(USD 组之和=1、USDT 组之和=1、全部相加=2),
118
+ > 第九轮已改回。**如果哪天又出现各组之和都等于 1 的情况,不要按 share 排名。**
119
+
120
+ 本 MCP 的占比图历来不用服务端的 \`share\`,而是**按 \`value\` 本地归一**,两种形态都不受影响:
121
+
122
+ 本 MCP 的图已经按此处理,不需要你在调用时额外规避:
123
+ - \`ceo.business_share*\`(环形):多币种时只画主币种并把币种标在圆心;
124
+ - \`ceo.business_gmv\` 等(柱状):按币种拆成**分组柱**;
125
+ - \`ceo.business_share_orders\`(笔数):跨币种合并——笔数与币种无关,可以相加。
126
+
127
+ ## CEO 舱
128
+ | 字段 | 中文 | 口径 |
129
+ |------|------|------|
130
+ | \`gmv\` | 成交总额 | **成功订单金额**口径;退款单独统计,不冲减 GMV |
131
+ | \`transactionCount\` | 成功交易笔数 | 仅成功状态 |
132
+ | \`revenue\` | 平台收入 | |
133
+ | \`grossProfit\` | 平台毛利润 | |
134
+ | \`activeMerchantCount\` | 活跃商户数 | |
135
+ | \`newMerchantCount\` | 新增商户数 | |
136
+ | \`successRate\` | 整体成功率 | 小数形式,如 0.9832 = 98.32% |
137
+ | \`aum\` | 平台管理资产 | |
138
+
139
+ ## 运营舱
140
+ | 字段 | 中文 | 口径 |
141
+ |------|------|------|
142
+ | \`orderCount\` | 订单总数 | 含全部终态 |
143
+ | \`successOrderCount\` / \`failOrderCount\` | 成功 / 失败订单数 | |
144
+ | \`exceptionOrderCount\` | 异常订单数 | 失败原因走 \`fail_reason\` 细分 |
145
+ | \`processingOrderCount\` | 处理中订单数 | |
146
+ | \`refundOrderCount\` | 退款订单数 | |
147
+ | \`averageProcessingSeconds\` | 平均处理耗时 | **单位是秒** |
148
+ | \`successRate\` | **成功率小数** | 与 \`share\` 已拆开,不要再用 \`share\` 当成功率 |
149
+ | platform-metrics 各字段 | 商户生命周期(新增/激活/活跃/沉默/流失)、VA 与 U 卡账户、渠道活跃/异常 | 宽表,含 \`latest\` 快照与 \`points\` 序列 |
150
+
151
+ ## 财务舱
152
+ | 字段 | 中文 | 口径 |
153
+ |------|------|------|
154
+ | \`totalAsset\` | 平台总资产 | |
155
+ | \`inAmount\` / \`outAmount\` | 资金流入 / 流出 | 摘要值为末日数据 |
156
+ | \`unsettledAmount\` | 待结算金额 | |
157
+ | \`unreconciledAmount\` | 待对账金额 | |
158
+ | \`exceptionAmount\` | 对账异常金额 | |
159
+ | \`frozenAmount\` | 冻结资金 | |
160
+ | \`availableAmount\` | 可用余额 | |
161
+
162
+ ## 金额单位
163
+ 所有金额均为**原币种原值**,未经汇率折算;每个数值旁都有 \`currency\` 字段标明币种。
164
+
165
+ \`MIXED\` 只剩一种形态(详见上文「金额与币种」):**行级**都已按币种拆开,
166
+ 只有 \`ceo/overview\` 顶层仍是 \`MIXED\`——它是"已拆分"而非错值。
167
+ \`ceo/overview\` 见到金额为 \`null\` 不是数据缺失,是接口不再给跨币种加总值,
168
+ 请读 \`amountsByCurrency\`(数组,每项含 \`currency\` 与分指标金额)。这是最常见的口径错误,
169
+ 务必向用户提示。
170
+ `;
171
+ export const LIMITS_AND_PRACTICES = `# 使用边界与最佳实践
172
+
173
+ ## 硬约束
174
+ - **只读**:本 MCP 不提供任何写操作。统计产出的重建、封板与作业调度均不在能力范围内。
175
+ - **日期跨度 ≤ 90 天**:超出请先分段查询再自行汇总。
176
+ - **报表时区 ${REPORT_TIME_ZONE}**:相对日期按此折算,与宿主机器时区无关。
177
+ - **鉴权**:仅平台 HMAC 凭证(\`X-Platform-*\`);商户 \`X-Api-Key\` 调这些路由**必然失败**,不要尝试。
178
+
179
+ ## 回答经营问题时的纪律
180
+ 1. 先看 \`meta.isFinal\`:未封板数据要标注"临时值,可能修正"。**查询窗口含今天时它必然是 \`false\`**,
181
+ 这是当日未封板的正常表现,不是故障;要看终值就查纯历史窗口。
182
+ 2. 跨币种不可直接相加:看 \`currency\`——只有它是具体币种码(如 \`USDT\`)才能合计。
183
+ 现在**所有金额路由的每一行都带 \`currency\`**(2026-09-21 第九轮起),不必再猜:
184
+ - \`ceo/overview\` 顶层 \`MIXED\` 时金额标量为 \`null\`、明细在 \`amountsByCurrency\`
185
+ ——**不要说「数据缺失」**,按币种分别引用;
186
+ - 其余路由同一主体会**按币种各占一行**(\`rank\` 币种内编号),不是重复数据,跨币种不可相加;
187
+ - \`TransactionCount\` 这类计数指标相加是对的,无需警告。
188
+ 3. \`filters\` 的币种清单现在是「字典配置 ∪ 日表 DISTINCT」,已覆盖实际币种(含 EUR),
189
+ 「按清单全查一遍」可以还原合计;该结论由 e2e 覆盖度探针持续盯住。
190
+ 3. \`gmv\` 与 \`transactionCount\` 同为**成功订单**口径,但一个是金额、一个是笔数,不可互推;退款不计入 GMV。
191
+ 4. 趋势默认为 GMV;要看别的指标请在题面说清。CEO 趋势现支持
192
+ GMV / Revenue / Profit / AUM / TransactionCount / SuccessRate / ActiveMerchantCount / NewMerchantCount。
193
+ 5. 数据为空时,如实说明"该区间无统计产物",**不要**用 0 或其它来源数字填补。
194
+ 6. **缺失 ≠ 零**:无统计产出的日期**不会再补 0**,而是整日不出现,并在 \`meta.missingDates\` 列出。
195
+ 看到曲线断了一截,要说"那几天无统计产出",**不要**说"跌到 0 了";反过来,
196
+ 出现在数据里的 \`0\` 才是真的零。
197
+ 7. \`successRate\` 才是成功率;\`share\` 是占比/构成比(历史上成功率曾被塞进 \`share\`,
198
+ 两者现已拆开,不要再用 \`share\` 当成功率)。
199
+ 8. 商户列表一次只返回前 10 条,\`totalMerchants\` 才是总数。要找特定商户必须传
200
+ \`keyword\` 搜索——**不能**因为前 10 条里没有就断定该商户不存在。
201
+
202
+ ## 可用日期预设
203
+ ${DATE_PRESETS.map((p) => `- \`${p}\``).join("\n")}
204
+
205
+ 也可以显式传 \`startDate\` / \`endDate\`(YYYY-MM-DD)。
206
+ `;
207
+ export function endpointTableMarkdown() {
208
+ const rows = ENDPOINTS.map((e) => ({
209
+ 路径: `${DASHBOARD_ROUTE_PREFIX}${e.path}`,
210
+ 舱: e.cabin,
211
+ 类别: e.kind,
212
+ 说明: e.summary,
213
+ }));
214
+ const headers = ["路径", "舱", "类别", "说明"];
215
+ const head = `| ${headers.join(" | ")} |`;
216
+ const sep = `| ${headers.map(() => "---").join(" | ")} |`;
217
+ const body = rows.map((r) => `| ${headers.map((h) => String(r[h])).join(" | ")} |`);
218
+ return [head, sep, ...body].join("\n");
219
+ }
220
+ export const ENDPOINT_REFERENCE_HEADER = `# 平台驾驶舱路由全表(${ENDPOINTS.length} 个,全部只读)
221
+
222
+ 以下路径均相对 \`POST\`,前缀为 \`${DASHBOARD_ROUTE_PREFIX}\`。
223
+
224
+ `;
225
+ /**
226
+ * 图表与报表模板清单。
227
+ *
228
+ * 单独做成 Resource 而不是塞进 tool description:图表有 20 多张,
229
+ * 全写进 description 会长期占用上下文,而 Agent 只在选图那一刻需要它。
230
+ */
231
+ export function chartCatalogMarkdown() {
232
+ const byCabin = {};
233
+ for (const spec of CHART_SPECS) {
234
+ (byCabin[spec.cabin] ??= []).push(spec);
235
+ }
236
+ const sections = [
237
+ `# 可用图表(${CHART_SPECS.length} 张)与报表模板(${REPORT_TEMPLATES.length} 套)`,
238
+ "",
239
+ "`render_chart` 的 `chart` 参数只能取下表 id——口径已固化,不要自己挑字段画图。",
240
+ "",
241
+ ];
242
+ const cabinTitles = {
243
+ ceo: "CEO 舱",
244
+ operation: "运营舱",
245
+ finance: "财务舱",
246
+ };
247
+ for (const [cabin, specs] of Object.entries(byCabin)) {
248
+ sections.push(`## ${cabinTitles[cabin] ?? cabin}`, "");
249
+ sections.push("| id | 图名 | 类型 | 用途与口径 | 数据来源 |");
250
+ sections.push("|----|------|------|------------|----------|");
251
+ for (const s of specs) {
252
+ sections.push(`| \`${s.id}\` | ${s.title} | ${s.kind} | ${s.purpose} | \`${s.endpointId}\` |`);
253
+ }
254
+ sections.push("");
255
+ }
256
+ sections.push("## 报表模板", "");
257
+ sections.push("| id | 报告 | 默认窗口 | 图表数 | 说明 |");
258
+ sections.push("|----|------|----------|--------|------|");
259
+ for (const t of REPORT_TEMPLATES) {
260
+ sections.push(`| \`${t.id}\` | ${t.title} | ${t.defaultPreset} | ${t.charts.length} | ${t.description} |`);
261
+ }
262
+ sections.push("", "## 使用要点", "", "- 图表产物是**自包含 SVG** 文件,落盘在 `TIMARAI_OUTPUT_DIR`(默认仓库根 `out/`),可直接嵌网页/PPT/Word。", "- 报告是**单文件 HTML**,图表内联、A4 可打印,Ctrl+P 导出 PDF。", "- 报告顶部会自动声明数据截止时间与封板状态;`isFinal=false` 会挂红条,切勿当作对外口径。", "- `narrative` 传你的结论段落——工具只负责数据与图形。");
263
+ return sections.join("\n");
264
+ }
265
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}