Files
FinDataHub/FinDataHub-代码分析与优化建议.md
FinDataHub d7d2a1e8ad chore(repo): 补齐长期未入库的核心源码、文档与本次复查修复
背景
- HEAD 长期停在 08-03 的安全审计提交,此后六周的工作全部只在工作区。
- 更严重的是部分源码从未进入过版本控制(非"改了没提交"):
    · Services/findatahub-core/  索引 0 条 —— 18 个核心模块(pipeline/gate/cleaner/
      db/cross_validator/health/retry…)全新 clone 拿不到
    · Services/findatahub-client/ 索引 0 条
    · App/Sources 磁盘 74 个 .swift、索引 54 —— 20 个未入库(AutoRecoveryManager、
      全套 Settings*Section、PowerSaver、MySQLOnDemandManager、DependencyScanner…)
  一次 `git clean -fd`、误删目录或磁盘故障即可不可恢复地丢失这些文件。

本提交内容
1. 补齐上述未跟踪源码、测试、文档与报告(Services/App/Docs/Tests/根报告)。
2. 纳入 .workbuddy/memory(项目知识)与 .github CI 配置。
3. 本次代码与架构复查的修复(详见下一段说明):
   - Scripts/bin/common.py         PidManager.status 改 split(":", 1),修复时间戳被截断到整点
   - Scripts/bin/db_pool.py        取连接加超时、归还前 rollback、失败归还池位、双检锁初始化
   - Scripts/bin/newsflash_backend.py  _query_all 改 try/finally 无条件归还连接
   - Scripts/bin/newsflash_collect.py 新增 _install_crash_handlers(faulthandler + excepthook)
   - tushare_fetcher/core/fetcher.py  _fetch_static 增量走 upsert,仅全量快照才 replace
   - tushare_fetcher/scripts/tushare_sync.sh 银层迁移补 stock_weekly/stock_monthly;
                                     月度增加分红按报告期全量刷新
   - kuaixun-service/extend/content_enricher.py 禁用自动重定向 + 逐跳 SSRF 校验
   - App/.../AutoRecoveryManager.swift 反复故障改告警不熔断(避免拉长数据空窗)
   - 新增 Scripts/bin/repair_dividend_history.py(分红历史修复,按报告期分页幂等 upsert)
   - 新增 Docs/repro/*(两个可运行的缺陷复现脚本)
   - 补齐 6 个文件共 20 条回归用例(均做过证伪:旧实现下必然失败)

安全
- 已确认未纳入任何凭据:Services/tushare_fetcher/.env 被其 .gitignore 覆盖;
  ~/.config/findatahub/env(0600)在仓库外。

验证
- Python 测试 1074 passed(Scripts/bin 207 / core 105 / tushare 174 / kuaixun 405 / akshare 183)
- Swift 经 `swift build --disable-sandbox` 编译通过,产物 v1.5.2 已部署
2026-09-18 22:37:55 +08:00

15 KiB
Raw Permalink Blame History

FinDataHub 项目全景分析与优化建议

分析日期:2026-08-09 | 当前版本:v1.4.7 | 分析范围:App / Services / Scripts / Docs 全仓


一、一句话定位

FinDataHub 是一个面向 A 股的本地化金融数据中枢:以「双源采集 → 七步清洗 → 四级质量门控 → SDK/API/MCP 多形态输出」为数据主线,外挂一个 macOS 菜单栏桌面端做可视化管理,以及一个财经快讯子系统做实时资讯采集推送。本质是把散落在 TuShare / AKShare / 各大财经网站的原始数据,治理成一份干净、可信、可被程序与 AI 直接消费的数据资产。

它的差异化定位在于三点:

  1. 数据质量优先 —— 不是简单"拉数据存库",而是有 Medallion 分层、质量分(0–1 六维加权)、门控 BLOCK/WARN/INFO 的完整治理链路。
  2. AI 原生 —— SDK → REST → Skills → MCP 四级抽象,让大模型能自然语言直连数据。
  3. 本地优先 —— MySQL 本地持久化 + macOS 原生 App,无云端依赖,隐私与可控性强。

二、技术栈全景

层 子系统 语言 / 框架 构建 备注
桌面端 App/ Swift 5.9 · SwiftUI · AppKit · Combine · CryptoKit SwiftPM(macOS 13+,零第三方依赖) MenuBarExtra 菜单栏应用
数据核心 Services/findatahub-core Python ≥3.10 · pandas · SQLAlchemy 2 · pymysql · structlog setuptools 公共核心库(被两 fetcher editable 依赖)
SDK/API Services/findatahub-client Python + FastAPI + uvicorn + MCP setuptools 11 方法 SDK + 14 端点 REST + 7 MCP 工具
采集器 A Services/tushare_fetcher Python ≥3.12 · Typer · pydantic-settings + Rust(PyO3 cdylib) hatchling + uv 39 个数据接口 + Rust 序列化加速
采集器 B Services/akshare_fetcher Python ≥3.10 · akshare · Typer · cryptography hatchling + uv 腾讯源优先 + 东财降级
快讯后端 Services/kuaixun-service Python ≥3.10 · FastAPI · jieba · websockets setuptools 12 源采集 + AI 增强 + 四层去重 + 多渠道推送
快讯前端 Services/kuaixun-frontend Vue 3(纯 JS,非 TS) · Vite 5 · Pinia · axios pnpm + Vite 实时快讯流 / 搜索 / 统计 / 标签云
胶水层 Scripts/bin Python — 25 个脚本,App 通过子进程调用
存储 — MySQL(fin_data_clean 等 3 库) — Swift 端从不直连,全走环境变量注入

⚠️ 注意:仓内统计的 954 个 .ts / 1020 个 .js 绝大多数是 node_modules 与 dist 构建产物,前端源码实际是 Vue 3 + 纯 JavaScript,并非 TypeScript。


三、架构分层与功能模块

┌─────────────────────────────────────────────────────────┐
│  L4 接入层   SDK(client.py) │ REST(api.py) │ MCP │ Skills │
├─────────────────────────────────────────────────────────┤
│  L3 使用层   findatahub-client 直读 fin_data_clean         │
├─────────────────────────────────────────────────────────┤
│  L2 预处理层 findatahub-core:七步 Pipeline + 四级门控      │
│             fetch→G1→clean→G2→impute→G3→store→G4         │
├─────────────────────────────────────────────────────────┤
│  L1 采集层   tushare_fetcher │ akshare_fetcher(双源对照)  │
├─────────────────────────────────────────────────────────┤
│  旁路       kuaixun 快讯子系统(后端 FastAPI + 前端 Vue)   │
│  呈现       macOS App(菜单栏,SwiftUI)                   │
└─────────────────────────────────────────────────────────┘

七步 Pipeline(findatahub-core):DAG 编排器,无依赖 Step 用 ThreadPoolExecutor 并行,指数退避重试 + 熔断 + 失败队列 + RerouteRequest 反馈回路(单步≤3 次/全局≤10 次),写 _data_lineage 血缘表。

四级门控(gate.py):

  • gate1_collection:非空 / 行数≥50%(BLOCK)
  • gate2_cleaning:OHLC 关系、负价 BLOCK、|pct_chg|>11% WARN
  • gate3_ingestion:(ts_code,trade_date) 唯一键 + 质量分≥0.60 BLOCK,可 reroute 回 G2
  • gate4_post:日期连续性 >7 天 gap(INFO)

macOS App 功能模块:Dashboard 概览 / AkShare·TuShare 同步控制 / 快讯流 / 定时任务 / 日志归档·日历历史 / 环境检查 / 设置(9 分区)。数据通路:App 不连库,通过 Process 拉起 Scripts/bin/*.py 子进程,读 stdout 的 JSON / tqdm 进度,MySQL 配置经环境变量注入。

快讯子系统:12 源抓取(cls/华尔街见闻/新浪/东财/金十/格隆汇/同花顺/腾讯…)→ 翻译/打标/评分(AI 增强,本地 Ollama)→ 四层去重(source_id 精确 + SimHash 汉明≤12 + TF-IDF 余弦≥0.85)→ 多渠道推送(Bark/飞书/企微/钉钉/Telegram)。


四、发展现状评估

文档层面:P1(采集层)/ P2(预处理层)/ P3(使用层)/ P4(AI 接入)全部标记完成,P5(云端扩展:阿里云同步/Redis/数据血缘/版本管理)为远期规划。文档体系按 pipeline / macos / tracking 三目录组织,较完整。

代码实证层面(探索核对结果):

维度 现状 评价
数据治理链路 七步+四级门控+双源交叉验证已落地,AKShare 成交额/单位/涨跌幅等多项修复 ✅ 完成度高
重构收敛 db.py 已收敛到 BaseDatabaseManager(280→30 行),bootstrap.py 移除反向依赖 ✅ 方向正确
测试覆盖 tushare ~169 + akshare ~149 + 快讯后端 262 通过;但 core 仅 8 个、client 0 个、Swift 0 个 🟡 严重不均
安全 2026-08-03 已做安全审计并修复;API Key、表名白名单、限流、Keychain 存储 ✅ 意识到位
工程一致性 Python 3.10/3.12/3.14 混用;setuptools/hatchling 两套后端;src/ 与 app/ 双轨 🔴 待统一

总体判断:核心数据链路已"能用且可信",完成了从"脚本集合"到"有架构的数据平台"的关键一跃。当前处于功能完备但工程债开始显现的阶段——重复代码、测试盲区、超大文件、性能隐患是下一步的主要矛盾。


五、优化方向(按四大维度,均可落地)

🚀 A. 性能提升

  1. 消除行级 pandas 操作(收益最大)

    • cross_validator.py:186 用 merged.iterrows() 逐行比对 → 改向量化 np.isclose / DataFrame 列运算,双源比对数据量大时提速 1–2 个数量级。
    • akshare_fetcher/core/fetcher.py 至少 8 处 df.apply(..., axis=1) 计算 pct_chg → 改为 (df['close']/df['pre_close']-1)*100 向量化。
  2. Pipeline 血缘写入连接复用

    • pipeline.py 每个 Step 的血缘记录都新建 pymysql 连接 → 注入共享连接池或批量 flush,减少高并发 Step 下的连接抖动。
  3. 并行 Step 的可变 context 竞态

    • 并行 Step 共享可变 PipelineContext → 为每个并行分支传快照/副本,或在 DAG 层明确读写隔离,避免隐蔽的数据竞争。
  4. 阻塞式限流

    • 两 fetcher 共 10 处 time.sleep → 改令牌桶 / asyncio 非阻塞限流,或至少集中到统一 RateLimiter,便于调参与观测。
  5. 快讯搜索 UNION LIKE

    • 多张 news_* 表 UNION + LIKE %kw% 全表扫描 → 建全文索引(MySQL FULLTEXT)或引入 Meilisearch/ES 轻量检索,并对结果集加 LIMIT 与覆盖索引。
  6. Rust 加速面扩大

    • 现有 rust_core 只做批量序列化 → 可顺势把去重 SimHash、双源比对这类 CPU 密集且边界清晰的计算下沉到 Rust,与现有 PyO3 基建复用。

🧹 B. 代码质量改进

  1. 修复已定位的真实 Bug(最优先)

    • findatahub-client/client.py 的 stats():COUNT(*) 结果赋给 df 却引用未定义变量 row_count → 运行即 NameError,属上线级缺陷。
    • pipeline.py:300 血缘写入失败 except: pass 静默吞错 → 至少记 structlog 警告。
    • 快讯 extend/dedup 用内置 hash() 做 SimHash 位映射 → hash() 跨进程不稳定(PYTHONHASHSEED 随机化),去重结果不可复现,改 hashlib.md5/blake2b。
  2. 治理超大文件与职责混杂(Swift 端最突出)

    • SettingsView.swift 2467 行、NewsFlashService 888 行、PythonProcessManager 827 行、DatabaseSetupGuideView 806 行 → 按"设置分区 / 进程管理·通知·过滤·健康监控"等职责拆分。
    • AppConstants.swift 混入完整 Cron 表达式模型、SyncLogEntry.swift 混放 DataSource/DBConfig/AppConfig → 各归其位到独立 Model 文件。
    • NewsFlashService 集进程管理+通知+过滤+健康监控于一身 → 拆 4 个单一职责服务。
  3. 消除强制解包与脆弱解析

    • try! 正则×5、.first!、group.next()!、data(using:)! → 全部改安全可选绑定或预处理常量。
    • 用"stdout 含 📡/✅/❌ emoji 判定日志级别"的解析与 Python 输出格式强耦合 → 改为结构化 JSON 行协议(Python 端 structlog 输出 JSON,Swift 端解码为 enum),一劳永逸解耦。
  4. 收口重复逻辑

    • MySQL 环境变量注入逻辑在 PythonProcessManager.executeSync / ContentView.checkDatabaseReady / NewsFlashService.runDetachedProcess 三处重复 → 统一走 PythonPathFinder.dbEnv()。
    • 两 fetcher 的 cache.py(规范化后 diff 仅 36 行)、report.py、validator.py、config.py 高度雷同 → 仿照 db.py 的收敛路径下沉 findatahub-core。
  5. 清理"双轨"与坏入口

    • 快讯 pyproject.toml 入口脚本指向不存在的 kuaixun_service.main → 修复或删除该 entry point。
    • src/kuaixun_service/ 与 app/+extend/ 双轨并存、unified_writer.py 两处重复 → 二选一,删除空壳迁移残留。
    • app/main.py 用 sys.path.insert hack → 改为正式打包安装。

✨ C. 功能扩展

  1. 补齐 SDK/数据覆盖面(承接 TODO P0 系列)

    • stock_weekly / stock_monthly / fina_indicator 的 clean schema + flow + SDK 方法(client.weekly/monthly/fina_indicator 已有签名,需打通迁移)。
    • 全量历史迁移:tushare 788 万行、akshare 1670 万行入 fin_data_clean,跑通双源交叉验证闭环。
  2. 统计/相关性/PCA 分析能力产品化

    • stats.py / correlation.py / pca.py 已实现但偏"管道内部件" → 暴露为 SDK/REST 端点,并在 App 增加"数据画像"页,把质量分、分布、冗余特征可视化。
  3. 快讯子系统的 Web 化与推送增强

    • 当前 Web 端强依赖打包 dist 易过期(DEVLOG 已踩坑)→ 加构建版本指纹 + 启动校验。
    • 推送渠道可加"重要度阈值 + 免打扰时段"的用户级策略(realtime 已分即时/5min 批量,可再上层配置)。
  4. 数据血缘可视化

    • _data_lineage 已在写入 → 在 App 或 Web 加血缘图谱页,为 P5 数据血缘治理打底。
  5. AI 能力深化

    • MCP 已有 7 工具 → 补"质量分查询""跨表联查""自然语言取数→图表"工具;快讯的 AI 评分/总结可统一收口到 Ollama 调用的 /api/chat+think:false 范式(DEVLOG 已验证)。

🛠 D. 可维护性增强

  1. 统一工程基线

    • Python 版本钉死一个(建议 3.12,两 fetcher 取高),消除 3.10/3.12/3.14 混跑;构建后端统一(建议全 hatchling + uv)。
    • 根目录加一个统一编排:Makefile 或 justfile / taskfile,把 build / test / lint / run 各子系统一条命令串起来。
  2. 补齐测试盲区(投入产出比最高)

    • findatahub-core(门控/编排/重试逻辑)从 8 → 覆盖核心路径;findatahub-client 从 0 → 至少 SDK 方法与导出路径。
    • Swift 端建 testTarget,先测 PythonProcessManager 的 stdout 解析、Cron 模型、Config/Keychain 读写(当前 0 测试是最大单点风险)。
    • 修复现存失败用例:快讯后端 3 failed / 前端 3 failed(含过期断言),让 CI 全绿。
  3. 引入质量门禁工具链

    • Python:ruff + mypy --strict(tushare 已声明,推广到 core/client/akshare/快讯)+ pytest-cov 覆盖率阈值。
    • Swift:SwiftLint;前端:eslint + vitest 纳入 CI。
    • 建 GitHub Actions / GitHub-hosted runner:PR 触发 lint+test,阻止回归。
  4. 依赖与产物治理

    • .gitignore 确认排除 node_modules/dist/__pycache__/.build(避免仓内混入构建产物,当前统计噪音很大)。
    • 根目录的 implementation-report/、kuaixun-architecture-spec/ 为生成的 HTML 报告 → 移入 Docs/reports/ 归档,保持根目录干净。
  5. 可观测性统一

    • structlog 已铺开 → 定义统一字段规范(trace_id / step / duration_ms / rows),血缘表 + 日志 + HealthMonitor 打通,形成"一次同步可全链路追溯"。

六、落地优先级建议(三步走)

阶段 目标 关键动作 预期产出
第 1 步(1 周内) 止血 修 client.py stats() Bug、SimHash hash()、血缘静默吞错、快讯坏入口;跑全量历史迁移 消除上线级缺陷,数据覆盖闭环
第 2 步(2–3 周) 提质 行级 pandas 向量化、Swift 超大文件拆分、测试盲区补齐、统一 Python 基线 + CI 性能与可维护性显著改善,回归有网
第 3 步(1 月起) 扩展 SDK 表类型补全、数据画像/血缘可视化、快讯检索升级、AI 工具深化 → 平滑衔接 P5 云端扩展 从"本地数据平台"走向"数据产品"

一句话总结:FinDataHub 已跨過"能不能用"的门槛,现在的核心是还工程债、补测试网、把已实现的治理与分析能力对外产品化。 先修 Bug、再向量化与拆分、最后扩展,是当前性价比最高的路径。