Vastai-ConnectHub/docs/STRUCTURE.md

5.9 KiB
Raw Blame History

.
├── app/                                # 核心框架层:加载/调度/执行/后台/安全/适配器
│   ├── main.py                         # FastAPI 入口;挂载 SQLAdmin启动时确保 key 与 DB schema
│   ├── admin/                          # SQLAdmin 管理后台
│   │   ├── views.py                    # Job/JobLog 的管理视图、校验、动作按钮、模板选择
│   │   ├── routes.py                   # Admin 自定义 POST 路由Retry/Run 等)
│   │   └── templates/                  # 覆盖/扩展 SQLAdmin 的模板list/details/edit 等)
│   ├── core/                           # 运行时基础设施(配置/日志/上下文/捕获)
│   │   ├── config.py                   # Settings从 .env 读取DB_URL/REDIS_URL/FERNET_KEY_PATH 等
│   │   ├── logging.py                  # 全局日志配置stdout + 可选文件)
│   │   ├── log_capture.py              # “尽力捕获”本次执行日志到 JobLog.run_log不影响执行
│   │   └── log_context.py              # 将 job_id/log_id 写入日志上下文(便于追踪)
│   ├── db/                             # 数据层SQLAlchemy
│   │   ├── models.py                   # Job / JobLog 模型定义
│   │   ├── engine.py                   # create_engine + SessionLocal
│   │   ├── crud.py                     # 基础 CRUD读 Job、写 JobLog、清理日志等
│   │   └── schema.py                   # 轻量 schema 自升级create_all + 补列)
│   ├── security/                       # 安全模块
│   │   └── fernet.py                   # Fernet key 管理 + JSON 加解密(兼容脏数据)
│   ├── plugins/                        # 插件加载
│   │   └── manager.py                  # handler_path -> import -> BaseJob 子类校验 -> instantiate
│   ├── jobs/                           # 插件规范
│   │   └── base.py                     # BaseJob 抽象基类run(params, secrets)
│   ├── integrations/                   # 适配器/SDK业务 Job 禁止直接写 HTTP
│   │   ├── base.py                     # BaseClient超时/重试/日志;统一 request/get_json/post_json
│   │   ├── seeyon.py                   # SeeyonClient致远 OA token 认证 + 自动携带 token header
│   │   └── didi.py                     # (若存在)滴滴侧 SDK/适配器封装
│   └── tasks/                          # Celery 任务引擎
│       ├── celery_app.py               # Celery 配置broker/backend、timezone、beat_schedule 等)
│       ├── dispatcher.py               # 定时调度:每分钟 tickcron_expr 命中则触发 execute_job
│       └── execute.py                  # 统一执行入口:读库->解密->加载插件->run->写 JobLog
├── extensions/                         # 业务插件层(必须独立于框架层)
│   ├── __init__.py
│   └── sync_oa_to_didi/                # 示例插件:仅演示 token 获取日志
│       ├── __init__.py
│       └── job.py                      # SyncOAToDidiTokenJob调用 SeeyonClient.authenticate 并记录日志)
├── docker/                             # 镜像构建
│   └── Dockerfile                      # Python 镜像 + APT 镜像源切换 + 安装依赖
├── docker-compose.yml                  # 生产基线backend/worker/beat/redis/postgres + ./data 挂载
├── docker-compose.dev.yml              # 开发叠加:源码挂载 + backend reload + worker/beat watchfiles 重启
├── env.example                         # 环境变量示例(本地复制为 .env
├── connecthub.sh                       # 一键脚本build/start/restart/stop + dev-* + log
├── pyproject.toml                      # Python 依赖FastAPI/Celery/SQLAdmin/psycopg/cryptography 等)
├── README.md                           # “开发手册”主文档运行指南、Admin 使用、示例配置)
└── data/                               # 运行数据目录(建议仅作为 volume不作为源码管理
    ├── logs/                           # 应用日志落点
    ├── pgdata/                         # PostgreSQL 数据目录volume
    └── connecthub.db                   # 旧 SQLite 残留(若已切换 PG可视情况清理

核心执行链路(从 Job 到 JobLog

  1. Job 定义在 DB 表 jobsid/cron_expr/handler_path/public_cfg/secret_cfg
  2. Beat 每分钟触发一次 dispatcher.tick:读取 jobs,用 cron_expr 判断是否到点
  3. 到点后 dispatcher 调用 execute_job.delay(job_id=...)
  4. Worker 执行 execute_job
    • 读 Job -> 解密 secret_cfgFernet仅内存
    • PluginManager 动态加载 handler_path 指向的 BaseJob 子类
    • 调用 job.run(params, secrets)
    • 捕获/汇总日志run_log与异常traceback写入 job_logsAdmin 可视化查看/重试)

框架层 vs 插件层(边界提示)

  • 框架层app/:只提供通用能力(调度、执行、加解密、日志、管理后台、适配器基类),不包含具体业务流程。
  • 插件层extensions/:只放“具体业务 Job”例如“同步员工/同步部门/同步 OA→滴滴”等必须继承 BaseJob
  • 外部系统调用:禁止在 Job 内直接写 HTTP必须通过 app/integrations/* 下的 Client。

运行数据与持久化data/

data/ 是运行时 volume

  • data/pgdata/PostgreSQL 持久化数据
  • data/logs/:应用日志
  • data/fernet.keyFernet key正式环境必须固定否则历史 secret_cfg 无法解密)

建议:data/ 仅作为挂载目录,不当作源码文件纳入版本管理。