跳转至

7_xgb_wiki × 2_xuangubao 合并分析与方案调研

2026-09-24 调研。方法:两项目并行深度代码调研(数据流/数据库/代码活跃度/部署/Git 状态)+ 三视角(PM/设计/工程)方案发想。 结论供拍板,本文档不进 mkdocs nav。

TL;DR

两项目是同一数据源、同一批数据的"一代/二代"关系,不是对等的两个产品。

  • 2_xuangubao(2026-04~06,研报浏览器)的核心浏览功能已被 xgb_wiki 覆盖且更强(/report 路由、静态站研报页、/daily 观点墙)。
  • 两库 report 行数完全一致(7,845 行,同步进度同至 2026-09-08),旧库无独有数据,吸收合并零数据损失。
  • 2_xuangubao 仍有 5 项独有资产值得吸收:栏目 tag 体系(15 分类)、sub_title 列、已读/日期筛选体验、离线 HTML 速览生成器、21:40 定时同步自动化 + 云服务器部署形态。
  • 推荐方案 A「吸收合并」:xgb_wiki 吸收上述资产,旧项目清安全债后归档封存;分 4 阶段,每阶段独立可验收。

1. 两项目画像

维度 2_xuangubao(旧) 7_xgb_wiki / xgb_wiki(新)
定位 脱水研报浏览器(15 类栏目导航 + 原文阅读 + 离线 HTML) 题材本体 Wiki(链/题材/个股/观点墙/每日简报/NLQ/MCP)
周期 2026-04-17 ~ 06-16(功能 commit 止于 06-16,之后仅数据同步到 09-08) 2026-08-30 起,45 commits / 9 天密集开发,活跃
数据源 MySQL 10.0.46.53:3306/xuangubao(read_user 只读) 完全相同(.env 逐字段相同,README 自述复制自 2_xuangubao)
本地库 reports.db 58MB,3 表(reports/report_tags/sync_meta) xgb_wiki.db 99MB,20+ 表(report/theme/stock/观点单元三表等)
数据量 report 7,845 行(live 4,387 + digest 3,458) report 7,845 行(完全同一批)
工程化 无测试、无 CI、遗留物多(CLI LLM 链、tools/、bmad、4 份无实现 PRD) 205 项测试、CI 必跑、同步校验/回退/日志、MCP + 2 个 skill
部署 公网云服务器 14.103.53.151:5000(gunicorn+systemd,rsync 更新) Cloudflare Pages 静态站(大陆直连)+ 本地 Flask :5010
自动化 Windows 定时任务每晚 21:40(sync→rsync→重启,失败弹通知) 手动 sync_data.py + push 触发 CI(无本地定时)
Git 内网 GitLab 10.0.16.158:8090,master,77MB,26 commits GitHub seuzxh/xgb_wiki,master,.git 约 497MB(历史 blob 遗留)
LLM Ark / minimax-m2.5,仅边缘化的 CLI 日报链在用 同一 Ark 配置;主链路零 LLM,仅观点升级 + /api/ask 可选

2. 关键发现

2.1 同源同数据(合并的根本依据)

  • 同一 MySQL 库、同一 read_user、同一 .env(xgb_wiki/.env 就是从 2_xuangubao 复制的,docs/design.md:50 有记录)。
  • 各自独立 ETL,但同步的都是 live_tuoshui_news + tuoshui_msgs + 两张 tag_related 表;两库 report 行数同为 7,845,同步进度同停在 2026-09-08(此后不在内网)。
  • 结论:reports.db 是 xgb_wiki.db report 表的(弱)子集,废弃旧 ETL 无数据损失。

2.2 功能覆盖关系

2_xuangubao 的活跃功能只有「Web 研报浏览器」(app.py 3 条路由 + db_web.py 查询层)。逐项对照 xgb_wiki:

2_xuangubao 功能 xgb_wiki 对应 覆盖情况
首页分类导航 + 日期范围统计 / 链总览、/timeline 部分覆盖(缺栏目 tag 维度)
分类列表页(15 栏目、日期筛选、limit 100) 无直接对应 未覆盖 —— xgb_wiki 用链/题材维度,无 tuoshui 栏目维度
报告详情(HTML 原文渲染) /report//(原文+实体标注+配图) 已覆盖且更强
已读标记(localStorage) daily.js 已读仅限观点墙 部分覆盖(研报页缺)
每日离线 HTML 速览(手机自包含单文件) /daily 观点墙(在线) 功能相邻但离线导出未覆盖
21:40 定时自动同步 + 失败通知 无 未覆盖(xgb_wiki 同步靠手动)
云服务器公网部署(手机随时访问) CF Pages(大陆直连) 基本覆盖,形态不同
CLI LLM 日报(generate_brief 链) 观点单元管线(规则引擎) 已被更强方案取代,可弃

