{"id":"2f202e3c-6c6e-4f02-9c65-80a10cdded89","entityType":"agent","slug":"clawhub-maojiebc-guanyuan-majia","name":"观远 BI · 马甲实战版","canonicalUrl":"https://www.xpersona.co/agent/clawhub-maojiebc-guanyuan-majia","canonicalPath":"/agent/clawhub-maojiebc-guanyuan-majia","generatedAt":"2026-10-10T08:59:29.675Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-09T07:52:54.293Z","emptyReason":null},"description":"观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。 Skill: 观远 BI · 马甲实战版 Owner: maojiebc Summary: 观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。 Tags: agent-skill:3.2.3, agen","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 3.5K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s171vv4g1xczzsxtgd1wg0626x83khts:guanyuan-majia","sourceUrl":"https://clawhub.ai/maojiebc/guanyuan-majia","homepage":"https://clawhub.ai/maojiebc/skills/guanyuan-majia","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/maojiebc/guanyuan-majia","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/maojiebc/skills/guanyuan-majia","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":71,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、Super"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T07:52:54.293Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T07:52:54.293Z","emptyReason":null},"stars":null,"forks":null,"downloads":3501,"packageName":null,"latestVersion":"3.2.3","tractionLabel":"3.5K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T07:52:54.293Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T07:52:54.293Z","lastCrawledAt":"2026-10-09T07:52:54.293Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T07:52:54.293Z","lastVerifiedAt":null,"highlights":[{"version":"3.2.3","createdAt":"2026-09-28T02:14:33.590Z","changelog":"对齐 guanskill 0.1.41 / guancli 1.0.63：单指标请求计划、指标创建恢复与编辑保护、ETL 输入类型修复和页面初始化保护。","fileCount":90,"zipByteSize":1185738},{"version":"3.2.1","createdAt":"2026-09-20T02:54:02.147Z","changelog":"对齐 guancli 1.0.62 与 guanskill 0.1.39，补齐批量失败判定、字段校验、下游检查及工作流调度兼容。","fileCount":87,"zipByteSize":1166772},{"version":"3.1.11","createdAt":"2026-09-14T03:51:46.403Z","changelog":"对齐官方 guanskill 0.1.35：指标批量查询与原始数值、批量上下线状态、页面草稿重置、目录与追加确认；刷新官方 Skill，修正旧命令和表单绕行。","fileCount":43,"zipByteSize":942997},{"version":"3.1.10","createdAt":"2026-08-25T04:07:00.449Z","changelog":"对齐观远 CLI 1.0.53：OIDC、SuperApp 整包下载、多行 SQL；页面/目录原地管理；计算字段期望态协调。","fileCount":43,"zipByteSize":1734201},{"version":"3.1.9","createdAt":"2026-08-19T13:26:44.139Z","changelog":"官方全家桶 07-24 以来 9 个聚合包一次性对齐：guanskill 0.1.17→0.1.26（guancli 1.0.51 insight / guanvis 0.1.38 live / guanetl 0.1.27 / guanwf 0.1.826 / guands 0.1.26 / guanmetric 0.1.8 指标树+加速）","fileCount":43,"zipByteSize":2213246},{"version":"3.1.8","createdAt":"2026-07-24T03:07:30.080Z","changelog":"官方全家桶 07-15 + 07-24 两批次一次性对齐：guanskill 0.1.12→0.1.17，六子包全部对齐最新（guancli 1.0.43 / guanvis 0.1.33 / guanetl 0.1.21 / guanwf 0.1.822 含 --confirm 破坏性变更 / guands 0.1.23 / guanmetric 0.1.3）；架构图重渲；护城河零删减。","fileCount":41,"zipByteSize":254353},{"version":"3.1.6","createdAt":"2026-07-10T09:51:07.034Z","changelog":"v3.1.6 官方全家桶 07-08/07-10 对齐 · 家族 5→6 员：guanmetric 0.1.1 指标写首次入桶（指标建/改/删+主题/目录+公共维度+Excel 标准化）；guancli 1.0.39 etl get 有效调度状态 / guanvis 0.1.30 checkout 线上页回写 / guanetl 0.1.19 move+run --run-upstream / guands 0.1.19 追加清理+schema 同步 / guanwf 0.1.7 依赖编排。路由表新增 guanmetric 行，架构图重画 6 件套。","fileCount":342,"zipByteSize":1340884},{"version":"3.1.5","createdAt":"2026-07-01T06:41:05.702Z","changelog":"v3.1.5 官方全家桶 07-01 对齐：guanskill 0.1.10（guancli 1.0.38 新增 PAT 登录 / guanvis 0.1.29 筛选器级联联动+自定义图表 dataView 联动+页面筛选器过滤自定义图表+表格卡只配维度+比较卡 / guanetl 0.1.18 目录类型诊断 / guands 0.1.18 import 按列类型+replace-data 编码分隔符）。护城河零删减，Part C-12 加 0.1.29 官方 selector 联动并存注记。","fileCount":342,"zipByteSize":1336048}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171vv4g1xczzsxtgd1wg0626x83khts:guanyuan-majia","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T08:59:29.671Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-maojiebc-guanyuan-majia/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-09T07:52:54.293Z","emptyReason":null},"readme":"Skill: 观远 BI · 马甲实战版\n\nOwner: maojiebc\n\nSummary: 观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。\n\nTags: agent-skill:3.2.3, agent-skills:3.2.3, ai-native-ads:3.2.3, bi:3.2.3, business-intelligence:3.2.3, chinese:3.2.3, claude-code:3.2.3, custom-chart:3.2.3, data-analysis:3.2.3, design-baseline:3.2.3, etl:3.2.3, guandata:3.2.3, guandata-bi:3.2.3, guanmetric:3.2.3, html-dashboard:3.2.3, latest:3.2.3, methodology:3.2.3, metric-query:3.2.3, mobile-adaptation:3.2.3, phonelayout:3.2.3, restaurant-bi-formulas:3.2.3, rfm-analysis:3.2.3, smartetl:3.2.3, superapp:3.2.3, v7-publish-pipeline:3.2.3\n\nVersion history:\n\nv3.2.3 | 2026-09-28T02:14:33.590Z | user\n\n对齐 guanskill 0.1.41 / guancli 1.0.63：单指标请求计划、指标创建恢复与编辑保护、ETL 输入类型修复和页面初始化保护。\n\nv3.2.1 | 2026-09-20T02:54:02.147Z | user\n\n对齐 guancli 1.0.62 与 guanskill 0.1.39，补齐批量失败判定、字段校验、下游检查及工作流调度兼容。\n\nv3.1.11 | 2026-09-14T03:51:46.403Z | user\n\n对齐官方 guanskill 0.1.35：指标批量查询与原始数值、批量上下线状态、页面草稿重置、目录与追加确认；刷新官方 Skill，修正旧命令和表单绕行。\n\nv3.1.10 | 2026-08-25T04:07:00.449Z | user\n\n对齐观远 CLI 1.0.53：OIDC、SuperApp 整包下载、多行 SQL；页面/目录原地管理；计算字段期望态协调。\n\nv3.1.9 | 2026-08-19T13:26:44.139Z | user\n\n官方全家桶 07-24 以来 9 个聚合包一次性对齐：guanskill 0.1.17→0.1.26（guancli 1.0.51 insight / guanvis 0.1.38 live / guanetl 0.1.27 / guanwf 0.1.826 / guands 0.1.26 / guanmetric 0.1.8 指标树+加速）\n\nv3.1.8 | 2026-07-24T03:07:30.080Z | user\n\n官方全家桶 07-15 + 07-24 两批次一次性对齐：guanskill 0.1.12→0.1.17，六子包全部对齐最新（guancli 1.0.43 / guanvis 0.1.33 / guanetl 0.1.21 / guanwf 0.1.822 含 --confirm 破坏性变更 / guands 0.1.23 / guanmetric 0.1.3）；架构图重渲；护城河零删减。\n\nv3.1.6 | 2026-07-10T09:51:07.034Z | user\n\nv3.1.6 官方全家桶 07-08/07-10 对齐 · 家族 5→6 员：guanmetric 0.1.1 指标写首次入桶（指标建/改/删+主题/目录+公共维度+Excel 标准化）；guancli 1.0.39 etl get 有效调度状态 / guanvis 0.1.30 checkout 线上页回写 / guanetl 0.1.19 move+run --run-upstream / guands 0.1.19 追加清理+schema 同步 / guanwf 0.1.7 依赖编排。路由表新增 guanmetric 行，架构图重画 6 件套。\n\nv3.1.5 | 2026-07-01T06:41:05.702Z | user\n\nv3.1.5 官方全家桶 07-01 对齐：guanskill 0.1.10（guancli 1.0.38 新增 PAT 登录 / guanvis 0.1.29 筛选器级联联动+自定义图表 dataView 联动+页面筛选器过滤自定义图表+表格卡只配维度+比较卡 / guanetl 0.1.18 目录类型诊断 / guands 0.1.18 import 按列类型+replace-data 编码分隔符）。护城河零删减，Part C-12 加 0.1.29 官方 selector 联动并存注记。\n\nv3.1.4 | 2026-06-26T04:06:09.726Z | user\n\nv3.1.4 官方全家桶 06-24 对齐：guanskill 0.1.8（guancli 1.0.36 metric 加指标主题/目录创建+SuperApp app create+页面搜索增强 / guanvis 0.1.28 修复自定义图表重复数据视图卡片 / guanetl·guands·guanwf 仅 install-skill WorkBuddy 兼容）。护城河零删减。\n\nv3.1.3 | 2026-06-22T03:59:11.396Z | user\n\nv3.1.3 官方全家桶 06-17 对齐：guanskill 0.1.7（guancli 1.0.35 login status 服务端校验+字段误用提示 / guanvis 0.1.27 发布探测放宽 / guanetl 0.1.16 save --dry-run+run 上游失败态+preview LEFT JOIN 全空告警 / guands 0.1.16 dataset list 目录搜索 / guanwf 0.1.5 不变）+ 滚入 rank9 去冗余，护城河零删减\n\nv3.1.2 | 2026-06-17T14:19:03.739Z | user\n\nv3.1.2 评审团驱动质量迭代：删除顺序矛盾 workshop513 实测定案（ds-first，修正 line219/Part D 写反与误记 6001）、page?force=true 纳入 B-7.0 安全闸、README/AGENTS/marketplace 元数据 drift 修正、References 行数回填、description 瘦身、餐饮锚点死链修。纯 correctness+safety+hygiene，护城河零删减。\n\nv3.1.1 | 2026-06-16T16:55:04.824Z | user\n\nv3.1.1 官方全家桶 06-15 对齐：guanskill 0.1.6（guancli 1.0.34 metric by-dataset / guanvis 0.1.26 / guanetl 0.1.15 / guanwf 0.1.5 Python 节点 DSL / guands 0.1.15 dataset update-fields）。路由表能力刷新 + Part B 补 0.1.15 note + SOP Step1 通用化。\n\nv3.1.0 | 2026-06-11T02:31:30.628Z | user\n\nv3.1.0 HTML 看板视觉设计底线落地：吸收 design-taste-skills（MIT）新建 part-c-design-baseline.md（模块首屏=数据判断 / KPI 口径 / 图表真实性禁假图表 / token 硬上限 / 反 AI 味红线表命中即重做）；C-12 验收四层→五层（guanvis screenshot 视觉验收）；模板 html_base.css 按底线校准（KPI 28px + tabular-nums + 行高 38px + 状态样式族）。覆盖 C-12 / Part D customChart / Part E SuperApp 三场景。\n\nv3.0.5 | 2026-06-09T05:31:50.465Z | user\n\nv3.0.5 官方全家桶 06-09 版本对齐：guancli 1.0.33（ds search --id 修复）、guanvis 0.1.24（新增 AreaTitle + CardGroup 布局组件）、guanetl 0.1.14（移除 delete 命令 + 修复 save 绑定输出 bug）。路由表 + B-0.5 + 清理坑段落同步更新。\n\nv3.0.4 | 2026-06-07T06:01:45.613Z | user\n\nv3.0.4 新增 B-0.5：guanetl edit 失效时改现有 ETL 的实测绕过（workshop513 一次性 ETL 全链路实测、净零改动）。实测三道墙：edit 逆向出空 etl.go / 手写重建撞 0.1.13 新增的输出绑定 guard（DSL 表达不出输出 dsId）/ save 合并对身份字段 base 优先（改名 3/3 被覆盖）+ 输出 dsId churn。实战路径：纯改名走 guands rename/alias、改逻辑走不可变重建、高级逃生手工 _exported.json 保留 dataSource.dsId；BI API 是 cookie 认证（token 直 curl 401）、delete 先删 ETL 再删数据集。修正旧 callout 的 save 清空风险措辞（0.1.13 guard 会拦下）。给观远的报告加深度复测段。无功能 / 无 Part 结构改动。\n\nv3.0.3 | 2026-06-07T05:28:09.372Z | user\n\nv3.0.3 官方全家桶 7→5 + 06-04 版本对齐：guanexport + guanadmin 退出全家桶（从 guanskill 聚合包移除、npm 下架）→ 官方现 5 件。版本对齐 guancli 1.0.32 / guanvis 0.1.23 / guanetl 0.1.13 / guands 0.1.14（guanwf 0.1.4 不变）。新能力入路由：guancli metric 从只读转可写、guanvis 指标卡片构建 + publish 覆盖前自动备份、guands dataset alias 改字段展示名。路由表 + 架构图 7→5 对齐。guanetl edit round-trip bug 在 0.1.13 复测仍复现（提交观远的报告已更新）。无功能 / 无 Part 结构改动。\n\nv3.0.2 | 2026-06-04T16:23:13.701Z | user\n\nv3.0.2 workshop513 实盘实测沉淀（无功能改动）：在真实 BI 8.2.1-hf6 上把官方全家桶 7 个 skill 读写全跑通，验证 v3 路由全部正确（guancli 查数 / guanvis 建卡发布截图 / guands 数据集写 / guanetl 新建均通过）。沉淀 2 条硬边界：Part B —— guanetl edit 逆向 5/5 全失败（含 guanetl 自己建的，空 etl.go + 静默 + 紧接 save 有清空线上 ETL 风险）→ 改现有 ETL 走 Part B guancli fetch；Part D —— 删 guanvis-published 页面唯一可行 DELETE /api/page/<id>?force=true、删 ETL 连带删输出集（先 ETL 后 ds）。guanetl edit bug 最小复现已提交观远官方。\n\nv3.0.1 | 2026-06-04T13:58:29.428Z | user\n\nv3.0.1 registry 渲染补丁（无功能改动）：README 架构图从相对路径 ./docs/architecture.svg 改绝对 raw URL + 新增 docs/architecture.png —— 相对路径只在 GitHub 仓库页渲染，ClawHub/npm 包页拿不到图（首图空白），换绝对 PNG（2880×1840，CJK 正确）后 GitHub/ClawHub/npm 三处都显示。清掉 references 目录树 (V2.1.x) 历史标注；svg/png/badge/H1/version 对齐 v3.0.1；本次重发把全部 tag 版本钉刷齐到 3.0.1。\n\nv3.0.0 | 2026-06-04T13:35:09.213Z | user\n\nv3.0.0 重定位为「官方全家桶之上的实战增益层」：观远官方全家桶 2026-06-03 公网化后，退役 2789 行自造客户端 guandata.py + 删 ~1600 行死代码 + 删 4 个镜像/过时 references（约 -5500 行）。标准查数/建卡/ETL/数据集 CRUD 路由官方（guancli/guanvis/guanetl/guanwf/guands/guanadmin），本 skill 专攻官方够不着的硬骨头：Part B 治理判断+10 类引擎报错+B-17、Part C/C-12 自定义图表注入+descriptor patch、Part D v7 状态机绕过+phoneLayout、Part E SuperApp 反向工程、AI-native ADS 方法论、餐饮 BI 公式库。前置依赖改 @guandata/guanskill，认证走 guancli auth login，品牌「马甲实战版」。Breaking: guandata.py 退役。\n\nv2.1.14 | 2026-05-29T07:57:16.010Z | user\n\nguancli 命令面对齐 1.0.29：新增 ds execute-sql（数据集只读 SQL + 跨集 JOIN）/ metric project（指标主题缩范围）/ server-version（BI 版本查询）/ card preview --dynamic-field+--dynamic-param/-o/--columns；依赖 ^1.0.24 → ^1.0.29。纯命令面对齐 + 文档补充，无 Part 结构变化、无代码改动。\n\nv2.1.13 | 2026-05-22T10:31:54.467Z | user\n\nAI-native ADS 设计方法论（~340 行，9 个 §小节，哲学层文档）— 沉淀自用户根判断「光数据治理没用，必须按适配 AI 的方式数据架构重搭一遍」: 现象层 demo 顺 vs 历史包袱 / 7 条字段约束（中文枚举+推荐预算好+复合拼好+TIMESTAMP+强约束+数值算好+权限冗余）/ ODS+DWD 不动 ADS 重建 / 客户预算分配 30%+30%+40% / 反模式 8 条\n\nv2.1.12 | 2026-05-22T10:08:59.982Z | user\n\nPart E SuperApp 开放应用开发流水线（~620 行，18 个 §小节）— guancli app publish 不读 .env / form 建表反向工程 POST /survey-engine/api/form/add / LLM 中转 ILLEGAL_JSON_RES 三路径解析 + 客户端模拟流式 / 同源 fetch credentials 绕过脚手架 get unwrap\n\nv2.1.11 | 2026-05-22T08:07:42.004Z | user\n\nv2.1.11 — docs-only patch：首次落地 ota-skill v0.14.0 Step 5.5 HARD GATE。版本记录段从 11 条截断到 3 条 + README 架构图 alt 同步到 v2.1.11 + 所有 version 字符串对齐。零代码 / 零 references 改动。\n\nv2.1.10 | 2026-05-22T07:44:39.599Z | user\n\nv2.1.10 — §16 移动端 phoneLayout 完整指南 + v7 草稿 save API 8 端点全 stub 实测 + scripts/inject_phone_layout.py 工具脚本（沉淀自给 9 个 demo 看板做移动端适配的 30+ 轮 API 探索）\n\nv2.1.7 | 2026-05-21T03:35:52.396Z | user\n\nv2.1.7 — 路由/触发层强化（docs-only）。SKILL.md frontmatter description 重写：加入 V2.1.6 Part D（v7 BI / 60004 草稿 / guanvis-skill / CSV 三态 / Spark CTE 中文别名 / 1012 同名文件）和 V2.1.5 餐饮库（复购率 / 客单价 / RFM / DWD 宽表 / 财务双源对账 / AC / ADS / Comp）触发关键词。新增 Part D stub section 对齐 Part A/B/C/C-12 可见度。修三处 V2.1.6 残留版本错位（主标题 V2.1.5→V2.1.7、openclaw npm 约束 ^1.0.21→^1.0.24、三件套表 majia-guanyuan 行 2.1.5→2.1.7）。零 references / templates / 命令面改动。\n\nv2.1.5 | 2026-05-18T09:42:42.591Z | user\n\nv2.1.5 — 新增 references/restaurant-bi-formulas/：餐饮连锁 BI 公式实战库（10 markdown / 2881 行 / 全脱敏）。蒸馏自两段连续的餐饮 BI 分析师履职 + 39 个生产 ETL：① 公式手册 7 章 60+ SQL（日期时间 / 顾客会员 / 营收 KPI / 渠道门店 / 券折扣 / SQL 工具 / 数据质量）+ RFM 8 类×营销策略 + R 阈值多档分级；② 6 大 ETL 工程范式（10-CTE DWD 宽表 / 轻节点重 SQL vs 重节点轻 SQL / 财务双源对账 / POS 归一化 / 会员生命周期多输出 / Cohort 日期×门店网格）；③ 39 V1 生产 ETL 索引（按 11 业务域 + 复用决策表）。SKILL.md 主路由新增餐饮业务公式入口。零 breaking change，纯 docs 增量。\n\nv2.1.4 | 2026-05-15T06:14:46.501Z | user\n\nv2.1.4 — 命令面对齐 @guandata/guancli@1.0.21：metric query 泛化查询（同比/累计/最近 N 天/占比/Top N）+ card preview -f excel 导出 + --limit 默认抬到 10000 + 1.0.21 错误输出 fix。零 breaking。详见 GitHub release。\n\nv2.1.3 | 2026-05-14T03:32:56.568Z | user\n\nv2.1.3 — docs-only patch. Refreshed docs/architecture.svg (三件套生态条带 + Part C-12 HTML 应用看板 NEW 高亮 + 数字校准) + 新增 docs/architecture.png 2880x1840 @2x DPI 渲染产物. package.json#files 把 docs/ 也补进 npm tarball.\n\nv2.1.2 | 2026-05-14T02:55:23.710Z | user\n\nV2.1.2 hotfix: package.json#files 字段补上 templates/ — 弥补 V2.1.1 的 npm tarball 缺模板包问题。零内容变更，npm 用户建议直接跳过 2.1.1 升 2.1.2。其他路径（GitHub/ClawHub/gh skill）不受影响。\n\nv2.1.1 | 2026-05-14T02:48:27.554Z | user\n\nV2.1.1: Part C-12 HTML 应用化看板生成 + selector descriptor patch + guancli card preview 命令面修正 (patch 版本，无 API 破坏)\n\nv2.1.0 | 2026-05-13T09:25:06.516Z | user\n\nV2.1.0 — guanvis-skill 内网 Nexus 路由 + 通用安装手册 (xattr -dr com.apple.quarantine 关键步骤)。Part A 标准建卡优先用 guanvis-skill JS DSL；与官方 skill 共存升级为三件套分工表 (guancli / guanvis-skill / majia-guanyuan)。详见 GitHub release v2.1.0。\n\nv2.0.1 | 2026-05-12T14:37:11.864Z | user\n\ndisplayName 统一为中文营销名（slug guanyuan-majia 因 CLI rename bug 保留；URL/npx/gh skill install 走 majia-guanyuan）\n\nv2.0.0 | 2026-05-12T14:06:07.653Z | user\n\nV2.0.0 — Major version bump: skill renamed guanyuan-majia → majia-guanyuan (BREAKING); command surface aligned with @guandata/guancli@1.0.19 (chatbi / app / status / multi-env auth). Node ≥20. See CHANGELOG.md for full details.\n\nv1.8.2 | 2026-05-12T13:26:45.887Z | user\n\nV1.8.2 hotfix — sanitize 3 V1.8.0 changelog/SKILL.md entries that contained a specific BI instance identifier. Supersedes V1.8.0 and V1.8.1 (both retained the identifier). No code changes.\n\nv1.8.1 | 2026-05-12T13:24:57.858Z | user\n\nV1.8.1 hotfix — redact a customer brand name that leaked into three V1.8.0 changelog/SKILL.md entries. No code changes. Same release as V1.8.0 but with sanitized text.\n\nv1.8.0 | 2026-05-12T13:18:21.429Z | user\n\nV1.8.0 — internal skill name renamed to majia-guanyuan; aligned with @guandata/guancli@1.0.19 (chatbi/app/status/multi-env auth); Node ≥20; sibling skills matrix verified 404 on npm\n\nv1.7.3 | 2026-05-11T10:36:07.172Z | user\n\nv1.7.3: 作者区追加到 SKILL.md 末尾，ClawHub 列表页可见渠道表\n\nv1.7.2 | 2026-05-11T10:26:18.308Z | user\n\nv1.7.2: 作者模板修正 ClawHub /p/ 前缀；删除 README 重复 author section；同步落后 1.5.3 -> 1.7.2\n\nv1.5.3 | 2026-05-09T17:19:25.659Z | user\n\nV1.5.3 — Distribution trust and brand polish. Aligns SKILL.md with Agent Skills spec, restores standard MIT LICENSE, adds SECURITY.md and llms.txt, adds gh skill / skills.sh / ClawHub install paths and Super Majia author links, and reduces registry false positives without changing the Guandata API payload.\n\nv1.5.2 | 2026-05-09T15:40:09.286Z | user\n\nV1.5.2 — ClawHub publication prep. Added metadata.openclaw frontmatter (emoji/homepage/os/requires/install) per skill-format spec. Added WorkBuddy/Qoder compat badges. No behavior changes from V1.5.1.\n\nArchive index:\n\nArchive v3.2.3: 90 files, 1185738 bytes\n\nFiles: AGENTS.md (8523b), ATTRIBUTIONS.md (8584b), bin/install.js (10802b), CHANGELOG.md (143454b), config.example.json (592b), docs/architecture.png (726336b), docs/architecture.svg (18011b), examples/store-mobile-scorecard-v2/build.mjs (28019b), examples/store-mobile-scorecard-v2/etl/active_stores.sql (761b), examples/store-mobile-scorecard-v2/etl/contact_daily.sql (488b), examples/store-mobile-scorecard-v2/etl/contact_stock.sql (752b), examples/store-mobile-scorecard-v2/etl/coupon_conversion.sql (5133b), examples/store-mobile-scorecard-v2/etl/customer_status.sql (2372b), examples/store-mobile-scorecard-v2/etl/dinein_repurchase.sql (2705b), examples/store-mobile-scorecard-v2/etl/dormant_customers.sql (469b), examples/store-mobile-scorecard-v2/etl/finance_daily.sql (2195b), examples/store-mobile-scorecard-v2/etl/group_daily.sql (488b), examples/store-mobile-scorecard-v2/etl/group_stock.sql (758b), examples/store-mobile-scorecard-v2/etl/hours_daily.sql (1670b), examples/store-mobile-scorecard-v2/etl/identified_daily.sql (1079b), examples/store-mobile-scorecard-v2/etl/member_30d.sql (1083b), examples/store-mobile-scorecard-v2/etl/member_7d.sql (1081b), examples/store-mobile-scorecard-v2/etl/member_anomaly_evidence.sql (1999b), examples/store-mobile-scorecard-v2/etl/member_anomaly_orders.sql (1755b), examples/store-mobile-scorecard-v2/etl/member_comparison.sql (937b), examples/store-mobile-scorecard-v2/etl/member_daily.sql (1028b), examples/store-mobile-scorecard-v2/etl/member_month.sql (1080b), examples/store-mobile-scorecard-v2/etl/member_peer_eligibility.sql (5780b), examples/store-mobile-scorecard-v2/etl/member_peer_ranking.sql (2248b), examples/store-mobile-scorecard-v2/etl/pipeline.json (6338b), examples/store-mobile-scorecard-v2/etl/products_7d.sql (1029b), examples/store-mobile-scorecard-v2/etl/README.md (2323b), examples/store-mobile-scorecard-v2/etl/repurchase_peers.sql (2058b), examples/store-mobile-scorecard-v2/etl/revenue_peers.sql (2882b), examples/store-mobile-scorecard-v2/etl/soup_7d.sql (546b), examples/store-mobile-scorecard-v2/etl/soup_coverage.sql (1185b), examples/store-mobile-scorecard-v2/etl/store_context.sql (2405b), examples/store-mobile-scorecard-v2/etl/store_ordering.sql (2817b), examples/store-mobile-scorecard-v2/preview.png (46511b), examples/store-mobile-scorecard-v2/README.md (4384b), examples/store-mobile-scorecard-v2/scorecard.css (23344b), examples/store-mobile-scorecard-v2/scorecard.js (73071b), examples/store-mobile-scorecard-v2/store-mobile-scorecard.html (391516b), examples/store-mobile-scorecard-v2/test.cjs (5303b), examples/store-mobile-scorecard/build.mjs (21428b), examples/store-mobile-scorecard/README.md (2380b), examples/store-mobile-scorecard/scorecard.css (14033b), examples/store-mobile-scorecard/scorecard.js (46275b), examples/store-mobile-scorecard/store-mobile-scorecard.html (159783b), examples/workshop513-咖啡连锁会员运营模拟案例/README.md (626b), LICENSE (1097b), llms.txt (4117b), manifest.json (3091b), package.json (1672b), README.en.md (28022b), README.md (26414b), references/agents-rule.md (271b), references/ai-native-ads-design.md (15317b), references/coupon-order-link-diagnosis.md (2419b), references/custom-chart-playbook.md (5416b), references/etl-rewrite-original.md (7889b), references/execplan-spec.md (14482b), references/official-cli-baseline.json (351b), references/official-cli-compatibility.md (14149b), references/order-join-cardinality.md (1717b), references/part-b-errors.md (4106b), references/part-b-payload.md (6926b), references/part-b-sdk.md (2026b), references/part-b17-fullchain-rewrite.md (14566b), references/part-c-design-baseline.md (12139b), references/part-c-html-dashboard.md (22994b), references/part-c-payload-json.md (1889b), references/part-c-store-mobile-scorecard-v2.md (7609b), references/part-c-store-mobile-scorecard.md (18442b), references/part-e-superapp-pipeline.md (30860b), references/restaurant-bi-formulas/README.md (603b), references/v7-page-card-publish-pipeline.md (51782b), scripts/inject_phone_layout.py (4684b), SECURITY.md (1321b), skill-card.md (2197b)\n\nFile v3.2.3:SKILL.md\n\n---\nname: majia-guanyuan\ndescription: 观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。\nlicense: MIT\nmetadata:\n  version: \"3.2.3\"\n  author: \"超级马甲 / maojiebc\"\n  homepage: https://github.com/maojiebc/majia-guanyuan\n  openclaw:\n    emoji: \"📊\"\n    homepage: https://github.com/maojiebc/majia-guanyuan\n    os:\n      - macos\n      - linux\n    requires:\n      bins:\n        - jq\n        - bash\n    install:\n      - kind: npm\n        package: \"@guandata/guanskill\"\n        bins:\n          - guancli\n          - guanvis\n          - guanetl\n          - guanwf\n          - guands\n          - guanmetric\n---\n\n# 观远 BI · 马甲实战版（V3.2.3）\n\n> **结构说明（V1.5.0 引入 progressive disclosure）**：本文档是**路由层 + 关键规则**，详细操作手册下沉到 `references/`。每个 Part 的入口章节会指出\"何时回到 references/ 查全表\"。完整章节索引见末尾的 [📚 References 目录](#-references-目录)。\n\n## 🧭 Part 选择\n\n| 你想做 | 走 |\n|---|---|\n| 查数据、建卡、出报表、标准 ETL / 数据集 CRUD / 指标写 / 洞察问答 | **🧭 路由层** → 交给官方全家桶（`guancli` / `guanvis` / `guanetl` / `guanwf` / `guands` / `guanmetric`），见路由总表 |\n| 扫整库 ETL 治理 / 新建/修改/删除 ETL / 字段使用度审计 / 修复 ETL 报错 | **Part B：ETL 治理与写入** |\n| 把整条 SmartETL 链改写成 SQL 版 + 页面副本验收 + 差异定位 + 空快照阻塞 | **Part B-17：全链路重写方法论**（拆到 [references/part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md)） |\n| 30+ 张表批量迁移 / 跨多日工程 / 复杂重构需要项目化追踪 | **B-17.11 ExecPlan 工作法**（同上文件 §11） |\n| 自定义图表 HTML/CSS/JS 注入、固定卡片/overlay、payload_json 取数、路由清理 | **Part C：自定义图表开发与排障** |\n| 从零生成 HTML 化经营分析应用（用户说\"更高级 / 应用化 / 自定义模块 / 最完美 / 不限标准看板\"）| **Part C-12：HTML 应用化看板生成**（拆到 [references/part-c-html-dashboard.md](references/part-c-html-dashboard.md)） |\n| 手机成绩单专供ETL / 红色异常提示 / 券转化明细 / 近7天营业额排序 / 核销未匹配订单 | **V2** [实践与口径](references/part-c-store-mobile-scorecard-v2.md)、[离线示例](examples/store-mobile-scorecard-v2/README.md)、[券关联排查](references/coupon-order-link-diagnosis.md) |\n| 加盟店老板手机成绩单 / 门店移动看板 / 换店后财务空白 / GDPlugin 视图顺序错位 / 对比组家数泄露 / 要一份可离线点的移动样本 | **Part C 门店手机成绩单**（拆到 [references/part-c-store-mobile-scorecard.md](references/part-c-store-mobile-scorecard.md)，离线 HTML： [examples/store-mobile-scorecard/](examples/store-mobile-scorecard/)） |\n| **v7 BI 实例**上端到端搭多个 HTML 应用看板 / 手撸 `POST /api/page+/api/card` 被 `60004 此操作只能在草稿页面执行` 卡住 / CSV 散客 `会员ID IS NOT NULL` 算出 100% 假指标 / Spark `WITH 中文别名` 报 `PARSE_SYNTAX_ERROR` / ETL update 报 `1012 输出数据集目录中存在同名文件` | **Part D：V7 Page/Card 发布流水线 + 三态硬规则**（V2.1.6 新增，拆到 [references/v7-page-card-publish-pipeline.md](references/v7-page-card-publish-pipeline.md)） |\n| **SuperApp / 超级应用 / 开放应用**开发流水线 / `guancli app create/publish` / `--app-id` 不传变成每次新建 / 数据集异步预览 3 步 / 表单结构先走 `guands form`；旧脚手架建表兼容问题按 §6/ **BI 中转 LLM 报 NOT_JSON_RES / ILLEGAL_JSON_RES**（响应被塞在 error_message）/ `/api/llm-config/list` 返回裸数组被脚手架 unwrap 吞 / 同源 fetch credentials 不带 cookie / 客户端模拟流式打字效果 / 任务池工作台「看 + 想 + 选 + 做 + 留痕」闭环 | **Part E：SuperApp 开放应用开发流水线**（V2.1.12 新增，拆到 [references/part-e-superapp-pipeline.md](references/part-e-superapp-pipeline.md)） |\n| **客户说\"想给现有 BI 接 AI / 上 LLM\"** / \"我们 ETL 治理做了一年还没出活\" / **判断 是该治理还是该重搭** / 客户预算分配讨论 / 评估底表 schema 是否 AI-friendly / 提案\"AI-native 数据底座\" | **AI-native ADS 设计方法论**（V2.1.13 新增，**majia-guanyuan 的哲学层文档**——不是操作手册而是范式判断，拆到 [references/ai-native-ads-design.md](references/ai-native-ads-design.md)） |\n| 写餐饮业务公式（AC / ADS / 复购率 / 新老客 / 用餐时段 / 留存流失 / RFM / Comp 老店）/ 查字段口径 / 排数据质量坑 / **ETL 工程范式（DWD 宽表 / 双源对账 / 评价 pipeline）** | **餐饮 BI 公式实战库**（[majia-huiyuan/公式库](https://github.com/maojiebc/majia-huiyuan/tree/main/公式库)，V2.1.5 蒸馏自两段餐饮连锁 BI 履职 + 39 个生产 ETL，全脱敏；**2026-07-12 迁至独立仓库 majia-huiyuan**，本仓库 references/restaurant-bi-formulas/ 仅留指针） |\n| 不知道用哪个 | 看 Part B \"推荐工作流\" 章节，或直接读各 Part 章节末尾的\"实战 ID 速查\" |\n\n> **作者**：马甲（Part B/C/D/E 实证）+ 观远 CTO 张进（B-17 SmartETL 改写方法论 + Part C 自定义图表经验）+ OpenAI Codex（ExecPlan 规范）\n> **版本**：V3.2.3（2026-09-28）· **环境**：Node ≥20 · **前置**：官方全家桶 `npm i -g @guandata/guanskill && guanskill install-skill`（装齐 guancli / guanvis / guanetl / guanwf / guands / guanmetric + 各自 AI skill）· **认证**：`guancli auth login`（全家桶共用一套 profile，本 skill 不再单独要 config.json）· **作用域**：本地私有 BI 实例\n> **安装**：`git clone https://github.com/maojiebc/majia-guanyuan.git`，或 `npx github:maojiebc/majia-guanyuan install`\n> **兼容工具**：Claude Code · OpenClaw · Codex · Hermes (gbrain) · 任何支持 `SKILL.md` frontmatter 的 agent。详见 [README · 兼容性](README.md#-兼容性--compatibility) 与 [AGENTS.md](AGENTS.md)。\n>\n> 🆕 **V3.2.3**（2026-09-28）：对齐 guanskill 0.1.41 / guancli 1.0.63；单指标先检查请求计划，指标批量创建使用官方 Flow 并保留恢复状态，补充 ETL 输入类型修复和页面初始化保护。详见 [兼容说明](references/official-cli-compatibility.md)；完整历史见 [CHANGELOG.md](CHANGELOG.md)。\n\n---\n\n# 🧭 路由层：标准活交给官方全家桶\n\n> **V3.0.0 心法**：观远官方已把\"查数 / 建卡 / ETL / 数据流 / 数据源 / 截图 / 管理\"做成公网全家桶（`npm i -g @guandata/guanskill`）。本 skill **不再自造这些轮子**——标准活一律路由给官方，本 skill 专攻官方 DSL/命令覆盖不到的\"业务实战 + 引擎级踩坑\"（Part B–E + 方法论 + 公式库）。\n\n## ⚠️ 跨 Part 通用工作原则\n\n1. **所有数值计算必须跑代码** —— 禁止在思考里口算百分比、环比、除法、占比。\n2. **必须确认数据范围** —— 用户没明确日期范围时**必须追问**（\"看哪段时间？今天 / 本周 / 上月？\"），不要自己假设。\n3. **遇到意外错误立即落档** —— 把新坑写进对应章节（Part B 报错 → `references/part-b-errors.md`，Part C → `references/part-c-payload-json.md`）或 ExecPlan 的 `Surprises & Discoveries`（B-17.11）。格式：`### [YYYY-MM-DD] 标题` + 场景 / 问题（含 task error 原文、payload 片段）/ 判断。\n4. **写操作前先治理、删除前先对账** —— 见 Part B-〇 工作流 + B-7.0 删除安全闸。\n\n## 官方全家桶 ↔ 本 skill 分工总表\n\n> 前置：`npm i -g @guandata/guanskill && guanskill install-skill`（装齐 7 个命令：guanskill + 6 组件，各带 AI skill）；认证 `guancli auth login`，全家桶共用一套 profile。\n\n| skill | 版本 | 角色 | 什么需求路由给它 |\n|---|---|---|---|\n| **`guancli`** | 1.0.63 | 查询分析、表单数据、SuperApp | 查 ETL/数据集/页面/卡片/血缘、SQL、指标查询/归因、ChatBI、仪表板洞察与 Dashboard Agent；独立基础指标用 `metric batch-query`，高级计算用 `metric query`；`analyze normalize/align/calculate/topn` 处理本地结果；Form 数据 CRUD；SuperApp create/list/download/publish。指标计算显式 `--value-format raw`，按 JSON 版本与 inline/file 分支读取，批量逐项检查状态，自动处理加 `--fail-on-error`；计算兼展示用 `valueFormat: \"both\"`，计算只读 `rows`。未知筛选字段须纠正，不能删条件重跑。单条查询先以相同参数加 `--explain-requests -f json` 核对请求计划；批量查询不支持此参数。 |\n| **`guanvis`** | 0.1.50 | 建卡、页面、发布、截图 | 图表 DSL、checkout/diff/preview/pack/publish/screenshot、指标卡、custom chart、筛选器联动及 `live`；页面与目录原地管理、`page save-as` 原生副本；高级筛选器、卡片池、交叉表 `filterBy` 逐格校验；`init` 遇到已有 `schema.js` 且无 `--force` 时保留文件并跳过认证/请求。新页面先确认目标目录；覆盖前备份，覆盖后重置目标页面草稿。`preview` 默认摘要，完整输出用 `--full`；复杂自定义图表走完整工程，不用 live 基础卡片命令模拟。 |\n| **`guanetl`** | 0.1.38 | ETL 编辑与运行 | create/edit/export/lint/preview/save/run/schedule、move、mkdir-pair；`rmdir` 只删空 ETL 目录，物理删除且需 `--yes`；仍无删除 ETL 命令。新建须明确 ETL 与输出数据集各自目录；按 ETL ID 跟踪执行，已移除全局 `task`。导出/校验按数据集详情的实际类型识别输入；历史节点下划线导出修复，DSL 类型化常量兼容旧字符串；保留输出绑定、字段物化、JOIN 类型及 dry-run 影响检查。 |\n| **`guanwf`** | 0.1.836 | 工作流与数据流 | workflow.go / Python / 多节点 DAG / 参数与调度 / 实例诊断；写操作先 `--dry-run` 再 `--confirm`（兼容 `--yes`）。新增 Python 运行环境 与内存预检、按 task/output slot 绑定输出；首次 CREATE_NEW 输出须绑定并发布保存后再跑。验证只在已有草稿执行，不注册真实输出；保存后回读、运行后逐项验收输出。调度 `--failure-strategy` 已废弃且仅接受 CONTINUE，失败走向由 FAILURE / ALL 连线决定。Python 版本优先读结构化镜像字段。类型化 DSL 兼容字符串。8.2.0 节点限制与失败恢复范围仍按官方 guanwf Skill 执行。 |\n| **`guands`** | 0.1.35 | 数据源、数据集、表单结构 | connector/account/dataset/dir 管理、导入/追加/替换、刷新调度、主键与计算字段；Form create/export/update/rename/move/folder。`dataset sync-schema` 支持 GUAN_FORM 原地同步并回读字段 ID/类型/状态。新建先确认目录，append-data/replace-data 实写需 `--yes`；按数据集 ID 跟踪，已移除全局 `task`。Excel 多 Sheet 必须显式选择。数据集目录不能移动；目录删除不可恢复。 |\n| **`guanmetric`** | 0.1.19 | 指标定义与管理 | 指标建/改/删、主题/目录、公共维度、指标树、查询加速、业务字典、Excel 模板及 `--check-only` 预检；标准模板批量创建走 `flow generate/plan/apply/verify`，结果未知先 `reconcile`，不盲重建；编辑用对应类型专用命令保留取数字段；批量上下线用 `batch online/offline`，先 dry-run、按依赖顺序逐项处理。失败不回滚已成功项，blocked 先核对影响再确认；上线请求获接受后仍须回读审批/发布状态。复合指标只引用原子或复合指标；指标查数仍走 guancli。 |\n| **`guanvis screenshot`** | — | 导出 | 页面 PNG/PDF 服务端截图（彻底取代 legacy `guanexport`）|\n| ~~`guanexport` / `guanadmin`~~ | **已退出** | — | **2026-06-04 起从 `guanskill` 聚合包移除、npm 也下架**：导出全归 `guanvis screenshot`；管理员级操作（dynamicCode / adminToken / svc SQL）已不在公开全家桶，需另装 standalone 或走 BI UI |\n| **`majia-guanyuan`**（本 skill） | **3.2.3** | 业务实战 + 引擎级踩坑 + 方法论 | **Part B** ETL 整库治理判断 + 10 类引擎报错 + 双源字段审计 + B-17 全链路重写/ExecPlan · **Part C** 既有页自定义图表 HTML/JS 注入排障 + 固定卡/overlay · **Part C-12** HTML 应用化看板 + descriptor patch 联 dataView + **视觉设计底线（反 AI 味红线 + 五层验收）** · **门店手机成绩单**（19 视图 + 列名识别 + 脱敏离线样本） · **Part D** v7 草稿-发布状态机绕过 + 节点化静默坑 + phoneLayout · **Part E** SuperApp 反向工程 · **AI-native ADS** 方法论 · **餐饮 BI 公式库** |\n\n**一句话路由**：标准查数 / 洞察 / Dashboard Agent → `guancli`；标准建卡/发布/截图 / `live` 实时工程 → `guanvis`；标准 ETL → `guanetl`；数据流 → `guanwf`；数据源/数据集 → `guands`；指标建/改/删 + 指标主题/目录 + 公共维度 + **指标树 / 查询加速** → `guanmetric`。**任何一个遇到官方 DSL/命令够不着的字段、报错、状态机、反向工程、业务口径**——回到本 skill 对应 Part。\n\n官方 `guandata-cli-suite` 负责选择组件，并已包含原地编辑与删除边界。本表补充本次核验版本及关键兼容规则；参数与完整操作流程以已安装的官方 Skill 为准。此前逐版本变化保存在 CHANGELOG，不在路由表重复累积。\n\n**当前执行边界**：单条指标取数先以相同参数检查 `--explain-requests -f json` 的请求计划；计划不是取数成功证明。同轮独立基础指标走批量查询，逐项检查失败；用于计算的单指标结果显式取原始数值。编辑既有资源须保留 ID、权限、调度与数据，不能用删除重建代替。新资源先核对环境与实际目录路径。常规表单结构创建/编辑优先走 `guands form`；历史 API 片段仅在具体兼容问题已复现时使用。完整迁移说明见 [官方 CLI 兼容说明](references/official-cli-compatibility.md)。\n\n**为什么还要本 skill**：整库治理的取舍、业务口径、BI 引擎报错、历史 v7/自定义图表兼容、SuperApp 的 LLM 中转问题与 ADS 架构判断，仍需结合实际业务和目标环境处理。先走官方正常路径，失败后再按本 skill 的适用条件定位；旧记录不代表最新版仍有同一个问题。\n\n**降歧义**：6 个官方 skill + 本 skill 同时启用时，只读场景（查 dsId/ETL）可能在 `guancli` 与本 skill 间双触发。本 skill **不与官方抢只读**——遇到纯查询/取数，直接路由 `guancli`，别自己拼 API。\n\n## 🔄 官方全家桶更新 SOP（高频操作）\n\n观远官方迭代节奏快（平均每周 1–2 次），本 skill 需要跟着对齐。以下是完整更新链路——从检查到落地，一条龙。\n\n自动跟进时用 [official-cli-baseline.json](references/official-cli-baseline.json) 作为已审阅版本记录，同时核对聚合包与六组件的 npm latest。发现变化后读官方 CHANGELOG 和随包 Skill，再决定兼容修改；检查失败不得写成“没有更新”。完成兼容审阅才更新此记录，商店发布失败单独跟踪，不靠重复升版本重发。\n\n### Step 0. 检查是否有新版本\n\n```bash\n# 看本机当前全家桶版本\nguanskill version\n\n# 看 npm 上最新聚合包版本\nnpm view @guandata/guanskill version\n\n# 逐个看子包最新版本（聚合包可能滞后）\nnpm view @guandata/guancli version\nnpm view @guandata/guanvis version\nnpm view @guandata/guanetl version\nnpm view @guandata/guands version\nnpm view @guandata/guanwf version\nnpm view @guandata/guanmetric version\n```\n\n如果 npm 版本 > 本机版本 → 继续 Step 1。即使 CLI 已是最新，也必须检查 Step 2：二进制更新不代表已安装的 SKILL.md 与 references 同步。另核对六组件 latest 是否与聚合包 dependencies 一致；不要混装未经核对的版本组合。\n\n### Step 1. 升级 CLI（npm 聚合包）\n\n```bash\n# 升级到最新聚合包（装到你的 npm 全局 prefix —— 先 `npm prefix -g` 确认当前目标）\nnpm i -g @guandata/guanskill@latest\n\n# 验证新版本\nguanskill version\n```\n\n> **安装路径坑（双装滞后）· 变体 A｜跨 prefix**：`guanskill` 的 forwarder 跟着 `which guancli` 解析到的 prefix 走。若曾用不同 node（如 Homebrew node 的 `/opt/homebrew` vs nvm/asdf/独立 `~/.local`）装过两份，PATH 靠前那份会\"赢\"，而 `npm i -g` 只更新当前 prefix 的那份、另一份滞后 →「升了却没生效 / 本地副本常滞后」。排查：`which -a guancli` 看是否多份；统一到单一 prefix（多余的用 `npm uninstall -g @guandata/guanskill --prefix <多余prefix>` 删掉）。\n>\n> **变体 B｜同 prefix 下「子包 vs 伞包」并存**（2026-07-15 实测）：即使只有一个 prefix，若**单独**装过某个子包（`npm i -g @guandata/guancli`），它会和伞包 `guanskill` 自带的内嵌版**抢同一个 `guancli` bin**——`which -a` 只有一条、看不出异常，`npm ls -g --depth=0` 才看得见两个顶层条目。**排查**：`npm ls -g --depth=1 | grep guan`，顶层应当**只有 `@guandata/guanskill` 一条**，六个组件都该是它的子依赖；顺带 `guancli version` 与 `npm view @guandata/guancli version` 对一下。**清理**：`npm uninstall -g @guandata/guancli` —— ⚠️ **卸载会连带删掉共享的 `guancli` bin symlink**（因为该包也声明了同名 bin），必须紧接着 `npm i -g @guandata/guanskill@latest` 把 bin 装回来，再逐个验 `guancli version` / `guanvis version` / …。\n\n### Step 2. 升级 AI Skill（SKILL.md + references）\n\n```bash\n# install-skill 把每个子包的 SKILL.md + references/ 装到 ~/.agents/skills/<name>/\nguanskill install-skill\n```\n\n落点：`~/.agents/skills/{guancli,guanvis,guanetl,guands,guanwf,guanmetric}/`。这些是 agent 路由用的 skill 定义，和 CLI 二进制分开更新。还需检查 `guandata-cli-suite`。完成后逐文件比较 npm 包 `skills/<name>/` 与已安装目录，至少覆盖 SKILL.md 和 references；退出 0 或一条安装提示不能代替内容一致性验证。\n\n### Step 3. 读 Changelog，摘要变更\n\n```bash\n# 各子包 CHANGELOG.md 在 npm 包目录下\nGUANSKILL_DIR=$(npm root -g)/@guandata/guanskill/node_modules/@guandata\nfor pkg in guancli guanvis guanetl guands guanwf guanmetric; do\n  echo \"=== $pkg ===\" && head -30 \"$GUANSKILL_DIR/$pkg/CHANGELOG.md\" 2>/dev/null && echo\ndone\n```\n\n重点关注：新增/移除命令、DSL 新组件、bug 修复（尤其影响 B-0.5 / Part C / Part D 的）、breaking change。\n\n### Step 4. 迭代 majia-guanyuan\n\n按 changelog 摘要，更新以下位置（有改动的才改）：\n\n| 位置 | 改什么 |\n|------|--------|\n| **路由总表**（本文件 `官方全家桶 ↔ 本 skill 分工总表`） | 版本号 + 能力描述 |\n| **V3.x.x 更新 callout**（本文件顶部 `> 🆕`） | 新版本摘要 |\n| **Part B 实测边界 callout** | 如果 guanetl 有 bug 修复 |\n| **Part D guanvis 版本引用** | 如果 guanvis 版本变了 |\n| **manifest.json / package.json** | `version` + `description` 里的版本号 |\n| **README.md / README.en.md** | 版本徽章 + 版本记录段（≤3 条） |\n| **CHANGELOG.md** | 新增 `[x.y.z] — YYYY-MM-DD` 条目 |\n\n版本号规则：官方对齐 = **patch**；影响 skill 自身逻辑（如 B-0.5 降级）= **minor**。\n\n### Step 5. 同步 + 发布\n\n```bash\n# 同步已发布的整包，包含 references/templates，不能只复制两个 Markdown 文件\npython3 ~/.codex/skills/majia-ota/scripts/sync_local_agents.py /path/to/majia-guanyuan --target all\n\n# commit + push（或走 /majia-ota-skill 完整发布链）\n```\n\n### 快速一键检查（日常用）\n\n```bash\n# 一行看完「本机 vs npm 最新」差异\necho \"LOCAL:\" && guanskill version && echo \"---\" && echo \"NPM latest:\" && npm view @guandata/guanskill version\n```\n\n## 通用错误码处理\n\n| 状态码 | 处理 |\n|--------|------|\n| 500 | 终止，服务器问题 |\n| 401 | 终止，登录失效（`guancli auth login` 重登） |\n| 403 | 终止，无权限 |\n| 404 | 终止，资源不存在 |\n\n---\n\n# 🅱️ Part B：ETL 治理与写入（V1.0）\n\n> 当前兼容基线为 `@guandata/guancli@1.0.63`。本 Part 的 API 路径、payload 字段、报错信息与治理判断维度来自既往真实跑通请求；本次 1.0.63 对齐完成 CLI/文档验证，不把未重跑的 BI 业务链冒充新版实证。累计覆盖整库治理扫描 + 60+ 张 ETL 创建/重构/修复/删除实战。\n>\n> ⚠️ 官方全家桶已把 BI 写操作拆成兄弟 skill 并**全部公网化**（2026-06-03，`npm i -g @guandata/guanskill`）：标准 ETL 写入有 `guanetl`、工作流数据流有 `guanwf`、数据源/数据集有 `guands`。**但 Part B 这套基于 `guancli fetch` + payload 的实战手册仍是底层事实源**——直接命中 API 路径 / payload 字段 / 报错码 / 治理判断的部分官方命令封装不到。遇到标准化 ETL 写入可路由到 `guanetl`，但**整库治理扫描、direct-save、payload_json、SmartETL 全链路重写、10 类报错速查继续走本 skill**。\n>\n> 🧪 **实测边界（2026-06-04 · workshop513 · BI 8.2.1-hf6）**：guanetl `edit` 的 base→etl.go 逆向在 **0.1.12 / 0.1.13 完全失效**（空 `return []Node{}`，5/5 ETL 全复现、`-v` 无报错）；`save` 的输出绑定 guard 也误触发。**0.1.14 两个 bug 均已修复**（2026-06-09 workshop513 实测：`ads_会员经营任务池` 6 节点 `edit→export→lint→save` 全链路通过）。改现有 ETL 现在可以走 `guanetl edit` 正常路径了。**B-0.5 绕过方案仍保留作 fallback 参考**（万一其他 BI 版本 / 节点类型仍触发）。\n>\n> ⚡ **0.1.14 修复确认**（2026-06-09 复测）：① `edit` 空 `etl.go`（Wall 1）→ ✅ 已修，6 节点完整逆向为 `BasicInputDataset×4 + BasicSqlScript + BasicOutputDatasetInDir`；② `save` 输出绑定 guard 误触发（Wall 2）→ ✅ 已修，save 直接成功不再拦截。另：**0.1.14 移除了 `delete` 命令**，删 ETL 改走 BI UI 或直接 `DELETE /api/etl/<id>` API。**0.1.15（2026-06-15）进一步增强 `save` 输出数据集保护（保留级联相关配置）+ 对追加写入场景的行数据结构提前校验**——改 ETL 走 `guanetl edit` 正常路径更稳。**0.1.16（2026-06-17）再加 `save --dry-run` 保存影响预览 + `run` 执行前提示上游数据集失败态 + `preview` 提示 LEFT JOIN 桥接列全空样本**，改 ETL 前可先 `--dry-run` 看影响面。**0.1.17（2026-06-24）仅 `install-skill` 适配 WorkBuddy 目录，ETL 行为无变化。** **0.1.18（2026-07-01）建 ETL 时目录类型诊断更清晰（识别误用工作流/经典数据流目录、提示用智能 ETL 目录）。** **0.1.19（2026-07-08）新增 `move`（移 ETL 到指定目录，接口异常时读回确认）+ `run --run-upstream`（递归解析上游链路按拓扑顺序执行，配 `--dry-run`）+ `run --wait` 遇 40001「已在运行」改为查找并等待现有任务（减少级联触发后重复 run 的误判失败）+ `export` 静态检查 JOIN 键类型不一致 warning（STRING/LONG 隐式 coercion 风险）。** **0.1.21（07-24）JOIN 类型检查扩至 preview/save/run。** **0.1.22–0.1.27（07-25～08-10）** 写操作回显实际目标环境 + 多节点并行 preview + 运行中任务可直接跟踪 + 输出落位闭环 / JOIN 未知类型拦截 + `save` 影响报告字段级明细 + 首次运行后临时输出集完成生成再做字段检查。\n\n> **2026-09-14 官方对齐**：`guanetl 0.1.34` 新建须明确两类目录，执行按 ETL ID 跟踪且不再提供全局 `task`；0.1.31 已修复历史节点 ID 下划线导出。上述为官方文档与命令核验，未重跑线上 ETL。详见 [兼容说明](references/official-cli-compatibility.md)。\n\n## B-0.5 guanetl `edit` 失效时的绕过方案（0.1.12–0.1.13 历史；0.1.14 已修复，保留作 fallback）\n\n> 0.1.14 已修复 `edit` 空 etl.go + `save` 输出绑定 guard 两 bug（确认详见上方 Part B 实测边界段），正常直接用 `guanetl edit`；以下绕过方案保留为 fallback——特定 BI 版本 / 节点类型仍触发时用。\n\n**原三道墙**（guanetl 0.1.12–0.1.13，0.1.14 已全部修复）：\n1. ~~`edit` 的 base→`etl.go` 逆向出空~~ → **0.1.14 已修**\n2. ~~`save` 撞输出绑定 guard 误触发~~ → **0.1.14 已修**\n3. `save` 的合并对「身份字段」base 优先（改 ETL 名 / 节点名被覆盖）+ 输出 dsId churn → **未验证是否修复**，改名仍建议走 `guands dataset rename` / `alias`\n\n**→ Fallback 路径**（仅在 `guanetl edit` 仍有问题时使用）：\n- **纯改名 / 字段展示名** → 别碰 ETL 图，直接 `guands dataset rename` / `guands dataset alias`。\n- **改逻辑 / 改结构（加节点、改 SQL）** → **不可变重建**（最稳）：读 `_base_etl.json` 拿旧定义 → `guanetl create` 写一份**新 outputDsName** 的新 ETL → `export/lint/save/verify` → 旧 ETL 退役。\n- **高级逃生**（仅在没法重建时）：手工构造 `_exported.json` = fresh `_base` 的 actions + 保留 output `dataSource.dsId` + 你的**逻辑**改动，再 `guanetl save`。\n- **认证别绕**：BI API 是 **cookie/session 认证**——写操作一律走 `guanetl save` / `guands`（它们持有正确会话）。\n\n**清理坑**：~~`guanetl delete --cascade`~~（0.1.14 起无 delete 命令）。删 ETL + 孤儿输出集走 `DELETE` API，**顺序必须先删输出数据集、再删 ETL（与 B-7.1 一致）**；反过来先删 ETL → `2002 输出数据集已存在` 失败。**2026-06-17 · workshop513 实测定案**（独立 DATAFLOW ETL，净零回归）：`DELETE /api/data-source/<输出dsId>`（ETL 还在）→ `DataSource deleted` 成功、**不报 6001**；再 `DELETE /api/etl/<id>` → 成功。churn 出的中间绑定是另一回事——删 ETL 后多为 `NOT_FOUND` 幽灵（`ds get`=1002 但 `ds delete`=6001，不可见、无害）。\n\n## B-〇. 推荐工作流（先治理再重建）\n\n```text\n1. 治理扫描     ← 批量抓全部 ETL 原始 JSON，分析依赖、循环、复杂度\n2. 决策保留     ← 用 8 维 ETL + 4 维字段判断：保留 / 合并 / 降级 / 删除\n3. 设计分层     ← 按 ODS/DIM/DWD/DWS/APP 重新分配\n4. 字段审计     ← 双源（page + etl）扫字段使用度，确定砍字段范围\n5. 新建目录     ← v2 目录与旧目录并行，不动旧链路\n6. 写入 ETL     ← 三节点骨架 INPUT→SQL→OUTPUT，本地编译 payload\n7. 预览节点     ← etl preview 先看 OUTPUT 节点能不能出数据\n8. 执行落表     ← execute + task get 轮询 + 拿 result.error\n9. 对账切流     ← 新旧并行验证，下游看板/ETL 逐张迁移\n10. 清理旧链路  ← 先 DELETE data-source，再 DELETE etl（顺序不能反）\n```\n\n跳过治理直接动手 = 把同样混乱重做一遍。第 1–4 步是写 ETL 之前最值钱的活。\n\n---\n\n## B-1. API 全图（11 个已实测 endpoint）\n\n```text\n🔧 写入类（POST）\nPOST /api/directory                  ← 建目录（dirType=ETL 或 DATA_SET）\nPOST /api/etl/direct-save --stdin    ← 创建/更新 ETL（payload 有 dataFlowId 即更新）\nPOST /api/etl/execute                ← 触发执行 {\"dataFlowId\":\"...\"} → taskId\n\n📖 读取类（GET）\nGET  /api/etl/<id>                   ← ETL 完整定义（含 actions/sql/relativeFieldAlias）\nGET  /api/directory/ETL/authorized-tree       ← ETL 目录树\nGET  /api/directory/DATA_SET/authorized-tree  ← 数据集目录树\nGET  /api/task/<taskId>              ← 任务状态 + 错误详情（关键修 bug 入口）\n\n🗑️ 删除类（DELETE）\nDELETE /api/data-source/<dsId>       ← 删数据集（必须先于 etl 删）\nDELETE /api/etl/<id>                 ← 删 ETL（输出数据集还在 → 失败）\n\n🔍 探测类（OPTIONS）\nOPTIONS /api/<any-path>              ← 返回 Allow 头，反推支持的 method\n```\n\n### B-1.1 反推未知 endpoint 的方法\n\n```bash\n# 步骤 1：探 method 集合（最高效）\nguancli fetch OPTIONS /api/<path>\n# Allow: POST,GET,HEAD,DELETE,OPTIONS\n\n# 步骤 2：盲发 POST，根据错误类型判断\n# - \"No static resource X\"               → endpoint 不存在\n# - \"Request method 'X' is not supported\" → endpoint 存在但方法不对\n# - \"InvalidJSON\" / \"missing field\"       → endpoint 对，body 不对（开始迭代）\n# - \"ResourceId(...) ResourceNotExist\"    → endpoint 模式错误\n\n# 步骤 3：根据错误反推 schema\n```\n\n**血泪经验**：BI 内部 endpoint 命名不一致——`data-source`（带连字符）、`dataflow`（无连字符）、`etl`（无连字符）、`directory/ETL`（驼峰大写）混用。靠 OPTIONS 探测比盲发 POST 高效 10 倍。\n\n---\n\n## B-2. 治理扫描：判断 ETL/字段去留\n\n### B-2.1 为什么扫描\n\n观远 BI 用久了的常见症状：核心表互相循环引用、同份业务规则散落多张计算列、维表混入下游经营字段、大量已创建未运行的废弃 ETL、名实不符。**不扫一遍直接动手，重建出来还是一团乱麻。**\n\n### B-2.2 扫描 3 步走\n\n```bash\n# Step 1：列出范围\nguancli etl tree                                       # 全库\nguancli etl search '' -d <PARENT_ETL_DIR_ID> --raw     # 按目录缩范围\n\n# Step 2：批量抓原始定义（--raw 关键，不带就只输出阉割版）\nmkdir -p raw\njq -r '.response.contents[].dataFlowId' etl-list.json | while read id; do\n  guancli --raw etl get $id > raw/$id.json\ndone\n\n# Step 3：本地脚本聚合分析\nnode analyze.mjs raw/ > analysis.json\n```\n\n### B-2.3 分析脚本要算的 10 个指标\n\n| 指标 | 怎么算 |\n|---|---|\n| 输出数据集 | `actions[].type==\"OUTPUT_DATASET\"` 的 `outputDsName` |\n| 上游 ETL 依赖 | `inputs[]` 里 `displayType==\"DATAFLOW\"` 的，反查归属哪个 ETL |\n| 节点数 | `actions.length` |\n| Join 数 | `actions[].type==\"JOIN_DATA\"` 的个数 |\n| 计算列数 | `actions[].type==\"CALCULATOR\"` 的个数 |\n| 透传聚合数 | `actions[].type==\"GROUP_BY\"` 的个数 |\n| 长公式数 | CALCULATOR 里 `formulas[].expr.length > N` 的个数 |\n| 输出行数/大小 | 输出 ds 的 `rowCount` / `storageSize` |\n| 调度方式 | `cron`（`AFTER_REFRESH` / 具体 cron / 无） |\n| 状态 | `status`（`FINISHED` / `CREATED` / `FAILED`） |\n\n构建依赖图（节点 = ETL，边 = \"本 ETL 输入了另一个 ETL 的输出表\"），DFS 三色标记找循环组，计算 fanIn/fanOut。\n\n### B-2.4 ETL 去留判断（8 维）\n\n| 维度 | 信号 | 处置 |\n|---|---|---|\n| **循环依赖** | 出现在循环组里 | **必拆**：找共同字段抽到 DIM/DWD，让两下游都读它 |\n| **状态异常** | `status=CREATED` 且无输出 / 0 次执行 | 删或重建为明确用途 |\n| **本地无下游** | 没有任何其他本地 ETL 引用其输出 | 区分两类：① 给看板用 → 标 APP 层；② 没人用 → 删或归档 |\n| **节点复杂度** | 节点 > 25、Join > 5、CALCULATOR > 3、长公式 > 0 | **拆**成多段：基础明细 / 规则映射 / 业务汇总 |\n| **输出大小** | 单表 > 1GB 或 > 1000 万行 | 检查是否不必要物化；规则计算应集中 |\n| **名实不符** | ETL 名跟输出表名差距大 | 改名或废弃 |\n| **历史补数** | 名字含\"补齐 / 历史 / 月末\"等，调度异常 | 移到补数/归档目录，不挂主链 |\n| **未调度** | `cron` 为空且不是被其他 ETL 触发 | 确认是否临时/手工 → 标记或删除 |\n\n### B-2.5 字段去留判断（4 维）\n\n| 维度 | 怎么判断 | 处置 |\n|---|---|---|\n| **下游 ETL 引用** | 在所有下游 ETL 的 SQL/CALCULATOR/SELECT_COLUMNS 里 grep 字段名 | 0 引用 → 候选删 |\n| **看板（page）引用** | 看板/卡片是否用了这个字段 | 有 → 不能删 |\n| **业务口径** | 字段名是否含业务规则（\"是否会员\"、\"是否新客\"） | 这类是规则字段，集中维护到专门的规则映射 ETL |\n| **冗余/派生** | 能否从其他字段推导（开业天数 vs 开业日期） | 派生字段尽量在下游算，不在维表物化 |\n\n详细双源审计方法见 **B-10**。\n\n### B-2.6 ODS/DIM/DWD/DWS/APP 分层\n\n| 层 | 放什么 | 关键约束 |\n|---|---|---|\n| **ODS** | 原始外部表、DB_EXTRACT、手工源表 | 只做轻清洗，不承载业务口径 |\n| **DIM** | 门店、会员、日期、支付通道、顾客标识映射 | **稳定、少依赖、可复用，禁止依赖 DWS/APP** |\n| **DWD** | 订单明细、券明细、好友明细、评价明细 | 固定主键和时间粒度 |\n| **DWS** | 复购、RFM、拉新、蓄水、门店日报 | 从 DWD/DIM 读，**禁止反向被 DIM 引用** |\n| **APP** | 看板专用宽表 | **只服务页面，不再作为基础上游** |\n\n调度按层推进 ODS → DIM → DWD → DWS → APP。\n\n**核心反模式**：维表（DIM）混入了下游经营结果字段——比如门店维表里塞了\"近 90 天订单数\"。这是循环依赖最常见的根源。\n\n### B-2.7 输出物建议\n\n- `analysis.json`：机器可读分析结果（summaries / cycleGroups / highComplexity / nodeTypes）\n- `governance-report.md`：人类可读治理报告（核心结论 + 循环组 + 合并主题域 + 清理对象 + 目标架构 + 实施路线）\n- `migration-plan.json`：每个旧 ETL → v2 的对应表（score / targetName / status）\n\n---\n\n## B-3. 第一步：新建目录\n\n### B-3.1 不要试这些路径（全部 5001 失败）\n\n```text\nPOST /api/directory/create\nPOST /api/directory/ETL/create\nPOST /api/directory/ETL/add\nPOST /api/directory/add\nGET  /api/directory                  ← Method 'GET' is not supported\nGET  /api/etl/tree                   ← ResourceId(tree)/ResourceKind(DataFlow) ResourceNotExist\nPOST /api/etl/dir                    ← Method 'POST' is not supported\nPOST /api/resource-atlas/dir         ← 'resourceTypeName missing'\n```\n\n合法 `dirType` 只有 **`ETL`** 和 **`DATA_SET`**（不要写 `DATA_PROCESS_ETL` `SMART_ETL` `DATAFLOW` `DATA_FLOW`）。\n\n### B-3.2 正确做法\n\nETL 树和数据集树是**两棵独立的树**：\n\n```bash\nguancli fetch GET /api/directory/ETL/authorized-tree\nguancli fetch GET /api/directory/DATA_SET/authorized-tree\n```\n\n**分别建**（同名也得建两次）：\n\n```bash\n# ETL 目录\nguancli fetch POST /api/directory \\\n  '{\"name\":\"warehouse_v2\",\"parentDirId\":\"<parent_etl_dir_id>\",\"dirType\":\"ETL\"}'\n\n# 数据集目录\nguancli fetch POST /api/directory \\\n  '{\"name\":\"warehouse_v2\",\"parentDirId\":\"<parent_ds_dir_id>\",\"dirType\":\"DATA_SET\"}'\n```\n\n记住返回的两个 dirId，写 ETL payload 时**两个都要用**：\n- ETL 目录 id → ETL 自身的顶层 `parentDirId`\n- 数据集目录 id → OUTPUT_DATASET 节点的 `parentDirId` + `dataSource.parentDirId`\n\n---\n\n## B-4. 第二步：构造 ETL payload（速查）\n\n最小骨架 = 3 节点：\n\n```text\nINPUT_DATASET → SQL_SCRIPT → OUTPUT_DATASET\n```\n\n**最关键的字段坑**（详细见 references）：\n- ⚠️ SQL 节点字段名是 **`sql`，不是 `sqlScript`**。写错时 direct-save 不报错，但 SQL 不生效（最隐蔽 bug）。\n- ⚠️ SQL 里 `input1/input2/...` 是**位置式索引**对应 `sources[]`，删除 INPUT 节点会让索引前移，**改 input 节点必须同时改 SQL**。\n- ⚠️ INPUT_DATASET 的 `relativeFieldAlias` 决定 SQL 里能引用什么字段名，必须读了再写 SQL。\n- ⚠️ OUTPUT_DATASET 的 `parentDirId` 是**数据集目录 id**，不是 ETL 目录 id（错填→\"保存路径无效\"）。\n\n📖 **[references/part-b-payload.md](references/part-b-payload.md)** — 完整 payload 模板（含 dataSource.dirPath）+ 三种节点的字段速查表 + 9 种已知节点类型 + dataFlowId 控制 create vs update + **B-8 复用模板：从扫描到落表的完整 4 阶段脚本**（治理扫描 → 建目录 → 写入执行 → 删除旧链）。\n\n---\n\n## B-5. 第三步：执行 + 拿真实错误\n\n### B-5.1 触发执行（status 字段误导）\n\n```bash\nguancli fetch POST /api/etl/execute '{\"dataFlowId\":\"<etl_id>\"}'\n# => {\"taskId\":\"<task_uuid>\",\"status\":\"FINISHED\"}\n```\n\n⚠️ **status 字段误导最坑**：返回的 `status:\"FINISHED\"` 是**任务触发**结果，不是 ETL 执行结果。\n\n### B-5.2 查任务详情（修 bug 必经路径）\n\n```bash\nguancli fetch GET /api/task/<taskId>\n# => {\"response\":{\"taskId\":\"...\",\"status\":\"FAILED\",\"result\":{\"error\":\"...\"},\"messages\":\"\"}}\n```\n\n`response.result.error` 才是 BI 引擎给的真实错误（SQL 报错、字段找不到等）。\n\n### B-5.3 错误定位三步走\n\n```bash\n# Step 1：触发 execute 拿 taskId\ntaskId=$(guancli fetch POST /api/etl/execute \"{\\\"dataFlowId\\\":\\\"$DFID\\\"}\" \\\n  | jq -r '.response.taskId')\n\n# Step 2：等几秒再查 task error\nsleep 4\nguancli fetch GET \"/api/task/$taskId\" | jq '.response.result.error'\n\n# Step 3：根据 error 类型对照 references/part-b-errors.md 修复手册\n```\n\n### B-5.4 异步轮询写法\n\n```bash\nTASK_ID=\"<task_id>\"\nfor i in $(seq 1 30); do\n  st=$(guancli task get $TASK_ID --raw | jq -r '.response.status')\n  echo \"[$i] $st\"\n  [ \"$st\" = \"FINISHED\" ] || [ \"$st\" = \"FAILED\" ] && break\n  sleep 10\ndone\n```\n\n复杂表给 5 分钟（30×10s）一般够。\n\n---\n\n## B-6. 第四步：校验工具集\n\n```bash\n# 1. ETL 视角\nguancli etl search <ETL_NAME> -d <ETL_DIR_ID> --raw \\\n  | jq '.response.contents[0] | {dataFlowId,name,status,lastExecution,outputs}'\n\n# 2. 节点级预览（不用 execute 也能看任意节点输出 — 修 bug 利器）\nguancli etl preview <DFID> <NODE_ID> --limit 5 --timeout 120\n\n# 3. 数据集视角\nguancli ds search <OUTPUT_DS_NAME> --raw\n\n# 4. 实际数据预览\nguancli ds preview <OUTPUT_DSID> --limit 10\n\n# 5. 行列数对账\nguancli ds get <OUTPUT_DSID> --brief\n```\n\n⚠️ 保存后 OUTPUT 节点 ID 会变成 `id_<ts>_<n>_out`，preview 时用新 id：\n\n```bash\nguancli etl get <DFID> --raw \\\n  | jq -r '.data.actions[] | select(.type==\"OUTPUT_DATASET\") | .id'\n```\n\n---\n\n## B-7. 第五步：删除拓扑\n\n### ⛔ B-7.0 删除前的硬性安全闸（V1.3.1 新增）\n\n**Agent 在执行任何 `DELETE /api/data-source/` 或 `DELETE /api/etl/` 前必须满足以下全部条件，否则拒绝执行：**\n\n1. **用户已逐项明确确认**：列出本次将删除的所有 dsId / etlId（含 ETL 名 + 输出表名 + 路径），用户回复\"确认删除\"或等价明确指令。**模糊回复（如\"嗯\"、\"可以\"、\"清理一下\"）不算确认。**\n2. **下游引用已切流**：通过 `guancli ds get <dsId> --assoc` 或 B-10 双源审计验证目标 ds 的下游 ETL 与看板（page）已切到 v2，无任何活跃引用。\n3. **新链路对账通过**：v2 对应 ETL `status:FINISHED`，行数与 v1 差异 <1%，关键字段一致（参考 B-7.3 checklist）。\n4. **批量删除分批确认**：单次删除 ≤ 5 张表；超过 5 张必须分批，每批单独走步骤 1。\n\n**Agent 默认行为**：在 ETL 治理 / 重写 / 字段裁剪等任务里，**永远不要主动建议删除**。把待删清单作为 `governance-report.md` / `migration-status.md` 的一节产出给用户审阅，由用户主动指令\"删 X / 删这一批\"才执行。**新旧并行是默认终态，不是过渡态**——除非用户明确要求收敛。\n\n> 这条闸跟 B-13 红线、B-17.10 完成标准里的\"对账确认后再处理旧表\"一脉相承。**误删一张被看板用着的 ds，恢复成本高过保留旧链一年。**\n\n### B-7.1 关键约束：先 ds 后 etl\n\n> ✅ **2026-06-17 · workshop513 实测复核（净零回归）**：独立 DATAFLOW ETL 两个方向各测一次——etl-first 撞 `2002 输出数据集已存在` 失败；ds-first（先 `DELETE /api/data-source/<输出dsId>`，后 `DELETE /api/etl/<id>`）两步皆 `ok`、**不报 6001**。本约束适用所有「ETL + 其输出数据集」清理。`6001 依赖于该数据集` **不**出现在这里，它只属于删*输入*数据集（ETL 仍读它）或 churn `NOT_FOUND` 幽灵场景（见 B-0.5 清理坑）。\n\n```bash\nguancli fetch DELETE /api/etl/<etl_id>\n# => {\"error\":{\"status\":2002,\"message\":\"输出数据集已存在\"}}  ← 失败！\n```\n\n正确顺序：\n\n```bash\n# Step 1：先删数据集\nguancli fetch DELETE /api/data-source/<dsId>\n\n# Step 2：再删 ETL\nguancli fetch DELETE /api/etl/<etlId>\n```\n\n### B-7.2 数据集 endpoint 反推血泪史\n\n```text\nDELETE /api/dataset/<id>     ← No static resource dataset/...\nDELETE /api/datasource/<id>  ← No static resource datasource/...\nDELETE /api/ds/<id>          ← No static resource ds/...\nDELETE /api/dataflow/<id>    ← No static resource dataflow/...\n✅ 正确：\nDELETE /api/data-source/<id>\n```\n\n### B-7.3 删除前 checklist\n\n- [ ] v3 对应 ETL Status = FINISHED\n- [ ] v3 输出数据集行数 vs v2 行数（差异 < 1%）\n- [ ] v3 输出字段集 = v2 字段集 - 设计砍掉的\n- [ ] 看板（page）依赖 v2 数据集的，已先切到 v3\n- [ ] 下游 ETL 依赖 v2 输出的，已先切到 v3\n\n---\n\n## B-9. 报错修复手册（10 类真坑 · 速查）\n\n每条只列**触发现象 + 一句根因 + 一句修复方向**；完整修复方案 + SQL 示例 + 升级版坑见 **[references/part-b-errors.md](references/part-b-errors.md)**。\n\n| 坑号 | 触发现象 | 根因 / 修复方向 |\n|---|---|---|\n| **1** | `请输入ETL名称` / `保存路径无效` | 顶层 `parentDirId` 缺失或填错 → 必须是 `dirType=ETL` 那棵树的 id |\n| **2** | 保存成功但 execute 数据为空 | 上游 `inputDsId` 只有读权限没运行权限 → 换有权限的输入或写自包含 ETL |\n| **3** | 列名带隐藏 `\\n` 找不到字段 | SQL 里要 `` `带换行的原字段名` AS `干净别名` ``；升级版坑：fieldAlias 与 SQL 中换行+空格不一致 |\n| **4** | `WHERE field <> NULL` 输出 0 行 | SQL 标准里 `<> NULL` 永远是 unknown → 必须 `IS NOT NULL` / `IS NULL` |\n| **5** | `cannot resolve column` | 字段引用与 INPUT_DATASET 的 `relativeFieldAlias` 错位 → 编译时按节点级别名替换 |\n| **6** | `Syntax error at or near ';'` | CTE 内 trailing `;` + 中文注释 → 用 regex 去除 `FROM n_id_xxx;` 后的 `;` 与注释 |\n| **7** | `AMBIGUOUS_REFERENCE` | FROM/JOIN 同表别名同名 → 改 FROM 别名为 s2，对齐 ON 子句 |\n| **8** | `s2.xxx 找不到` | FROM 表错位（自连而非 JOIN 不同表） → 修正 JOIN 目标表 |\n| **9** | `NUM_COLUMNS_MISMATCH` | UNION 列数不一致（老引擎自动补 NULL，新引擎严格化） → 手工对齐 SELECT，缺的用 `NULL AS xxx` |\n| **10** | 日期比较恒为 false | `WHERE order_date < 'today_field'` 字符串字面量 → 改 `date_sub(current_date(), 1)` |\n\n---\n\n## B-10. 字段使用度审计（双源扫描）\n\n### B-10.1 方法论\n\n字段裁剪不能只看看板（page）—— 下游 ETL 也消费字段。**双源 0 引用**才能安全裁。\n\n```bash\n# 1. 拉数据集所有下游\nguancli ds get <dsId> --assoc\n# 输出 N 个下游：M 个 ETL + K 个 PAGE\n\n# 2. 批量 page get + etl get 落本地\nfor id in <ids>; do\n  guancli page get $id > pages/$id.txt\n  guancli etl get $id > etls/$id.txt\ndone\n\n# 3. 对每个字段做 grep 双源统计\nfor fld in <field_list>; do\n  page_cnt=$(grep -c \"$fld\" pages/*.txt)\n  etl_cnt=$(grep -c \"$fld\" etls/*.txt)\n  if [ \"$page_cnt\" = \"0\" ] && [ \"$etl_cnt\" = \"0\" ]; then\n    echo \"🟥 $fld → 真 0 引用，可裁\"\n  fi\ndone\n```\n\n### B-10.2 实测对照（必看）\n\n```text\n某千万级订单明细表：43 字段、5GB\n全量扫描：29 page + 14 etl\n仅看板抽样：17 个 0 引用候选\n双源全扫描：仅 2 个真 0 引用\n误删任何一个 → 下游 ETL 跑挂\n```\n\n**只看看板会高估 8 倍可裁字段，必须 page+etl 双源。**\n\n---\n\n## B-11. v2 → v3 批量改造 SDK（速查）\n\n`v3_sdk.mjs` 三个核心 API：\n\n```js\ntransformV2ToV3({ v2PayloadFile, v3Name, removeInputs, newSql, inputMap, description })\npushAndExecute(v3Name, payloadPath)   // direct-save → execute\ncheckStatus(v3Name)                    // guancli etl search → parse Status\n```\n\n`transformV2ToV3` 有 4 个关键陷阱，头号坑是 **SQL 字段名是 `sql` 不是 `sqlScript`**（写错不报错、SQL 静默不生效）；完整 4 条清单见下方 reference。\n\n📖 **[references/part-b-sdk.md](references/part-b-sdk.md)** — 完整 7 步实现 + 时间窗口缩减实战（v2 近 3 月 → v3 昨日窗口的 regex 替换样板）。\n\n---\n\n## B-12. 批量迁移工程经验（30+ 表实战）\n\n1. **先治理后写入**：跳过治理直接写 = 把混乱重做一遍。\n2. **payload 全部本地生成**：写编译器把每个旧 ETL 的 meta 编译成三段式 payload，存 `payloads/<name>.json`。\n3. **分批保存**：一次 5–10 张 direct-save，避免单次失败影响整批。\n4. **预览先于执行**：保存完先 `etl preview` 看 OUTPUT 节点能不能出数据；能出来再 execute。\n5. **节点 ID 重映射**：保存后 OUTPUT 节点 ID 变成 `id_<ts>_<n>_out`，从 `etl get` 拿新 id。\n6. **失败修复就地更新**：改 payload 加 `dataFlowId` 再 POST，不要删了重建。\n7. **复用旧 payload**：v2 payload 作为模板，改名+改 SQL+改输入。30 个 ETL 中 22 个用这种方式。\n8. **失败定位用 task error**：每个 task 详情里 `result.error` 是真实失败原因，必看。\n9. **批量任务异步监控**：`until` 循环 + `etl search | grep -c PROCESSING` 比单 task 轮询效率高。\n10. **新旧并行**：v2 链路与 v1 并行，对账无误后再下线 v1。\n\n> 💡 **30+ 张表跨多日的工程必须走 ExecPlan**：不要靠零散 todo + 群消息 + 临时 markdown 来追踪进度。直接走 **B-17.11**（在 [references/part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md)）的 ExecPlan 工作法——四个活文档章节（Progress / Surprises & Discoveries / Decision Log / Outcomes & Retrospective）能把治理判断、循环依赖拆法、字段隐藏换行这类\"踩坑—修复\"轨迹完整落到一份自包含文档里，下一个接手的人不用问任何上下文就能继续。\n\n---\n\n## B-13. ETL 治理与写入红线\n\n- ❌ 不要试 `/api/directory/create` 这类拼凑路径，全部 5001。\n- ❌ 不要给 `dirType` 写 `DATA_PROCESS_ETL` `SMART_ETL` `DATAFLOW`，只接受 `ETL` 和 `DATA_SET`。\n- ❌ 不要把 `OUTPUT_DATASET.parentDirId` 填成 ETL 目录 id —— 报\"保存路径无效\"。\n- ❌ **不要把 SQL 字段名写成 `sqlScript`**，正确是 `sql`（写错时 direct-save 不报错但 SQL 不生效）。\n- ❌ 不要在 SQL 里写 `<> NULL` 或 `= NULL`，用 `IS NOT NULL` / `IS NULL`。\n- ❌ 不要假设 INPUT_DATASET 字段名干净 —— 先看 `relativeFieldAlias` 和实际预览。\n- ❌ 不要 execute 完就走人 —— `status:FINISHED` 是任务触发结果，不是 ETL 执行结果。要 `GET /api/task/<id>` 拿 `result.error`。\n- ❌ 不要假设节点 ID 重排不影响 SQL —— 删除 INPUT_DATASET 后 input 位置式索引会变。\n- ❌ **删除类操作（`DELETE /api/data-source/`、`/api/etl/`、`/api/page/<id>?force=true` 级联删页）一律回到 B-7 删除章节**——安全闸（逐项确认 + 下游切流 + 对账 + 单批 ≤5）见 **B-7.0**；先删数据集再删 ETL 的顺序见 **B-7.1**；正确路径是 `/api/data-source/`（带连字符，别试 `/dataset/`、`/datasource/`、`/ds/`）见 **B-7.2**。未经用户逐项明确确认绝不执行，模糊回复（\"嗯\"、\"可以\"、\"清理一下\"）不算确认；新旧并行是默认终态，不是过渡态。\n- ❌ 不要给 INPUT_DATASET 用没有运行权限的 dsId —— 保存能过，执行会拿不到数据。\n- ❌ 不要复用 OUTPUT 节点 id 作为 preview 参数 —— 保存后会变成 `id_<ts>_<n>_out`。\n- ❌ 不要跳过治理扫描直接重建 —— 不识别循环依赖和重复主题域，重建出来还是一团乱麻。\n- ❌ 不要把\"是不是被引用\"等同于\"该不该保留\" —— 看板 APP 表常常没下游 ETL，要单独看看板侧。\n- ❌ 不要让 DIM 维表依赖 DWS/APP 层 —— 这是循环依赖最常见的根源。\n- ❌ 不要只看看板做字段裁剪 —— 实测仅看板会高估 8 倍可裁字段，必须 page+etl 双源。\n- ❌ 不要假设老 ETL SQL 写法在新引擎也能跑 —— 5 类历史 bug（trailing `;` / UNION 列差 / 字段名换行+空格 / self-join 别名同名 / 字符串字面量与 DATE 比较）会暴露。\n- ❌ 不要忘记 OPTIONS 探测 —— 找未知 endpoint 时比盲发 POST 高效 10 倍。\n\n---\n\n## B-14. ETL 写入侧 API 速查\n\n| 操作 | 方法 | 路径 / 命令 |\n|---|---|---|\n| 探测 method | OPTIONS | `/api/<any-path>` |\n| ETL 目录树 | GET | `/api/directory/ETL/authorized-tree` |\n| 数据集目录树 | GET | `/api/directory/DATA_SET/authorized-tree` |\n| 建目录 | POST | `/api/directory` body: `{name, parentDirId, dirType}` |\n| 抓 ETL 详情 | – | `guancli --raw etl get <id>` |\n| 写入 ETL（创建/更新） | POST | `/api/etl/direct-save --stdin` |\n| 触发执行 | POST | `/api/etl/execute` body: `{dataFlowId}` |\n| 查任务真错误 | GET | `/api/task/<taskId>` → `.response.result.error` |\n| 节点级预览 | – | `guancli etl preview <DFID> <node_id>` |\n| 删数据集（先） | DELETE | `/api/data-source/<dsId>` |\n| 删 ETL（后） | DELETE | `/api/etl/<id>` |\n\n---\n\n## B-15. 实战 ID 速查（模板）\n\n> 跨多日的大型重构（B-17 / 30+ 表）建议在仓库根维护一份本地 ID 速查表，避免每次都用 `guancli` 翻树。下面是模板，把 `<...>` 占位符替换成你自己 BI 实例里的真实 ID。**不要把这份表 commit 到公开仓库。**\n\n| 名称 | ID | 说明 |\n|---|---|---|\n| 旧 ETL 父目录 | `<v1_etl_dir_id>` | v1 ETL 目录 |\n| 旧数据集父目录 | `<v1_ds_dir_id>` | v1 数据集目录 |\n| **v2 ETL 目录** | `<v2_etl_dir_id>` | 新建 ETL 落这里 |\n| **v2 数据集目录** | `<v2_ds_dir_id>` | OUTPUT_DATASET 落这里 |\n| 数据集树根目录 | `<ds_root_id>` | dirPath 第一层 |\n| ETL 树根目录 | `<etl_root_id>` | – |\n| PoC ETL | `<poc_etl_id>` | 第一个跑通的最小 ETL |\n| PoC 输出数据集 | `<poc_output_ds_id>` | 同上输出 |\n| PoC 输入数据集 | `<poc_input_ds_id>` | 小表，权限可运行 |\n\n如果上面 ID 失效（被删/改名），用以下命令重新拿：\n\n```bash\nguancli fetch GET /api/directory/ETL/authorized-tree | jq '.response | .. | objects | select(.name==\"<你的 v2 目录名>\")'\nguancli fetch GET /api/directory/DATA_SET/authorized-tree | jq '.response | .. | objects | select(.name==\"<你的 v2 目录名>\")'\n```\n\n---\n\n## B-17. 全链路重写方法论（CTO 张进）\n\n> 这套是观远 CTO 张进的 SmartETL 完整改写经验。它跟 B-2 治理扫描互补：B-2 解决\"有哪些 ETL 该治理\"，B-17 解决\"具体重写一条链路时怎么做才不留尾巴\"。\n>\n> **核心区别**：B-17 强调**全链路追到原始源**，不接受只重写最终 ADS。如果用户说\"把这条链路重新做一遍\" / \"替换数据源\" / \"做副本页验收\"，必走 B-17。\n\n📖 **[references/part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md)** — 完整方法论 11 节：何时用 B-17 / 4 件交付 / 8 条硬规则 / 5 步标准工作流 / 三层验收（数据集/副本页/卡片级）/ 差异追踪 5 步法 / 空快照处理标准 / 标准交付物清单 / 6 类专属常见坑 / 完成标准 6 项 / **B-17.11 用 ExecPlan 管理重写工程**（含 SmartETL 改写专用 ExecPlan 骨架，拿去直接填空）。\n\n**最简口诀**（10 秒决定要不要进 B-17）：\n- 只新建 1 个 SQL 节点数据集 → 走 B-3 ~ B-9，不进 B-17\n- 涉及\"页面副本验收\"或\"卡片级数值对账\"或\"全链路追到原始源\" → 必进 B-17\n- 30+ 表 / 跨多日 / 循环依赖拆解 → 进 B-17 + 走 B-17.11 ExecPlan\n\n---\n\n# 🆎 Part C：自定义图表开发与排障（V1.1 新增）\n\n> **并行参考（V2.0 标注）**：观远 maintainer wubaoqi 在 2026-04-29 发布了 `@wubaoqi/guan-chart-kit`（React + ECharts 组件库，专为观远 BI 设计）和 `@wubaoqi/guan-chart-kit-usage-skill`（agent-skill，教 SuperApp 接 chart-kit）。两条路线区别：\n> - **chart-kit 路线**（wubaoqi）：从零搭新看板，走**组件接入** + npm 依赖管理，适合标准化复用\n> - **本 Part C 路线**：在既有卡片上做 HTML/CSS/JS 注入 hack，绕过组件直接改 DOM/data，适合改造既有页面、临时 overlay、固定卡片\n>\n> 两者互补，按\"是新搭还是改造\"分流。\n\n> 来源：观远 CTO 张进的自定义图表注入实战经验。涵盖 HTML/CSS/JS 注入、runtime 取数、固定卡片、遮罩层、z-index/stacking context、路由清理，以及任何**必须在真实观远页面里做浏览器验证**的前端问题。\n\n## C-〇. 何时用 Part C\n\n任务涉及观远 BI **自定义图表**的：\n- 前端代码（HTML/CSS/JS）\n- 运行时取数（`renderChart` 的 `data` 参数解析）\n- 页面级 DOM 操作（固定卡片、overlay、mask）\n- 浏览器层级问题（z-index、stacking context、pointer-events）\n- 路由切换清理、复制页 card id 重定位\n- 懒加载导致脚本不执行\n- 必须在真实页面验证的问题\n\n不用 Part C 的情况：只是在观远 UI 里点几下做卡片配置，不写代码 → 走路由层（标准建卡交 guanvis）。\n\n## C-1. 快速开始原则（6 条）\n\n1. **要注入 HTML/CSS/JS** → 用「自定义图表」，不用「自定义图表 Lite」\n2. **先在真实观远页面复现问题，再改代码**\n3. **先确认 live 页实际运行的是哪份脚本**，再判断问题\n4. **脚本开始漂移或多次局部修补失效时，优先给完整 JS**，不要继续发零碎 diff\n5. **每次结构性修改后回浏览器重新验证**\n6. **遇到取数问题，先看 `GDPlugin().init(renderChart)` 的 runtime 入参**，不要先假设它等于 `/api/card/.../data` 的 HTTP 包裹层\n\n## C-2. runtime 契约（必须知道）\n\n观远当前的 runtime 回调签名是：\n\n```javascript\nfunction renderChart(data, clickFunc, config, helpers) {}\n```\n\n⚠️ **常见误解**：\n- ❌ 把第一个参数 `data` 当 DOM 根节点 —— 错。要自己从 `document.querySelector(...)` 或 `document.body` 获取 DOM。\n- ✅ `helpers` 常见为 `{ refreshData, clickFunc }`\n\n`data` 形态多变，常见 5 种：\n\n```javascript\n// 形态 1（最常见）\n[\n  [\n    { name: \"payload_json\", data: [\"{...}\"] },\n    { name: \"report_date\", data: [\"2026-03-18\"] }\n  ]\n]\n\n// 形态 2\n[{ name, data }, ...]\n\n// 形态 3\n{ chartMain: { columns: [...] } }\n\n// 形态 4\n{ response: { viewData: [...] } }\n\n// 形态 5\n[{ payload_json, report_date }]\n```\n\n**结论**：优先围绕 runtime `data` 写解析逻辑。`/api/card/.../data` 只用于核对证据，不要把它当 callback 结构直接照搬。\n\n## C-3. payload_json 取数排障（速查）\n\n📖 **[references/part-c-payload-json.md](references/part-c-payload-json.md)** — 三种\"拿不到 payload\"的细分 / 最快判断方式 / `JSON.parse` 硬规则 / 截断错误（`Unterminated string` / `Unexpected end of JSON input`）的判断 / 推荐方案：拆列而非整包 JSON。\n\n**最简结论**：JSON.parse 失败且报截断错时，**优先判断为数据链路把长字符串截断了**，不要继续堆兼容解析逻辑。改数据方案——把整份报告拆成多列（`report_date` / `key_insights_md` / 各 section 列）传给前端，比 runtime 再 `JSON.parse(payload_json)` 稳得多。\n\n## C-4. 固定卡片 / overlay 场景\n\n### C-4.1 保守做法\n\n- ✅ **只移动目标卡片内容**，不要把整页都抽进 overlay\n- ✅ overlay 和 mask **挂到当前页面根节点**，**不要挂到 `body`**\n  - 挂到 body 的后果：切页后残留 / 与原生浮层打架 / 跟右侧锚点导航层级冲突\n- ✅ overlay 的 z-index 要够用，但**不能压过观远原生导航、浮层、工具条**\n- ✅ 卡片尺寸变化时，主动派发 `resize`（立即一次 + 延迟几次）让图表重排\n\n### C-4.2 z-index 基线（已验证）\n\n```text\noverlay 容器     约 8\nmask            约 1\n固定卡项        约 20，按需要递减\n```\n\n目标：**高于滚动内容，低于观远原生导航、菜单、工具层。**\n\n### C-4.3 让加载器看得到注入卡，但用户不必看到\n\n- 观远自定义图表 iframe **是懒加载的**\n- 注入卡放在首屏以下 → 初次进页时脚本可能根本不执行\n\n**可靠做法**：\n1. 把注入卡**放在首屏**\n2. 查看态视觉隐藏\n3. **编辑态恢复可见**（让用户能找到并编辑）\n\n## C-5. 页面生命周期管理\n\n### C-5.1 必须主动销毁注入物的场景\n\n- URL 不再匹配目标 page id\n- 进入编辑态\n- 切到 `pageRenderType=phoneView`\n- 客户端路由离开当前页\n\n**只在目标桌面查看态重建。**\n\n### C-5.2 复制页面后 card id 全变\n\n- 观远复制页面会生成新的 card id\n- 继续使用原页面硬编码 id 通常**不会显式报错，只会悄悄失效**\n- 复制页一定要重新确认 card id\n\n### C-5.3 MutationObserver 死循环陷阱\n\n- 监听 `body subtree` 后又在回调里改样式 → 容易反复触发，卡死页面\n- ✅ 更稳的做法：低频轮询 + 精准 rect 比较\n\n## C-6. 浏览器排障清单\n\n### C-6.1 改代码前先看 live runtime\n\n检查：\n- 当前 URL 和 page id\n- `window` 上是否已有旧版注入 key\n- `__gd_overlay__` 和 `__gd_overlay_mask__` 是否存在\n- 页面里是否留有历史实验节点\n\n### C-6.2 找到真正可点击的 DOM\n\n不要把\"看到的文本节点\"误当成真正交互节点。对右侧锚点导航，真正有用的目标往往是：\n- 打开按钮图标\n- tab 按钮\n- pin 图标\n\n### C-6.3 用 `elementFromPoint` 查层级问题\n\n控件可见但点不动时，查控件中心点命中的真实元素：\n- 命中 fixed card 或 overlay 子节点 → 层级问题\n- 命中正确控件但还不工作 → 之前点错节点 / 某个祖先禁用了 pointer events\n\n### C-6.4 最终用真实浏览器点击验收\n\n不要只靠 `page.evaluate(... click())`。要用真实浏览器点击，确认：\n- tab 切换是否真的生效\n- 页面滚动位置是否真的变化\n- pin 状态是否真的切换\n\n## C-7. 保留原生浮动 UI\n\n- ❌ 没必要时，**不要重绘或克隆**观远原生浮动控件\n- ✅ 优先修 stacking context、pointer-events、opacity，而不是复制一套控件\n\n原生控件不可点时，按这个顺序排查：\n1. overlay 是否盖住它\n2. mask 是否拦截事件\n3. 祖先节点是否被设成 `pointer-events: none`\n4. 原控件是否被历史实验隐藏\n\n## C-8. 交付规则\n\n- ✅ 用户要手工粘贴时，**默认给完整 JS**，不给局部片段\n- ✅ 如有需要，同时明确给出 HTML / CSS\n- ✅ 脚本不稳定时，完整替换优于局部修改\n- ✅ 页面已经完全坏掉时，先给最小恢复版救回来：\n\n```javascript\nfunction renderChart() {}\nnew GDPlugin().init(renderChart);\n```\n\n提醒用户执行：**保存 → 发布 → 强刷查看页**。\n\n## C-9. 最终验收清单\n\n最终一定要在真实页面验证：\n- [x] 页面加载\n- [x] 查询 / 筛选切换\n- [x] 滚动\n- [x] 左侧栏展开收起\n- [x] 路由切页\n- [x] 编辑态进出\n- [x] 桌面 / 手机态切换\n- [x] 原生浮动控件是否仍可见、可点\n\n## C-11. 深度参考资料\n\n遇到复杂的固定卡片 / overlay / 锚点导航问题时，读：\n\n- [references/custom-chart-playbook.md](references/custom-chart-playbook.md) — 张进的完整自定义图表排障手册原文（含固定层与真实布局错位修正、右侧原生导航失效详细处理、elementFromPoint 实战、MutationObserver 死循环深入分析）\n- [references/etl-rewrite-original.md](references/etl-rewrite-original.md) — 张进的 SmartETL 改写经验原文（B-17 章节就是基于它整合的，这里是未删减版）\n\n## C-12. HTML 应用化看板生成（V2.1.1 新增）\n\n> **触发**：用户说\"更高级 / 更复杂 / 更好 / 应用 / 自定义模块 / 不要限制在标准看板 / 最完美版本 / HTML 看板\"——立刻切到这条路线，**不要**按 guanvis 标准 KPI/折线/柱状图套路交付。\n>\n> **架构**：原生 Page + 原生 selector + HTML SDK 可见层（`createCustomChart().setSubType(CustomChartSubType.SDK).loadContent(...)`）+ DATA_GRID dataView 数据层。后端负责权限/刷新/聚合/筛选，前端负责叙事/布局/SVG-HTML 可视化。\n>\n> **不能跳的两条坑**（2026-05-14 `app.guandata.com` 上 `<demo-domain>` 实例实测）：\n> 1. `guanvis` DSL 的 `.linkToAll()` **不会** 把 selector 联到 custom chart 内部 dataView——必须走 **资源包级 descriptor patch**（不要去调 `/api/card/.../edit/session`，会返回 `60004 此操作只能在草稿页面执行`）。\n> 2. `guancli card preview` 的命令面 V2.1 起 **不再有 `--pg-id`**，老写法 `card data <id> --pg-id <pg_id>` 已废弃；同时不同子命令返回根字段不同（`page get → .data`、`card get → .response`），jq 统一写 `.data // .response // .`。\n\n📖 **[references/part-c-html-dashboard.md](references/part-c-html-dashboard.md)** — 完整方法论 15 节：何时切到 HTML 应用看板 / 总体架构 / SDK vs ECHARTS_LITE 决策 / dataView contract / 共享 runtime API / 24 字符 ID 校验 / selector → custom chart dataView 联动补丁 / 12 步 pack-patch-upload 工作流 / 字段粒度后缀兼容（`月份` / `月份 (月)` / `年月`）/ guancli V2.1 命令面（含 `.data // .response` 兼容）/ **五层验收清单（四层管道 + §11.5 视觉验收）** / 13 类常见错误表 / 模板包索引。\n\n🎨 **视觉设计底线（V3.1.0 新增）**：[references/part-c-design-baseline.md](references/part-c-design-baseline.md) — 管道通了 ≠ 看板能看。模块第一视觉位=数据判断 / KPI 3-4 个 + 28-32px + 单位/对比基准 / 图表真实性（禁 CSS 假图表）/ token 硬上限 / 反 AI 味红线表（命中即重做）/ `guanvis screenshot` 视觉验收。吸收 design-taste-skills（MIT），覆盖 C-12 / Part D / Part E 三场景。\n\n🧰 **模板包**：[`templates/html-dashboard/`](templates/html-dashboard/) — `charts/html_common.js` (GDHTML runtime) + `html_base.css`（V3.1.0 按设计底线校准）+ 2 个起手模块（executive / trend）+ `scripts/patch_selector_linkage.js`（CLI 参数化，弥补 `linkToAll` 联不到 custom chart dataView 的盲区）。🆕 **guanvis 0.1.29 起官方新增「页面筛选器过滤自定义图表 + custom chart dataView 作点击联动来源」**——新页可先试官方 selector 联动，覆盖到位则此脚本可省；旧版/未覆盖场景仍用兜底（官方能力未净零实测，暂并存）。\n\n**手机成绩单 V2**：新增专供ETL与确定性异常规则、周期明细标题、冻结表头及券转化。沿用单卡结构，见 [V2实践](references/part-c-store-mobile-scorecard-v2.md) 与 [离线示例](examples/store-mobile-scorecard-v2/README.md)。\n\n📱 **门店手机成绩单（V1 版）**：加盟店老板每天打开的单卡成绩单，不要按本章六模块驾驶舱去堆，也不要把桌面看板缩小。产品规则、19 视图契约、换店滤空、列名识别、对比不写家数、不取 RFM 见 [references/part-c-store-mobile-scorecard.md](references/part-c-store-mobile-scorecard.md)；可离线点的脱敏 HTML 在 [examples/store-mobile-scorecard/](examples/store-mobile-scorecard/)。\n\n---\n\n# 🆎 Part D：V7 Page/Card 发布流水线 + 三态硬规则（V2.1.6 新增）\n\n> **触发**：用户说\"v7 BI 实例上端到端搭多个 HTML 应用看板\"，或卡在以下任一报错——立刻进 Part D，**不要** 在标准建卡（guanvis）/ Part C 链路上继续挣扎，没用：\n> - `POST /api/page` + `POST /api/card` 返回 `60004 此操作只能在草稿页面执行`\n> - PUT 草稿页 cdId 后，published page 拿到的 cdId 跟 draft 的不映射，整页拼不出来\n> - CSV 散客订单 `会员ID IS NOT NULL` 算出 \"会员销售占比 = 100%\" 假指标\n> - Spark `WITH 订单汇总 AS (...)` 报 `PARSE_SYNTAX_ERROR Syntax error at or near '订'`\n> - ETL update 报 `1012 输出数据集目录中存在同名文件，请修改`\n> - `dim_是否新店 = '1'` 永远空表（CSV 布尔字段实际是 `'TRUE'/'FALSE'` 字符串）\n> - 50 店 / 90 天 / 45 万订单 openpyxl 写 Excel 4-5 分钟\n>\n> **架构**：v7 BI 的草稿/发布分离机制使**手撸 `/api/page` + `/api/card` 全链路废弃**；优先使用官方 `guanvis`（原 `guanvis-skill`，全家桶成员，现公网 `@guandata/guanvis@0.1.50`），按官方预览、覆盖前备份和发布流程处理 page + custom chart + dataView；0.1.47 覆盖后会重置草稿，发布后分别验收浏览态与编辑态。桌面端 另有 `guanvis live` 对话式路径（`live project validate/publish` 走完整 DSL；**不得用 P0 命令模拟自定义图表**，C-12 descriptor patch / 60004 / phoneLayout 仍走本 Part）。配套硬规则：CSV 散客 `会员ID` 是 `\"\"` 不是 NULL（三态判断必须 `IS NOT NULL AND <> ''`）；STRING 字段才能 `<> ''`，日期/数字 Spark 严格类型不行；Spark CTE 别名必须英文；ETL update 必须带 `OUTPUT_DATASET.dataSource.dsId` 否则 1012；数据集上传 / 建集走官方 `guands`（`create-db` / `import` / `replace-data`，不必再 BI UI 手动）；大表 pandas 用 `to_csv` 而非 `to_excel`（50 倍速差）。\n>\n> 🗑️ **删除 guanvis-published 页面 / ETL（2026-06-05 · workshop513 实测）**：`guanvis publish` 出的页面，卡片**内嵌在 `page.cards` + `meta.layout`、不是独立 `/api/card` 资源**——所以 `DELETE /api/card/<cdId>` 报 `1002 找不到`、`DELETE /api/page/<id>` 报 `1004 无法删除包含卡片的页面`、guanvis 也不让覆盖成空页（validation 拒 `No layout items`）。**唯一可行**：`guancli fetch DELETE \"/api/page/<pgId>?force=true\"` → `Page deleted`（级联删卡）。⚠️ **`force=true` 级联删整页内嵌卡片且不可逆，属 B-7.0 安全闸覆盖的 DELETE**：执行前用户须逐项确认页 ID + 页名（模糊回复不算确认）。**仅当本地保有该 page 的 guanvis 源（`page.js` / card 定义）可 `guanvis publish` 重建时，确认即可、无需对账；若是 BI UI 手搭、本地无源的发布页，按不可逆 DELETE 对待、走 B-7.0 完整对账。** 删 ETL + 输出集 → **先删输出数据集、再删 ETL**（与 B-7.1 一致；2026-06-17 实测：反过来先删 ETL 撞 `2002 输出数据集已存在`，ds-first 不报 6001）；`guanetl delete --cascade` 0.1.14 起已无此命令。\n>\n> **不能跳的硬约束**（2026-05-20/21 v7 demo 实战 · 90 天 / 1200 门店 / 80K 会员 / 20 表 / 17 ETL / 6 HTML 看板）：\n> 1. **直接手撸 page+card API 全废**：draft cdId ≠ published cdId 不会自动映射回 published page，光走 `POST /api/page` 拼不出来；走 `guanvis publish` 才能跨过状态机。\n> 2. **CSV 类型三态硬规则**：STRING 字段可以 `<> ''`，日期/数字字段不能（Spark 严格类型直接报错）；CSV 布尔字段实际是 `'TRUE'/'FALSE'` 字符串而非 int 1/0，`= '1'` 永远空表。\n\n📖 **[references/v7-page-card-publish-pipeline.md](references/v7-page-card-publish-pipeline.md)** — 完整 16 节：v7 草稿/发布机制详解 / HTML 应用看板 SDK 最小骨架（schema.js + card_01_html.js + page.js + charts/dashboard.{html,css,js} 4 文件） / CSV 三态判断硬规则 / Spark SQL 4 个硬限制（中文别名 / 嵌套窗口 / `<> NULL` / 字面量日期）/ ETL update OUTPUT_DATASET dsId 注入脚本（`guancli ds search` 自动查 dsId 注入）/ 数据集上传 / 建集走官方 `guands` / pandas to_csv vs to_excel 性能对比 + 向量化 30 倍速差 / JOIN 键全局统一命名（COL_MAP）/ 奶白 `#faf7f2` + 暖蓝 `#2563eb` 主题 / 端到端时间预算 / 反模式与硬约束总表 / 工程目录参考结构 / 与 Part C-12 的边界关系 / **§14 SmartETL 节点化两大静默坑（V2.1.8 新增）** / **§15 customChart 三大坑 + autoBootstrap + chip toolbar 兜底（V2.1.9 新增）** / **§16 移动端 phoneLayout ZIP inject + v7 草稿 save API 死路（V2.1.10 新增）**。\n\n---\n\n## 📚 References 目录\n\n> 本 SKILL.md 主文是路由层 + 关键规则；以下马甲蒸馏档（官方够不着的硬骨头）+ 餐饮公式库 + 贡献者原文构成完整知识库。详细索引：\n\n**马甲蒸馏版：**\n\n| 文件 | 何时读 | 行数 |\n|---|---|---|\n| [part-b-payload.md](references/part-b-payload.md) | 写新 ETL payload / 复用 4 阶段脚本时 | ~175 |\n| [part-b-errors.md](references/part-b-errors.md) | execute 失败、对照 `task error` 找修复方案时 | ~150 |\n| [part-b-sdk.md](references/part-b-sdk.md) | 30+ 表批量改造、写 `transformV2ToV3` 时 | ~60 |\n| [part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md) | 全链路 SmartETL 重写、副本页验收、ExecPlan 管理时 | ~290 |\n| [part-c-payload-json.md](references/part-c-payload-json.md) | runtime 拿不到 payload_json / JSON.parse 失败时 | ~60 |\n| [part-c-html-dashboard.md](references/part-c-html-dashboard.md) | 用户说\"更高级 / 应用化 / 不限标准看板\"，从零生成 HTML 化分析应用时（V2.1.1 新建） | ~620 |\n| [part-c-store-mobile-scorecard.md](references/part-c-store-mobile-scorecard.md) | 加盟店老板手机成绩单 / 换店滤空 / GDPlugin 视图顺序错位 / 对比组家数泄露 / 要离线可点的移动样本时（V3.2.0） | ~280 |\n| [part-c-design-baseline.md](references/part-c-design-baseline.md) | 生成/修改任何 HTML 看板的视觉层时；用户说\"做好看点 / 太丑 / AI 味重\"时；C-12 §11.5 视觉验收时。模块首屏=数据判断 / KPI 与数值口径 / 图表真实性 / token 硬上限 / 反 AI 味红线 / `guanvis screenshot` 验收清单。吸收 [design-taste-skills](https://github.com/xiaomingtx666/design-taste-skills)（MIT），覆盖 C-12 / Part D / Part E（V3.1.0 新建） | ~150 |\n| [v7-page-card-publish-pipeline.md](references/v7-page-card-publish-pipeline.md) | V7 BI 实例端到端搭多个 HTML 看板 / 手撸 page+card API 被 `60004` 草稿页面错误卡住 / CSV 散客 `会员ID IS NOT NULL` 算出 100% 假指标 / Spark `WITH 中文别名` 报错 / ETL update `1012 同名文件` / SmartETL `COUNT_DISTINCT`/`JOIN_DATA` 多键/`FULL_OUTER` 节点化坑（V2.1.8）/ HTML customChart `renderChart` 不调 + `autoBootstrap` + chip toolbar 兜底（V2.1.9）/ 移动端 phoneLayout v7 草稿 save API 死路 + ZIP inject 唯一可行路径 + CSS @media 模板（V2.1.10） | ~1120 |\n| [part-e-superapp-pipeline.md](references/part-e-superapp-pipeline.md) | SuperApp 开放应用开发流水线 / `guancli app create/publish` 不读 `.env` 必须显式传 `--app-id` / 脚手架 bi-services 速查 / 数据集异步预览 3 步链路 / **`/survey-engine/api/form/add` 建表反向工程**（脚手架没暴露） / **BI LLM 中转 NOT_JSON_RES/ILLEGAL_JSON_RES 三路径解析模板**（含从 error_message 抠 LLM 响应）/ 客户端模拟流式 + prompt 模板 / 原生 fetch + credentials: 'include' 绕过脚手架 `get` unwrap / `<base href>` + Router basename / 设计纪律 + 反模式表 + 决策树（V2.1.12 新建） | ~760 |\n| [ai-native-ads-design.md](references/ai-native-ads-design.md) | **majia-guanyuan 哲学层文档**——客户问\"想给现有 BI 接 AI\"时判断\"治理 vs 重搭\" / 7 条 AI-native ADS 字段约束（中文枚举 / 推荐预算 / 复合拼好 / TIMESTAMP / 强约束取值 / 数值算好 / 权限冗余） / ODS+DWD 不动 ADS 重建 / 预算分配 30%+30%+40% / 与 Part D/E + 餐饮 BI 公式库的关系 / 反模式 8 条（V2.1.13 新建） | ~260 |\n\n**餐饮 BI 公式实战库（V2.1.5 新建，去敏蒸馏自两段餐饮连锁 BI 履职 + 39 个生产 ETL；➡️ 2026-07-12 已迁至独立仓库 [majia-huiyuan](https://github.com/maojiebc/majia-huiyuan)，下表链接直达新家，本仓库 references/restaurant-bi-formulas/ 仅留指针）：**\n\n| 文件 | 何时读 | 行数 |\n|---|---|---|\n| [restaurant-bi-formulas/README.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/README.md) | 进入业务公式库的总入口 / 字段词典 / 5 条最常踩坑 | ~70 |\n| [restaurant-bi-formulas/01-date-and-time.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/01-date-and-time.md) | 写时间范围（T-1 / 本月 / 上月 / 近 N 天 / 时间宏 / 用餐时段 / 跨月对齐） | ~180 |\n| [restaurant-bi-formulas/02-customer-and-membership.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/02-customer-and-membership.md) | 新老客 / 会员属性 / 消费频次（3 口径）/ 复购（跨天 vs 非跨天）/ 留存流失 / RFM / 注册前后行为 / 90 天复购分桶 | ~700 |\n| [restaurant-bi-formulas/03-revenue-kpi.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/03-revenue-kpi.md) | AC / ADS / ADT / AUD / Comp / TC_CRM% / NS_CRM% / 营收占比 / 客单分桶 / 累计消费 | ~240 |\n| [restaurant-bi-formulas/04-channel-and-store.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/04-channel-and-store.md) | 业务渠道（堂食/外卖）/ 订单子渠道大 case / 时效类型 / 搭配类型 / StoreDate / 成长类型 / 注册门店优先级回填 | ~410 |\n| [restaurant-bi-formulas/05-coupon-and-discount.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/05-coupon-and-discount.md) | 核销率 / 折扣率 / 折扣分桶 / 券类型分流 / 注册第一张券 / 30 日优惠订单比例 | ~160 |\n| [restaurant-bi-formulas/06-sql-utils.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/06-sql-utils.md) | 字符串拆解 / `explode+split` / `collect_set+concat_ws` / 开窗排名（ROW_NUMBER/RANK/DENSE_RANK）/ 累计窗口 / 多表 LEFT JOIN | ~350 |\n| [restaurant-bi-formulas/07-data-quality-traps.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/07-data-quality-traps.md) | `NULL vs 0` / 三态判断 / 口径歧义 / 重复字段名 / A↔B↔通用字段对照表 / 日期边界 | ~250 |\n| [restaurant-bi-formulas/08-etl-engineering-patterns.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/08-etl-engineering-patterns.md) | **ETL 工程范式**：10-CTE DWD 宽表底座 / 轻节点重 SQL vs 重节点轻 SQL 哲学 / 财务双源对账 / POS 系统归一化 / 会员生命周期多输出 / Cohort 日期×门店网格（蒸馏自 39 个 V1 生产 ETL）| ~280 |\n| [restaurant-bi-formulas/09-etl-catalog.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/09-etl-catalog.md) | **39 个 V1 生产 ETL 索引清单**：按 11 业务域分类（基础维表 / DWD / 会员档案 / 顾客行为 / 财务营收 / 营销目标 / 私域社群 / 活动券 / 评价管理 / 业务标签 / 数据质量）+ 每 ETL 的节点/输入/输出/SQL 速查 + 复用决策表 | ~190 |\n\n> 触发场景：\"如何算复购率 / 客单价 / 同店增长\" / \"怎么判新老客\" / \"用餐时段怎么分桶\" / \"为什么会员数对不上\" / **\"我要写 DWD 宽表 / 评价 pipeline / 财务对账\"** — 直接进 [restaurant-bi-formulas/README.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/README.md) 路由表。和 Part B/C 正交（按业务领域分，非按平台操作分）。\n\n**贡献者原文（不修改，照引）：**\n\n| 文件 | 来源 |\n|---|---|\n| [etl-rewrite-original.md](references/etl-rewrite-original.md) | CTO 张进 — SmartETL 改写经验未删减原文 |\n| [custom-chart-playbook.md](references/custom-chart-playbook.md) | CTO 张进 — 自定义图表排障完整 playbook |\n| [execplan-spec.md](references/execplan-spec.md) | OpenAI Codex — ExecPlan 完整规范 |\n| [agents-rule.md](references/agents-rule.md) | OpenAI Codex — AGENTS.md 极简调度规则 |\n\n---\n\n## 📋 版本记录\n\n> 顶部 🆕 callout 是最新版摘要；完整逐版记录见 [CHANGELOG.md](CHANGELOG.md) 或 [GitHub Releases](https://github.com/maojiebc/majia-guanyuan/releases)。以下只留最近三版一句话索引：\n\n- **V3.2.3**（2026-09-28）对齐 guanskill 0.1.41；指标请求计划、创建恢复与编辑保护、ETL 输入类型和页面初始化保护。\n- **V3.2.2**（2026-09-23）同步移动看板编号标签、顾客归属与复购规则，更新脱敏前端和28步SQL参考。\n- **V3.2.1**（2026-09-20）对齐 guanskill 0.1.39 / guancli 1.0.62，修正指标批量结果与工作流调度说明。\n## 👤 作者 / 联系\n\n**马甲（@maojiebc）** · 超级马甲\n\n如果这份 skill 帮到你，欢迎在以下任意渠道找我交流踩坑实录、提需求、报 bug，也欢迎切磋用户运营 / 数据中台 / BI 工程的实战经验：\n\n| 渠道 | 链接 |\n|---|---|\n| 📧 Email | [m9224@163.com](mailto:m9224@163.com) |\n| 🐙 GitHub | [github.com/maojiebc](https://github.com/maojiebc) |\n| 🪝 ClawHub | [clawhub.ai/p/maojiebc](https://clawhub.ai/p/maojiebc) |\n| 🐦 X | [@maojiebc](https://x.com/maojiebc) |\n| 📕 小红书 | [超级马甲](https://xhslink.com/m/4fQMJeHHWKC) |\n| 📰 微信公众号 | **超级马甲** |\n\n> 这份 skill 是 14 年用户运营 + 观远 BI 实战 + 60+ 张 ETL 写入实证沉淀出来的，问题/合作随时聊。\n\nFile v3.2.3:examples/store-mobile-scorecard-v2/etl/README.md\n\n# 专供 ETL 参考\n\n`pipeline.json` 声明10个逻辑源、28个计算节点及19个输出。每个SQL的 `input1`、`input2` 等按对应步骤的 `inputs` 顺序绑定。未携带任何租户数据集、目录、连接或页面ID。\n\n商品排除项“示例排除商品”是脱敏占位，接入时须替换为本组织的有效商品分类规则。\n\n字段使用业务别名，例如“订单日期”“total_实付”。接入时先核查本组织字段语义、类型、时区、订单状态、取餐方式、门店名称与编号映射，再通过官方 guanetl 组装隔离流程。文件不是 guanetl 完整导出包，不能直接覆盖生产ETL。前端视图契约由 build.mjs 的 `packViews` 和 scorecard.js 的列名识别共同展示。\n\n财务与顾客订单用于有效门店并集；多数逐日输出保留70天，窗口去重、对比、异常证据与汤底覆盖分别聚合。订单和券号仅参与后端关联，不下发浏览器。会员证据与券转化为版本化JSON，在19个既有输出内扩展。\n\n所有默认规则、阈值及口径限制见 [V2实践](../../../references/part-c-store-mobile-scorecard-v2.md)。SQL保留 Spark 3.4 语法；本公开包没有执行真实数据库查询，不承诺任意字段、POS或租户开箱即用。调度应绑定实际上游刷新，核查时间水位并观察自然运行；不要在公共模板硬编码生产调度或凭据。\n\n本次新增 `dinein_repurchase.sql` 与 `repurchase_peers.sql`，结果并入门店档案而不增加前端视图数。顾客、周期会员与门店档案使用字符串门店编号，输入依赖以最新 pipeline 为准。\n\n`DEMO_NEW_STORE`、`示例重新开业店` 和日期 `2026-03-19` 是重开店历史边界的合成占位，展示需要跨模块一致处理的特例；不是通用营业起点规则。接入时删除不适用特例或改为经核验的门店历史映射。财务参考还保留开业前微额测试日识别（全渠道合计1至2单、0至2元且无负数），须按本组织业务核验，不能随意删除正常营业日。\n\n订单源在门店关联前须满足 JOIN 基数约束，见 [订单关联去重](../../../references/order-join-cardinality.md)。公共SQL没有执行目标租户查询；离线构建与测试不代表这些SQL已在任何新环境运行。\n\nFile v3.2.3:examples/store-mobile-scorecard-v2/README.md\n\n# 门店手机成绩单 V2：专供 ETL、异常提示与券转化\n\n这是一份可离线操作的移动端案例。门店、日期、业务数字、券名与异常证据全部为合成数据；不含企业数据、账号、平台资源 ID 或线上截图。V1 保留在相邻目录，作为历史版本。\n\n下载 [单文件 HTML](store-mobile-scorecard.html) 后用浏览器打开即可，不需要登录、联网或大模型。源码修改后执行：\n\n```sh\nnode examples/store-mobile-scorecard-v2/build.mjs\nnode examples/store-mobile-scorecard-v2/test.cjs\n```\n\n<img src=\"https://raw.githubusercontent.com/maojiebc/majia-guanyuan/main/examples/store-mobile-scorecard-v2/preview.png\" alt=\"V2券转化明细，合成数据\" width=\"390\"/>\n\n## 2026-09-23 同步\n\n本次对齐当前线上移动版的前端与SQL口径。门店名称旁显示编号标签，随选店变化；长店名自动换行，编号缺失或归属不唯一时隐藏。保留字符串编号的前导零。\n\n顾客状态按门店编号归属，90天观察期不足时不判断流失。会员和非会员新增固定近30天的堂食跨日复购率，以及同店型前25%参照；观察期不足、每组顾客不足50名或参照门店不足10家时暂不评定。城北店合成样本包含观察期不足场景。百分比以整数为主，小于1%的差异保留显示。\n\n客单价翻倍的根因与上游修复见 [订单关联去重](../../references/order-join-cardinality.md)。公开包保持合成数据，生产门店特例已替换为明确的示例占位。\n\n## 可以直接体验\n\n顶部先选分公司，再选门店；同分公司按固定近7天总营业额降序排列。示例城南店演示会员集中高额订单与堂食汤底缺失，示例镇中店没有异常警示，示例北区的城北店演示无券核销与会员识别覆盖不足。\n\n昨日、近7天、近30天、本月同步改变数据范围，以及“昨日明细／近7天明细／近30天明细／本月明细”和对应的转化明细标题。每日明细有总额、堂食、外卖三个切片；标题、合计与表头固定，只滚动数据。日期与星期分行，周末浅色标记。近8周趋势的月份与日期分行，避免横轴挤在一起。\n\n“跟其他门店比”分别展示近7天日均营业额、固定近30天会员订单占比。只给本店名次和中位数，不披露其他店的明细。会员占比参评要求和前后期变化条件见口径弹层，不用该占比决定顶部选店顺序。\n\n异常警示主标题为红色，只有达到规则才出现。会员订单提示给出集中笔数、跨天数、金额占比及原始支付类别，不判断操作人身份或直接认定刷单；汤底异常区分堂食收银点选与外卖商品映射。页尾为业务分析用途说明，联系对象使用通用的“运营支持”。\n\n优惠券转化明细分“营收贡献／优惠折扣”，展示核销张数、订单数、关联实付、客单、整单优惠、加权实付折扣和每优惠1元对应实付。叠券总计独立按订单去重，不能将券种行相加。未匹配、金额冲突、券作支付和非完成订单保留数量，不把未知金额当成0。\n\n## 文件与使用边界\n\n| 文件 | 用途 |\n|---|---|\n| `scorecard.js` / `scorecard.css` | 当前前端交互与统一字号间距；离线筛选器适配在 JS 末尾 |\n| `build.mjs` | 固定种子生成三个门店的合成聚合数据，封装单文件 HTML |\n| `test.cjs` | 叠券去重、折扣加权、未知金额、跨周期隔离与异常边界检查 |\n| `etl/pipeline.json` | 10类逻辑输入、28个计算步骤与19个输出的依赖关系 |\n| `etl/*.sql` | Spark SQL 计算参考，`input1` 等顺序由 pipeline 声明 |\n| [完整实践说明](../../references/part-c-store-mobile-scorecard-v2.md) | 数据口径、性能取舍、移动规范与发布验证 |\n| [券关联排查](../../references/coupon-order-link-diagnosis.md) | “已核销但无关联订单”的分层追溯方式 |\n\n演示数据按模块合成，用于验证交互和边界，不能作为真实经营基准。ETL 是字段与依赖参考，并非可直接覆盖任意租户的部署包：须先映射本地源字段，用官方 guanetl / guanvis 创建隔离副本，校验权限、筛选、调度及真实数据，再发布。不要把离线示例当作已接入真实数据或已证明加载速度提升。\n\nFile v3.2.3:examples/store-mobile-scorecard/README.md\n\n# 门店手机成绩单 · 脱敏离线案例\n\n> 当前迭代见 [V2](../store-mobile-scorecard-v2/README.md)。本文件保留 V1 约定与历史验证。\n\n给加盟店老板看的手机成绩单样本。和桌面看板不是同一张页，也不是把桌面缩小。\n\n**V1 版**（2026-09-14 封存）：单卡内滚动，19 个 DATA_GRID，不取 RFM，外卖色 `#FFD100`。不要为了切店先出营业额拆成两张卡。\n\n经验总结（产品规则、19 视图契约、换店滤空、列名识别、对比不写家数、发布链路）：\n\n[`references/part-c-store-mobile-scorecard.md`](../../references/part-c-store-mobile-scorecard.md)\n\n## 打开\n\n双击 `store-mobile-scorecard.html`，或：\n\n```bash\nopen examples/store-mobile-scorecard/store-mobile-scorecard.html\n```\n\n不需要观远、不需要登录、没有网络请求。页顶横条写明：虚构门店、虚构数字、锚点冻在 2026-03-20。\n\n生产页用页面筛选器换店。本样本用页内「示例镇中店 / 示例城南店」代替，方便离线看换店后数字一起变。\n\n## 重新生成\n\n改 `scorecard.js` / `scorecard.css` / `build.mjs` 之后：\n\n```bash\nnode examples/store-mobile-scorecard/build.mjs\n```\n\n生成器会自检：除 RFM 外的视图都能按列名识别（`detectV.rfm === -1`）；昨天合计 ≠ 近 7 天日均；两店数字不同；会员频次高于非会员且两店不同；对比组够 3 家（只用于算名次，页面不展示家数）。\n\n## 点击清单\n\n打开后按这个表点一遍，每一项都应该仍有数：\n\n1. 两店切换（店名、首屏、顾客、私域、商品一起变）\n2. 昨天 / 近 7 天 / 近 30 天 / 本月\n3. 每日明细\n4. 堂食、外卖下钻\n5. 近 30 天折线滑块、近 8 周柱\n6. 跟其他门店比三张卡 + 弹层（看不见家数、看不见其他店名）\n7. 顾客与会员（消费会员跟周期去重、新老客条、当前状态）\n8. 会员和非会员（一级模块：人均贡献 + 右侧客单价，下方只有组内营业额）\n9. 私域 KPI + 哪些券用得最多（一级模块，不折叠）\n10. 饭点条（在热销上面）+ 热销展开、汤底堂食/外卖\n11. 口径说明\n\n## 不要用它做什么\n\n不要把这个 HTML 当成 guanvis 工程去 `pack` / `upload`。上线仍是：原生 Page + 门店筛选器 + HTML 父卡 + 19 个 DATA_GRID + 必要时补 `phoneLayout`。\n\nFile v3.2.3:examples/workshop513-咖啡连锁会员运营模拟案例/README.md\n\n# ➡️ 已迁移：majia-huiyuan（独立仓库）\n\n本案例（咖啡连锁会员运营模拟数据中台 · 54 数据集 / 25 ETL / 12 看板整库快照）已从本仓库独立，作为**开源会员运营家底**项目持续迭代：\n\n**👉 https://github.com/maojiebc/majia-huiyuan**\n\n- 独立仓库含完整的结构定义、200 行/表数据样本、口径 SQL、观远原始 JSON，并新增 AI Agent 友好层（`llms.txt` + `AGENTS.md`）\n- 本目录自 2026-07-12 起不再更新；历史版本可在本仓库 git 历史（≤ v3.1.6）中找回\n- 分工：**工具在 majia-guanyuan，数据在 majia-huiyuan**\n\nFile v3.2.3:README.md\n\n# majia-guanyuan · 观远 BI 实战增益层 · 马甲实战版\n\n> **官方全家桶之上的实战增益层** —— 观远官方 BI 全家桶（`guancli` 查数 / `guanvis` 建卡发布截图 / `guanetl` ETL / `guanwf` 数据流 / `guands` 数据源 / `guanmetric` 指标写）全部公网化后（2026-06-03 首发五件套、2026-07-08 `guanmetric` 入桶扩至 6 员），本 skill **不再自造轮子**：标准查数/建卡/ETL/数据集 CRUD 一律**路由官方全家桶**，只攻官方 DSL/命令够不着的硬骨头 —— ETL 治理判断 + 引擎报错手册、自定义图表注入 + descriptor patch、v7 状态机绕过、SuperApp 反向工程、AI-native ADS 方法论、餐饮公式库。\n> 兼容 **Claude Code** · **OpenClaw** · **Codex** · **Hermes (gbrain)** 等所有支持 SKILL.md 的 agent 工具。\n> 60+ 张 ETL 创建/重构/修复 + 治理扫描 + 自定义图表注入排障的真实战场记录。\n\n[![Skill Version](https://img.shields.io/badge/skill-v3.2.3-blue)](./SKILL.md)\n[![GitHub Release](https://img.shields.io/github/v/release/maojiebc/majia-guanyuan?label=release&color=success)](https://github.com/maojiebc/majia-guanyuan/releases)\n[![skills.sh](https://skills.sh/b/maojiebc/majia-guanyuan)](https://skills.sh/maojiebc/majia-guanyuan)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)\n[![Claude Code](https://img.shields.io/badge/Claude_Code-✓-orange)](https://docs.claude.com/en/docs/claude-code/skills)\n[![OpenClaw](https://img.shields.io/badge/OpenClaw-✓-blueviolet)](https://docs.openclaw.ai/tools/skills)\n[![Codex](https://img.shields.io/badge/Codex-✓-black)](https://developers.openai.com/codex/skills)\n[![Hermes](https://img.shields.io/badge/Hermes_(gbrain)-✓-darkgreen)](https://github.com/garrytan/gbrain)\n[![WorkBuddy](https://img.shields.io/badge/WorkBuddy-compat-1abc9c)](https://www.codebuddy.cn)\n[![Qoder](https://img.shields.io/badge/Qoder-compat-fa8231)](https://qoder.com)\n[![BI](https://img.shields.io/badge/Guandata-BI_6.x_/_7.x-purple)](https://www.guandata.com/)\n\n**[English README](README.en.md)** · 中文文档 ↓\n**本次兼容更新**：已对齐 guancli 1.0.63 / guanskill 0.1.41。单指标先看请求计划；批量创建指标先生成计划，断线后核对已有资源，避免重复创建；已有页面结构文件默认保留。详见 [兼容说明](references/official-cli-compatibility.md)。\n\n\n**手机案例最新版：** [V2 离线演示与源码](examples/store-mobile-scorecard-v2/README.md) · [ETL 与数据口径](references/part-c-store-mobile-scorecard-v2.md)。\n\n---\n\n## 概述\n\n**V3.0.0 重定位**：观远官方已把\"查数 / 建卡 / ETL / 数据流 / 数据源 / 截图 / 管理\"做成公网全家桶（`npm i -g @guandata/guanskill`）。本 skill 从早期\"自造全栈 + fallback\"**彻底重构为「官方全家桶之上的实战增益层」**——退役 2789 行自造 HTTP 客户端 `guandata.py`、删 ~1600 行死代码、砍掉所有镜像官方命令的章节。\n\n两层分工：\n- **🧭 路由层**：标准查数 / 建卡 / ETL / 数据集 CRUD 一律**路由给官方全家桶**（`guancli` / `guanvis` / `guanetl` / `guanwf` / `guands` / `guanmetric`），本 skill 不再自造这些轮子。\n- **💪 实战增益层（本 skill 主体）**：只攻官方 DSL/命令覆盖不到的硬骨头——3 大支柱：① **治理与引擎踩坑**（Part B ETL 整库治理判断 + 10 类引擎报错手册 + 双源审计 + B-17 全链路重写）② **前端注入与发布状态机**（Part C 既有页自定义图表注入排障 + Part C-12 HTML 应用化看板 descriptor patch + Part D v7 草稿-发布状态机绕过 + phoneLayout）③ **反向工程与方法论**（Part E SuperApp 开放应用反向工程 + AI-native ADS 数据架构方法论 + 餐饮 BI 公式实战库）。\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/maojiebc/majia-guanyuan/main/docs/architecture.png\" alt=\"majia-guanyuan v3.2.3 · 马甲实战版 架构图：官方全家桶路由层（guancli 1.0.63 查数 / guanvis 0.1.50 建卡发布截图 live / guanetl 0.1.38 ETL / guanwf 0.1.836 数据流 / guands 0.1.35 数据源 / guanmetric 0.1.19 指标写，6 件套）+ 本 skill 实战增益层 3 支柱——① 治理与引擎踩坑（Part B ETL 整库治理判断 + 10 类引擎报错手册 + 双源字段审计 + B-17 全链路重写/ExecPlan）② 前端注入与发布状态机（Part C 既有页自定义图表 HTML/JS 注入排障 + Part C-12 HTML 应用化看板 descriptor patch 联 dataView + Part D v7 草稿-发布状态机绕过 + customChart autoBootstrap + 移动端 phoneLayout ZIP inject）③ 反向工程与方法论（Part E SuperApp 开放应用反向工程 + form 历史兼容 + LLM 中转 ILLEGAL_JSON_RES 三路径解析 + AI-native ADS 设计方法论）\" width=\"100%\"/>\n</p>\n\n| 层 | 你想做 | 走 |\n|---|---|---|\n| 🧭 **路由层** | 查数据、建卡、出报表、标准 ETL / 数据集 CRUD | 交给官方全家桶（`guancli` / `guanvis` / `guanetl` / `guanwf` / `guands` / `guanmetric`） |\n| 🅱️ **Part B** | ETL 整库治理判断 + 引擎报错手册 + 双源字段审计 | \"扫一遍 ETL 看哪些可以删\" / \"direct-save 报错怎么修\" / \"字段裁剪安不安全\" |\n| 🅱️ **B-17** | 全链路重写方法论 | \"把这条 SmartETL 链整个改成 SQL 版\" / \"副本页验收 / 卡片级对比\" |\n| 🆎 **Part C / C-12** | 自定义图表注入排障 + HTML 应用化看板 + 门店手机成绩单 | \"payload_json 解析失败\" / \"固定卡片错位\" / \"更高级/应用化看板\" / \"加盟店老板手机成绩单\" |\n| 🇩 **Part D** | v7 草稿-发布状态机绕过 + phoneLayout | \"v7 page+card 被 60004 卡住\" / \"移动端 phoneLayout 怎么注入\" |\n| 🇪 **Part E** | SuperApp 开放应用反向工程 | \"表单结构先走 guands form；旧脚手架兼容问题再查 E\" / \"LLM 中转 ILLEGAL_JSON_RES\" |\n| 🧠 **方法论 / 公式库** | AI-native ADS 判断 + 餐饮 BI 公式（公式库已迁至 [majia-huiyuan](https://github.com/maojiebc/majia-huiyuan)） | \"想给现有 BI 接 AI，该治理还是该重搭\" / \"复购率/RFM/客单价怎么算\" |\n\n---\n\n## ✨ 效果\n\n### 🧭 路由层（标准活交给官方全家桶）\n\n- ✅ 标准查数 / 同环比 / Top N / 归因 / ChatBI 问数 / 仪表板洞察 / Dashboard Agent → `guancli`\n- ✅ 74 种图表 JS DSL 建卡 + Page 装配 + 服务端截图出 PNG + `live` 实时工程 → `guanvis`\n- ✅ 单个 ETL 新建/改/lint/preview/save/run/schedule → `guanetl`\n- ✅ 工作流数据流 Dataflow（DB 直连回写、增量输出）→ `guanwf`\n- ✅ 数据源 + 数据集 CRUD（建连接、create-db/import/replace-data、追加/清理、schema 同步）→ `guands`\n- ✅ 指标建/改/删 + 指标主题/目录 + 公共维度 + 指标树 + 查询加速 + 指标 Excel 标准化 → `guanmetric` 🆕（07-08 入桶第 6 员）\n- ⚠️ 管理员级操作（dynamicCode / svc SQL）：`guanadmin` **2026-06-04 已退出全家桶**（需另装 standalone 或走 BI UI）\n- 一句话路由：**标准查数 / 洞察 / Dashboard Agent → `guancli`；标准建卡/发布/截图 / live → `guanvis`；标准 ETL → `guanetl`；数据流 → `guanwf`；数据源/数据集 → `guands`；指标建/改/删 + 指标树 / 查询加速 → `guanmetric`。** 遇到官方够不着的字段/报错/状态机/反向工程/业务口径 → 回到本 skill 对应 Part。\n\n### ETL 治理写入侧（Part B）\n\n- ✅ **11 个已实测 BI HTTP API endpoint**（POST/GET/DELETE/OPTIONS 全覆盖）\n- ✅ **批量治理扫描**：构建依赖图 → 检测循环依赖 → 计算复杂度 → 8 维 ETL + 4 维字段去留判断\n- ✅ **ODS/DIM/DWD/DWS/APP 五层架构**重组指引\n- ✅ **字段使用度双源审计**（page + etl 双源 grep，避免**仅看板会高估 8 倍可裁字段**）\n- ✅ **POST /api/etl/direct-save** create + update 同接口的完整 payload schema\n- ✅ **task error 真错误定位**（`status:FINISHED` 是任务触发结果，真错误在 `GET /api/task/<id>.response.result.error`）\n- ✅ **删除拓扑**：`DELETE /api/data-source/` 必须先于 `DELETE /api/etl/`\n- ✅ **v2→v3 批量改造 SDK**：`transformV2ToV3()` 7 步重写 + 节点 ID 重映射\n- ✅ **CTO 张进的全链路重写方法论**：4 件交付 + 8 条硬规则 + 5 步标准工作流 + 三层验收 + 差异追踪 5 步法 + 空快照处理标准\n\n### 自定义图表侧（Part C）\n\n- ✅ **`renderChart` 4 参数 runtime 契约**详解（不是把第一个参数当 DOM 根节点）\n- ✅ **5 种 `data` 形态**识别\n- ✅ **payload_json 截断判断 3 步**（`Unterminated string` → 优先改数据方案，不堆兼容逻辑）\n- ✅ **拆列推荐方案**（替代单字段长 JSON）\n- ✅ **z-index 基线**（容器 8 / mask 1 / 固定卡 20）\n- ✅ **生命周期管理**（URL 不匹配/编辑态/phoneView/路由离开 → 销毁注入物）\n- ✅ **MutationObserver 死循环陷阱**（用低频轮询 + 精准 rect 比较替代）\n- ✅ **复制页 card id 重定位**（不会显式报错，只会悄悄失效）\n- ✅ **真实浏览器验收 8 项**\n\n### 报错修复手册\n\n- 🔧 **10 类 ETL 高频报错**：`请输入ETL名称` / `保存路径无效` / 上游运行权限不足 / 字段隐藏换行 / `<> NULL` / relativeFieldAlias 错位 / CTE 内 `;` / self-join 别名同名 / UNION 列差 / 字符串字面量与 DATE 比较\n\n---\n\n## ✅ 适合 / ❌ 不适合\n\n### ✅ 适合\n\n- 已经装了官方全家桶（`@guandata/guanskill`），想在标准命令之上补\"官方够不着的硬骨头\"\n- 做 ETL 治理（识别循环依赖、判断字段去留、重新分层、整库扫描）\n- 批量重建 ETL（30+ 张 v2→v3 改造）/ SmartETL 全链路重写 + 副本页验收 + 卡片级对比\n- 自定义图表 HTML/CSS/JS 注入开发与排障 / HTML 应用化看板（descriptor patch 联 dataView）\n- v7 草稿-发布状态机绕过 / SuperApp 开放应用反向工程\n- 给客户做\"治理 vs 重搭\"判断 / AI-native ADS 数据架构提案 / 餐饮连锁 BI 业务公式\n- 不会写代码但想让 AI 帮你完成上面这些事\n\n### ❌ 不适合\n\n- 用其他 BI 平台（Tableau / Power BI / Superset）—— 本 skill 只针对**观远 BI / Guandata**\n- **只做标准查数 / 标准建卡 / 标准 ETL** —— 那是官方全家桶的活，直接用 `guancli` / `guanvis` / `guanetl`，不需要本 skill\n- 完全不允许调用底层 HTTP API 的合规环境\n- 没有 BI 账号 + 写权限（Part B 写入需要 ETL 创建权限 + 数据集运行权限）\n\n---\n\n## 🔌 兼容性 / Compatibility\n\n本 skill **工具无关**，凡是支持 `SKILL.md` frontmatter 标准的 agent 都能加载。已在以下工具上验证：\n\n| 工具 | 状态 | 安装路径 | 入口文件 | 备注 |\n|---|:---:|---|---|---|\n| **Claude Code** | ✅ 已验证 | `~/.claude/skills/majia-guanyuan/` | `SKILL.md` | 原生支持 |\n| **OpenClaw** | ✅ 已验证 | `~/.openclaw/skills/majia-guanyuan/` 或 `<workspace>/skills/majia-guanyuan/` | `SKILL.md` | 大小写敏感 |\n| **Codex (OpenAI)** | ✅ 已验证 | `~/.codex/skills/majia-guanyuan/` 或 `<repo>/.codex/skills/majia-guanyuan/` | `SKILL.md` + 仓库根 `AGENTS.md`（项目指令） | 见 [Codex skills docs](https://developers.openai.com/codex/skills) |\n| **Hermes / gbrain** | ✅ 已验证 | `<workspace>/skills/majia-guanyuan/` | `SKILL.md` + 仓库根 `AGENTS.md`（resolver） | 见 [garrytan/gbrain](https://github.com/garrytan/gbrain) |\n| **Cursor / Aider** 等 AGENTS.md-aware | 🟡 理论兼容 | 任意 | `AGENTS.md` 作项目指令 | 仅会用到路由层 + Part B/C/D/E 的 navigation pointer |\n| 其他 | 🟡 通用清单 | 任意 | `manifest.json` 作工具无关元数据 | frontmatter + manifest 双保险 |\n\n## 📦 安装\n\n> **本仓库以 git 为唯一 source of truth**，未发布到 npm registry。但保留了一行 install 体验——通过 `node bin/install.js` 或 `npx github:` 直接走 GitHub。\n\n### 方式 0：GitHub CLI `gh skill`（GitHub CLI 2.90.0+）\n\n```bash\n# 安装到用户级 Codex / Claude Code / OpenClaw / Qoder 等 agent\ngh skill install maojiebc/majia-guanyuan majia-guanyuan --agent codex --scope user\ngh skill install maojiebc/majia-guanyuan majia-guanyuan --agent claude-code --scope user\ngh skill install maojiebc/majia-guanyuan majia-guanyuan --agent openclaw --scope user\ngh skill install maojiebc/majia-guanyuan majia-guanyuan --agent qoder --scope user\n\n# 安装前预览\ngh skill preview maojiebc/majia-guanyuan majia-guanyuan\n```\n\n### ⭐ 方式 1：克隆 + 内置 install CLI（推荐）\n\n```bash\n# 一键克隆 + 自动安装到当前机器上所有已装的 agent 工具\ngit clone https://github.com/maojiebc/majia-guanyuan.git ~/majia-guanyuan\ncd ~/majia-guanyuan\nnode bin/install.js install                  # 自动检测全装\nnode bin/install.js install --tool claude-code\nnode bin/install.js install --tool openclaw\nnode bin/install.js install --tool codex\nnode bin/install.js install --tool hermes\nnode bin/install.js install --tool all       # 4 个全装\n\n# 其他命令\nnode bin/install.js list                     # 列出当前安装情况\nnode bin/install.js uninstall --tool codex   # 移除该工具下的 skill\n```\n\n### 方式 2：`npx` 直接走 GitHub URL（不需要 clone）\n\n```bash\n# 一行装，npx 自动从 GitHub 拉取并跑 bin/install.js\nnpx github:maojiebc/majia-guanyuan install --tool claude-code\nnpx github:maojiebc/majia-guanyuan install --tool all\n```\n\n**`bin/install.js` 行为**（两种方式相同）：\n- 自动复制 `SKILL.md` / `AGENTS.md` / `manifest.json` / `scripts/` / `references/` / `templates/` 等到目标工具的 skill 目录\n- 已装时默认跳过，要 `--force` 才覆盖\n- **认证不在 skill 内**：本 skill 不再带 `config.json`——认证统一走官方全家桶的 `guancli auth login`（见下「前置依赖」）\n\n### 方式 3：手动 `git clone` 直接放到工具 skill 目录\n\n```bash\n# Claude Code\ngit clone https://github.com/maojiebc/majia-guanyuan.git ~/.claude/skills/majia-guanyuan\n\n# OpenClaw（个人级）\ngit clone https://github.com/maojiebc/majia-guanyuan.git ~/.openclaw/skills/majia-guanyuan\n\n# Codex（个人级）\ngit clone https://github.com/maojiebc/majia-guanyuan.git ~/.codex/skills/majia-guanyuan\n\n# Codex（项目级）\ngit clone https://github.com/maojiebc/majia-guanyuan.git <your-repo>/.codex/skills/majia-guanyuan\n\n# Hermes / gbrain（workspace 级）\ngit clone https://github.com/maojiebc/majia-guanyuan.git <your-workspace>/skills/majia-guanyuan\n```\n\n### 方式 4：OpenClaw / ClawHub 一键安装\n\n```bash\nopenclaw skills install majia-guanyuan\nclawhub install majia-guanyuan\n```\n\n> V3.0.0 起本 skill 已退役自造 HTTP 客户端 `guandata.py`，**不再在本地发送任何登录凭据**——查数/写入全部委托官方全家桶命令，认证走 `guancli auth login`（凭据由官方 CLI 管理）。安全说明见 [SECURITY.md](./SECURITY.md)。\n\n### 方式 5：Hermes skillpack 安装（如发布到 gbrain registry）\n\n```bash\ngbrain skillpack install majia-guanyuan\n```\n\n### 🔑 前置依赖：官方全家桶（所有工具相同）\n\n本 skill 的标准活全部路由给官方全家桶，所以**先装官方聚合包并登录一次**：\n\n```bash\n# 1. 一键装齐官方全家桶（guancli / guanvis / guanetl / guanwf / guands / guanmetric + 各自 AI skill）\nnpm i -g @guandata/guanskill\nguanskill install-skill\n\n# 2. 认证（全家桶共用一套 profile，本 skill 不再单独要 config.json）\nguancli auth login\n```\n\n| 命令 | 角色 | 路由什么需求给它 |\n|---|---|---|\n| `guancli` | 只读分析中枢 + 表单 CRUD + 洞察 | 查 ETL/dsId/page/card/血缘、`ds execute-sql`、`metric query` 同环比/Top N、归因、ChatBI 问数、`insight` 仪表板洞察 / Dashboard Agent、取数导出 |\n| `guanvis` | 标准建卡 + Page 装配 + 服务端截图 + live | 74 种图表 JS DSL、selector 联动、custom chart、`guanvis pack/publish/upload`、`guanvis live` 实时工程、`guanvis screenshot` 出 PNG |\n| `guanetl` | ETL 写操作闭环 | 单个 ETL 新建/改/lint/preview/save/run/schedule |\n| `guanwf` | 工作流数据流 Dataflow | 工作流引擎里建/编/存/跑数据流（DB 直连回写、增量输出；写操作要 `--confirm`） |\n| `guands` | 数据源 + 数据集 CRUD | 建连接、`dataset create-db/create-query/import/replace-data`、批量移删、增量更新、追加/清理、schema 同步 |\n| `guanmetric` 🆕 | 指标写操作（2026-07-08 入桶） | 指标 `create`/`edit`/`delete`（均支持 `--dry-run`）、指标主题/指标目录、公共维度、`metric-tree` 指标树、`accelerate` 查询加速、`template normalize` 指标 Excel 标准化；指标查询仍走 `guancli` |\n| ~~`guanadmin`~~ | 已退出全家桶（2026-06-04） | 管理员操作不再在公开全家桶，需另装 standalone |\n\n> ⚠️ **认证不再用 `config.json`**：V3.0.0 退役了自造客户端 `guandata.py`，凭据统一由 `guancli auth login` 管理，本 skill 不再读写 `config.json`。\n\n---\n\n## 🚀 快速开始\n\n### 🧭 路由层：标准查数 / 建卡（交给官方全家桶）\n\n```bash\n# 标准查数 → guancli（不需要本 skill）\nguancli ds search 营业额 --raw\nguancli metric query --ds <ds_id> --dim 城市 --metric 销售额:SUM \\\n  --filter 营业日期:BT:2026-02-01,2026-02-28\n\n# 标准建卡 + 服务端截图 → guanvis\nguanvis publish .\nguanvis screenshot <page_id> -o out.png\n```\n\n> 标准查数/建卡是官方全家桶的活，本 skill **不再自造**。只有遇到下面这些\"官方够不着\"的场景才进对应 Part。\n\n### Part B：建 ETL（数据建模）\n\n```bash\n# 1. 治理扫描\nguancli etl tree\nguancli --raw etl get <id> > raw/<id>.json\n# 本地脚本分析依赖图、循环组、复杂度 → analysis.json + governance-report.md\n\n# 2. 建 v2 目录（ETL + DATA_SET 各一个）\nguancli fetch POST /api/directory \\\n  '{\"name\":\"warehouse_v2\",\"parentDirId\":\"<父>\",\"dirType\":\"ETL\"}'\nguancli fetch POST /api/directory \\\n  '{\"name\":\"warehouse_v2\",\"parentDirId\":\"<父>\",\"dirType\":\"DATA_SET\"}'\n\n# 3. 写入 + 执行\nguancli fetch POST /api/etl/direct-save --stdin < payload.json\nguancli fetch POST /api/etl/execute '{\"dataFlowId\":\"<id>\"}'\n\n# 4. 失败定位（关键！别只看 status:FINISHED）\nguancli fetch GET /api/task/<taskId> | jq '.response.result.error'\n```\n\n### Part C：自定义图表（前端排障）\n\n```javascript\n// 观远 runtime 真实签名（不是把第一个参数当 DOM 根节点！）\nfunction renderChart(data, clickFunc, config, helpers) {\n  // data 常见形态：\n  // [[ {name:\"payload_json\",data:[\"{...}\"]}, {name:\"report_date\",data:[\"2026-03-18\"]} ]]\n\n  // 关键：如果 JSON.parse(payload_json) 报 Unterminated string\n  //  → 优先判断为\"数据链路截断\"，改数据方案（拆列），不堆前端兼容逻辑\n}\n\nnew GDPlugin().init(renderChart);\n```\n\n---\n\n## 📁 目录结构\n\n```text\nmajia-guanyuan/\n├── SKILL.md                          # AI 读的主文档（路由层 + Part B/C/D/E + 方法论）\n├── AGENTS.md                         # Codex 项目指令 / Hermes resolver（V1.3 新增）\n├── manifest.json                     # 工具无关 skill 元数据（V1.3 新增）\n├── README.md                         # 本文件（中文）\n├── README.en.md                      # English README\n├── CHANGELOG.md                      # 完整变更历史\n├── ATTRIBUTIONS.md                   # 致谢与来源\n├── LICENSE                           # MIT\n├── .gitignore\n├── scripts/\n│   └── inject_phone_layout.py        # Part D 移动端 phoneLayout ZIP inject 工具\n├── templates/\n│   └── html-dashboard/               # Part C-12 HTML 应用化看板模板包（GDHTML runtime + 起手模块 + selector 联动 patch）\n├── examples/\n│   └── store-mobile-scorecard/       # 门店手机成绩单脱敏离线 HTML（V1 版）\n└── references/                       # 深度参考资料\n    ├── part-b-errors.md              # Part B 10 类报错详方案\n    ├── part-b-payload.md             # ETL payload schema 详解\n    ├── part-b-sdk.md                 # v2→v3 批量改造 SDK\n    ├── part-b17-fullchain-rewrite.md # B-17 全链路重写方法论全章节 + ExecPlan 工作法\n    ├── part-c-payload-json.md        # C-3 payload_json 排障详解\n    ├── part-c-html-dashboard.md      # C-12 HTML 应用化看板生成方法论\n    ├── part-c-store-mobile-scorecard.md # 门店手机成绩单经验（产品规则 / 19 视图 / 换店 / 对比脱敏）\n    ├── part-c-design-baseline.md     # HTML 看板视觉设计底线（V3.1.0，吸收 design-taste-skills）\n    ├── v7-page-card-publish-pipeline.md  # Part D v7 草稿/发布状态机 + 节点化静默坑 + phoneLayout\n    ├── part-e-superapp-pipeline.md   # Part E SuperApp 反向工程流水线\n    ├── ai-native-ads-design.md       # AI-native ADS 设计方法论（哲学层文档）\n    ├── restaurant-bi-formulas/       # ➡️ 指针：公式库已迁至独立仓库 majia-huiyuan（公式库/）\n    ├── custom-chart-playbook.md      # CTO 张进自定义图表完整排障手册原文（V1.1）\n    ├── etl-rewrite-original.md       # CTO 张进 SmartETL 改写经验原文（V1.1）\n    ├── execplan-spec.md              # OpenAI Codex ExecPlan 规范（V1.2）\n    └── agents-rule.md                # OpenAI Codex 极简调度规则（V1.2）\n```\n\n---\n\n## 🎯 路由速查：标准活给官方，硬骨头进对应 Part\n\n| 用户需求 | 走 |\n|---|---|\n| \"查一下 2 月各城市营业额\" / \"做一张交叉表\" / \"删掉这张卡片\" | 🧭 官方全家桶（`guancli` / `guanvis`） |\n| \"建一个标准 ETL\" / \"上传个数据集\" / \"建数据连接\" | 🧭 官方全家桶（`guanetl` / `guands`） |\n| \"扫一遍 BI 的 ETL 看哪些可以删\" / \"ETL 之间有循环依赖怎么办\" | **B** |\n| \"direct-save 报错怎么修\" / \"字段使用度审计安不安全裁\" | **B** |\n| \"把这条 SmartETL 链整个改成 SQL 版\" / \"做副本页验收 / 卡片级对比\" | **B-17** |\n| \"上游空快照怎么写结论\" / \"差异定位到底在 SQL 还是执行时点\" | **B-17** |\n| \"30+ 表跨多日工程怎么管 / 给我 ExecPlan 骨架\" | **B-17.11** |\n| \"自定义图表脚本不执行 / payload_json 报错\" / \"固定卡片错位 / overlay 切页残留\" | **C** |\n| \"更高级 / 应用化看板 / selector 联不到 custom chart dataView\" | **C-12** |\n| \"加盟店老板手机成绩单 / 换店后财务空白 / 对比不要写多少家店\" | **门店手机成绩单** |\n| \"v7 page+card 被 60004 草稿页面卡住\" / \"移动端 phoneLayout 怎么注入\" | **D** |\n| \"常规表单建改用 guands form；历史兼容 / LLM 中转报错\" | **E** |\n| \"想给现有 BI 接 AI，该治理还是该重搭\" / \"AI-native ADS 怎么设计\" | **方法论** |\n| \"复购率 / 客单价 / RFM / 同店增长怎么算\" | **餐饮公式库** |\n\n---\n\n## 👤 作者 / 联系\n\n**马甲（@maojiebc）** · 超级马甲\n\n如果这份 skill 帮到你，欢迎在以下任意渠道找我交流踩坑实录、提需求、报 bug，也欢迎切磋用户运营 / 数据中台 / BI 工程的实战经验：\n\n| 渠道 | 链接 |\n|---|---|\n| 📧 Email | [m9224@163.com](mailto:m9224@163.com) |\n| 🐙 GitHub | [github.com/maojiebc](https://github.com/maojiebc) |\n| 🪝 ClawHub | [clawhub.ai/p/maojiebc](https://clawhub.ai/p/maojiebc) |\n| 🐦 X | [@maojiebc](https://x.com/maojiebc) |\n| 📕 小红书 | [超级马甲](https://xhslink.com/m/4fQMJeHHWKC) |\n| 📰 微信公众号 | **超级马甲** |\n\n> 这份 skill 是 14 年用户运营 + 观远 BI 实战 + 60+ 张 ETL 写入实证沉淀出来的，问题/合作随时聊。\n\n---\n\n## ❤️ 致谢与来源\n\n本 skill 站在多个前辈项目和经验贡献者的肩膀上，详细致谢见 [ATTRIBUTIONS.md](./ATTRIBUTIONS.md)：\n\n- **[guandata-bi @ ClawHub](https://clawhub.ai/skills/guandata-bi)** — 观远 BI 通用版 skill，本项目最早的灵感来源\n- **[zhengyuhe123/guandata](https://github.com/zhengyuhe123/guandata)** — guandata 原始 GitHub 项目\n- **小小郑3号 · guandata70** — 观远 7.0+ 适配版（draft/release 机制），本项目 Part A 的直接前身\n- **观远 BI CTO 张进** — Part B-17（SmartETL 全链路重写方法论）+ Part C（自定义图表开发与排障）的核心经验贡献者\n- **OpenAI Codex** — V1.2 引入的 [ExecPlan 规范](./references/execplan-spec.md)（自包含活文档 + 四章节项目管理结构），用于 30+ 张表跨多日 SmartETL 重写工程的项目化追踪\n- **马甲（@maojiebc）** — Part A/B 实战整合与 60+ 张 ETL 写入实证记录\n\n> 没有 ClawHub / 张进 / 小小郑3号 / OpenAI Codex 的开源精神，这份 skill 不可能存在。\n\n---\n\n## 📋 版本记录\n\n**最新：V3.2.3** (2026-09-28) — 跟进官方请求计划、指标创建恢复与编辑保护、ETL 输入类型修复和页面初始化保护。详见 [兼容说明](references/official-cli-compatibility.md)。\n\n**V3.2.2** (2026-09-23) — 同步当前移动看板的门店编号标签、顾客编号归属、观察期和堂食复购规则，更新脱敏源码、离线示例及28步SQL参考。补充订单关联重复导致金额翻倍的修复经验。详见 [移动看板 V2](examples/store-mobile-scorecard-v2/README.md)。\n\n**V3.2.1** (2026-09-20) — 对齐 guancli 1.0.62，补齐批量失败判定、字段校验与工作流调度说明。\n\n完整变更历史见 [CHANGELOG.md](CHANGELOG.md) 或 [GitHub Releases](https://github.com/maojiebc/majia-guanyuan/releases)。\n\n## 🤝 贡献\n\n欢迎 issue 和 PR：\n\n- 🐛 发现报错没在手册里的：欢迎提交 issue 描述报错信息 + payload + 真实错误（`/api/task/<id>.response.result.error`）\n- 📝 你跑通了新的 BI HTTP API endpoint：欢迎补充到 Part B 的 API 全图\n- 🎨 自定义图表新场景：欢迎补充到 Part C\n- 📚 文档优化、翻译、错别字修正：直接 PR\n\n---\n\n## 📄 License\n\n[MIT](./LICENSE) © 2026 [maojiebc](https://github.com/maojiebc) and contributors.\n\n本 skill 基于他人开源工作整合而成，详细 attribution 见 [ATTRIBUTIONS.md](./ATTRIBUTIONS.md)。\n\nFile v3.2.3:references/restaurant-bi-formulas/README.md\n\n# ➡️ 已迁移：majia-huiyuan/公式库（独立仓库）\n\n餐饮零售 BI 公式实战库（README + 9 篇分册，60+ SQL / 复购 / RFM / DWD 宽表范式 / 39 生产 ETL 索引）已于 2026-07-12 迁至独立的\"开源会员运营家底\"仓库，与咖啡连锁模拟数据中台（54 数据集 / 25 ETL / 12 看板）合并维护：\n\n**👉 https://github.com/maojiebc/majia-huiyuan/tree/main/公式库**\n\n- 本目录只留此指针，不再更新；历史版本在本仓库 git 历史（≤ v3.1.6）\n- 分工：**工具与踩坑手册在 majia-guanyuan，数据与公式在 majia-huiyuan**\n\nFile v3.2.3:templates/html-dashboard/README.md\n\n# templates/html-dashboard\n\nHTML 应用化看板模板包，配合 [`references/part-c-html-dashboard.md`](../../references/part-c-html-dashboard.md) 使用。\n\n随 majia-guanyuan **V2.1.1** (2026-05-14) 首次落地，源自 2026-05-14 `app.guandata.com` 上 `<demo-domain>` 实例的 `马甲—测试` 页面（资源 ID 已脱敏为占位符）实测沉淀。\n\n## 文件清单\n\n```text\ncharts/\n├─ html_common.js          GDHTML 共享 runtime（safeCols / money / yuan / pct / esc / bar / stacked / lineSvg / scatterSvg / mount）\n├─ html_base.css           共享样式（指标卡 / 列表 / 表格 / 标签 / 网格）\n├─ html_executive.html     经营驾驶舱 root 节点\n├─ html_executive.js       经营驾驶舱渲染（data[0..3]：KPI / 城市 Top / 低效 / 样板）\n├─ html_trend.html         月度渠道趋势 root 节点\n└─ html_trend.js           月度渠道趋势渲染（data[0]：月份 + 渠道 + 销售额）\n\nscripts/\n└─ patch_selector_linkage.js   把 HTML dataView 注入 selector.asFilter（弥补 guanvis linkToAll 的盲区）\n```\n\n## 使用\n\n### 起步\n\n```bash\nSKILL_DIR=~/.claude/skills/majia-guanyuan   # 或对应 agent 的安装路径\ncp -r \"$SKILL_DIR/templates/html-dashboard/charts\"   ./my-page/\ncp -r \"$SKILL_DIR/templates/html-dashboard/scripts\"  ./my-page/\n```\n\n### 一条命令补 selector 联动\n\n```bash\nnode ./my-page/scripts/patch_selector_linkage.js \\\n  --descriptor /tmp/unzipped-pkg/descriptor.json \\\n  --selector 城市:<fdId-城市> \\\n  --selector 门店类型:<fdId-门店类型> \\\n  --targets <html_dv_id_1>,<html_dv_id_2>,...\n```\n\n完整 pack → patch → upload → verify 工作流见 [part-c-html-dashboard.md §8](../../references/part-c-html-dashboard.md#8-packpatchupload-标准工作流)。\n\n## 扩展更多模块\n\n模板里只放了 `executive` + `trend` 两个起手模块。实战中常用的另 4 个（city / matrix / structure / actions）按相同的\"data contract → GDHTML mount → renderChart 注册\"结构扩出来即可，组件可以复用 `GDHTML.bar / stacked / lineSvg / scatterSvg / esc / money / yuan / pct`，不必重写。\n\n门店老板每天打开的手机成绩单不要用本模板硬套六模块驾驶舱，走 [门店手机成绩单](../../references/part-c-store-mobile-scorecard.md) 和 [离线样本](../../examples/store-mobile-scorecard/)。\n\n## 与 Part C 其他章节的关系\n\n- C-1 ~ C-11：既有页面的 HTML/JS 注入 hack（runtime DOM）\n- **C-12 / 本模板**：从零生成 HTML 应用看板（发布期 DSL + descriptor patch）\n\n两者共享 runtime 契约（`renderChart(data, ...)`）和 dataView 取数模型，但工具链完全不同。\n\n## 字段名兼容（重要）\n\n涉及日期粒度的模块都会自动兼容粒度后缀：\n\n```text\n日期 / 日期 (日)\n月份 / 月份 (月) / 年月 / year_month\n季度 / 季度 (季)\n年份 / 年份 (年)\n```\n\n实现在 `html_common.js` 的 `GDHTML.col()` 里，业务代码直接 `GDHTML.col(cols, \"月份\")` 即可，不要自己硬编码字段名。\n\nFile v3.2.3:_meta.json\n\n{\n  \"ownerId\": \"kn71njkqkab6a75db7hqb6ekz982jd29\",\n  \"slug\": \"guanyuan-majia\",\n  \"version\": \"3.2.3\",\n  \"publishedAt\": 1790561673590\n}\n\nFile v3.2.3:references/agents-rule.md\n\n# ExecPlans\n执行复杂任务或者重构时, 在计划和实施阶段，都使用 ExecPlan (参考.codex/PLANS.md的说明) 来追踪项目。\n\n# Project Knowledge\n如果有与项目相关的背景材料，都会放置在source文件夹下，可以查阅后理解项目\n\nFile v3.2.3:references/ai-native-ads-design.md\n\n# AI-native ADS 层设计 · 推倒重来 vs 渐进治理的范式判断\n\n> **来源**：2026-05-22 跑「会员经营任务池 OS」SuperApp demo（见 Part E）后，用户的根判断：「光数据治理没用，必须按适配 AI 的方式数据架构重搭一遍，要是在历史业务积累上做东西，估计全是阻碍」。这条心得不是 demo 期间凑出来的策略，是反复对照\"新建底表一路畅通\"和\"历史宽表寸步难行\"两种状态后蒸馏出来的范式判断。\n>\n> **何时读这里**：客户说\"想给现有 BI 接 AI / 上 LLM / 做 AI 副驾\" / \"我们 ETL 治理做了一年还没出活\" / \"数据资产丰富但模型用不起来\" / 评估\"是该治理还是该重搭\" / 跟客户做 BI 项目预算分配讨论。**这是 majia-guanyuan 哲学层文档，不是操作手册**——决定走哪条路，操作手册看 Part A-E。\n\n---\n\n## §1 现象层：demo 一路畅通 vs 历史包袱寸步难行\n\n跑完 Part E SuperApp demo 后回头看 `ads_会员经营任务池`（32 字段），每个字段的设计本身就是 AI-native 的：\n\n| 字段 | 设计选择 | LLM 视角的友好度 |\n|------|----------|-----------------|\n| `推荐动作` / `推荐权益` / `推荐原因` | **推荐结果预计算 + 落字符串** | 直接当 prompt 输入，不用临时拼 |\n| `会员等级` / `人群标签` / `角色标签` | **低基数中文枚举** | LLM 一眼看懂\"沉睡 / 流失 / 活跃\" |\n| `任务优先级` | **P0/P1/P2 标准化标签** | 优先级是推理输入，不用映射 |\n| `任务生成时间` / `截止时间` / `失效时间` | **TIMESTAMP 标准格式** | LLM 自己脑补\"今晚下班前\"\"周末\" |\n| `门店名称` | **城市 + 地标 + 编号拼成完整字符串** | LLM 自动用\"0783 店小张\"做角色扮演 |\n| `推荐权益 = \"满 30 减 10\"` | **直接落业务可读文案** | 短信\"明天午饭前下单刚好\" |\n\nLLM 能输出「我是 0783 店小张，上回您点的那单还记得吧」不是 claude-opus-4-6 多神，是**这张表把它能做角色扮演的信号全部铺好了**。\n\n### §1.1 反过来：历史业务积累的宽表会长什么样\n\n设想同样要做这个工作台，但底表是 10 年餐饮 ERP 沉淀的：\n\n| AI-native 版（demo 实际） | 传统业务积累版（典型客户现状） |\n|----|----|\n| `推荐动作 = \"电话回访+召回券\"` | `proc_act_type_v3 = 'P_CB_VCH'`（要查 dim_action_type 码表） |\n| `人群标签 = \"沉睡\"` | `seg_id = 7`（要 LEFT JOIN dim_segment 取 seg_name） |\n| `门店名称 = \"上海CBD0769店\"` | `store_code = 'S00769'`（要 JOIN dim_store 拼 `city + addr + store_no`） |\n| `推荐权益 = \"满30减10\"` | `coupon_rule_json = '{\"rule_type\":3,\"thresh\":30,\"discount\":10}'`（LLM 还得 JSON.parse 业务规则） |\n| 一张宽表 32 列 | 一个 view JOIN 11 张表，每张表都带历史 V2/V3 后缀 |\n\n把这种 schema 喂给 LLM 写\"老熟客闲聊\"语气的话术？它根本看不懂 `P_CB_VCH` 是啥意思，看不懂 `seg_id=7` 对应什么人群，更看不懂 `rule_type=3` 是哪种营销规则。**所以不管 LLM 多强，输出都是空中楼阁。**\n\n---\n\n## §2 本质层：两种 schema 假设的根本差异\n\n| 维度 | 传统 BI schema 假设 | AI-native ADS schema 假设 |\n|------|---------------------|--------------------------|\n| 消费者 | **人 + SQL** | **LLM + 人** |\n| 字段命名 | 业务系统打孔保留原名 / V2/V3 后缀堆叠 | 语义自描述（中文 + 业务可读） |\n| 维度取值 | enum code + ID 引用（节省空间） | 中文枚举落库（节省 LLM token + 跨字段对账） |\n| 复合语义 | 拆字段 + JOIN 还原 | 直接拼好落库 |\n| 推荐 / 标签字段 | 现场算 / 现场 JOIN 维表 | ETL 提前算好落库 |\n| 时间字段 | epoch / yyyymmdd 数字 / 各种字符串格式并存 | 统一 `TIMESTAMP YYYY-MM-DD HH:mm:ss` |\n| 优先级 / 排序 | 数字 1/2/3 + 注释含义 | 强约束取值（P0/P1/P2 / high/mid/low） |\n| 行级权限 | 推断（按 user 关联多表 JOIN） | 字段冗余进表（门店 ID / 加盟商 ID 直接落 ADS） |\n| 主要服务 | 月报 / 上下钻 / 交叉表 | LLM prompt / AI 应用 / 写回操作 |\n\n**核心差异是消费者**。传统 BI 默认消费者是「写 SQL 的人」——他可以查码表、可以 JOIN、可以 parse JSON、可以现场拼字段；AI-native ADS 默认消费者是「LLM + 业务方」——LLM 的\"现场计算能力\"远不如 SQL 引擎，**所有该问的、能猜的、要算的东西都要提前 ETL 进去**，把 LLM 的思考留给\"怎么说话给人听\"那一段。\n\n---\n\n## §3 推倒重来 ≠ 重做 ODS / DWD\n\n值得讲清楚的是：**不需要动 ODS / DWD**。需要重搭的是 ADS 层和它的字段命名 + 取值约束。\n\n| 层 | 是否动 | 原因 |\n|----|---|----|\n| 业务系统 | 不动 | 一线该咋写还咋写，业务流程零干扰 |\n| ODS / 缓冲层 | 不动 | 原始打孔合规 / 审计 / 数据血缘的源头 |\n| DIM / 维度层 | **不动** | 维表本身的码值映射是企业级标准 |\n| DWD / 明细汇总层 | **不动** | 已经做了清洗、维表打平、口径统一（按 Part D `restaurant-bi-formulas/08-etl-engineering-patterns.md` 的\"10-CTE DWD 宽表底座\"那套） |\n| **ADS / 应用层** | **整层重建** | 这才是给 LLM + SuperApp + AI 副驾直接消费的层 |\n\n这跟 [`restaurant-bi-formulas/08-etl-engineering-patterns.md`](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/08-etl-engineering-patterns.md) 的「10-CTE DWD 宽表底座 + 轻节点重 SQL 哲学」是**兼容互补**的——DWD 还是按宽表底座那套（财务双源对账 / POS 归一化 / 会员生命周期多输出 / Cohort 日期×门店网格都不动），**新建的是 DWD 之上、一对一面向某个 AI 应用场景的 AI-ready ADS 表**。\n\n一个客户可能有 1 张 DWD 主宽表 + N 张 AI-native ADS（每个 AI 应用一张）：\n\n```\ndwd_会员主宽表（500 字段，覆盖全业务口径）\n    ├── ads_会员经营任务池（32 字段，给\"任务池 SuperApp\"用，AI-native）\n    ├── ads_会员私域驾驶舱（28 字段，给\"会员副驾\"用，AI-native）\n    ├── ads_体验风险专题（22 字段，给\"风险预警副驾\"用，AI-native）\n    └── ads_加盟商单店报告（45 字段，给\"加盟商 PWA\"用，AI-native）\n```\n\n每张 ADS 表是**一对一面向具体 AI 应用场景**设计的——这是和传统\"通用宽表\"最大的区别。\n\n---\n\n## §4 AI-native ADS 七条字段约束\n\n蒸馏自 `ads_会员经营任务池` 实战，每条都有具体的 LLM 友好性原因：\n\n### §4.1 维度全用中文枚举值\n\n```\n✗ 传统:        seg_id INT (1=活跃, 2=流失, 3=沉睡, ...)\n✓ AI-native:   人群标签 STRING (\"活跃\" / \"流失\" / \"沉睡\")\n```\n\n**Why**：LLM 看 `seg_id=7` 不知道含义，看 `\"沉睡\"` 直接懂业务语境。**别担心 STRING 比 INT 慢** —— ADS 表本来就是 N 张小宽表，每张 < 100 万行，全表扫描照样秒级。\n\n### §4.2 推荐 / 标签字段提前 ETL 算好\n\n```\n✗ 传统:        现场算 RFM 评分 / 现场 JOIN 推荐引擎\n✓ AI-native:   推荐动作 STRING / 推荐权益 STRING / 推荐原因 STRING\n```\n\n**Why**：LLM 不擅长\"先看数据再决定推荐什么\"，但**非常擅长\"基于推荐结果写话术\"**。把 RFM / 推荐引擎跑完，把结果作为字符串字段落到 ADS 表里，LLM 接到这个就能写话术。\n\n### §4.3 复合语义直接拼好\n\n```\n✗ 传统:        门店编号 + 维表 JOIN 拼名字\n✓ AI-native:   门店名称 = \"城市 + 地标 + 编号\" 直接落库（\"上海CBD0769店\"）\n```\n\n**Why**：LLM 看到\"上海CBD0769店\"自动能拆出\"我是 0769 店小张\"\"上海 CBD 店\"等多种角色扮演方式；看到 `store_code='S00769'` 则啥也做不了。\n\n### §4.4 时间字段统一 `TIMESTAMP YYYY-MM-DD HH:mm:ss`\n\n```\n✗ 传统:        混合 (epoch / yyyymmdd / \"2026/05/22\" / \"22-May-26\")\n✓ AI-native:   全部 TIMESTAMP \"2026-05-22 14:30:00\"\n```\n\n**Why**：LLM 看标准 TIMESTAMP 能脑补出\"今晚下班前\"\"周末\"\"明天午饭前\"这种自然时间锚点；epoch 数字它需要心算还容易错。\n\n### §4.5 优先级 / 排序字段强约束取值\n\n```\n✗ 传统:        priority_level INT (1/2/3) + 注释含义\n✓ AI-native:   任务优先级 STRING (\"P0\" / \"P1\" / \"P2\" / \"P3\")\n```\n\n**Why**：业务方和 LLM 都能直接读 P0 = 紧急；1/2/3 谁是高优都说不清。\n\n### §4.6 数值字段提前算好\n\n```\n✗ 传统:        现场算 ROI / 净利率 / 折扣率\n✓ AI-native:   预计价值 DOUBLE (已算好) / 折扣率 DOUBLE (已算好)\n```\n\n**Why**：LLM 算复杂业务计算容易错（特别是涉及多张表 JOIN 的），ETL 跑准确算法 + 落数值字段是 100% 准的。\n\n### §4.7 行级权限字段冗余进表\n\n```\n✗ 传统:        靠 user_id → ... 多张关系表推断当前用户能看哪些行\n✓ AI-native:   归属门店ID / 加盟商ID / 区域ID 全部冗余进 ADS 表\n```\n\n**Why**：SuperApp 拉数据时直接按权限字段过滤，LLM prompt 也不用拼复杂权限判断。冗余存储换的是简化推理。\n\n---\n\n## §5 完整命名公约模板\n\n实际 ETL 写完，ADS 表的字段长这样（节选自 ads_会员经营任务池）：\n\n```sql\n-- ads_会员经营任务池 字段示例\n任务ID            STRING       -- \"T00012345\"\n任务优先级        STRING       -- \"P0\" / \"P1\" / \"P2\"\n任务类型          STRING       -- \"沉睡召回\" / \"流失预警\" / \"首单后二单\" / \"高价值维护\"\n任务来源          STRING       -- \"规则生成\" / \"AI 推荐\" / \"手动指派\"\n会员ID            STRING       -- \"M0064858\"\n会员等级          STRING       -- \"普卡\" / \"银卡\" / \"金卡\" / \"黑卡\"\n会员城市          STRING       -- \"上海\" / \"北京\" / \"深圳\" ...\n人群标签          STRING       -- \"活跃\" / \"流失\" / \"沉睡\" / \"高价值\"\n门店名称          STRING       -- \"上海CBD0769店\"（城市+地标+编号拼好）\n店型              STRING       -- \"旗舰店\" / \"快取店\" / \"外卖店\"\n推荐动作          STRING       -- \"电话回访+召回券\" / \"发二单券+推荐爆款\"\n推荐权益          STRING       -- \"满30减10\" / \"沉睡唤醒 9 折\"\n推荐原因          STRING       -- \"消费间隔接近流失阈值\"\n预计价值          DOUBLE       -- 84.5（提前算好，LLM 不算）\n任务生成时间      TIMESTAMP    -- \"2026-05-22 09:33:00\"\n任务截止时间      TIMESTAMP    -- \"2026-05-26 09:33:00\"\n触达状态          STRING       -- \"未触达\" / \"已触达\" / \"触达失败\"\n触达方式          STRING       -- \"企微1V1\" / \"电话\" / \"短信\"\n转化阶段          STRING       -- \"未触达\" / \"已触达未转化\" / \"已转化\"\n```\n\n**核心特征**：\n- 全部中文字段名（不需要 i18n，LLM 中文输出本来就强）\n- 全部字符串枚举值（除了金额 / 时间）\n- 复合字段提前拼好\n- 时间字段统一格式\n- 推荐字段是 ETL 算法的输出，不是 ADS 表的输入\n\n---\n\n## §6 客户视角的预算分配建议\n\n### §6.1 旧叙事 vs 新叙事\n\n| 旧叙事（渐进治理） | 新叙事（AI-native 重搭 ADS） |\n|------|------|\n| \"我们 ETL 太多了，先做治理\" | \"我们要给业务方做 AI 副驾，先重搭 ADS\" |\n| 12 个月项目周期 | 3 个月项目周期 |\n| 产出：删 30% 冗余 ETL / 修 50 个对账差异 / 字段命名规范文档 | 产出：3-5 个 AI 应用上线 / 业务方直接用 / ROI 可量化 |\n| 高层视角：\"看不出价值变化\" | 高层视角：\"业务方在用 AI 副驾发券，单量涨 8%\" |\n| 治理预算 100 万 | 重搭 ADS 50 万 + AI 应用 50 万（同样预算） |\n\n### §6.2 推荐预算分配（同样 100 万）\n\n```\n旧分配:  治理 100% (100 万) → 价值产出: 删冗余 + 改命名 = 内部 PR 友好,业务无感知\n新分配:\n   - 治理 30% (30 万)  → 必要的脏数据清理 + 关键对账\n   - 重搭 ADS 30% (30 万)  → 3-5 张 AI-native ADS 表\n   - AI 应用 40% (40 万)   → 3-5 个 SuperApp(任务池 / 副驾 / PWA)\n   → 价值产出: 业务方天天在用,可量化 ROI\n```\n\n**关键判断**：**治理预算的一半挪去重搭 ADS + 上 AI 应用，产出比直接治理高一个数量级**——治理只清\"脏数据\"，重搭才换\"schema 假设\"。\n\n---\n\n## §7 与 majia-guanyuan 既有 Part 的关系\n\n| Part | 关系 |\n|------|------|\n| **Part A 数据查询与卡片创建** | 跟 AI-native ADS 正交——不管 ADS 是什么形态都能查 |\n| **Part B ETL 治理与写入** | **正交补充**：Part B 是 ETL 操作手册（怎么写 / 怎么治），本文是 **要不要治 vs 要不要重搭** 的判断 |\n| **Part B-17 全链路重写方法论** | **同源**：B-17 是\"把一条 SmartETL 链改写成 SQL 版\"，本文是\"为什么要重搭一整层 ADS\"——后者是前者的战略升级版 |\n| **Part C 自定义图表 / Part C-12 HTML 看板** | 互补——AI-native ADS 让 Part C 的图表参数（颜色 / 标签 / 推荐文案）也可以直接读 ADS 字段 |\n| **Part D V7 Page/Card 发布流水线** | 正交 |\n| **Part E SuperApp 开放应用** | **强依赖**：SuperApp 能跑顺的前提是 ADS 是 AI-native。本文是 Part E 的\"前置假设\"——读完 Part E 再回来读本文最有体感 |\n| **restaurant-bi-formulas（餐饮 BI 公式实战库，已迁至 [majia-huiyuan](https://github.com/maojiebc/majia-huiyuan)）** | **兼容**：餐饮库的\"10-CTE DWD 宽表底座\"作为 DWD 层不动；本文新建的是 DWD 之上的 ADS 层 |\n\n---\n\n## §8 反模式 · 不要做这些\n\n| 反模式 | 为什么不行 | 替代 |\n|--------|-----------|------|\n| 把 enum code 落 ADS 表（如 `seg_id=7`） | LLM 看不懂码值 | 中文枚举落库（`人群标签=\"沉睡\"`） |\n| ADS 表设计成\"通用宽表\"覆盖所有场景 | 字段语义打架 / LLM token 浪费 | 一对一面向 AI 应用场景，每个应用一张 ADS |\n| 时间字段保留 epoch / 8 位数字格式 | LLM 心算容易错 | 统一 `TIMESTAMP YYYY-MM-DD HH:mm:ss` |\n| 推荐字段让 LLM 现场算（\"你看下这个会员的 RFM...\"） | LLM 算业务逻辑不稳 | ETL 算法跑完 + 字符串字段落库 |\n| 行级权限靠 JOIN 推断 | SuperApp / LLM 拼权限判断超复杂 | 权限字段冗余进 ADS 表 |\n| 跳过 DWD 直接从 ODS 建 ADS | 错过维表打平 / 口径统一 / 双源对账 | 走 DWD → ADS 两步 |\n| 把\"治理预算\"全部砸在 ETL 治理上 | 治理只清脏数据，不换 schema 假设 | 治理 30% + 重搭 ADS 30% + AI 应用 40% |\n| **把 SuperApp 当目标，跳过 ADS 重搭** | 历史宽表喂给 LLM 出不来好结果，demo 永远做不通 | **先重搭 ADS 再做 SuperApp** |\n\n---\n\n## §9 何时回到这份文档\n\n| 触发场景 | 跳到 |\n|----------|------|\n| 客户问\"我们 ETL 治理做了一年还没出活\" | §6 预算分配 + 全文核心叙事 |\n| 客户问\"我们底表 schema 看起来不太适合 LLM\" | §4 七条字段约束 |\n| 评估\"是治理还是重搭\" | §3 ADS 层重建 + §2 schema 假设差异 |\n| 客户问\"重搭 ADS 不会破坏现有报表吧\" | §3 强调 ODS/DIM/DWD 不动 |\n| Part E SuperApp demo 跑得不顺 | §1 反过来看 ADS 是不是 AI-native |\n| 跟客户提案怎么写\"AI-native 数据底座\" | §5 完整命名公约模板 + §6 预算分配 |\n\nFile v3.2.3:references/coupon-order-link-diagnosis.md\n\n# 券已核销，但没有关联订单：怎么排查\n\n“已核销”只证明券系统记录了一次使用动作。要计算关联实付，还必须有可核验的券→交易→订单链路。缺失不是0元收入，也不能直接说没有消费。\n\n## 按链路逐层确认\n\n| 观察 | 能确认什么 | 下一步 |\n|---|---|---|\n| 原始券表的使用订单流水ID为空 | 关联字段在进入看板之前就缺失 | 看核销时间、后续回写、撤销及POS核销请求日志 |\n| 流水ID存在，但交易日志找不到 | 上游关联目标缺失或未同步 | 检查日志抽取范围、刷新时间、补传、归档 |\n| 交易日志存在，POS订单找不到 | 两条数据链未完整对齐 | 用订单号检查门店映射、日期边界和订单源覆盖 |\n| 附近有同顾客交易，但使用的是另一张券 | 原核销不能直接归到这笔成交 | 核对是否换券、重新核销或前次未撤销 |\n| 附近订单只记手工折扣，无券号 | 有打折消费线索，但不能精确到券 | 核查小票与收银日志，不按时间自动补关联 |\n| 券作为支付方式 | 记录金额不能直接当顾客现金实付 | 与结算、支付流水核对 |\n\n同一顾客、同一门店、相近时间只能找候选，不能作为金额入账的唯一依据。例如合成案例中先核销券A，随后核销券B，完成订单只带券B；把订单补给A会重复归因。即使两张券名称相同，也不能当作一张券。\n\n若历史多日仍缺流水ID，短时同步延迟的解释就不足；但仅凭BI快照仍不能确认具体操作人、软件接口错误或是否发生人工核销。应把具体时间、券标识和请求链提供给内部支持人员核查，不把这些敏感样本放进公开仓库。\n\n## 可以每日自动判断的范围\n\n用确定性规则细分“缺关联流水”“有流水但日志缺失”“有日志但订单缺失”“关联金额待核验”，对异常记录保留数量、来源更新时间和待核原因。只有有稳定关联键且状态、门店、金额均通过校验，才允许计入金额。\n\n本发布示例仍保留原有 unmatched 聚合分类；这份排查说明不是已上线的细分类改造。增加上游关联字段、异常子类或重试调度时，应单独测试数据血缘、去重及权限。不要只改提示文案就声称已经修复数据链路。自动判断无须调用大模型。\n\nArchive v3.2.1: 87 files, 1166772 bytes\n\nFiles: AGENTS.md (8523b), ATTRIBUTIONS.md (8584b), bin/install.js (10802b), CHANGELOG.md (141454b), config.example.json (592b), docs/architecture.png (724899b), docs/architecture.svg (18020b), examples/store-mobile-scorecard-v2/build.mjs (26705b), examples/store-mobile-scorecard-v2/etl/active_stores.sql (761b), examples/store-mobile-scorecard-v2/etl/contact_daily.sql (488b), examples/store-mobile-scorecard-v2/etl/contact_stock.sql (752b), examples/store-mobile-scorecard-v2/etl/coupon_conversion.sql (5133b), examples/store-mobile-scorecard-v2/etl/customer_status.sql (457b), examples/store-mobile-scorecard-v2/etl/dormant_customers.sql (469b), examples/store-mobile-scorecard-v2/etl/finance_daily.sql (643b), examples/store-mobile-scorecard-v2/etl/group_daily.sql (488b), examples/store-mobile-scorecard-v2/etl/group_stock.sql (758b), examples/store-mobile-scorecard-v2/etl/hours_daily.sql (1670b), examples/store-mobile-scorecard-v2/etl/identified_daily.sql (647b), examples/store-mobile-scorecard-v2/etl/member_30d.sql (752b), examples/store-mobile-scorecard-v2/etl/member_7d.sql (748b), examples/store-mobile-scorecard-v2/etl/member_anomaly_evidence.sql (1999b), examples/store-mobile-scorecard-v2/etl/member_anomaly_orders.sql (1755b), examples/store-mobile-scorecard-v2/etl/member_comparison.sql (937b), examples/store-mobile-scorecard-v2/etl/member_daily.sql (546b), examples/store-mobile-scorecard-v2/etl/member_month.sql (745b), examples/store-mobile-scorecard-v2/etl/member_peer_eligibility.sql (4130b), examples/store-mobile-scorecard-v2/etl/member_peer_ranking.sql (2248b), examples/store-mobile-scorecard-v2/etl/pipeline.json (5969b), examples/store-mobile-scorecard-v2/etl/products_7d.sql (1029b), examples/store-mobile-scorecard-v2/etl/README.md (1419b), examples/store-mobile-scorecard-v2/etl/revenue_peers.sql (716b), examples/store-mobile-scorecard-v2/etl/soup_7d.sql (546b), examples/store-mobile-scorecard-v2/etl/soup_coverage.sql (1185b), examples/store-mobile-scorecard-v2/etl/store_context.sql (1669b), examples/store-mobile-scorecard-v2/etl/store_ordering.sql (1262b), examples/store-mobile-scorecard-v2/preview.png (46511b), examples/store-mobile-scorecard-v2/README.md (3582b), examples/store-mobile-scorecard-v2/scorecard.css (22243b), examples/store-mobile-scorecard-v2/scorecard.js (67205b), examples/store-mobile-scorecard-v2/store-mobile-scorecard.html (369645b), examples/store-mobile-scorecard-v2/test.cjs (2804b), examples/store-mobile-scorecard/build.mjs (21428b), examples/store-mobile-scorecard/README.md (2380b), examples/store-mobile-scorecard/scorecard.css (14033b), examples/store-mobile-scorecard/scorecard.js (46275b), examples/store-mobile-scorecard/store-mobile-scorecard.html (159783b), examples/workshop513-咖啡连锁会员运营模拟案例/README.md (626b), LICENSE (1097b), llms.txt (4117b), manifest.json (3091b), package.json (1672b), README.en.md (28164b), README.md (26616b), references/agents-rule.md (271b), references/ai-native-ads-design.md (15317b), references/coupon-order-link-diagnosis.md (2419b), references/custom-chart-playbook.md (5416b), references/etl-rewrite-original.md (7889b), references/execplan-spec.md (14482b), references/official-cli-baseline.json (351b), references/official-cli-compatibility.md (10682b), references/part-b-errors.md (4106b), references/part-b-payload.md (6926b), references/part-b-sdk.md (2026b), references/part-b17-fullchain-rewrite.md (14566b), references/part-c-design-baseline.md (12139b), references/part-c-html-dashboard.md (22994b), references/part-c-payload-json.md (1889b), references/part-c-store-mobile-scorecard-v2.md (6195b), references/part-c-store-mobile-scorecard.md (18442b), references/part-e-superapp-pipeline.md (30860b), references/restaurant-bi-formulas/README.md (603b), references/v7-page-card-publish-pipeline.md (51782b), scripts/inject_phone_layout.py (4684b), SECURITY.md (1321b), skill-card.md (2830b), SKILL.md (77618b), templates/html-dashboard/charts/html_base.css (3096b), templates/html-dashboard/charts/html_common.js (7581b)\n\nFile v3.2.1:SKILL.md\n\n---\nname: majia-guanyuan\ndescription: 观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。\nlicense: MIT\nmetadata:\n  version: \"3.2.1\"\n  author: \"超级马甲 / maojiebc\"\n  homepage: https://github.com/maojiebc/majia-guanyuan\n  openclaw:\n    emoji: \"📊\"\n    homepage: https://github.com/maojiebc/majia-guanyuan\n    os:\n      - macos\n      - linux\n    requires:\n      bins:\n        - jq\n        - bash\n    install:\n      - kind: npm\n        package: \"@guandata/guanskill\"\n        bins:\n          - guancli\n          - guanvis\n          - guanetl\n          - guanwf\n          - guands\n          - guanmetric\n---\n\n# 观远 BI · 马甲实战版（V3.2.1）\n\n> **结构说明（V1.5.0 引入 progressive disclosure）**：本文档是**路由层 + 关键规则**，详细操作手册下沉到 `references/`。每个 Part 的入口章节会指出\"何时回到 references/ 查全表\"。完整章节索引见末尾的 [📚 References 目录](#-references-目录)。\n\n## 🧭 Part 选择\n\n| 你想做 | 走 |\n|---|---|\n| 查数据、建卡、出报表、标准 ETL / 数据集 CRUD / 指标写 / 洞察问答 | **🧭 路由层** → 交给官方全家桶（`guancli` / `guanvis` / `guanetl` / `guanwf` / `guands` / `guanmetric`），见路由总表 |\n| 扫整库 ETL 治理 / 新建/修改/删除 ETL / 字段使用度审计 / 修复 ETL 报错 | **Part B：ETL 治理与写入** |\n| 把整条 SmartETL 链改写成 SQL 版 + 页面副本验收 + 差异定位 + 空快照阻塞 | **Part B-17：全链路重写方法论**（拆到 [references/part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md)） |\n| 30+ 张表批量迁移 / 跨多日工程 / 复杂重构需要项目化追踪 | **B-17.11 ExecPlan 工作法**（同上文件 §11） |\n| 自定义图表 HTML/CSS/JS 注入、固定卡片/overlay、payload_json 取数、路由清理 | **Part C：自定义图表开发与排障** |\n| 从零生成 HTML 化经营分析应用（用户说\"更高级 / 应用化 / 自定义模块 / 最完美 / 不限标准看板\"）| **Part C-12：HTML 应用化看板生成**（拆到 [references/part-c-html-dashboard.md](references/part-c-html-dashboard.md)） |\n| 手机成绩单专供ETL / 红色异常提示 / 券转化明细 / 近7天营业额排序 / 核销未匹配订单 | **V2** [实践与口径](references/part-c-store-mobile-scorecard-v2.md)、[离线示例](examples/store-mobile-scorecard-v2/README.md)、[券关联排查](references/coupon-order-link-diagnosis.md) |\n| 加盟店老板手机成绩单 / 门店移动看板 / 换店后财务空白 / GDPlugin 视图顺序错位 / 对比组家数泄露 / 要一份可离线点的移动样本 | **Part C 门店手机成绩单**（拆到 [references/part-c-store-mobile-scorecard.md](references/part-c-store-mobile-scorecard.md)，离线 HTML： [examples/store-mobile-scorecard/](examples/store-mobile-scorecard/)） |\n| **v7 BI 实例**上端到端搭多个 HTML 应用看板 / 手撸 `POST /api/page+/api/card` 被 `60004 此操作只能在草稿页面执行` 卡住 / CSV 散客 `会员ID IS NOT NULL` 算出 100% 假指标 / Spark `WITH 中文别名` 报 `PARSE_SYNTAX_ERROR` / ETL update 报 `1012 输出数据集目录中存在同名文件` | **Part D：V7 Page/Card 发布流水线 + 三态硬规则**（V2.1.6 新增，拆到 [references/v7-page-card-publish-pipeline.md](references/v7-page-card-publish-pipeline.md)） |\n| **SuperApp / 超级应用 / 开放应用**开发流水线 / `guancli app create/publish` / `--app-id` 不传变成每次新建 / 数据集异步预览 3 步 / 表单结构先走 `guands form`；旧脚手架建表兼容问题按 §6/ **BI 中转 LLM 报 NOT_JSON_RES / ILLEGAL_JSON_RES**（响应被塞在 error_message）/ `/api/llm-config/list` 返回裸数组被脚手架 unwrap 吞 / 同源 fetch credentials 不带 cookie / 客户端模拟流式打字效果 / 任务池工作台「看 + 想 + 选 + 做 + 留痕」闭环 | **Part E：SuperApp 开放应用开发流水线**（V2.1.12 新增，拆到 [references/part-e-superapp-pipeline.md](references/part-e-superapp-pipeline.md)） |\n| **客户说\"想给现有 BI 接 AI / 上 LLM\"** / \"我们 ETL 治理做了一年还没出活\" / **判断 是该治理还是该重搭** / 客户预算分配讨论 / 评估底表 schema 是否 AI-friendly / 提案\"AI-native 数据底座\" | **AI-native ADS 设计方法论**（V2.1.13 新增，**majia-guanyuan 的哲学层文档**——不是操作手册而是范式判断，拆到 [references/ai-native-ads-design.md](references/ai-native-ads-design.md)） |\n| 写餐饮业务公式（AC / ADS / 复购率 / 新老客 / 用餐时段 / 留存流失 / RFM / Comp 老店）/ 查字段口径 / 排数据质量坑 / **ETL 工程范式（DWD 宽表 / 双源对账 / 评价 pipeline）** | **餐饮 BI 公式实战库**（[majia-huiyuan/公式库](https://github.com/maojiebc/majia-huiyuan/tree/main/公式库)，V2.1.5 蒸馏自两段餐饮连锁 BI 履职 + 39 个生产 ETL，全脱敏；**2026-07-12 迁至独立仓库 majia-huiyuan**，本仓库 references/restaurant-bi-formulas/ 仅留指针） |\n| 不知道用哪个 | 看 Part B \"推荐工作流\" 章节，或直接读各 Part 章节末尾的\"实战 ID 速查\" |\n\n> **作者**：马甲（Part B/C/D/E 实证）+ 观远 CTO 张进（B-17 SmartETL 改写方法论 + Part C 自定义图表经验）+ OpenAI Codex（ExecPlan 规范）\n> **版本**：V3.2.1（2026-09-20）· **环境**：Node ≥20 · **前置**：官方全家桶 `npm i -g @guandata/guanskill && guanskill install-skill`（装齐 guancli / guanvis / guanetl / guanwf / guands / guanmetric + 各自 AI skill）· **认证**：`guancli auth login`（全家桶共用一套 profile，本 skill 不再单独要 config.json）· **作用域**：本地私有 BI 实例\n> **安装**：`git clone https://github.com/maojiebc/majia-guanyuan.git`，或 `npx github:maojiebc/majia-guanyuan install`\n> **兼容工具**：Claude Code · OpenClaw · Codex · Hermes (gbrain) · 任何支持 `SKILL.md` frontmatter 的 agent。详见 [README · 兼容性](README.md#-兼容性--compatibility) 与 [AGENTS.md](AGENTS.md)。\n>\n> 🆕 **V3.2.1**（2026-09-20）：对齐 guancli 1.0.62 与 guanskill 0.1.39；补齐批量失败判定、原始值与展示值一次返回、字段校验、下游检查及工作流调度兼容。详见 [兼容说明](references/official-cli-compatibility.md)；完整历史见 [CHANGELOG.md](CHANGELOG.md)。\n\n---\n\n# 🧭 路由层：标准活交给官方全家桶\n\n> **V3.0.0 心法**：观远官方已把\"查数 / 建卡 / ETL / 数据流 / 数据源 / 截图 / 管理\"做成公网全家桶（`npm i -g @guandata/guanskill`）。本 skill **不再自造这些轮子**——标准活一律路由给官方，本 skill 专攻官方 DSL/命令覆盖不到的\"业务实战 + 引擎级踩坑\"（Part B–E + 方法论 + 公式库）。\n\n## ⚠️ 跨 Part 通用工作原则\n\n1. **所有数值计算必须跑代码** —— 禁止在思考里口算百分比、环比、除法、占比。\n2. **必须确认数据范围** —— 用户没明确日期范围时**必须追问**（\"看哪段时间？今天 / 本周 / 上月？\"），不要自己假设。\n3. **遇到意外错误立即落档** —— 把新坑写进对应章节（Part B 报错 → `references/part-b-errors.md`，Part C → `references/part-c-payload-json.md`）或 ExecPlan 的 `Surprises & Discoveries`（B-17.11）。格式：`### [YYYY-MM-DD] 标题` + 场景 / 问题（含 task error 原文、payload 片段）/ 判断。\n4. **写操作前先治理、删除前先对账** —— 见 Part B-〇 工作流 + B-7.0 删除安全闸。\n\n## 官方全家桶 ↔ 本 skill 分工总表\n\n> 前置：`npm i -g @guandata/guanskill && guanskill install-skill`（装齐 7 个命令：guanskill + 6 组件，各带 AI skill）；认证 `guancli auth login`，全家桶共用一套 profile。\n\n| skill | 版本 | 角色 | 什么需求路由给它 |\n|---|---|---|---|\n| **`guancli`** | 1.0.62 | 查询分析、表单数据、SuperApp | 查 ETL/数据集/页面/卡片/血缘、SQL、指标查询/归因、ChatBI、仪表板洞察与 Dashboard Agent；独立基础指标用 `metric batch-query`，高级计算用 `metric query`；`analyze normalize/align/calculate/topn` 处理本地结果；Form 数据 CRUD；SuperApp create/list/download/publish。指标计算显式 `--value-format raw`，按 JSON 版本与 inline/file 分支读取，批量逐项检查状态，自动处理加 `--fail-on-error`；计算兼展示用 `valueFormat: \"both\"`，计算只读 `rows`。未知筛选字段须纠正，不能删条件重跑。 |\n| **`guanvis`** | 0.1.49 | 建卡、页面、发布、截图 | 图表 DSL、checkout/diff/preview/pack/publish/screenshot、指标卡、custom chart、筛选器联动及 `live`；页面与目录原地管理、`page save-as` 原生副本；新增高级筛选器、卡片池、交叉表 `filterBy` 逐格校验。新页面先确认目标目录；覆盖前备份，覆盖后重置目标页面草稿。`preview` 默认摘要，完整输出用 `--full`；复杂自定义图表走完整工程，不用 live 基础卡片命令模拟。 |\n| **`guanetl`** | 0.1.37 | ETL 编辑与运行 | create/edit/export/lint/preview/save/run/schedule、move、mkdir-pair；`rmdir` 只删空 ETL 目录，物理删除且需 `--yes`；仍无删除 ETL 命令。新建须明确 ETL 与输出数据集各自目录；按 ETL ID 跟踪执行，已移除全局 `task`。历史节点下划线导出修复，DSL 类型化常量兼容旧字符串；保留输出绑定、字段物化、JOIN 类型及 dry-run 影响检查。 |\n| **`guanwf`** | 0.1.836 | 工作流与数据流 | workflow.go / Python / 多节点 DAG / 参数与调度 / 实例诊断；写操作先 `--dry-run` 再 `--confirm`（兼容 `--yes`）。新增 Python 运行环境 与内存预检、按 task/output slot 绑定输出；首次 CREATE_NEW 输出须绑定并发布保存后再跑。验证只在已有草稿执行，不注册真实输出；保存后回读、运行后逐项验收输出。调度 `--failure-strategy` 已废弃且仅接受 CONTINUE，失败走向由 FAILURE / ALL 连线决定。Python 版本优先读结构化镜像字段。类型化 DSL 兼容字符串。8.2.0 节点限制与失败恢复范围仍按官方 guanwf Skill 执行。 |\n| **`guands`** | 0.1.35 | 数据源、数据集、表单结构 | connector/account/dataset/dir 管理、导入/追加/替换、刷新调度、主键与计算字段；Form create/export/update/rename/move/folder。`dataset sync-schema` 支持 GUAN_FORM 原地同步并回读字段 ID/类型/状态。新建先确认目录，append-data/replace-data 实写需 `--yes`；按数据集 ID 跟踪，已移除全局 `task`。Excel 多 Sheet 必须显式选择。数据集目录不能移动；目录删除不可恢复。 |\n| **`guanmetric`** | 0.1.18 | 指标定义与管理 | 指标建/改/删、主题/目录、公共维度、指标树、查询加速、业务字典、Excel 模板及 `--check-only` 预检；批量上下线用 `batch online/offline`，先 dry-run、按依赖顺序逐项处理。失败不回滚已成功项，blocked 先核对影响再确认；上线请求获接受后仍须回读审批/发布状态。复合指标只引用原子或复合指标；指标查数仍走 guancli。 |\n| **`guanvis screenshot`** | — | 导出 | 页面 PNG/PDF 服务端截图（彻底取代 legacy `guanexport`）|\n| ~~`guanexport` / `guanadmin`~~ | **已退出** | — | **2026-06-04 起从 `guanskill` 聚合包移除、npm 也下架**：导出全归 `guanvis screenshot`；管理员级操作（dynamicCode / adminToken / svc SQL）已不在公开全家桶，需另装 standalone 或走 BI UI |\n| **`majia-guanyuan`**（本 skill） | **3.2.1** | 业务实战 + 引擎级踩坑 + 方法论 | **Part B** ETL 整库治理判断 + 10 类引擎报错 + 双源字段审计 + B-17 全链路重写/ExecPlan · **Part C** 既有页自定义图表 HTML/JS 注入排障 + 固定卡/overlay · **Part C-12** HTML 应用化看板 + descriptor patch 联 dataView + **视觉设计底线（反 AI 味红线 + 五层验收）** · **门店手机成绩单**（19 视图 + 列名识别 + 脱敏离线样本） · **Part D** v7 草稿-发布状态机绕过 + 节点化静默坑 + phoneLayout · **Part E** SuperApp 反向工程 · **AI-native ADS** 方法论 · **餐饮 BI 公式库** |\n\n**一句话路由**：标准查数 / 洞察 / Dashboard Agent → `guancli`；标准建卡/发布/截图 / `live` 实时工程 → `guanvis`；标准 ETL → `guanetl`；数据流 → `guanwf`；数据源/数据集 → `guands`；指标建/改/删 + 指标主题/目录 + 公共维度 + **指标树 / 查询加速** → `guanmetric`。**任何一个遇到官方 DSL/命令够不着的字段、报错、状态机、反向工程、业务口径**——回到本 skill 对应 Part。\n\n官方 `guandata-cli-suite` 负责选择组件，并已包含原地编辑与删除边界。本表补充本次核验版本及关键兼容规则；参数与完整操作流程以已安装的官方 Skill 为准。此前逐版本变化保存在 CHANGELOG，不在路由表重复累积。\n\n**当前执行边界**：同轮独立基础指标走批量查询，逐项检查失败；用于计算的单指标结果显式取原始数值。编辑既有资源须保留 ID、权限、调度与数据，不能用删除重建代替。新资源先核对环境与实际目录路径。常规表单结构创建/编辑优先走 `guands form`；历史 API 片段仅在具体兼容问题已复现时使用。完整迁移说明见 [官方 CLI 兼容说明](references/official-cli-compatibility.md)。\n\n**为什么还要本 skill**：整库治理的取舍、业务口径、BI 引擎报错、历史 v7/自定义图表兼容、SuperApp 的 LLM 中转问题与 ADS 架构判断，仍需结合实际业务和目标环境处理。先走官方正常路径，失败后再按本 skill 的适用条件定位；旧记录不代表最新版仍有同一个问题。\n\n**降歧义**：6 个官方 skill + 本 skill 同时启用时，只读场景（查 dsId/ETL）可能在 `guancli` 与本 skill 间双触发。本 skill **不与官方抢只读**——遇到纯查询/取数，直接路由 `guancli`，别自己拼 API。\n\n## 🔄 官方全家桶更新 SOP（高频操作）\n\n观远官方迭代节奏快（平均每周 1–2 次），本 skill 需要跟着对齐。以下是完整更新链路——从检查到落地，一条龙。\n\n自动跟进时用 [official-cli-baseline.json](references/official-cli-baseline.json) 作为已审阅版本记录，同时核对聚合包与六组件的 npm latest。发现变化后读官方 CHANGELOG 和随包 Skill，再决定兼容修改；检查失败不得写成“没有更新”。完成兼容审阅才更新此记录，商店发布失败单独跟踪，不靠重复升版本重发。\n\n### Step 0. 检查是否有新版本\n\n```bash\n# 看本机当前全家桶版本\nguanskill version\n\n# 看 npm 上最新聚合包版本\nnpm view @guandata/guanskill version\n\n# 逐个看子包最新版本（聚合包可能滞后）\nnpm view @guandata/guancli version\nnpm view @guandata/guanvis version\nnpm view @guandata/guanetl version\nnpm view @guandata/guands version\nnpm view @guandata/guanwf version\nnpm view @guandata/guanmetric version\n```\n\n如果 npm 版本 > 本机版本 → 继续 Step 1。即使 CLI 已是最新，也必须检查 Step 2：二进制更新不代表已安装的 SKILL.md 与 references 同步。另核对六组件 latest 是否与聚合包 dependencies 一致；不要混装未经核对的版本组合。\n\n### Step 1. 升级 CLI（npm 聚合包）\n\n```bash\n# 升级到最新聚合包（装到你的 npm 全局 prefix —— 先 `npm prefix -g` 确认当前目标）\nnpm i -g @guandata/guanskill@latest\n\n# 验证新版本\nguanskill version\n```\n\n> **安装路径坑（双装滞后）· 变体 A｜跨 prefix**：`guanskill` 的 forwarder 跟着 `which guancli` 解析到的 prefix 走。若曾用不同 node（如 Homebrew node 的 `/opt/homebrew` vs nvm/asdf/独立 `~/.local`）装过两份，PATH 靠前那份会\"赢\"，而 `npm i -g` 只更新当前 prefix 的那份、另一份滞后 →「升了却没生效 / 本地副本常滞后」。排查：`which -a guancli` 看是否多份；统一到单一 prefix（多余的用 `npm uninstall -g @guandata/guanskill --prefix <多余prefix>` 删掉）。\n>\n> **变体 B｜同 prefix 下「子包 vs 伞包」并存**（2026-07-15 实测）：即使只有一个 prefix，若**单独**装过某个子包（`npm i -g @guandata/guancli`），它会和伞包 `guanskill` 自带的内嵌版**抢同一个 `guancli` bin**——`which -a` 只有一条、看不出异常，`npm ls -g --depth=0` 才看得见两个顶层条目。**排查**：`npm ls -g --depth=1 | grep guan`，顶层应当**只有 `@guandata/guanskill` 一条**，六个组件都该是它的子依赖；顺带 `guancli version` 与 `npm view @guandata/guancli version` 对一下。**清理**：`npm uninstall -g @guandata/guancli` —— ⚠️ **卸载会连带删掉共享的 `guancli` bin symlink**（因为该包也声明了同名 bin），必须紧接着 `npm i -g @guandata/guanskill@latest` 把 bin 装回来，再逐个验 `guancli version` / `guanvis version` / …。\n\n### Step 2. 升级 AI Skill（SKILL.md + references）\n\n```bash\n# install-skill 把每个子包的 SKILL.md + references/ 装到 ~/.agents/skills/<name>/\nguanskill install-skill\n```\n\n落点：`~/.agents/skills/{guancli,guanvis,guanetl,guands,guanwf,guanmetric}/`。这些是 agent 路由用的 skill 定义，和 CLI 二进制分开更新。还需检查 `guandata-cli-suite`。完成后逐文件比较 npm 包 `skills/<name>/` 与已安装目录，至少覆盖 SKILL.md 和 references；退出 0 或一条安装提示不能代替内容一致性验证。\n\n### Step 3. 读 Changelog，摘要变更\n\n```bash\n# 各子包 CHANGELOG.md 在 npm 包目录下\nGUANSKILL_DIR=$(npm root -g)/@guandata/guanskill/node_modules/@guandata\nfor pkg in guancli guanvis guanetl guands guanwf guanmetric; do\n  echo \"=== $pkg ===\" && head -30 \"$GUANSKILL_DIR/$pkg/CHANGELOG.md\" 2>/dev/null && echo\ndone\n```\n\n重点关注：新增/移除命令、DSL 新组件、bug 修复（尤其影响 B-0.5 / Part C / Part D 的）、breaking change。\n\n### Step 4. 迭代 majia-guanyuan\n\n按 changelog 摘要，更新以下位置（有改动的才改）：\n\n| 位置 | 改什么 |\n|------|--------|\n| **路由总表**（本文件 `官方全家桶 ↔ 本 skill 分工总表`） | 版本号 + 能力描述 |\n| **V3.x.x 更新 callout**（本文件顶部 `> 🆕`） | 新版本摘要 |\n| **Part B 实测边界 callout** | 如果 guanetl 有 bug 修复 |\n| **Part D guanvis 版本引用** | 如果 guanvis 版本变了 |\n| **manifest.json / package.json** | `version` + `description` 里的版本号 |\n| **README.md / README.en.md** | 版本徽章 + 版本记录段（≤3 条） |\n| **CHANGELOG.md** | 新增 `[x.y.z] — YYYY-MM-DD` 条目 |\n\n版本号规则：官方对齐 = **patch**；影响 skill 自身逻辑（如 B-0.5 降级）= **minor**。\n\n### Step 5. 同步 + 发布\n\n```bash\n# 同步已发布的整包，包含 references/templates，不能只复制两个 Markdown 文件\npython3 ~/.codex/skills/majia-ota/scripts/sync_local_agents.py /path/to/majia-guanyuan --target all\n\n# commit + push（或走 /majia-ota-skill 完整发布链）\n```\n\n### 快速一键检查（日常用）\n\n```bash\n# 一行看完「本机 vs npm 最新」差异\necho \"LOCAL:\" && guanskill version && echo \"---\" && echo \"NPM latest:\" && npm view @guandata/guanskill version\n```\n\n## 通用错误码处理\n\n| 状态码 | 处理 |\n|--------|------|\n| 500 | 终止，服务器问题 |\n| 401 | 终止，登录失效（`guancli auth login` 重登） |\n| 403 | 终止，无权限 |\n| 404 | 终止，资源不存在 |\n\n---\n\n# 🅱️ Part B：ETL 治理与写入（V1.0）\n\n> 当前兼容基线为 `@guandata/guancli@1.0.62`。本 Part 的 API 路径、payload 字段、报错信息与治理判断维度来自既往真实跑通请求；本次 1.0.62 对齐完成 CLI/文档验证，不把未重跑的 BI 业务链冒充新版实证。累计覆盖整库治理扫描 + 60+ 张 ETL 创建/重构/修复/删除实战。\n>\n> ⚠️ 官方全家桶已把 BI 写操作拆成兄弟 skill 并**全部公网化**（2026-06-03，`npm i -g @guandata/guanskill`）：标准 ETL 写入有 `guanetl`、工作流数据流有 `guanwf`、数据源/数据集有 `guands`。**但 Part B 这套基于 `guancli fetch` + payload 的实战手册仍是底层事实源**——直接命中 API 路径 / payload 字段 / 报错码 / 治理判断的部分官方命令封装不到。遇到标准化 ETL 写入可路由到 `guanetl`，但**整库治理扫描、direct-save、payload_json、SmartETL 全链路重写、10 类报错速查继续走本 skill**。\n>\n> 🧪 **实测边界（2026-06-04 · workshop513 · BI 8.2.1-hf6）**：guanetl `edit` 的 base→etl.go 逆向在 **0.1.12 / 0.1.13 完全失效**（空 `return []Node{}`，5/5 ETL 全复现、`-v` 无报错）；`save` 的输出绑定 guard 也误触发。**0.1.14 两个 bug 均已修复**（2026-06-09 workshop513 实测：`ads_会员经营任务池` 6 节点 `edit→export→lint→save` 全链路通过）。改现有 ETL 现在可以走 `guanetl edit` 正常路径了。**B-0.5 绕过方案仍保留作 fallback 参考**（万一其他 BI 版本 / 节点类型仍触发）。\n>\n> ⚡ **0.1.14 修复确认**（2026-06-09 复测）：① `edit` 空 `etl.go`（Wall 1）→ ✅ 已修，6 节点完整逆向为 `BasicInputDataset×4 + BasicSqlScript + BasicOutputDatasetInDir`；② `save` 输出绑定 guard 误触发（Wall 2）→ ✅ 已修，save 直接成功不再拦截。另：**0.1.14 移除了 `delete` 命令**，删 ETL 改走 BI UI 或直接 `DELETE /api/etl/<id>` API。**0.1.15（2026-06-15）进一步增强 `save` 输出数据集保护（保留级联相关配置）+ 对追加写入场景的行数据结构提前校验**——改 ETL 走 `guanetl edit` 正常路径更稳。**0.1.16（2026-06-17）再加 `save --dry-run` 保存影响预览 + `run` 执行前提示上游数据集失败态 + `preview` 提示 LEFT JOIN 桥接列全空样本**，改 ETL 前可先 `--dry-run` 看影响面。**0.1.17（2026-06-24）仅 `install-skill` 适配 WorkBuddy 目录，ETL 行为无变化。** **0.1.18（2026-07-01）建 ETL 时目录类型诊断更清晰（识别误用工作流/经典数据流目录、提示用智能 ETL 目录）。** **0.1.19（2026-07-08）新增 `move`（移 ETL 到指定目录，接口异常时读回确认）+ `run --run-upstream`（递归解析上游链路按拓扑顺序执行，配 `--dry-run`）+ `run --wait` 遇 40001「已在运行」改为查找并等待现有任务（减少级联触发后重复 run 的误判失败）+ `export` 静态检查 JOIN 键类型不一致 warning（STRING/LONG 隐式 coercion 风险）。** **0.1.21（07-24）JOIN 类型检查扩至 preview/save/run。** **0.1.22–0.1.27（07-25～08-10）** 写操作回显实际目标环境 + 多节点并行 preview + 运行中任务可直接跟踪 + 输出落位闭环 / JOIN 未知类型拦截 + `save` 影响报告字段级明细 + 首次运行后临时输出集完成生成再做字段检查。\n\n> **2026-09-14 官方对齐**：`guanetl 0.1.34` 新建须明确两类目录，执行按 ETL ID 跟踪且不再提供全局 `task`；0.1.31 已修复历史节点 ID 下划线导出。上述为官方文档与命令核验，未重跑线上 ETL。详见 [兼容说明](references/official-cli-compatibility.md)。\n\n## B-0.5 guanetl `edit` 失效时的绕过方案（0.1.12–0.1.13 历史；0.1.14 已修复，保留作 fallback）\n\n> 0.1.14 已修复 `edit` 空 etl.go + `save` 输出绑定 guard 两 bug（确认详见上方 Part B 实测边界段），正常直接用 `guanetl edit`；以下绕过方案保留为 fallback——特定 BI 版本 / 节点类型仍触发时用。\n\n**原三道墙**（guanetl 0.1.12–0.1.13，0.1.14 已全部修复）：\n1. ~~`edit` 的 base→`etl.go` 逆向出空~~ → **0.1.14 已修**\n2. ~~`save` 撞输出绑定 guard 误触发~~ → **0.1.14 已修**\n3. `save` 的合并对「身份字段」base 优先（改 ETL 名 / 节点名被覆盖）+ 输出 dsId churn → **未验证是否修复**，改名仍建议走 `guands dataset rename` / `alias`\n\n**→ Fallback 路径**（仅在 `guanetl edit` 仍有问题时使用）：\n- **纯改名 / 字段展示名** → 别碰 ETL 图，直接 `guands dataset rename` / `guands dataset alias`。\n- **改逻辑 / 改结构（加节点、改 SQL）** → **不可变重建**（最稳）：读 `_base_etl.json` 拿旧定义 → `guanetl create` 写一份**新 outputDsName** 的新 ETL → `export/lint/save/verify` → 旧 ETL 退役。\n- **高级逃生**（仅在没法重建时）：手工构造 `_exported.json` = fresh `_base` 的 actions + 保留 output `dataSource.dsId` + 你的**逻辑**改动，再 `guanetl save`。\n- **认证别绕**：BI API 是 **cookie/session 认证**——写操作一律走 `guanetl save` / `guands`（它们持有正确会话）。\n\n**清理坑**：~~`guanetl delete --cascade`~~（0.1.14 起无 delete 命令）。删 ETL + 孤儿输出集走 `DELETE` API，**顺序必须先删输出数据集、再删 ETL（与 B-7.1 一致）**；反过来先删 ETL → `2002 输出数据集已存在` 失败。**2026-06-17 · workshop513 实测定案**（独立 DATAFLOW ETL，净零回归）：`DELETE /api/data-source/<输出dsId>`（ETL 还在）→ `DataSource deleted` 成功、**不报 6001**；再 `DELETE /api/etl/<id>` → 成功。churn 出的中间绑定是另一回事——删 ETL 后多为 `NOT_FOUND` 幽灵（`ds get`=1002 但 `ds delete`=6001，不可见、无害）。\n\n## B-〇. 推荐工作流（先治理再重建）\n\n```text\n1. 治理扫描     ← 批量抓全部 ETL 原始 JSON，分析依赖、循环、复杂度\n2. 决策保留     ← 用 8 维 ETL + 4 维字段判断：保留 / 合并 / 降级 / 删除\n3. 设计分层     ← 按 ODS/DIM/DWD/DWS/APP 重新分配\n4. 字段审计     ← 双源（page + etl）扫字段使用度，确定砍字段范围\n5. 新建目录     ← v2 目录与旧目录并行，不动旧链路\n6. 写入 ETL     ← 三节点骨架 INPUT→SQL→OUTPUT，本地编译 payload\n7. 预览节点     ← etl preview 先看 OUTPUT 节点能不能出数据\n8. 执行落表     ← execute + task get 轮询 + 拿 result.error\n9. 对账切流     ← 新旧并行验证，下游看板/ETL 逐张迁移\n10. 清理旧链路  ← 先 DELETE data-source，再 DELETE etl（顺序不能反）\n```\n\n跳过治理直接动手 = 把同样混乱重做一遍。第 1–4 步是写 ETL 之前最值钱的活。\n\n---\n\n## B-1. API 全图（11 个已实测 endpoint）\n\n```text\n🔧 写入类（POST）\nPOST /api/directory                  ← 建目录（dirType=ETL 或 DATA_SET）\nPOST /api/etl/direct-save --stdin    ← 创建/更新 ETL（payload 有 dataFlowId 即更新）\nPOST /api/etl/execute                ← 触发执行 {\"dataFlowId\":\"...\"} → taskId\n\n📖 读取类（GET）\nGET  /api/etl/<id>                   ← ETL 完整定义（含 actions/sql/relativeFieldAlias）\nGET  /api/directory/ETL/authorized-tree       ← ETL 目录树\nGET  /api/directory/DATA_SET/authorized-tree  ← 数据集目录树\nGET  /api/task/<taskId>              ← 任务状态 + 错误详情（关键修 bug 入口）\n\n🗑️ 删除类（DELETE）\nDELETE /api/data-source/<dsId>       ← 删数据集（必须先于 etl 删）\nDELETE /api/etl/<id>                 ← 删 ETL（输出数据集还在 → 失败）\n\n🔍 探测类（OPTIONS）\nOPTIONS /api/<any-path>              ← 返回 Allow 头，反推支持的 method\n```\n\n### B-1.1 反推未知 endpoint 的方法\n\n```bash\n# 步骤 1：探 method 集合（最高效）\nguancli fetch OPTIONS /api/<path>\n# Allow: POST,GET,HEAD,DELETE,OPTIONS\n\n# 步骤 2：盲发 POST，根据错误类型判断\n# - \"No static resource X\"               → endpoint 不存在\n# - \"Request method 'X' is not supported\" → endpoint 存在但方法不对\n# - \"InvalidJSON\" / \"missing field\"       → endpoint 对，body 不对（开始迭代）\n# - \"ResourceId(...) ResourceNotExist\"    → endpoint 模式错误\n\n# 步骤 3：根据错误反推 schema\n```\n\n**血泪经验**：BI 内部 endpoint 命名不一致——`data-source`（带连字符）、`dataflow`（无连字符）、`etl`（无连字符）、`directory/ETL`（驼峰大写）混用。靠 OPTIONS 探测比盲发 POST 高效 10 倍。\n\n---\n\n## B-2. 治理扫描：判断 ETL/字段去留\n\n### B-2.1 为什么扫描\n\n观远 BI 用久了的常见症状：核心表互相循环引用、同份业务规则散落多张计算列、维表混入下游经营字段、大量已创建未运行的废弃 ETL、名实不符。**不扫一遍直接动手，重建出来还是一团乱麻。**\n\n### B-2.2 扫描 3 步走\n\n```bash\n# Step 1：列出范围\nguancli etl tree                                       # 全库\nguancli etl search '' -d <PARENT_ETL_DIR_ID> --raw     # 按目录缩范围\n\n# Step 2：批量抓原始定义（--raw 关键，不带就只输出阉割版）\nmkdir -p raw\njq -r '.response.contents[].dataFlowId' etl-list.json | while read id; do\n  guancli --raw etl get $id > raw/$id.json\ndone\n\n# Step 3：本地脚本聚合分析\nnode analyze.mjs raw/ > analysis.json\n```\n\n### B-2.3 分析脚本要算的 10 个指标\n\n| 指标 | 怎么算 |\n|---|---|\n| 输出数据集 | `actions[].type==\"OUTPUT_DATASET\"` 的 `outputDsName` |\n| 上游 ETL 依赖 | `inputs[]` 里 `displayType==\"DATAFLOW\"` 的，反查归属哪个 ETL |\n| 节点数 | `actions.length` |\n| Join 数 | `actions[].type==\"JOIN_DATA\"` 的个数 |\n| 计算列数 | `actions[].type==\"CALCULATOR\"` 的个数 |\n| 透传聚合数 | `actions[].type==\"GROUP_BY\"` 的个数 |\n| 长公式数 | CALCULATOR 里 `formulas[].expr.length > N` 的个数 |\n| 输出行数/大小 | 输出 ds 的 `rowCount` / `storageSize` |\n| 调度方式 | `cron`（`AFTER_REFRESH` / 具体 cron / 无） |\n| 状态 | `status`（`FINISHED` / `CREATED` / `FAILED`） |\n\n构建依赖图（节点 = ETL，边 = \"本 ETL 输入了另一个 ETL 的输出表\"），DFS 三色标记找循环组，计算 fanIn/fanOut。\n\n### B-2.4 ETL 去留判断（8 维）\n\n| 维度 | 信号 | 处置 |\n|---|---|---|\n| **循环依赖** | 出现在循环组里 | **必拆**：找共同字段抽到 DIM/DWD，让两下游都读它 |\n| **状态异常** | `status=CREATED` 且无输出 / 0 次执行 | 删或重建为明确用途 |\n| **本地无下游** | 没有任何其他本地 ETL 引用其输出 | 区分两类：① 给看板用 → 标 APP 层；② 没人用 → 删或归档 |\n| **节点复杂度** | 节点 > 25、Join > 5、CALCULATOR > 3、长公式 > 0 | **拆**成多段：基础明细 / 规则映射 / 业务汇总 |\n| **输出大小** | 单表 > 1GB 或 > 1000 万行 | 检查是否不必要物化；规则计算应集中 |\n| **名实不符** | ETL 名跟输出表名差距大 | 改名或废弃 |\n| **历史补数** | 名字含\"补齐 / 历史 / 月末\"等，调度异常 | 移到补数/归档目录，不挂主链 |\n| **未调度** | `cron` 为空且不是被其他 ETL 触发 | 确认是否临时/手工 → 标记或删除 |\n\n### B-2.5 字段去留判断（4 维）\n\n| 维度 | 怎么判断 | 处置 |\n|---|---|---|\n| **下游 ETL 引用** | 在所有下游 ETL 的 SQL/CALCULATOR/SELECT_COLUMNS 里 grep 字段名 | 0 引用 → 候选删 |\n| **看板（page）引用** | 看板/卡片是否用了这个字段 | 有 → 不能删 |\n| **业务口径** | 字段名是否含业务规则（\"是否会员\"、\"是否新客\"） | 这类是规则字段，集中维护到专门的规则映射 ETL |\n| **冗余/派生** | 能否从其他字段推导（开业天数 vs 开业日期） | 派生字段尽量在下游算，不在维表物化 |\n\n详细双源审计方法见 **B-10**。\n\n### B-2.6 ODS/DIM/DWD/DWS/APP 分层\n\n| 层 | 放什么 | 关键约束 |\n|---|---|---|\n| **ODS** | 原始外部表、DB_EXTRACT、手工源表 | 只做轻清洗，不承载业务口径 |\n| **DIM** | 门店、会员、日期、支付通道、顾客标识映射 | **稳定、少依赖、可复用，禁止依赖 DWS/APP** |\n| **DWD** | 订单明细、券明细、好友明细、评价明细 | 固定主键和时间粒度 |\n| **DWS** | 复购、RFM、拉新、蓄水、门店日报 | 从 DWD/DIM 读，**禁止反向被 DIM 引用** |\n| **APP** | 看板专用宽表 | **只服务页面，不再作为基础上游** |\n\n调度按层推进 ODS → DIM → DWD → DWS → APP。\n\n**核心反模式**：维表（DIM）混入了下游经营结果字段——比如门店维表里塞了\"近 90 天订单数\"。这是循环依赖最常见的根源。\n\n### B-2.7 输出物建议\n\n- `analysis.json`：机器可读分析结果（summaries / cycleGroups / highComplexity / nodeTypes）\n- `governance-report.md`：人类可读治理报告（核心结论 + 循环组 + 合并主题域 + 清理对象 + 目标架构 + 实施路线）\n- `migration-plan.json`：每个旧 ETL → v2 的对应表（score / targetName / status）\n\n---\n\n## B-3. 第一步：新建目录\n\n### B-3.1 不要试这些路径（全部 5001 失败）\n\n```text\nPOST /api/directory/create\nPOST /api/directory/ETL/create\nPOST /api/directory/ETL/add\nPOST /api/directory/add\nGET  /api/directory                  ← Method 'GET' is not supported\nGET  /api/etl/tree                   ← ResourceId(tree)/ResourceKind(DataFlow) ResourceNotExist\nPOST /api/etl/dir                    ← Method 'POST' is not supported\nPOST /api/resource-atlas/dir         ← 'resourceTypeName missing'\n```\n\n合法 `dirType` 只有 **`ETL`** 和 **`DATA_SET`**（不要写 `DATA_PROCESS_ETL` `SMART_ETL` `DATAFLOW` `DATA_FLOW`）。\n\n### B-3.2 正确做法\n\nETL 树和数据集树是**两棵独立的树**：\n\n```bash\nguancli fetch GET /api/directory/ETL/authorized-tree\nguancli fetch GET /api/directory/DATA_SET/authorized-tree\n```\n\n**分别建**（同名也得建两次）：\n\n```bash\n# ETL 目录\nguancli fetch POST /api/directory \\\n  '{\"name\":\"warehouse_v2\",\"parentDirId\":\"<parent_etl_dir_id>\",\"dirType\":\"ETL\"}'\n\n# 数据集目录\nguancli fetch POST /api/directory \\\n  '{\"name\":\"warehouse_v2\",\"parentDirId\":\"<parent_ds_dir_id>\",\"dirType\":\"DATA_SET\"}'\n```\n\n记住返回的两个 dirId，写 ETL payload 时**两个都要用**：\n- ETL 目录 id → ETL 自身的顶层 `parentDirId`\n- 数据集目录 id → OUTPUT_DATASET 节点的 `parentDirId` + `dataSource.parentDirId`\n\n---\n\n## B-4. 第二步：构造 ETL payload（速查）\n\n最小骨架 = 3 节点：\n\n```text\nINPUT_DATASET → SQL_SCRIPT → OUTPUT_DATASET\n```\n\n**最关键的字段坑**（详细见 references）：\n- ⚠️ SQL 节点字段名是 **`sql`，不是 `sqlScript`**。写错时 direct-save 不报错，但 SQL 不生效（最隐蔽 bug）。\n- ⚠️ SQL 里 `input1/input2/...` 是**位置式索引**对应 `sources[]`，删除 INPUT 节点会让索引前移，**改 input 节点必须同时改 SQL**。\n- ⚠️ INPUT_DATASET 的 `relativeFieldAlias` 决定 SQL 里能引用什么字段名，必须读了再写 SQL。\n- ⚠️ OUTPUT_DATASET 的 `parentDirId` 是**数据集目录 id**，不是 ETL 目录 id（错填→\"保存路径无效\"）。\n\n📖 **[references/part-b-payload.md](references/part-b-payload.md)** — 完整 payload 模板（含 dataSource.dirPath）+ 三种节点的字段速查表 + 9 种已知节点类型 + dataFlowId 控制 create vs update + **B-8 复用模板：从扫描到落表的完整 4 阶段脚本**（治理扫描 → 建目录 → 写入执行 → 删除旧链）。\n\n---\n\n## B-5. 第三步：执行 + 拿真实错误\n\n### B-5.1 触发执行（status 字段误导）\n\n```bash\nguancli fetch POST /api/etl/execute '{\"dataFlowId\":\"<etl_id>\"}'\n# => {\"taskId\":\"<task_uuid>\",\"status\":\"FINISHED\"}\n```\n\n⚠️ **status 字段误导最坑**：返回的 `status:\"FINISHED\"` 是**任务触发**结果，不是 ETL 执行结果。\n\n### B-5.2 查任务详情（修 bug 必经路径）\n\n```bash\nguancli fetch GET /api/task/<taskId>\n# => {\"response\":{\"taskId\":\"...\",\"status\":\"FAILED\",\"result\":{\"error\":\"...\"},\"messages\":\"\"}}\n```\n\n`response.result.error` 才是 BI 引擎给的真实错误（SQL 报错、字段找不到等）。\n\n### B-5.3 错误定位三步走\n\n```bash\n# Step 1：触发 execute 拿 taskId\ntaskId=$(guancli fetch POST /api/etl/execute \"{\\\"dataFlowId\\\":\\\"$DFID\\\"}\" \\\n  | jq -r '.response.taskId')\n\n# Step 2：等几秒再查 task error\nsleep 4\nguancli fetch GET \"/api/task/$taskId\" | jq '.response.result.error'\n\n# Step 3：根据 error 类型对照 references/part-b-errors.md 修复手册\n```\n\n### B-5.4 异步轮询写法\n\n```bash\nTASK_ID=\"<task_id>\"\nfor i in $(seq 1 30); do\n  st=$(guancli task get $TASK_ID --raw | jq -r '.response.status')\n  echo \"[$i] $st\"\n  [ \"$st\" = \"FINISHED\" ] || [ \"$st\" = \"FAILED\" ] && break\n  sleep 10\ndone\n```\n\n复杂表给 5 分钟（30×10s）一般够。\n\n---\n\n## B-6. 第四步：校验工具集\n\n```bash\n# 1. ETL 视角\nguancli etl search <ETL_NAME> -d <ETL_DIR_ID> --raw \\\n  | jq '.response.contents[0] | {dataFlowId,name,status,lastExecution,outputs}'\n\n# 2. 节点级预览（不用 execute 也能看任意节点输出 — 修 bug 利器）\nguancli etl preview <DFID> <NODE_ID> --limit 5 --timeout 120\n\n# 3. 数据集视角\nguancli ds search <OUTPUT_DS_NAME> --raw\n\n# 4. 实际数据预览\nguancli ds preview <OUTPUT_DSID> --limit 10\n\n# 5. 行列数对账\nguancli ds get <OUTPUT_DSID> --brief\n```\n\n⚠️ 保存后 OUTPUT 节点 ID 会变成 `id_<ts>_<n>_out`，preview 时用新 id：\n\n```bash\nguancli etl get <DFID> --raw \\\n  | jq -r '.data.actions[] | select(.type==\"OUTPUT_DATASET\") | .id'\n```\n\n---\n\n## B-7. 第五步：删除拓扑\n\n### ⛔ B-7.0 删除前的硬性安全闸（V1.3.1 新增）\n\n**Agent 在执行任何 `DELETE /api/data-source/` 或 `DELETE /api/etl/` 前必须满足以下全部条件，否则拒绝执行：**\n\n1. **用户已逐项明确确认**：列出本次将删除的所有 dsId / etlId（含 ETL 名 + 输出表名 + 路径），用户回复\"确认删除\"或等价明确指令。**模糊回复（如\"嗯\"、\"可以\"、\"清理一下\"）不算确认。**\n2. **下游引用已切流**：通过 `guancli ds get <dsId> --assoc` 或 B-10 双源审计验证目标 ds 的下游 ETL 与看板（page）已切到 v2，无任何活跃引用。\n3. **新链路对账通过**：v2 对应 ETL `status:FINISHED`，行数与 v1 差异 <1%，关键字段一致（参考 B-7.3 checklist）。\n4. **批量删除分批确认**：单次删除 ≤ 5 张表；超过 5 张必须分批，每批单独走步骤 1。\n\n**Agent 默认行为**：在 ETL 治理 / 重写 / 字段裁剪等任务里，**永远不要主动建议删除**。把待删清单作为 `governance-report.md` / `migration-status.md` 的一节产出给用户审阅，由用户主动指令\"删 X / 删这一批\"才执行。**新旧并行是默认终态，不是过渡态**——除非用户明确要求收敛。\n\n> 这条闸跟 B-13 红线、B-17.10 完成标准里的\"对账确认后再处理旧表\"一脉相承。**误删一张被看板用着的 ds，恢复成本高过保留旧链一年。**\n\n### B-7.1 关键约束：先 ds 后 etl\n\n> ✅ **2026-06-17 · workshop513 实测复核（净零回归）**：独立 DATAFLOW ETL 两个方向各测一次——etl-first 撞 `2002 输出数据集已存在` 失败；ds-first（先 `DELETE /api/data-source/<输出dsId>`，后 `DELETE /api/etl/<id>`）两步皆 `ok`、**不报 6001**。本约束适用所有「ETL + 其输出数据集」清理。`6001 依赖于该数据集` **不**出现在这里，它只属于删*输入*数据集（ETL 仍读它）或 churn `NOT_FOUND` 幽灵场景（见 B-0.5 清理坑）。\n\n```bash\nguancli fetch DELETE /api/etl/<etl_id>\n# => {\"error\":{\"status\":2002,\"message\":\"输出数据集已存在\"}}  ← 失败！\n```\n\n正确顺序：\n\n```bash\n# Step 1：先删数据集\nguancli fetch DELETE /api/data-source/<dsId>\n\n# Step 2：再删 ETL\nguancli fetch DELETE /api/etl/<etlId>\n```\n\n### B-7.2 数据集 endpoint 反推血泪史\n\n```text\nDELETE /api/dataset/<id>     ← No static resource dataset/...\nDELETE /api/datasource/<id>  ← No static resource datasource/...\nDELETE /api/ds/<id>          ← No static resource ds/...\nDELETE /api/dataflow/<id>    ← No static resource dataflow/...\n✅ 正确：\nDELETE /api/data-source/<id>\n```\n\n### B-7.3 删除前 checklist\n\n- [ ] v3 对应 ETL Status = FINISHED\n- [ ] v3 输出数据集行数 vs v2 行数（差异 < 1%）\n- [ ] v3 输出字段集 = v2 字段集 - 设计砍掉的\n- [ ] 看板（page）依赖 v2 数据集的，已先切到 v3\n- [ ] 下游 ETL 依赖 v2 输出的，已先切到 v3\n\n---\n\n## B-9. 报错修复手册（10 类真坑 · 速查）\n\n每条只列**触发现象 + 一句根因 + 一句修复方向**；完整修复方案 + SQL 示例 + 升级版坑见 **[references/part-b-errors.md](references/part-b-errors.md)**。\n\n| 坑号 | 触发现象 | 根因 / 修复方向 |\n|---|---|---|\n| **1** | `请输入ETL名称` / `保存路径无效` | 顶层 `parentDirId` 缺失或填错 → 必须是 `dirType=ETL` 那棵树的 id |\n| **2** | 保存成功但 execute 数据为空 | 上游 `inputDsId` 只有读权限没运行权限 → 换有权限的输入或写自包含 ETL |\n| **3** | 列名带隐藏 `\\n` 找不到字段 | SQL 里要 `` `带换行的原字段名` AS `干净别名` ``；升级版坑：fieldAlias 与 SQL 中换行+空格不一致 |\n| **4** | `WHERE field <> NULL` 输出 0 行 | SQL 标准里 `<> NULL` 永远是 unknown → 必须 `IS NOT NULL` / `IS NULL` |\n| **5** | `cannot resolve column` | 字段引用与 INPUT_DATASET 的 `relativeFieldAlias` 错位 → 编译时按节点级别名替换 |\n| **6** | `Syntax error at or near ';'` | CTE 内 trailing `;` + 中文注释 → 用 regex 去除 `FROM n_id_xxx;` 后的 `;` 与注释 |\n| **7** | `AMBIGUOUS_REFERENCE` | FROM/JOIN 同表别名同名 → 改 FROM 别名为 s2，对齐 ON 子句 |\n| **8** | `s2.xxx 找不到` | FROM 表错位（自连而非 JOIN 不同表） → 修正 JOIN 目标表 |\n| **9** | `NUM_COLUMNS_MISMATCH` | UNION 列数不一致（老引擎自动补 NULL，新引擎严格化） → 手工对齐 SELECT，缺的用 `NULL AS xxx` |\n| **10** | 日期比较恒为 false | `WHERE order_date < 'today_field'` 字符串字面量 → 改 `date_sub(current_date(), 1)` |\n\n---\n\n## B-10. 字段使用度审计（双源扫描）\n\n### B-10.1 方法论\n\n字段裁剪不能只看看板（page）—— 下游 ETL 也消费字段。**双源 0 引用**才能安全裁。\n\n```bash\n# 1. 拉数据集所有下游\nguancli ds get <dsId> --assoc\n# 输出 N 个下游：M 个 ETL + K 个 PAGE\n\n# 2. 批量 page get + etl get 落本地\nfor id in <ids>; do\n  guancli page get $id > pages/$id.txt\n  guancli etl get $id > etls/$id.txt\ndone\n\n# 3. 对每个字段做 grep 双源统计\nfor fld in <field_list>; do\n  page_cnt=$(grep -c \"$fld\" pages/*.txt)\n  etl_cnt=$(grep -c \"$fld\" etls/*.txt)\n  if [ \"$page_cnt\" = \"0\" ] && [ \"$etl_cnt\" = \"0\" ]; then\n    echo \"🟥 $fld → 真 0 引用，可裁\"\n  fi\ndone\n```\n\n### B-10.2 实测对照（必看）\n\n```text\n某千万级订单明细表：43 字段、5GB\n全量扫描：29 page + 14 etl\n仅看板抽样：17 个 0 引用候选\n双源全扫描：仅 2 个真 0 引用\n误删任何一个 → 下游 ETL 跑挂\n```\n\n**只看看板会高估 8 倍可裁字段，必须 page+etl 双源。**\n\n---\n\n## B-11. v2 → v3 批量改造 SDK（速查）\n\n`v3_sdk.mjs` 三个核心 API：\n\n```js\ntransformV2ToV3({ v2PayloadFile, v3Name, removeInputs, newSql, inputMap, description })\npushAndExecute(v3Name, payloadPath)   // direct-save → execute\ncheckStatus(v3Name)                    // guancli etl search → parse Status\n```\n\n`transformV2ToV3` 有 4 个关键陷阱，头号坑是 **SQL 字段名是 `sql` 不是 `sqlScript`**（写错不报错、SQL 静默不生效）；完整 4 条清单见下方 reference。\n\n📖 **[references/part-b-sdk.md](references/part-b-sdk.md)** — 完整 7 步实现 + 时间窗口缩减实战（v2 近 3 月 → v3 昨日窗口的 regex 替换样板）。\n\n---\n\n## B-12. 批量迁移工程经验（30+ 表实战）\n\n1. **先治理后写入**：跳过治理直接写 = 把混乱重做一遍。\n2. **payload 全部本地生成**：写编译器把每个旧 ETL 的 meta 编译成三段式 payload，存 `payloads/<name>.json`。\n3. **分批保存**：一次 5–10 张 direct-save，避免单次失败影响整批。\n4. **预览先于执行**：保存完先 `etl preview` 看 OUTPUT 节点能不能出数据；能出来再 execute。\n5. **节点 ID 重映射**：保存后 OUTPUT 节点 ID 变成 `id_<ts>_<n>_out`，从 `etl get` 拿新 id。\n6. **失败修复就地更新**：改 payload 加 `dataFlowId` 再 POST，不要删了重建。\n7. **复用旧 payload**：v2 payload 作为模板，改名+改 SQL+改输入。30 个 ETL 中 22 个用这种方式。\n8. **失败定位用 task error**：每个 task 详情里 `result.error` 是真实失败原因，必看。\n9. **批量任务异步监控**：`until` 循环 + `etl search | grep -c PROCESSING` 比单 task 轮询效率高。\n10. **新旧并行**：v2 链路与 v1 并行，对账无误后再下线 v1。\n\n> 💡 **30+ 张表跨多日的工程必须走 ExecPlan**：不要靠零散 todo + 群消息 + 临时 markdown 来追踪进度。直接走 **B-17.11**（在 [references/part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md)）的 ExecPlan 工作法——四个活文档章节（Progress / Surprises & Discoveries / Decision Log / Outcomes & Retrospective）能把治理判断、循环依赖拆法、字段隐藏换行这类\"踩坑—修复\"轨迹完整落到一份自包含文档里，下一个接手的人不用问任何上下文就能继续。\n\n---\n\n## B-13. ETL 治理与写入红线\n\n- ❌ 不要试 `/api/directory/create` 这类拼凑路径，全部 5001。\n- ❌ 不要给 `dirType` 写 `DATA_PROCESS_ETL` `SMART_ETL` `DATAFLOW`，只接受 `ETL` 和 `DATA_SET`。\n- ❌ 不要把 `OUTPUT_DATASET.parentDirId` 填成 ETL 目录 id —— 报\"保存路径无效\"。\n- ❌ **不要把 SQL 字段名写成 `sqlScript`**，正确是 `sql`（写错时 direct-save 不报错但 SQL 不生效）。\n- ❌ 不要在 SQL 里写 `<> NULL` 或 `= NULL`，用 `IS NOT NULL` / `IS NULL`。\n- ❌ 不要假设 INPUT_DATASET 字段名干净 —— 先看 `relativeFieldAlias` 和实际预览。\n- ❌ 不要 execute 完就走人 —— `status:FINISHED` 是任务触发结果，不是 ETL 执行结果。要 `GET /api/task/<id>` 拿 `result.error`。\n- ❌ 不要假设节点 ID 重排不影响 SQL —— 删除 INPUT_DATASET 后 input 位置式索引会变。\n- ❌ **删除类操作（`DELETE /api/data-source/`、`/api/etl/`、`/api/page/<id>?force=true` 级联删页）一律回到 B-7 删除章节**——安全闸（逐项确认 + 下游切流 + 对账 + 单批 ≤5）见 **B-7.0**；先删数据集再删 ETL 的顺序见 **B-7.1**；正确路径是 `/api/data-source/`（带连字符，别试 `/dataset/`、`/datasource/`、`/ds/`）见 **B-7.2**。未经用户逐项明确确认绝不执行，模糊回复（\"嗯\"、\"可以\"、\"清理一下\"）不算确认；新旧并行是默认终态，不是过渡态。\n- ❌ 不要给 INPUT_DATASET 用没有运行权限的 dsId —— 保存能过，执行会拿不到数据。\n- ❌ 不要复用 OUTPUT 节点 id 作为 preview 参数 —— 保存后会变成 `id_<ts>_<n>_out`。\n- ❌ 不要跳过治理扫描直接重建 —— 不识别循环依赖和重复主题域，重建出来还是一团乱麻。\n- ❌ 不要把\"是不是被引用\"等同于\"该不该保留\" —— 看板 APP 表常常没下游 ETL，要单独看看板侧。\n- ❌ 不要让 DIM 维表依赖 DWS/APP 层 —— 这是循环依赖最常见的根源。\n- ❌ 不要只看看板做字段裁剪 —— 实测仅看板会高估 8 倍可裁字段，必须 page+etl 双源。\n- ❌ 不要假设老 ETL SQL 写法在新引擎也能跑 —— 5 类历史 bug（trailing `;` / UNION 列差 / 字段名换行+空格 / self-join 别名同名 / 字符串字面量与 DATE 比较）会暴露。\n- ❌ 不要忘记 OPTIONS 探测 —— 找未知 endpoint 时比盲发 POST 高效 10 倍。\n\n---\n\n## B-14. ETL 写入侧 API 速查\n\n| 操作 | 方法 | 路径 / 命令 |\n|---|---|---|\n| 探测 method | OPTIONS | `/api/<any-path>` |\n| ETL 目录树 | GET | `/api/directory/ETL/authorized-tree` |\n| 数据集目录树 | GET | `/api/directory/DATA_SET/authorized-tree` |\n| 建目录 | POST | `/api/directory` body: `{name, parentDirId, dirType}` |\n| 抓 ETL 详情 | – | `guancli --raw etl get <id>` |\n| 写入 ETL（创建/更新） | POST | `/api/etl/direct-save --stdin` |\n| 触发执行 | POST | `/api/etl/execute` body: `{dataFlowId}` |\n| 查任务真错误 | GET | `/api/task/<taskId>` → `.response.result.error` |\n| 节点级预览 | – | `guancli etl preview <DFID> <node_id>` |\n| 删数据集（先） | DELETE | `/api/data-source/<dsId>` |\n| 删 ETL（后） | DELETE | `/api/etl/<id>` |\n\n---\n\n## B-15. 实战 ID 速查（模板）\n\n> 跨多日的大型重构（B-17 / 30+ 表）建议在仓库根维护一份本地 ID 速查表，避免每次都用 `guancli` 翻树。下面是模板，把 `<...>` 占位符替换成你自己 BI 实例里的真实 ID。**不要把这份表 commit 到公开仓库。**\n\n| 名称 | ID | 说明 |\n|---|---|---|\n| 旧 ETL 父目录 | `<v1_etl_dir_id>` | v1 ETL 目录 |\n| 旧数据集父目录 | `<v1_ds_dir_id>` | v1 数据集目录 |\n| **v2 ETL 目录** | `<v2_etl_dir_id>` | 新建 ETL 落这里 |\n| **v2 数据集目录** | `<v2_ds_dir_id>` | OUTPUT_DATASET 落这里 |\n| 数据集树根目录 | `<ds_root_id>` | dirPath 第一层 |\n| ETL 树根目录 | `<etl_root_id>` | – |\n| PoC ETL | `<poc_etl_id>` | 第一个跑通的最小 ETL |\n| PoC 输出数据集 | `<poc_output_ds_id>` | 同上输出 |\n| PoC 输入数据集 | `<poc_input_ds_id>` | 小表，权限可运行 |\n\n如果上面 ID 失效（被删/改名），用以下命令重新拿：\n\n```bash\nguancli fetch GET /api/directory/ETL/authorized-tree | jq '.response | .. | objects | select(.name==\"<你的 v2 目录名>\")'\nguancli fetch GET /api/directory/DATA_SET/authorized-tree | jq '.response | .. | objects | select(.name==\"<你的 v2 目录名>\")'\n```\n\n---\n\n## B-17. 全链路重写方法论（CTO 张进）\n\n> 这套是观远 CTO 张进的 SmartETL 完整改写经验。它跟 B-2 治理扫描互补：B-2 解决\"有哪些 ETL 该治理\"，B-17 解决\"具体重写一条链路时怎么做才不留尾巴\"。\n>\n> **核心区别**：B-17 强调**全链路追到原始源**，不接受只重写最终 ADS。如果用户说\"把这条链路重新做一遍\" / \"替换数据源\" / \"做副本页验收\"，必走 B-17。\n\n📖 **[references/part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md)** — 完整方法论 11 节：何时用 B-17 / 4 件交付 / 8 条硬规则 / 5 步标准工作流 / 三层验收（数据集/副本页/卡片级）/ 差异追踪 5 步法 / 空快照处理标准 / 标准交付物清单 / 6 类专属常见坑 / 完成标准 6 项 / **B-17.11 用 ExecPlan 管理重写工程**（含 SmartETL 改写专用 ExecPlan 骨架，拿去直接填空）。\n\n**最简口诀**（10 秒决定要不要进 B-17）：\n- 只新建 1 个 SQL 节点数据集 → 走 B-3 ~ B-9，不进 B-17\n- 涉及\"页面副本验收\"或\"卡片级数值对账\"或\"全链路追到原始源\" → 必进 B-17\n- 30+ 表 / 跨多日 / 循环依赖拆解 → 进 B-17 + 走 B-17.11 ExecPlan\n\n---\n\n# 🆎 Part C：自定义图表开发与排障（V1.1 新增）\n\n> **并行参考（V2.0 标注）**：观远 maintainer wubaoqi 在 2026-04-29 发布了 `@wubaoqi/guan-chart-kit`（React + ECharts 组件库，专为观远 BI 设计）和 `@wubaoqi/guan-chart-kit-usage-skill`（agent-skill，教 SuperApp 接 chart-kit）。两条路线区别：\n> - **chart-kit 路线**（wubaoqi）：从零搭新看板，走**组件接入** + npm 依赖管理，适合标准化复用\n> - **本 Part C 路线**：在既有卡片上做 HTML/CSS/JS 注入 hack，绕过组件直接改 DOM/data，适合改造既有页面、临时 overlay、固定卡片\n>\n> 两者互补，按\"是新搭还是改造\"分流。\n\n> 来源：观远 CTO 张进的自定义图表注入实战经验。涵盖 HTML/CSS/JS 注入、runtime 取数、固定卡片、遮罩层、z-index/stacking context、路由清理，以及任何**必须在真实观远页面里做浏览器验证**的前端问题。\n\n## C-〇. 何时用 Part C\n\n任务涉及观远 BI **自定义图表**的：\n- 前端代码（HTML/CSS/JS）\n- 运行时取数（`renderChart` 的 `data` 参数解析）\n- 页面级 DOM 操作（固定卡片、overlay、mask）\n- 浏览器层级问题（z-index、stacking context、pointer-events）\n- 路由切换清理、复制页 card id 重定位\n- 懒加载导致脚本不执行\n- 必须在真实页面验证的问题\n\n不用 Part C 的情况：只是在观远 UI 里点几下做卡片配置，不写代码 → 走路由层（标准建卡交 guanvis）。\n\n## C-1. 快速开始原则（6 条）\n\n1. **要注入 HTML/CSS/JS** → 用「自定义图表」，不用「自定义图表 Lite」\n2. **先在真实观远页面复现问题，再改代码**\n3. **先确认 live 页实际运行的是哪份脚本**，再判断问题\n4. **脚本开始漂移或多次局部修补失效时，优先给完整 JS**，不要继续发零碎 diff\n5. **每次结构性修改后回浏览器重新验证**\n6. **遇到取数问题，先看 `GDPlugin().init(renderChart)` 的 runtime 入参**，不要先假设它等于 `/api/card/.../data` 的 HTTP 包裹层\n\n## C-2. runtime 契约（必须知道）\n\n观远当前的 runtime 回调签名是：\n\n```javascript\nfunction renderChart(data, clickFunc, config, helpers) {}\n```\n\n⚠️ **常见误解**：\n- ❌ 把第一个参数 `data` 当 DOM 根节点 —— 错。要自己从 `document.querySelector(...)` 或 `document.body` 获取 DOM。\n- ✅ `helpers` 常见为 `{ refreshData, clickFunc }`\n\n`data` 形态多变，常见 5 种：\n\n```javascript\n// 形态 1（最常见）\n[\n  [\n    { name: \"payload_json\", data: [\"{...}\"] },\n    { name: \"report_date\", data: [\"2026-03-18\"] }\n  ]\n]\n\n// 形态 2\n[{ name, data }, ...]\n\n// 形态 3\n{ chartMain: { columns: [...] } }\n\n// 形态 4\n{ response: { viewData: [...] } }\n\n// 形态 5\n[{ payload_json, report_date }]\n```\n\n**结论**：优先围绕 runtime `data` 写解析逻辑。`/api/card/.../data` 只用于核对证据，不要把它当 callback 结构直接照搬。\n\n## C-3. payload_json 取数排障（速查）\n\n📖 **[references/part-c-payload-json.md](references/part-c-payload-json.md)** — 三种\"拿不到 payload\"的细分 / 最快判断方式 / `JSON.parse` 硬规则 / 截断错误（`Unterminated string` / `Unexpected end of JSON input`）的判断 / 推荐方案：拆列而非整包 JSON。\n\n**最简结论**：JSON.parse 失败且报截断错时，**优先判断为数据链路把长字符串截断了**，不要继续堆兼容解析逻辑。改数据方案——把整份报告拆成多列（`report_date` / `key_insights_md` / 各 section 列）传给前端，比 runtime 再 `JSON.parse(payload_json)` 稳得多。\n\n## C-4. 固定卡片 / overlay 场景\n\n### C-4.1 保守做法\n\n- ✅ **只移动目标卡片内容**，不要把整页都抽进 overlay\n- ✅ overlay 和 mask **挂到当前页面根节点**，**不要挂到 `body`**\n  - 挂到 body 的后果：切页后残留 / 与原生浮层打架 / 跟右侧锚点导航层级冲突\n- ✅ overlay 的 z-index 要够用，但**不能压过观远原生导航、浮层、工具条**\n- ✅ 卡片尺寸变化时，主动派发 `resize`（立即一次 + 延迟几次）让图表重排\n\n### C-4.2 z-index 基线（已验证）\n\n```text\noverlay 容器     约 8\nmask            约 1\n固定卡项        约 20，按需要递减\n```\n\n目标：**高于滚动内容，低于观远原生导航、菜单、工具层。**\n\n### C-4.3 让加载器看得到注入卡，但用户不必看到\n\n- 观远自定义图表 iframe **是懒加载的**\n- 注入卡放在首屏以下 → 初次进页时脚本可能根本不执行\n\n**可靠做法**：\n1. 把注入卡**放在首屏**\n2. 查看态视觉隐藏\n3. **编辑态恢复可见**（让用户能找到并编辑）\n\n## C-5. 页面生命周期管理\n\n### C-5.1 必须主动销毁注入物的场景\n\n- URL 不再匹配目标 page id\n- 进入编辑态\n- 切到 `pageRenderType=phoneView`\n- 客户端路由离开当前页\n\n**只在目标桌面查看态重建。**\n\n### C-5.2 复制页面后 card id 全变\n\n- 观远复制页面会生成新的 card id\n- 继续使用原页面硬编码 id 通常**不会显式报错，只会悄悄失效**\n- 复制页一定要重新确认 card id\n\n### C-5.3 MutationObserver 死循环陷阱\n\n- 监听 `body subtree` 后又在回调里改样式 → 容易反复触发，卡死页面\n- ✅ 更稳的做法：低频轮询 + 精准 rect 比较\n\n## C-6. 浏览器排障清单\n\n### C-6.1 改代码前先看 live runtime\n\n检查：\n- 当前 URL 和 page id\n- `window` 上是否已有旧版注入 key\n- `__gd_overlay__` 和 `__gd_overlay_mask__` 是否存在\n- 页面里是否留有历史实验节点\n\n### C-6.2 找到真正可点击的 DOM\n\n不要把\"看到的文本节点\"误当成真正交互节点。对右侧锚点导航，真正有用的目标往往是：\n- 打开按钮图标\n- tab 按钮\n- pin 图标\n\n### C-6.3 用 `elementFromPoint` 查层级问题\n\n控件可见但点不动时，查控件中心点命中的真实元素：\n- 命中 fixed card 或 overlay 子节点 → 层级问题\n- 命中正确控件但还不工作 → 之前点错节点 / 某个祖先禁用了 pointer events\n\n### C-6.4 最终用真实浏览器点击验收\n\n不要只靠 `page.evaluate(... click())`。要用真实浏览器点击，确认：\n- tab 切换是否真的生效\n- 页面滚动位置是否真的变化\n- pin 状态是否真的切换\n\n## C-7. 保留原生浮动 UI\n\n- ❌ 没必要时，**不要重绘或克隆**观远原生浮动控件\n- ✅ 优先修 stacking context、pointer-events、opacity，而不是复制一套控件\n\n原生控件不可点时，按这个顺序排查：\n1. overlay 是否盖住它\n2. mask 是否拦截事件\n3. 祖先节点是否被设成 `pointer-events: none`\n4. 原控件是否被历史实验隐藏\n\n## C-8. 交付规则\n\n- ✅ 用户要手工粘贴时，**默认给完整 JS**，不给局部片段\n- ✅ 如有需要，同时明确给出 HTML / CSS\n- ✅ 脚本不稳定时，完整替换优于局部修改\n- ✅ 页面已经完全坏掉时，先给最小恢复版救回来：\n\n```javascript\nfunction renderChart() {}\nnew GDPlugin().init(renderChart);\n```\n\n提醒用户执行：**保存 → 发布 → 强刷查看页**。\n\n## C-9. 最终验收清单\n\n最终一定要在真实页面验证：\n- [x] 页面加载\n- [x] 查询 / 筛选切换\n- [x] 滚动\n- [x] 左侧栏展开收起\n- [x] 路由切页\n- [x] 编辑态进出\n- [x] 桌面 / 手机态切换\n- [x] 原生浮动控件是否仍可见、可点\n\n## C-11. 深度参考资料\n\n遇到复杂的固定卡片 / overlay / 锚点导航问题时，读：\n\n- [references/custom-chart-playbook.md](references/custom-chart-playbook.md) — 张进的完整自定义图表排障手册原文（含固定层与真实布局错位修正、右侧原生导航失效详细处理、elementFromPoint 实战、MutationObserver 死循环深入分析）\n- [references/etl-rewrite-original.md](references/etl-rewrite-original.md) — 张进的 SmartETL 改写经验原文（B-17 章节就是基于它整合的，这里是未删减版）\n\n## C-12. HTML 应用化看板生成（V2.1.1 新增）\n\n> **触发**：用户说\"更高级 / 更复杂 / 更好 / 应用 / 自定义模块 / 不要限制在标准看板 / 最完美版本 / HTML 看板\"——立刻切到这条路线，**不要**按 guanvis 标准 KPI/折线/柱状图套路交付。\n>\n> **架构**：原生 Page + 原生 selector + HTML SDK 可见层（`createCustomChart().setSubType(CustomChartSubType.SDK).loadContent(...)`）+ DATA_GRID dataView 数据层。后端负责权限/刷新/聚合/筛选，前端负责叙事/布局/SVG-HTML 可视化。\n>\n> **不能跳的两条坑**（2026-05-14 `app.guandata.com` 上 `<demo-domain>` 实例实测）：\n> 1. `guanvis` DSL 的 `.linkToAll()` **不会** 把 selector 联到 custom chart 内部 dataView——必须走 **资源包级 descriptor patch**（不要去调 `/api/card/.../edit/session`，会返回 `60004 此操作只能在草稿页面执行`）。\n> 2. `guancli card preview` 的命令面 V2.1 起 **不再有 `--pg-id`**，老写法 `card data <id> --pg-id <pg_id>` 已废弃；同时不同子命令返回根字段不同（`page get → .data`、`card get → .response`），jq 统一写 `.data // .response // .`。\n\n📖 **[references/part-c-html-dashboard.md](references/part-c-html-dashboard.md)** — 完整方法论 15 节：何时切到 HTML 应用看板 / 总体架构 / SDK vs ECHARTS_LITE 决策 / dataView contract / 共享 runtime API / 24 字符 ID 校验 / selector → custom chart dataView 联动补丁 / 12 步 pack-patch-upload 工作流 / 字段粒度后缀兼容（`月份` / `月份 (月)` / `年月`）/ guancli V2.1 命令面（含 `.data // .response` 兼容）/ **五层验收清单（四层管道 + §11.5 视觉验收）** / 13 类常见错误表 / 模板包索引。\n\n🎨 **视觉设计底线（V3.1.0 新增）**：[references/part-c-design-baseline.md](references/part-c-design-baseline.md) — 管道通了 ≠ 看板能看。模块第一视觉位=数据判断 / KPI 3-4 个 + 28-32px + 单位/对比基准 / 图表真实性（禁 CSS 假图表）/ token 硬上限 / 反 AI 味红线表（命中即重做）/ `guanvis screenshot` 视觉验收。吸收 design-taste-skills（MIT），覆盖 C-12 / Part D / Part E 三场景。\n\n🧰 **模板包**：[`templates/html-dashboard/`](templates/html-dashboard/) — `charts/html_common.js` (GDHTML runtime) + `html_base.css`（V3.1.0 按设计底线校准）+ 2 个起手模块（executive / trend）+ `scripts/patch_selector_linkage.js`（CLI 参数化，弥补 `linkToAll` 联不到 custom chart dataView 的盲区）。🆕 **guanvis 0.1.29 起官方新增「页面筛选器过滤自定义图表 + custom chart dataView 作点击联动来源」**——新页可先试官方 selector 联动，覆盖到位则此脚本可省；旧版/未覆盖场景仍用兜底（官方能力未净零实测，暂并存）。\n\n**手机成绩单 V2**：新增专供ETL与确定性异常规则、周期明细标题、冻结表头及券转化。沿用单卡结构，见 [V2实践](references/part-c-store-mobile-scorecard-v2.md) 与 [离线示例](examples/store-mobile-scorecard-v2/README.md)。\n\n📱 **门店手机成绩单（V1 版）**：加盟店老板每天打开的单卡成绩单，不要按本章六模块驾驶舱去堆，也不要把桌面看板缩小。产品规则、19 视图契约、换店滤空、列名识别、对比不写家数、不取 RFM 见 [references/part-c-store-mobile-scorecard.md](references/part-c-store-mobile-scorecard.md)；可离线点的脱敏 HTML 在 [examples/store-mobile-scorecard/](examples/store-mobile-scorecard/)。\n\n---\n\n# 🆎 Part D：V7 Page/Card 发布流水线 + 三态硬规则（V2.1.6 新增）\n\n> **触发**：用户说\"v7 BI 实例上端到端搭多个 HTML 应用看板\"，或卡在以下任一报错——立刻进 Part D，**不要** 在标准建卡（guanvis）/ Part C 链路上继续挣扎，没用：\n> - `POST /api/page` + `POST /api/card` 返回 `60004 此操作只能在草稿页面执行`\n> - PUT 草稿页 cdId 后，published page 拿到的 cdId 跟 draft 的不映射，整页拼不出来\n> - CSV 散客订单 `会员ID IS NOT NULL` 算出 \"会员销售占比 = 100%\" 假指标\n> - Spark `WITH 订单汇总 AS (...)` 报 `PARSE_SYNTAX_ERROR Syntax error at or near '订'`\n> - ETL update 报 `1012 输出数据集目录中存在同名文件，请修改`\n> - `dim_是否新店 = '1'` 永远空表（CSV 布尔字段实际是 `'TRUE'/'FALSE'` 字符串）\n> - 50 店 / 90 天 / 45 万订单 openpyxl 写 Excel 4-5 分钟\n>\n> **架构**：v7 BI 的草稿/发布分离机制使**手撸 `/api/page` + `/api/card` 全链路废弃**；优先使用官方 `guanvis`（原 `guanvis-skill`，全家桶成员，现公网 `@guandata/guanvis@0.1.49`），按官方预览、覆盖前备份和发布流程处理 page + custom chart + dataView；0.1.47 覆盖后会重置草稿，发布后分别验收浏览态与编辑态。桌面端 另有 `guanvis live` 对话式路径（`live project validate/publish` 走完整 DSL；**不得用 P0 命令模拟自定义图表**，C-12 descriptor patch / 60004 / phoneLayout 仍走本 Part）。配套硬规则：CSV 散客 `会员ID` 是 `\"\"` 不是 NULL（三态判断必须 `IS NOT NULL AND <> ''`）；STRING 字段才能 `<> ''`，日期/数字 Spark 严格类型不行；Spark CTE 别名必须英文；ETL update 必须带 `OUTPUT_DATASET.dataSource.dsId` 否则 1012；数据集上传 / 建集走官方 `guands`（`create-db` / `import` / `replace-data`，不必再 BI UI 手动）；大表 pandas 用 `to_csv` 而非 `to_excel`（50 倍速差）。\n>\n> 🗑️ **删除 guanvis-published 页面 / ETL（2026-06-05 · workshop513 实测）**：`guanvis publish` 出的页面，卡片**内嵌在 `page.cards` + `meta.layout`、不是独立 `/api/card` 资源**——所以 `DELETE /api/card/<cdId>` 报 `1002 找不到`、`DELETE /api/page/<id>` 报 `1004 无法删除包含卡片的页面`、guanvis 也不让覆盖成空页（validation 拒 `No layout items`）。**唯一可行**：`guancli fetch DELETE \"/api/page/<pgId>?force=true\"` → `Page deleted`（级联删卡）。⚠️ **`force=true` 级联删整页内嵌卡片且不可逆，属 B-7.0 安全闸覆盖的 DELETE**：执行前用户须逐项确认页 ID + 页名（模糊回复不算确认）。**仅当本地保有该 page 的 guanvis 源（`page.js` / card 定义）可 `guanvis publish` 重建时，确认即可、无需对账；若是 BI UI 手搭、本地无源的发布页，按不可逆 DELETE 对待、走 B-7.0 完整对账。** 删 ETL + 输出集 → **先删输出数据集、再删 ETL**（与 B-7.1 一致；2026-06-17 实测：反过来先删 ETL 撞 `2002 输出数据集已存在`，ds-first 不报 6001）；`guanetl delete --cascade` 0.1.14 起已无此命令。\n>\n> **不能跳的硬约束**（2026-05-20/21 v7 demo 实战 · 90 天 / 1200 门店 / 80K 会员 / 20 表 / 17 ETL / 6 HTML 看板）：\n> 1. **直接手撸 page+card API 全废**：draft cdId ≠ published cdId 不会自动映射回 published page，光走 `POST /api/page` 拼不出来；走 `guanvis publish` 才能跨过状态机。\n> 2. **CSV 类型三态硬规则**：STRING 字段可以 `<> ''`，日期/数字字段不能（Spark 严格类型直接报错）；CSV 布尔字段实际是 `'TRUE'/'FALSE'` 字符串而非 int 1/0，`= '1'` 永远空表。\n\n📖 **[references/v7-page-card-publish-pipeline.md](references/v7-page-card-publish-pipeline.md)** — 完整 16 节：v7 草稿/发布机制详解 / HTML 应用看板 SDK 最小骨架（schema.js + card_01_html.js + page.js + charts/dashboard.{html,css,js} 4 文件） / CSV 三态判断硬规则 / Spark SQL 4 个硬限制（中文别名 / 嵌套窗口 / `<> NULL` / 字面量日期）/ ETL update OUTPUT_DATASET dsId 注入脚本（`guancli ds search` 自动查 dsId 注入）/ 数据集上传 / 建集走官方 `guands` / pandas to_csv vs to_excel 性能对比 + 向量化 30 倍速差 / JOIN 键全局统一命名（COL_MAP）/ 奶白 `#faf7f2` + 暖蓝 `#2563eb` 主题 / 端到端时间预算 / 反模式与硬约束总表 / 工程目录参考结构 / 与 Part C-12 的边界关系 / **§14 SmartETL 节点化两大静默坑（V2.1.8 新增）** / **§15 customChart 三大坑 + autoBootstrap + chip toolbar 兜底（V2.1.9 新增）** / **§16 移动端 phoneLayout ZIP inject + v7 草稿 save API 死路（V2.1.10 新增）**。\n\n---\n\n## 📚 References 目录\n\n> 本 SKILL.md 主文是路由层 + 关键规则；以下马甲蒸馏档（官方够不着的硬骨头）+ 餐饮公式库 + 贡献者原文构成完整知识库。详细索引：\n\n**马甲蒸馏版：**\n\n| 文件 | 何时读 | 行数 |\n|---|---|---|\n| [part-b-payload.md](references/part-b-payload.md) | 写新 ETL payload / 复用 4 阶段脚本时 | ~175 |\n| [part-b-errors.md](references/part-b-errors.md) | execute 失败、对照 `task error` 找修复方案时 | ~150 |\n| [part-b-sdk.md](references/part-b-sdk.md) | 30+ 表批量改造、写 `transformV2ToV3` 时 | ~60 |\n| [part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md) | 全链路 SmartETL 重写、副本页验收、ExecPlan 管理时 | ~290 |\n| [part-c-payload-json.md](references/part-c-payload-json.md) | runtime 拿不到 payload_json / JSON.parse 失败时 | ~60 |\n| [part-c-html-dashboard.md](references/part-c-html-dashboard.md) | 用户说\"更高级 / 应用化 / 不限标准看板\"，从零生成 HTML 化分析应用时（V2.1.1 新建） | ~620 |\n| [part-c-store-mobile-scorecard.md](references/part-c-store-mobile-scorecard.md) | 加盟店老板手机成绩单 / 换店滤空 / GDPlugin 视图顺序错位 / 对比组家数泄露 / 要离线可点的移动样本时（V3.2.0） | ~280 |\n| [part-c-design-baseline.md](references/part-c-design-baseline.md) | 生成/修改任何 HTML 看板的视觉层时；用户说\"做好看点 / 太丑 / AI 味重\"时；C-12 §11.5 视觉验收时。模块首屏=数据判断 / KPI 与数值口径 / 图表真实性 / token 硬上限 / 反 AI 味红线 / `guanvis screenshot` 验收清单。吸收 [design-taste-skills](https://github.com/xiaomingtx666/design-taste-skills)（MIT），覆盖 C-12 / Part D / Part E（V3.1.0 新建） | ~150 |\n| [v7-page-card-publish-pipeline.md](references/v7-page-card-publish-pipeline.md) | V7 BI 实例端到端搭多个 HTML 看板 / 手撸 page+card API 被 `60004` 草稿页面错误卡住 / CSV 散客 `会员ID IS NOT NULL` 算出 100% 假指标 / Spark `WITH 中文别名` 报错 / ETL update `1012 同名文件` / SmartETL `COUNT_DISTINCT`/`JOIN_DATA` 多键/`FULL_OUTER` 节点化坑（V2.1.8）/ HTML customChart `renderChart` 不调 + `autoBootstrap` + chip toolbar 兜底（V2.1.9）/ 移动端 phoneLayout v7 草稿 save API 死路 + ZIP inject 唯一可行路径 + CSS @media 模板（V2.1.10） | ~1120 |\n| [part-e-superapp-pipeline.md](references/part-e-superapp-pipeline.md) | SuperApp 开放应用开发流水线 / `guancli app create/publish` 不读 `.env` 必须显式传 `--app-id` / 脚手架 bi-services 速查 / 数据集异步预览 3 步链路 / **`/survey-engine/api/form/add` 建表反向工程**（脚手架没暴露） / **BI LLM 中转 NOT_JSON_RES/ILLEGAL_JSON_RES 三路径解析模板**（含从 error_message 抠 LLM 响应）/ 客户端模拟流式 + prompt 模板 / 原生 fetch + credentials: 'include' 绕过脚手架 `get` unwrap / `<base href>` + Router basename / 设计纪律 + 反模式表 + 决策树（V2.1.12 新建） | ~760 |\n| [ai-native-ads-design.md](references/ai-native-ads-design.md) | **majia-guanyuan 哲学层文档**——客户问\"想给现有 BI 接 AI\"时判断\"治理 vs 重搭\" / 7 条 AI-native ADS 字段约束（中文枚举 / 推荐预算 / 复合拼好 / TIMESTAMP / 强约束取值 / 数值算好 / 权限冗余） / ODS+DWD 不动 ADS 重建 / 预算分配 30%+30%+40% / 与 Part D/E + 餐饮 BI 公式库的关系 / 反模式 8 条（V2.1.13 新建） | ~260 |\n\n**餐饮 BI 公式实战库（V2.1.5 新建，去敏蒸馏自两段餐饮连锁 BI 履职 + 39 个生产 ETL；➡️ 2026-07-12 已迁至独立仓库 [majia-huiyuan](https://github.com/maojiebc/majia-huiyuan)，下表链接直达新家，本仓库 references/restaurant-bi-formulas/ 仅留指针）：**\n\n| 文件 | 何时读 | 行数 |\n|---|---|---|\n| [restaurant-bi-formulas/README.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/README.md) | 进入业务公式库的总入口 / 字段词典 / 5 条最常踩坑 | ~70 |\n| [restaurant-bi-formulas/01-date-and-time.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/01-date-and-time.md) | 写时间范围（T-1 / 本月 / 上月 / 近 N 天 / 时间宏 / 用餐时段 / 跨月对齐） | ~180 |\n| [restaurant-bi-formulas/02-customer-and-membership.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/02-customer-and-membership.md) | 新老客 / 会员属性 / 消费频次（3 口径）/ 复购（跨天 vs 非跨天）/ 留存流失 / RFM / 注册前后行为 / 90 天复购分桶 | ~700 |\n| [restaurant-bi-formulas/03-revenue-kpi.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/03-revenue-kpi.md) | AC / ADS / ADT / AUD / Comp / TC_CRM% / NS_CRM% / 营收占比 / 客单分桶 / 累计消费 | ~240 |\n| [restaurant-bi-formulas/04-channel-and-store.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/04-channel-and-store.md) | 业务渠道（堂食/外卖）/ 订单子渠道大 case / 时效类型 / 搭配类型 / StoreDate / 成长类型 / 注册门店优先级回填 | ~410 |\n| [restaurant-bi-formulas/05-coupon-and-discount.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/05-coupon-and-discount.md) | 核销率 / 折扣率 / 折扣分桶 / 券类型分流 / 注册第一张券 / 30 日优惠订单比例 | ~160 |\n| [restaurant-bi-formulas/06-sql-utils.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/06-sql-utils.md) | 字符串拆解 / `explode+split` / `collect_set+concat_ws` / 开窗排名（ROW_NUMBER/RANK/DENSE_RANK）/ 累计窗口 / 多表 LEFT JOIN | ~350 |\n| [restaurant-bi-formulas/07-data-quality-traps.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/07-data-quality-traps.md) | `NULL vs 0` / 三态判断 / 口径歧义 / 重复字段名 / A↔B↔通用字段对照表 / 日期边界 | ~250 |\n| [restaurant-bi-formulas/08-etl-engineering-patterns.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/08-etl-engineering-patterns.md) | **ETL 工程范式**：10-CTE DWD 宽表底座 / 轻节点重 SQL vs 重节点轻 SQL 哲学 / 财务双源对账 / POS 系统归一化 / 会员生命周期多输出 / Cohort 日期×门店网格（蒸馏自 39 个 V1 生产 ETL）| ~280 |\n| [restaurant-bi-formulas/09-etl-catalog.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/09-etl-catalog.md) | **39 个 V1 生产 ETL 索引清单**：按 11 业务域分类（基础维表 / DWD / 会员档案 / 顾客行为 / 财务营收 / 营销目标 / 私域社群 / 活动券 / 评价管理 / 业务标签 / 数据质量）+ 每 ETL 的节点/输入/输出/SQL 速查 + 复用决策表 | ~190 |\n\n> 触发场景：\"如何算复购率 / 客单价 / 同店增长\" / \"怎么判新老客\" / \"用餐时段怎么分桶\" / \"为什么会员数对不上\" / **\"我要写 DWD 宽表 / 评价 pipeline / 财务对账\"** — 直接进 [restaurant-bi-formulas/README.md](https://github.com/maojiebc/majia-huiyuan/blob/main/公式库/README.md) 路由表。和 Part B/C 正交（按业务领域分，非按平台操作分）。\n\n**贡献者原文（不修改，照引）：**\n\n| 文件 | 来源 |\n|---|---|\n| [etl-rewrite-original.md](references/etl-rewrite-original.md) | CTO 张进 — SmartETL 改写经验未删减原文 |\n| [custom-chart-playbook.md](references/custom-chart-playbook.md) | CTO 张进 — 自定义图表排障完整 playbook |\n| [execplan-spec.md](references/execplan-spec.md) | OpenAI Codex — ExecPlan 完整规范 |\n| [agents-rule.md](references/agents-rule.md) | OpenAI Codex — AGENTS.md 极简调度规则 |\n\n---\n\n## 📋 版本记录\n\n> 顶部 🆕 callout 是最新版摘要；完整逐版记录见 [CHANGELOG.md](CHANGELOG.md) 或 [GitHub Releases](https://github.com/maojiebc/majia-guanyuan/releases)。以下只留最近三版一句话索引：\n\n- **V3.2.1**（2026-09-20）对齐 guanskill 0.1.39 / guancli 1.0.62，修正指标批量结果与工作流调度说明。\n- **V3.2.0**（2026-09-15）手机成绩单 V2、19输出专供ETL、异常提示与券转化明细，全部示例为合成数据。\n- **V3.1.12**（2026-09-14）门店手机成绩单经验 + 脱敏离线 HTML 样本；官方全家桶版本仍按 3.1.11。\n## 👤 作者 / 联系\n\n**马甲（@maojiebc）** · 超级马甲\n\n如果这份 skill 帮到你，欢迎在以下任意渠道找我交流踩坑实录、提需求、报 bug，也欢迎切磋用户运营 / 数据中台 / BI 工程的实战经验：\n\n| 渠道 | 链接 |\n|---|---|\n| 📧 Email | [m9224@163.com](mailto:m9224@163.com) |\n| 🐙 GitHub | [github.com/maojiebc](https://github.com/maojiebc) |\n| 🪝 ClawHub | [clawhub.ai/p/maojiebc](https://clawhub.ai/p/maojiebc) |\n| 🐦 X | [@maojiebc](https://x.com/maojiebc) |\n| 📕 小红书 | [超级马甲](https://xhslink.com/m/4fQMJeHHWKC) |\n| 📰 微信公众号 | **超级马甲** |\n\n> 这份 skill 是 14 年用户运营 + 观远 BI 实战 + 60+ 张 ETL 写入实证沉淀出来的，问题/合作随时聊。\n\nFile v3.2.1:examples/store-mobile-scorecard-v2/etl/README.md\n\n# 专供 ETL 参考\n\n`pipeline.json` 声明10个逻辑源、26个计算节点及19个输出。每个SQL的 `input1`、`input2` 等按对应步骤的 `inputs` 顺序绑定。未携带任何租户数据集、目录、连接或页面ID。\n\n商品排除项“示例排除商品”是脱敏占位，接入时须替换为本组织的有效商品分类规则。\n\n字段使用业务别名，例如“订单日期”“total_实付”。接入时先核查本组织字段语义、类型、时区、订单状态、取餐方式、门店名称与编号映射，再通过官方 guanetl 组装隔离流程。文件不是 guanetl 完整导出包，不能直接覆盖生产ETL。前端视图契约由 build.mjs 的 `packViews` 和 scorecard.js 的列名识别共同展示。\n\n财务与顾客订单用于有效门店并集；多数逐日输出保留70天，窗口去重、对比、异常证据与汤底覆盖分别聚合。订单和券号仅参与后端关联，不下发浏览器。会员证据与券转化为版本化JSON，在19个既有输出内扩展。\n\n所有默认规则、阈值及口径限制见 [V2实践](../../../references/part-c-store-mobile-scorecard-v2.md)。SQL保留 Spark 3.4 语法；本公开包没有执行真实数据库查询，不承诺任意字段、POS或租户开箱即用。调度应绑定实际上游刷新，核查时间水位并观察自然运行；不要在公共模板硬编码生产调度或凭据。\n\nFile v3.2.1:examples/store-mobile-scorecard-v2/README.md\n\n# 门店手机成绩单 V2：专供 ETL、异常提示与券转化\n\n这是一份可离线操作的移动端案例。门店、日期、业务数字、券名与异常证据全部为合成数据；不含企业数据、账号、平台资源 ID 或线上截图。V1 保留在相邻目录，作为历史版本。\n\n下载 [单文件 HTML](store-mobile-scorecard.html) 后用浏览器打开即可，不需要登录、联网或大模型。源码修改后执行：\n\n```sh\nnode examples/store-mobile-scorecard-v2/build.mjs\nnode examples/store-mobile-scorecard-v2/test.cjs\n```\n\n<img src=\"https://raw.githubusercontent.com/maojiebc/majia-guanyuan/main/examples/store-mobile-scorecard-v2/preview.png\" alt=\"V2券转化明细，合成数据\" width=\"390\"/>\n\n## 可以直接体验\n\n顶部先选分公司，再选门店；同分公司按固定近7天总营业额降序排列。示例城南店演示会员集中高额订单与堂食汤底缺失，示例镇中店没有异常警示，示例北区的城北店演示无券核销与会员识别覆盖不足。\n\n昨日、近7天、近30天、本月同步改变数据范围，以及“昨日明细／近7天明细／近30天明细／本月明细”和对应的转化明细标题。每日明细有总额、堂食、外卖三个切片；标题、合计与表头固定，只滚动数据。日期与星期分行，周末浅色标记。近8周趋势的月份与日期分行，避免横轴挤在一起。\n\n“跟其他门店比”分别展示近7天日均营业额、固定近30天会员订单占比。只给本店名次和中位数，不披露其他店的明细。会员占比参评要求和前后期变化条件见口径弹层，不用该占比决定顶部选店顺序。\n\n异常警示主标题为红色，只有达到规则才出现。会员订单提示给出集中笔数、跨天数、金额占比及原始支付类别，不判断操作人身份或直接认定刷单；汤底异常区分堂食收银点选与外卖商品映射。页尾为业务分析用途说明，联系对象使用通用的“运营支持”。\n\n优惠券转化明细分“营收贡献／优惠折扣”，展示核销张数、订单数、关联实付、客单、整单优惠、加权实付折扣和每优惠1元对应实付。叠券总计独立按订单去重，不能将券种行相加。未匹配、金额冲突、券作支付和非完成订单保留数量，不把未知金额当成0。\n\n## 文件与使用边界\n\n| 文件 | 用途 |\n|---|---|\n| `scorecard.js` / `scorecard.css` | 当前前端交互与统一字号间距；离线筛选器适配在 JS 末尾 |\n| `build.mjs` | 固定种子生成三个门店的合成聚合数据，封装单文件 HTML |\n| `test.cjs` | 叠券去重、折扣加权、未知金额、跨周期隔离与异常边界检查 |\n| `etl/pipeline.json` | 10类逻辑输入、26个计算步骤与19个输出的依赖关系 |\n| `etl/*.sql` | Spark SQL 计算参考，`input1` 等顺序由 pipeline 声明 |\n| [完整实践说明](../../references/part-c-store-mobile-scorecard-v2.md) | 数据口径、性能取舍、移动规范与发布验证 |\n| [券关联排查](../../references/coupon-order-link-diagnosis.md) | “已核销但无关联订单”的分层追溯方式 |\n\n演示数据按模块合成，用于验证交互和边界，不能作为真实经营基准。ETL 是字段与依赖参考，并非可直接覆盖任意租户的部署包：须先映射本地源字段，用官方 guanetl / guanvis 创建隔离副本，校验权限、筛选、调度及真实数据，再发布。不要把离线示例当作已接入真实数据或已证明加载速度提升。\n\nFile v3.2.1:examples/store-mobile-scorecard/README.md\n\n# 门店手机成绩单 · 脱敏离线案例\n\n> 当前迭代见 [V2](../store-mobile-scorecard-v2/README.md)。本文件保留 V1 约定与历史验证。\n\n给加盟店老板看的手机成绩单样本。和桌面看板不是同一张页，也不是把桌面缩小。\n\n**V1 版**（2026-09-14 封存）：单卡内滚动，19 个 DATA_GRID，不取 RFM，外卖色 `#FFD100`。不要为了切店先出营业额拆成两张卡。\n\n经验总结（产品规则、19 视图契约、换店滤空、列名识别、对比不写家数、发布链路）：\n\n[`references/part-c-store-mobile-scorecard.md`](../../references/part-c-store-mobile-scorecard.md)\n\n## 打开\n\n双击 `store-mobile-scorecard.html`，或：\n\n```bash\nopen examples/store-mobile-scorecard/store-mobile-scorecard.html\n```\n\n不需要观远、不需要登录、没有网络请求。页顶横条写明：虚构门店、虚构数字、锚点冻在 2026-03-20。\n\n生产页用页面筛选器换店。本样本用页内「示例镇中店 / 示例城南店」代替，方便离线看换店后数字一起变。\n\n## 重新生成\n\n改 `scorecard.js` / `scorecard.css` / `build.mjs` 之后：\n\n```bash\nnode examples/store-mobile-scorecard/build.mjs\n```\n\n生成器会自检：除 RFM 外的视图都能按列名识别（`detectV.rfm === -1`）；昨天合计 ≠ 近 7 天日均；两店数字不同；会员频次高于非会员且两店不同；对比组够 3 家（只用于算名次，页面不展示家数）。\n\n## 点击清单\n\n打开后按这个表点一遍，每一项都应该仍有数：\n\n1. 两店切换（店名、首屏、顾客、私域、商品一起变）\n2. 昨天 / 近 7 天 / 近 30 天 / 本月\n3. 每日明细\n4. 堂食、外卖下钻\n5. 近 30 天折线滑块、近 8 周柱\n6. 跟其他门店比三张卡 + 弹层（看不见家数、看不见其他店名）\n7. 顾客与会员（消费会员跟周期去重、新老客条、当前状态）\n8. 会员和非会员（一级模块：人均贡献 + 右侧客单价，下方只有组内营业额）\n9. 私域 KPI + 哪些券用得最多（一级模块，不折叠）\n10. 饭点条（在热销上面）+ 热销展开、汤底堂食/外卖\n11. 口径说明\n\n## 不要用它做什么\n\n不要把这个 HTML 当成 guanvis 工程去 `pack` / `upload`。上线仍是：原生 Page + 门店筛选器 + HTML 父卡 + 19 个 DATA_GRID + 必要时补 `phoneLayout`。\n\nFile v3.2.1:examples/workshop513-咖啡连锁会员运营模拟案例/README.md\n\n# ➡️ 已迁移：majia-huiyuan（独立仓库）\n\n本案例（咖啡连锁会员运营模拟数据中台 · 54 数据集 / 25 ETL / 12 看板整库快照）已从本仓库独立，作为**开源会员运营家底**项目持续迭代：\n\n**👉 https://github.com/maojiebc/majia-huiyuan**\n\n- 独立仓库含完整的结构定义、200 行/表数据样本、口径 SQL、观远原始 JSON，并新增 AI Agent 友好层（`llms.txt` + `AGENTS.md`）\n- 本目录自 2026-07-12 起不再更新；历史版本可在本仓库 git 历史（≤ v3.1.6）中找回\n- 分工：**工具在 majia-guanyuan，数据在 majia-huiyuan**\n\nFile v3.2.1:README.md\n\n# majia-guanyuan · 观远 BI 实战增益层 · 马甲实战版\n\n> **官方全家桶之上的实战增益层** —— 观远官方 BI 全家桶（`guancli` 查数 / `guanvis` 建卡发布截图 / `guanetl` ETL / `guanwf` 数据流 / `guands` 数据源 / `guanmetric` 指标写）全部公网化后（2026-06-03 首发五件套、2026-07-08 `guanmetric` 入桶扩至 6 员），本 skill **不再自造轮子**：标准查数/建卡/ETL/数据集 CRUD 一律**路由官方全家桶**，只攻官方 DSL/命令够不着的硬骨头 —— ETL 治理判断 + 引擎报错手册、自定义图表注入 + descriptor patch、v7 状态机绕过、SuperApp 反向工程、AI-native ADS 方法论、餐饮公式库。\n> 兼容 **Claude Code** · **OpenClaw** · **Codex** · **Hermes (gbrain)** 等所有支持 SKILL.md 的 agent 工具。\n> 60+ 张 ETL 创建/重构/修复 + 治理扫描 + 自定义图表注入排障的真实战场记录。\n\n[![Skill Version](https://img.shields.io/badge/skill-v3.2.1-blue)](./SKILL.md)\n[![GitHub Release](https://img.shields.io/github/v/release/maojiebc/majia-guanyuan?label=release&color=success)](https://github.com/maojiebc/majia-guanyuan/releases)\n[![skills.sh](https://skills.sh/b/maojiebc/majia-guanyuan)](https://skills.sh/maojiebc/majia-guanyuan)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)\n[![Claude Code](https://img.shields.io/badge/Cl...","readmeExcerpt":"Skill: 观远 BI · 马甲实战版 Owner: maojiebc Summary: 观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。 Tags: agent-skill:3.2.3, agen","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# 看本机当前全家桶版本\nguanskill version\n\n# 看 npm 上最新聚合包版本\nnpm view @guandata/guanskill version\n\n# 逐个看子包最新版本（聚合包可能滞后）\nnpm view @guandata/guancli version\nnpm view @guandata/guanvis version\nnpm view @guandata/guanetl version\nnpm view @guandata/guands version\nnpm view @guandata/guanwf version\nnpm view @guandata/guanmetric version"},{"language":"bash","snippet":"# 升级到最新聚合包（装到你的 npm 全局 prefix —— 先 `npm prefix -g` 确认当前目标）\nnpm i -g @guandata/guanskill@latest\n\n# 验证新版本\nguanskill version"},{"language":"bash","snippet":"# install-skill 把每个子包的 SKILL.md + references/ 装到 ~/.agents/skills/<name>/\nguanskill install-skill"},{"language":"bash","snippet":"# 各子包 CHANGELOG.md 在 npm 包目录下\nGUANSKILL_DIR=$(npm root -g)/@guandata/guanskill/node_modules/@guandata\nfor pkg in guancli guanvis guanetl guands guanwf guanmetric; do\n  echo \"=== $pkg ===\" && head -30 \"$GUANSKILL_DIR/$pkg/CHANGELOG.md\" 2>/dev/null && echo\ndone"},{"language":"bash","snippet":"# 同步已发布的整包，包含 references/templates，不能只复制两个 Markdown 文件\npython3 ~/.codex/skills/majia-ota/scripts/sync_local_agents.py /path/to/majia-guanyuan --target all\n\n# commit + push（或走 /majia-ota-skill 完整发布链）"},{"language":"bash","snippet":"# 一行看完「本机 vs npm 最新」差异\necho \"LOCAL:\" && guanskill version && echo \"---\" && echo \"NPM latest:\" && npm view @guandata/guanskill version"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: majia-guanyuan\ndescription: 观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。\nlicense: MIT\nmetadata:\n  version: \"3.2.3\"\n  author: \"超级马甲 / maojiebc\"\n  homepage: https://github.com/maojiebc/majia-guanyuan\n  openclaw:\n    emoji: \"📊\"\n    homepage: https://github.com/maojiebc/majia-guanyuan\n    os:\n      - macos\n      - linux\n    requires:\n      bins:\n        - jq\n        - bash\n    install:\n      - kind: npm\n        package: \"@guandata/guanskill\"\n        bins:\n          - guancli\n          - guanvis\n          - guanetl\n          - guanwf\n          - guands\n          - guanmetric\n---\n\n# 观远 BI · 马甲实战版（V3.2.3）\n\n> **结构说明（V1.5.0 引入 progressive disclosure）**：本文档是**路由层 + 关键规则**，详细操作手册下沉到 `references/`。每个 Part 的入口章节会指出\"何时回到 references/ 查全表\"。完整章节索引见末尾的 [📚 References 目录](#-references-目录)。\n\n## 🧭 Part 选择\n\n| 你想做 | 走 |\n|---|---|\n| 查数据、建卡、出报表、标准 ETL / 数据集 CRUD / 指标写 / 洞察问答 | **🧭 路由层** → 交给官方全家桶（`guancli` / `guanvis` / `guanetl` / `guanwf` / `guands` / `guanmetric`），见路由总表 |\n| 扫整库 ETL 治理 / 新建/修改/删除 ETL / 字段使用度审计 / 修复 ETL 报错 | **Part B：ETL 治理与写入** |\n| 把整条 SmartETL 链改写成 SQL 版 + 页面副本验收 + 差异定位 + 空快照阻塞 | **Part B-17：全链路重写方法论**（拆到 [references/part-b17-fullchain-rewrite.md](references/part-b17-fullchain-rewrite.md)） |\n| 30+ 张表批量迁移 / 跨多日工程 / 复杂重构需要项目化追踪 | **B-17.11 ExecPlan 工作法**（同上文件 §11） |\n| 自定义图表 HTML/CSS/JS 注入、固定卡片/overlay、payload_json 取数、路由清理 | **Part C：自定义图表开发与排障** |\n| 从零生成 HTML 化经营分析应用（用户说\"更高级 / 应用化 / 自定义模块 / 最完美 / 不限标准看板\"）| **Part C-12：HTML 应用化看板生成**（拆到 [references/part-c-html-dashboard.md](references/part-c-html-dashboard.md)） |\n| 手机成绩单专供ETL / 红色异常提示 / 券转化明细 / 近7天营业额排序 / 核销未匹配订单 | **V2** [实践与口径](references/part-c-store-mobile-scorecard-v2.md)、[离线示例](examples/store-mobile-scorecard-v2/README.md)、[券关联排查](references/coupon-order-link-diagnosis.md) |\n| 加盟店老板手机成绩单 / 门店移动看板 / 换店后财务空白 / GDPlugin 视图顺序错位 / 对比组家数泄露 / 要一份可离线点的移动样本 | **Part C 门店手机成绩单**（拆到 [references/part-c-store-mobile-scorecard.md](references/part-c-store-mobile-scorecard.md)，离线 HTML： [examples/store-mobile-scorecard/](examples/store-mobile-scorecard/)） |\n| **v7 BI 实例**上端到端搭多个 HTML 应用看板 / 手撸 `POST /api/page+/api/card` 被 `60004 此操作只能在草稿页面执行` 卡住 / CSV 散客 `会员ID IS NOT NULL` 算出 100% 假指标 / Spark `WITH 中文别名` 报 `PARSE_SYNTAX_ERROR` / ETL update 报 `1012 输出数据集目录中存在同名文件` | **Part D：V7 Page/Card 发布流水线 + 三态硬规则**（V2.1.6 新增，拆到 [references/v7-page-card-publish-pipeline.md](references/v7-page-card-publish-pipeline.md)） |\n| **SuperApp / 超级应用 / 开放应用**开发流水线 / `guancli app create/publish` / `--app-id` 不传变成每次新建 / 数据集异步预览 3 步 / 表单结构先走 `guands form`；旧脚手架建表兼容问题按 §6/ **BI 中转 LLM 报 NOT_JSON_RES / ILLEGAL_JSON_RES**（响应被塞在 error_message）/ `/api/llm-config/list` 返回裸数组被脚手架 unwrap 吞 / 同源 fetch credentials 不带 cookie / 客户端模拟流式打字效果 / 任务池工作"},{"path":"examples/store-mobile-scorecard-v2/etl/README.md","content":"# 专供 ETL 参考\n\n`pipeline.json` 声明10个逻辑源、28个计算节点及19个输出。每个SQL的 `input1`、`input2` 等按对应步骤的 `inputs` 顺序绑定。未携带任何租户数据集、目录、连接或页面ID。\n\n商品排除项“示例排除商品”是脱敏占位，接入时须替换为本组织的有效商品分类规则。\n\n字段使用业务别名，例如“订单日期”“total_实付”。接入时先核查本组织字段语义、类型、时区、订单状态、取餐方式、门店名称与编号映射，再通过官方 guanetl 组装隔离流程。文件不是 guanetl 完整导出包，不能直接覆盖生产ETL。前端视图契约由 build.mjs 的 `packViews` 和 scorecard.js 的列名识别共同展示。\n\n财务与顾客订单用于有效门店并集；多数逐日输出保留70天，窗口去重、对比、异常证据与汤底覆盖分别聚合。订单和券号仅参与后端关联，不下发浏览器。会员证据与券转化为版本化JSON，在19个既有输出内扩展。\n\n所有默认规则、阈值及口径限制见 [V2实践](../../../references/part-c-store-mobile-scorecard-v2.md)。SQL保留 Spark 3.4 语法；本公开包没有执行真实数据库查询，不承诺任意字段、POS或租户开箱即用。调度应绑定实际上游刷新，核查时间水位并观察自然运行；不要在公共模板硬编码生产调度或凭据。\n\n本次新增 `dinein_repurchase.sql` 与 `repurchase_peers.sql`，结果并入门店档案而不增加前端视图数。顾客、周期会员与门店档案使用字符串门店编号，输入依赖以最新 pipeline 为准。\n\n`DEMO_NEW_STORE`、`示例重新开业店` 和日期 `2026-03-19` 是重开店历史边界的合成占位，展示需要跨模块一致处理的特例；不是通用营业起点规则。接入时删除不适用特例或改为经核验的门店历史映射。财务参考还保留开业前微额测试日识别（全渠道合计1至2单、0至2元且无负数），须按本组织业务核验，不能随意删除正常营业日。\n\n订单源在门店关联前须满足 JOIN 基数约束，见 [订单关联去重](../../../references/order-join-cardinality.md)。公共SQL没有执行目标租户查询；离线构建与测试不代表这些SQL已在任何新环境运行。"},{"path":"examples/store-mobile-scorecard-v2/README.md","content":"# 门店手机成绩单 V2：专供 ETL、异常提示与券转化\n\n这是一份可离线操作的移动端案例。门店、日期、业务数字、券名与异常证据全部为合成数据；不含企业数据、账号、平台资源 ID 或线上截图。V1 保留在相邻目录，作为历史版本。\n\n下载 [单文件 HTML](store-mobile-scorecard.html) 后用浏览器打开即可，不需要登录、联网或大模型。源码修改后执行：\n\n```sh\nnode examples/store-mobile-scorecard-v2/build.mjs\nnode examples/store-mobile-scorecard-v2/test.cjs\n```\n\n<img src=\"https://raw.githubusercontent.com/maojiebc/majia-guanyuan/main/examples/store-mobile-scorecard-v2/preview.png\" alt=\"V2券转化明细，合成数据\" width=\"390\"/>\n\n## 2026-09-23 同步\n\n本次对齐当前线上移动版的前端与SQL口径。门店名称旁显示编号标签，随选店变化；长店名自动换行，编号缺失或归属不唯一时隐藏。保留字符串编号的前导零。\n\n顾客状态按门店编号归属，90天观察期不足时不判断流失。会员和非会员新增固定近30天的堂食跨日复购率，以及同店型前25%参照；观察期不足、每组顾客不足50名或参照门店不足10家时暂不评定。城北店合成样本包含观察期不足场景。百分比以整数为主，小于1%的差异保留显示。\n\n客单价翻倍的根因与上游修复见 [订单关联去重](../../references/order-join-cardinality.md)。公开包保持合成数据，生产门店特例已替换为明确的示例占位。\n\n## 可以直接体验\n\n顶部先选分公司，再选门店；同分公司按固定近7天总营业额降序排列。示例城南店演示会员集中高额订单与堂食汤底缺失，示例镇中店没有异常警示，示例北区的城北店演示无券核销与会员识别覆盖不足。\n\n昨日、近7天、近30天、本月同步改变数据范围，以及“昨日明细／近7天明细／近30天明细／本月明细”和对应的转化明细标题。每日明细有总额、堂食、外卖三个切片；标题、合计与表头固定，只滚动数据。日期与星期分行，周末浅色标记。近8周趋势的月份与日期分行，避免横轴挤在一起。\n\n“跟其他门店比”分别展示近7天日均营业额、固定近30天会员订单占比。只给本店名次和中位数，不披露其他店的明细。会员占比参评要求和前后期变化条件见口径弹层，不用该占比决定顶部选店顺序。\n\n异常警示主标题为红色，只有达到规则才出现。会员订单提示给出集中笔数、跨天数、金额占比及原始支付类别，不判断操作人身份或直接认定刷单；汤底异常区分堂食收银点选与外卖商品映射。页尾为业务分析用途说明，联系对象使用通用的“运营支持”。\n\n优惠券转化明细分“营收贡献／优惠折扣”，展示核销张数、订单数、关联实付、客单、整单优惠、加权实付折扣和每优惠1元对应实付。叠券总计独立按订单去重，不能将券种行相加。未匹配、金额冲突、券作支付和非完成订单保留数量，不把未知金额当成0。\n\n## 文件与使用边界\n\n| 文件 | 用途 |\n|---|---|\n| `scorecard.js` / `scorecard.css` | 当前前端交互与统一字号间距；离线筛选器适配在 JS 末尾 |\n| `build.mjs` | 固定种子生成三个门店的合成聚合数据，封装单文件 HTML |\n| `test.cjs` | 叠券去重、折扣加权、未知金额、跨周期隔离与异常边界检查 |\n| `etl/pipeline.json` | 10类逻辑输入、28个计算步骤与19个输出的依赖关系 |\n| `etl/*.sql` | Spark SQL 计算参考，`input1` 等顺序由 pipeline 声明 |\n| [完整实践说明](../../references/part-c-store-mobile-scorecard-v2.md) | 数据口径、性能取舍、移动规范与发布验证 |\n| [券关联排查](../../references/coupon-order-link-diagnosis.md) | “已核销但无关联订单”的分层追溯方式 |\n\n演示数据按模块合成，用于验证交互和边界，不能作为真实经营基准。ETL 是字段与依赖参考，并非可直接覆盖任意租户的部署包：须先映射本地源字段，用官方 guanetl / guanvis 创建隔离副本，校验权限、筛选、调度及真实数据，再发布。不要把离线示例当作已接入真实数据或已证明加载速度提升。"},{"path":"examples/store-mobile-scorecard/README.md","content":"# 门店手机成绩单 · 脱敏离线案例\n\n> 当前迭代见 [V2](../store-mobile-scorecard-v2/README.md)。本文件保留 V1 约定与历史验证。\n\n给加盟店老板看的手机成绩单样本。和桌面看板不是同一张页，也不是把桌面缩小。\n\n**V1 版**（2026-09-14 封存）：单卡内滚动，19 个 DATA_GRID，不取 RFM，外卖色 `#FFD100`。不要为了切店先出营业额拆成两张卡。\n\n经验总结（产品规则、19 视图契约、换店滤空、列名识别、对比不写家数、发布链路）：\n\n[`references/part-c-store-mobile-scorecard.md`](../../references/part-c-store-mobile-scorecard.md)\n\n## 打开\n\n双击 `store-mobile-scorecard.html`，或：\n\n```bash\nopen examples/store-mobile-scorecard/store-mobile-scorecard.html\n```\n\n不需要观远、不需要登录、没有网络请求。页顶横条写明：虚构门店、虚构数字、锚点冻在 2026-03-20。\n\n生产页用页面筛选器换店。本样本用页内「示例镇中店 / 示例城南店」代替，方便离线看换店后数字一起变。\n\n## 重新生成\n\n改 `scorecard.js` / `scorecard.css` / `build.mjs` 之后：\n\n```bash\nnode examples/store-mobile-scorecard/build.mjs\n```\n\n生成器会自检：除 RFM 外的视图都能按列名识别（`detectV.rfm === -1`）；昨天合计 ≠ 近 7 天日均；两店数字不同；会员频次高于非会员且两店不同；对比组够 3 家（只用于算名次，页面不展示家数）。\n\n## 点击清单\n\n打开后按这个表点一遍，每一项都应该仍有数：\n\n1. 两店切换（店名、首屏、顾客、私域、商品一起变）\n2. 昨天 / 近 7 天 / 近 30 天 / 本月\n3. 每日明细\n4. 堂食、外卖下钻\n5. 近 30 天折线滑块、近 8 周柱\n6. 跟其他门店比三张卡 + 弹层（看不见家数、看不见其他店名）\n7. 顾客与会员（消费会员跟周期去重、新老客条、当前状态）\n8. 会员和非会员（一级模块：人均贡献 + 右侧客单价，下方只有组内营业额）\n9. 私域 KPI + 哪些券用得最多（一级模块，不折叠）\n10. 饭点条（在热销上面）+ 热销展开、汤底堂食/外卖\n11. 口径说明\n\n## 不要用它做什么\n\n不要把这个 HTML 当成 guanvis 工程去 `pack` / `upload`。上线仍是：原生 Page + 门店筛选器 + HTML 父卡 + 19 个 DATA_GRID + 必要时补 `phoneLayout`。"},{"path":"examples/workshop513-咖啡连锁会员运营模拟案例/README.md","content":"# ➡️ 已迁移：majia-huiyuan（独立仓库）\n\n本案例（咖啡连锁会员运营模拟数据中台 · 54 数据集 / 25 ETL / 12 看板整库快照）已从本仓库独立，作为**开源会员运营家底**项目持续迭代：\n\n**👉 https://github.com/maojiebc/majia-huiyuan**\n\n- 独立仓库含完整的结构定义、200 行/表数据样本、口径 SQL、观远原始 JSON，并新增 AI Agent 友好层（`llms.txt` + `AGENTS.md`）\n- 本目录自 2026-07-12 起不再更新；历史版本可在本仓库 git 历史（≤ v3.1.6）中找回\n- 分工：**工具在 majia-guanyuan，数据在 majia-huiyuan**"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。 Skill: 观远 BI · 马甲实战版 Owner: maojiebc Summary: 观远 BI（Guandata）实战增益层。标准查数、指标批量查询、本地分析、建卡发布、ETL、数据集和表单结构管理、工作流、指标写入路由官方六组件。专攻 ETL 整库治理、SmartETL 全链路重写、引擎报错、自定义图表与 HTML 看板排障、v7 发布兼容、移动端 phoneLayout、门店手机成绩单、SuperApp 的 LLM 中转及历史兼容、AI-native ADS 架构判断。餐饮会员公式见 majia-huiyuan。触发：观远、Guandata、会员、订单、复购率、RFM、ETL 治理、payload_json、自定义图表、HTML 看板、门店手机成绩单、换店滤空、phoneLayout、60004、SuperApp、ILLEGAL_JSON_RES、数据架构。 Tags: agent-skill:3.2.3, agen","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":856,"uniquenessScore":52,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T07:52:54.293Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T07:52:54.293Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:59:29.675Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}