Files
gyxx-flow/docs/architecture.md
T

5.3 KiB

GYXX Flow 架构

目标

GYXX Flow 是一个 Python 3.12 模块化单体。项目在同一部署单元中提供工作流目录、LangGraph 编排、Python 定时调度、外部系统适配和运行审计,同时保持业务模块之间互不依赖。

核心约束:

  • 每个定时任务都是一个独立工作流,并编译为 LangGraph StateGraph
  • 业务模块只能依赖共享契约,不能导入其他业务模块的内部实现。
  • PostgreSQL 使用运行时注入的云端连接;Hermes 使用本机回环地址;飞书保持现有身份和调用方式。
  • 手动执行默认 dry-run,真实外部副作用必须显式使用 --execute
  • 代码、配置和运行数据分离;生产数据根目录必须位于项目目录之外。

项目边界

gyxx-flow/
├─ src/gyxx_flow/
│  ├─ core/                 配置、上下文、产物、记录和锁
│  ├─ workflow/             LangGraph 构建、步骤协议和执行引擎
│  ├─ adapters/             进程、浏览器和外部服务适配
│  ├─ modules/              四个业务模块,生产代码直接位于模块目录
│  ├─ source_sync/          可选的业务源码漂移检查
│  └─ scheduler_service.py  跨平台 Python 常驻调度器
├─ config/                  工作流、时间规则和运行绑定
├─ deploy/                  PostgreSQL 与进程守护定义
├─ docs/                    架构、部署和运维主文档
└─ tests/                   开发和验收测试,不进入生产运行包

var/ 只是开发环境的默认运行目录,不是源码。生产环境通过 GYXX_DATA_ROOT 使用独立持久化目录。

运行链路

flowchart TD
    A["CLI / Python Scheduler"] --> B["WorkflowCatalog"]
    B --> C["Workflow Registry + Factory"]
    C --> D["LangGraph StateGraph"]
    D --> E1["content_marketing"]
    D --> E2["product_commerce"]
    D --> E3["shop_intelligence"]
    D --> E4["supply_chain"]
    E1 --> F["Shared Adapters"]
    E2 --> F
    E3 --> F
    E4 --> F
    F --> G1["Cloud PostgreSQL"]
    F --> G2["Local Hermes collector / analyzer"]
    F --> G3["Existing Feishu identity"]
    F --> G4["Per-script CDP and browser state"]
    D --> H["Journal / Locks / EffectLedger"]
    D --> I["Layered DataLayout"]

工作流与调度

config/workflows.json 只保存由 Python 调度器托管的工作流,记录稳定 ID、所属模块、入口、显式步骤、依赖和失败策略。每个目录项必须在 config/schedules.json 中有且只有一条时间规则。模块工厂负责注入超时、重试、资源锁和副作用策略。

config/commands.json 保存可手动执行的脚本白名单,也承载补采、重试、映射刷新和受保护写操作。命令不是新的定时工作流;--date 可渲染命令声明的 {business_date} 默认参数,--arg 用于追加脚本参数。

config/schedules.json 只保存时间规则。scheduler_service.py 负责 Asia/Shanghai 时区计算、业务日期偏移、时间槽防重、同工作流不重叠、有限错过触发补偿和优雅停止。

服务器只守护一个 gyxx schedule run 进程。systemd 或兼容的 NSSM 只负责进程生命周期,不保存业务时间规则;不得再向 Windows Task Scheduler 或多条 cron 复制工作流时间。

外部系统

  • PostgreSQL:云端模式不提供地址、数据库、用户或密码的源码默认值;由 GYXX_POSTGRES_DSN 在运行时注入,并拒绝回环数据库地址。
  • Hermes:保留本机 data-analyzerdata-collector 两个角色,以及各自 API 和 gateway。
  • 飞书:复用现有 lark-cli profile、应用身份、表格和消息调用方式。
  • 浏览器:每个脚本从 config/runtime-bindings.json 获得唯一 CDP 端口及独立 Profile、Cookie、storage state 路径,不共享可写 Profile。

数据布局

所有运行路径由 GYXX_DATA_ROOT 推导:

data/raw         原始响应、JSON、CSV、Excel、下载文件和截图
data/normalized  清洗和标准化数据
data/curated     聚合事实和业务结果
data/exports     Markdown、Excel 等交付文件
data/evidence    对账、验收和追溯证据
state            调度、图状态、锁、账本和浏览器状态
logs             调度器与工作流日志
tmp              可清理临时文件

原始数据采用追加式保存。迁移部署时停止调度器,完整复制数据根目录并重新注入 GYXX_DATA_ROOT,不修改代码中的路径。

扩展方式

新增定时任务时:

  1. 在所属 modules/<module>/ 中实现可独立测试的业务入口。
  2. 在工作流目录声明 LangGraph 步骤和依赖,并同步增加唯一时间规则。
  3. 为工作流使用的脚本登记公开命令和独立浏览器绑定。
  4. 通过共享适配器访问数据库、Hermes、飞书和数据目录。
  5. 增加 dry-run、失败边界、业务日期和模块回归测试。

新增补采或维护能力时,只在命令目录注册,不增加工作流或调度规则;只有形成新的独立定时任务后才升级为工作流。

新增模块不应要求修改其他业务模块;新增步骤不应要求修改调度器或执行引擎。

四个模块下的 runtime/__init__.py 仅用于兼容历史 Python 导入路径,不承载生产 代码。项目内部代码和新增实现必须使用模块正式路径。