2.3 旧项目独有资产清单(吸收候选)

  1. 栏目 tag 体系:tag_id↔栏目名映射(live 9 类 + digest 6 类,硬编码在 db_web.py:20-62 与 generate_daily_digest.py:8-13 两处)。xgb_wiki 同步源里已有 tag_related 表但没有落入 SQLite——吸收需在 ETL 加一张 report_tag 表。
  2. sub_title 列:xgb_wiki 的 LIVE_SQL 没取 sub_title(src/pipeline/etl.py:129-142),旧项目有。
  3. 浏览体验细节:日期范围筛选、tag 过滤、已读标记、limit 分页。
  4. 离线 HTML 速览生成器:generate_daily_digest.py(自包含单文件,手机可开),可改造为读 xgb_wiki.db。
  5. 自动化与部署资产:21:40 Windows 定时任务框架(含失败通知)、云服务器直装部署脚本(deploy_direct.sh / update.sh,systemd+gunicorn+rsync 增量)。

2.4 旧项目的债(归档前必须清)

  • src/config.py:32、src/db_brief.py:18 代码默认值硬编码数据库密码;docs/database/daily_research_report_fetch_plan.md:265 文档明文密码。
  • GIT_PUSH_GUIDE.md 内有内网 GitLab OAuth token。
  • 云服务器 :5000 公网无鉴权暴露(单用户设计,合并后需决策去留)。
  • 已知 bug:sync_data.py 增量清理 tag 时用 msg_id 冒充 report_id 执行 DELETE(sync_data.py:196-200, 288-292)——若旧库继续使用需修,归档则随档封存。
  • 仓库 77MB(reports.db 历史入库);GitLab remote 为内网地址。

3. 三视角方案发想

3.1 产品经理视角(价值/ fit/ 维护成本)

  • P1 统一工作台:合并后一个入口覆盖 研报浏览→题材→观点→(未来)股池策略;股池策略 PRD(docs/stock-pool-strategy-prd.md)正好缺结构化数据底座,合并后直接建在单库上,避免出现第三个分叉项目。
  • P2 保留真实在用的手机链路:旧「每日研报 HTML」产出止于 06-18,说明该链路已被 /daily 取代或闲置——需确认是否还值得保留形态。
  • P3 维护成本减半:一份 .env、一条 ETL、一套测试、一个文档站;不再担心旧库的静默数据漂移。
  • P4 归档即交付:旧项目安全清债后打 tag 封存,是「完成」而非「丢弃」,历史可查。
  • P5 自动化补课:xgb_wiki 目前同步全靠手动,吸收旧项目 21:40 定时任务是对新项目的净增益,与合并互为独立收益。

3.2 设计师视角(体验)

  • D1 补「栏目」维度入口:xgb_wiki 的导航是链/题材/时间线,缺散户视角的「今天脱水研报/评级慧选」栏目浏览;加 /reports 栏目页补齐心智。
  • D2 继承已读/筛选细节:研报列表的日期范围筛选 + localStorage 已读标记迁到新站。
  • D3 观点墙加「导出离线 HTML」:把旧离线速览改造成 /daily 的一键导出,手机离线可看。
  • D4 统一设计系统:旧站是默认 Bootstrap,直接套 xgb_wiki 的「研报纸×行情终端」设计系统,无需迁移样式代码。
  • D5 移动端验收:合并后以手机实际网络验收 CF Pages 可达性,替代对云服务器的依赖判断。

