Files
gyxx-flow/design.md
T

158 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GYXX Flow 统一编排平台设计
## 1. 目标
`D:\yingxiaoyunying``D:\shop-data-flow`
`D:\product-collector-analyze-flow``E:\auto-flow` 的业务源码、启动脚本和工作流
完整迁移到 `D:\gyxx-flow`。新系统采用模块化单体、统一 CLI、声明式调度和分层
数据目录,同时允许旧任务在迁移期继续运行并能逐任务回滚。
“完整迁移”的硬性定义是:删除、改名或断开四个旧项目目录后,新项目仍能完成
入口发现、导入、dry-run、手工执行和调度执行。旧项目只能作为迁移输入和生产对照,
不得成为新项目运行时依赖。仅登记旧入口或通过环境变量调用旧脚本不算迁移完成。
## 2. 边界
- 新代码和迁移工具只写入 `D:\gyxx-flow`
- 在生产切换门禁前,不修改四个旧项目或现有计划任务。
- 允许从旧项目做一次性只读复制;复制后的代码归属新项目并在新项目内改造、测试。
- 运行时代码不得读取 `GYXX_LEGACY_*_ROOT`,不得导入或启动四个旧目录中的文件。
- `D:\comment-data-collector` 不在迁移范围内;它与内容模块共享数据库表的字段
所有权以外部契约表示。
- 真实 Cookie、密码、应用密钥、访问令牌和浏览器 Profile 不进入源码仓库。
## 3. 方案
选择模块化单体而不是原样拼目录或直接拆微服务。四个业务模块为:
1. `content_marketing`:内容指标、评论、达人、周报/月报和登录维护。
2. `product_commerce`:ERP、商品、画像、主图、市场排名、分析和告警。
3. `shop_intelligence`:店铺及竞店周数据。
4. `supply_chain`:采购确认、库存预警、补货和采购单更新。
共享能力通过端口和适配器提供:文件产物、PostgreSQL、飞书、Hermes、浏览器和
平台采集。业务模块不得导入其他业务模块的内部实现。
每个业务模块包含自己的 `jobs/``collectors/``services/``models/`
`resources/`。一次性复制阶段可以在模块内保留原相对结构以降低行为变化风险,但
所有入口必须改为由模块清单定位,所有数据/日志/Profile/临时文件必须改由
`RunContext``DataLayout` 提供。模块间共享只允许依赖 `core``workflow`
`adapters` 和显式契约。
## 4. 运行模型
调度器只调用稳定命令 `gyxx run <workflow-id>`。工作流引擎负责:
- 创建 `run_id``RunContext`
- 获取工作流及资源锁;
- 按依赖顺序执行步骤;
- 记录步骤状态、退出码、耗时和错误;
- 进行有上限的步骤级重试;
- 生成不可变产物清单和 SHA-256;
- 在 shadow 模式关闭生产写入和正式通知。
Windows Task Scheduler 只是一个调度适配器。工作流和时间表的唯一事实来源是仓库
内的声明式配置,因此可以生成 Windows、Cron 或其他平台的调度配置。
## 5. 数据模型
运行根目录由 `GYXX_DATA_ROOT` 指定,默认是仓库下 `var`
```text
var/
data/raw/<domain>/<source>/<dataset>/business_date=<date>/run_id=<id>/
data/normalized/<domain>/<dataset>/schema_vN/
data/curated/<domain>/<dataset>/
data/exports/<consumer>/<workflow>/<date>/<run_id>/
data/evidence/<workflow>/<run_id>/
data/legacy/<source_project>/
runs/<workflow>/<yyyy>/<mm>/<dd>/<run_id>/
state/{browser_profiles,cookies,checkpoints,locks}/
logs/<workflow>/<yyyy>/<mm>/<dd>/
quarantine/
tmp/
```
原始数据只追加。每个产物都有 `artifact_id`、数据集、业务日期、schema 版本、行数、
字节数、SHA-256、源路径和上游产物引用。历史文件先原样复制到 `legacy`,校验通过后
再生成标准化数据。
## 6. 安全和幂等
- 配置只保存环境变量名或凭据引用,不保存密钥值。
- 生产写入使用 `workflow + business_date + entity_id + schema_version` 幂等键。
- 外部通知使用 outbox/回执,失败重试不会重复发送。
- 飞书、数据库和通知都是可替换 Sink;shadow 模式使用测试 Sink。
- 浏览器 Profile 使用独立资源锁,禁止不同工作流并发写同一 Profile。
## 7. 迁移策略
采用源码接管迁移:基线清单 -> 新基础设施 -> 源码只读复制 -> 新项目内路径与配置
改造 -> 无旧目录测试 -> 影子运行 -> 单任务切换 -> 观察 -> 退役。旧命令适配器只
用于盘点阶段,不能出现在最终工作流定义中。切换时只禁用一个旧任务,不删除;失败
时关闭新任务并重新启用旧任务。旧项目至少保留只读 30 天。
迁移顺序为 `shop_intelligence``supply_chain``content_marketing`
`product_commerce`。最后才合并真正重复的适配器,避免因名称相同而过早抽象不同语义
的采集器。
## 8. 验收原则
工程验收依赖自动化测试、静态扫描、源码哈希清单、入口覆盖、旧根目录引用扫描、
隔离旧目录的导入/dry-run、调度生成和历史回放。四模块所有纳入迁移范围的源码必须
在新项目中有目标文件和来源哈希;所有真实入口必须标明 scheduled、manual、library
或 intentionally-excluded,不能静默遗漏。生产验收必须以真实任务运行记录为证据:
日任务连续 7 天,周任务连续 2 个周期,月任务通过历史月份回放。任何缺少证据的
项目保持未勾选状态。
## 9. 统一运行时适配器
每个可执行脚本以完整 `script_id=<module>:<entry>` 作为运行时隔离主键。
`config/runtime-bindings.json` 显式保存 130 个脚本的固定 CDP 端口,范围为
`22000..22999`;配置加载时必须同时满足入口 100% 覆盖、端口唯一和回环地址约束。
新增脚本只能领取未使用端口,已有脚本端口不得随发现顺序漂移。
每个脚本的浏览器状态固定落到:
```text
<GYXX_DATA_ROOT>/state/browser/<module>/<script-name>-<id-digest>/
profile/
cookies.json
storage_state.json
```
同一脚本跨运行复用上述目录,不同脚本不共享端口、Profile、Cookie 或 storage state。
顶层 workflow 和 `gyxx scripts run` 均由 `ModuleCommandAdapter` 注入绑定;嵌套 Python
进程在业务模块导入前由 adapter-owned `sitecustomize` 按真实子脚本路径重新绑定,且会
纠正父进程遗留的 `--cdp-port``--cdp-url``--user-data-dir` 参数。PowerShell/BAT
需要浏览器时通过 `python -m gyxx_flow.runtime_exec env <script-id>` 读取目标叶子脚本绑定。
外部系统策略是运行时硬边界,而不是更换原业务后端:
- 飞书继续使用原来的 lark-cli profile、身份和原 OpenAPI 应用;适配器只透传并禁止误覆盖。
- PostgreSQL 继续使用现有云端配置,统一映射 `PG_*``DB_*``AUTOFLOW_PG_*`,拒绝回环数据库。
- Hermes 继续使用本机 HTTP/CLI,所有 HTTP 端点只允许 `localhost``127.0.0.1``::1`
- Cookie 和 storage state 通过原子替换保存;日志和绑定输出只包含路径、端口和计数,不包含值。
dry-run 只解析和验证绑定,不创建 Profile/Cookie 目录,不探测或启动浏览器,也不触发任何
飞书、数据库或 Hermes 调用。
## 10. 采集数据统一分层
`GYXX_DATA_ROOT` 表示整套运行数据根,不直接等同于 raw 目录。四个业务模块通过共享的 `ModuleDataPaths` 解析固定目录,模块脚本继续使用原有公开常量,避免业务逻辑与物理目录结构耦合:
```text
<GYXX_DATA_ROOT>/
data/
raw/<module>/ # 原始 JSON、CSV、Excel、下载文件、原始截图
normalized/<module>/ # 清洗并统一字段后的数据
curated/<module>/ # 聚合、分析和可供下游复用的数据
exports/<module>/ # Markdown、Excel 等面向人员或外部消费的报告
evidence/<module>/ # 产物清单、哈希和验收证据
state/<module>/ # checkpoint;浏览器状态仍按 script_id 隔离
logs/<module>/
tmp/<module>/
```
raw 数据保持追加语义;浏览器直接下载的 XLS/XLSX/CSV、接口原始 JSON 和采集截图归 raw,处理过程中的临时下载归 tmp,清洗结果归 normalized,跨来源汇总归 curated,最终 MD/XLSX 报告归 exports。现有 `data/raw/<module>/legacy` 只读保留,不在本次收口中移动或重写。路径对象只负责解析,不在导入或 dry-run 时创建目录,因此项目根和数据根可分别迁移。