3.3 工程师视角(架构/实施)

  • E1 数据层吸收:xgb_wiki ETL 增加 report_tag 表(源表已有)+ sub_title 列,一次 --full 重建即得;旧的 3 表 schema 直接废弃。
  • E2 应用层吸收:把 db_web.py 的栏目查询逻辑移植为 src 下一个模块(tag 字典统一进 src/config.py 栏目字典),新增 /reports 路由 + 静态站栏目页;不搬 app.py/模板(体验按 D4 重做)。
  • E3 同步自动化合并:Windows 定时任务改为执行 xgb_wiki 的 scripts/sync/sync_data.py(自带校验/回退/日志,退出码 2/3 可触发通知),可选成功后自动 commit+push 触发 CI(GitHub 间歇不可达需隔时重试)。
  • E4 部署形态收敛:三选一——(a) 云服务器退役,全靠 CF Pages;(b) 云服务器改跑 xgb_wiki Flask 完整版(保留公网 /api/ask,但 LLM key 上云);(c) 云服务器只挂每日离线 HTML 静态文件。
  • E5 Git 历史处理:不建议 subtree merge 保两库历史(remote 分属内网 GitLab 与公网 GitHub,且旧库 77MB 含 db 历史、有价值的历史很少)——归档 tag + 把仍被引用的文档(脱水研报数据库Wiki文档.md)显式复制进 xgb_wiki docs 更实用。

4. 合并路线 Top 5 对比

评分维度(合并场景权重):数据单源化(解决双维护)、实施速度、对现有线上功能的风险、保留价值完整性。

# 路线 做法 单源化 速度 风险 保留价值 评语
A 吸收合并(推荐) xgb_wiki 吸收 5 项独有资产(tag 表+栏目页+sub_title+离线 HTML+定时自动化),旧项目清债归档 ★★★ ★★☆(1~2 天) 低(新项目增量,不碰旧线) ★★★ 唯一同时解决双维护+保留价值的路线
B 松耦合并存 代码不动,仅文档声明分工 ☆ ★★★ 零 ★ 「不合并」,双维护问题原样保留
C 反向合并 xgb_wiki 部署搬到云服务器为主 ★★ ★☆ 中(LLM key 上云、服务器装依赖) ★★ 只解决部署形态,代码仍是两套
D Monorepo 双应用 一仓两 app 共享 src ★★ ★☆ 中 ★★ 数据语义已统一,保留两个 app 是过度工程
E 大爆炸重写 统一新应用推倒重来 ★★★ ☆ 高 ★★ 205 项测试和已上线功能全部重验,无必要

5. 推荐方案 A:吸收合并(分阶段)

阶段 1:数据与应用吸收(xgb_wiki 侧,约 1~1.5 天)

  1. ETL 增补:report_tag 表入库 + sub_title 列 + tag 字典统一进 src/config.py(消灭两处硬编码)。
  2. 新增 /reports 栏目浏览:路由 + 静态站栏目页(15 栏目、日期筛选、已读标记);全量 7,845 篇的详情页静态化体积需评估(可列表全量、详情近 N 月 + 更早跳本地/云端)。
  3. 移植离线 HTML 生成器:读 xgb_wiki.db,挂到 /daily 或 scripts/。
  4. 测试扩展:栏目导航/离线导出/tag 完整性纳入 run_tests.py(205→~220 项)。

阶段 2:自动化切换(半天)

  1. Windows 定时任务改为跑 xgb_wiki sync_data.py;退出码非 0 弹通知(沿用旧 auto_update.bat 通知机制);可选成功后自动 push(带 GitHub 重试)。
  2. 旧 ResearchAssistantUpdate 任务禁用(保留定义便于回退)。

阶段 3:旧项目收尾(半天)

  1. 安全清债:移除硬编码密码默认值、文档明文密码、GitLab token;data 未提交项处理。
  2. 归档:GitLab 打 archive/v-final tag,README 顶部加「已并入 xgb_wiki,见 …」声明;脱水研报数据库Wiki文档.md 复制进 xgb_wiki docs(注意 data-model.md:320 已标注其列名过时,复制时附勘误说明)。
  3. 云服务器决策执行(见待拍板 #2)。

阶段 4(可选):远期

  1. 股池策略项目直接建在合并后的单库/单仓上。

验收标准

  • [ ] xgb_wiki.db 含 tag/sub_title,一次 --full 通过 E0-E5 校验
  • [ ] /reports 15 栏目可浏览、可筛选、已读标记生效
  • [ ] 离线 HTML 从新库生成,手机可开
  • [ ] 21:40 定时任务只跑新管线,连续 3 晚成功(在内网环境下)
  • [ ] 旧仓库无明文凭据,打 tag,README 有归档声明
  • [ ] run_tests.py 全绿

6. 风险与坑

  • GitHub 间歇不可达:定时任务若自动 push 必须带隔时重试(本机已知网络特性)。
  • 静态站体积:全量研报详情页约 7,845 页可能显著超当前 41MB 产物,CF Pages 单文件/总量限制需先测。
  • 栏目语义漂移:tag 字典以旧项目 docs/database/data_structure.md:69-93 为准抄录,但 xgb_wiki 的 src/config.py 已有自己的栏目字典口径,合并时需对齐命名。
  • 云服务器无鉴权公网暴露:无论去留,都建议至少加基础防护或改 bind。
  • xgb_wiki .git 497MB:与本合并正交,但若后续要并仓/推大改,建议先做已规划的 git filter 瘦身收尾。
  • 两库同步进度停在 09-08:合并期间需在内网环境做一次全量同步验证(当前 4 次 env_failed 均因不在内网)。

7. 待拍板清单(供确认)

  1. 合并动机确认:主要为了 (a) 减少双维护 / (b) 旧项目退休 / (c) 统一入口做股池策略底座?——动机不影响推荐路线 A,但影响优先级排序(c 会把阶段 1 的 /reports 提到最前)。
  2. 云服务器 14.103.53.151 去留:(a) 退役(全靠 CF Pages)/ (b) 改跑 xgb_wiki Flask 完整版(公网保留 /api/ask,需上 LLM key)/ (c) 只挂每日离线 HTML。默认建议 (a),若手机网络下 CF Pages 实测不稳再考虑 (c)。
  3. 离线 HTML 速览是否还保留:旧产出止于 06-18,疑似已被 /daily 取代。若确认弃用,阶段 1 第 3 步可删,工作量再减。
  4. 旧 GitLab 仓库处置:封存只读 / 迁移最后状态到 GitHub 私有仓备份。默认封存。
  5. 是否保留 sub_title:仅详情页副标题展示用,若不用可不吸收,少一列 schema 变更。

8. 拍板记录与实施结果(2026-09-24)

拍板:① 动机=减少双维护,只维护一个库;② 云服务器逐步退役,主用 xgb_wiki(CF Pages 部署);③ 离线速览不保留;④ 旧 GitLab 全部迁移完成后再归档;⑤ sub_title 不保留;⑥ 定时任务暂不做;⑦ 新增需求:LLM 配置页。

已实施(当日完成,测试 224/0 全绿):

项 结果
report_tag 表 ETL 新增 etl.sync_tags:每次同步(增量/全量)从源库两张 tag_related 表全量重建;E3 外键校验扩到八组(含 report_tag→report);删除连带剔除
数据刷新 增量同步成功:live +76 / digest +60(7,845→7,981 篇),report_tag 6,393 行,校验全过(仅 W2 回补提示)
/reports 栏目页 Flask 导航页(3 组 15 栏目 + 计数/最新日期 + 未打 tag 说明)+ 栏目列表页(日期范围筛选、已读 localStorage、只看未读、核心个股数);导航加入 base.html
静态站 reports.html 升级为栏目 hub + 新增 reports/<src>-<tag>.html 15 个子页(全库列表、标题/日期客户端筛选、已读标记),研报详情页记录已读
LLM 配置页 /settings/llm(生效配置展示/env 与覆盖来源/编辑保存 data/llm_config.json/校验)+ POST /api/llm/test 连通测试;call_llm 改为调用时读取 llm_settings(),配置即时生效
顺手修复 ① trends.py streak executemany 参数绑定反序(自上线以来 streak 列从未真正写入,静默 no-op;今日新数据暴露);② 测试 /api/ask 断言「answer>20 字」把「问答失败:…」误判为通过——改为先探测 /api/llm/test,失败跳过并打印原因,成功时禁含「问答失败」前缀
测试 205→224 项(栏目导航/列表/筛选/已读、report_tag 完整性、LLM 配置流程、静态站栏目页、同步 tag 重建)

新发现的待办(用户侧): - LLM 订阅已失效:.env 的 ark…/api/coding/v3 + minimax-m2.5 实测 404(UnsupportedModel;coding 套餐 key 探测 ark-code-latest/doubao-seed-codee/kimi 均 InvalidSubscription,标准 /api/v3 也无 minimax 访问权)。/api/ask、extract_viewpoints_llm、gen_chain_map 当前不可用——主链路(同步/观点单元/每日简报)不受影响(规则引擎零 LLM)。修复入口:/settings/llm 配置页直接改端点/模型/Key。 - 云服务器逐步退役:旧项目 ResearchAssistantUpdate 定时任务仍每晚跑(旧库继续更新),退役时间表由用户定;退役前 2_xuangubao 保持现状不动。