project-structure-root-cleanup-inventory.md 21.8 KB

BettaFish 根目录清理清单与处理策略

版本:v3.4
状态:Active
更新时间:2026-04-09

更新说明(2026-04-09 / T-517,T-114,T-521):根目录历史兼容包目录与旧 CLI 兼容目录 QueryEngine/MediaEngine/InsightEngine/ReportEngine/ForumEngine/MindSpider/frontend/SingleEngineApp/SentimentAnalysisModel/ 已完成清理;根目录 Dockerfile / docker-compose*.yml 已在 T-521 删除;var/output/chrome-headless/ 已在 T-114 完成受控回收。本文中的当前现状应以 docs/root-compatibility-shim-inventory.md、task 文档和 memory 文档为准。

关联文档:

1. 文档目的

本清单用于落实 T-104:把当前根目录中的临时残留、历史运行目录、兼容入口和目标态保留目录明确分类,给出后续可执行的处理策略。

本阶段的目标不是立刻删除所有旧内容,而是先把“哪些可以马上清”“哪些必须先迁移”“哪些要保留兼容层”说清楚,避免后续在 apps/services/ 重组阶段误删有效链路。

2. 当前边界

截至 2026-04-07,以下边界已经成立:

  • 运行时目录的新归属已经统一到 var/
  • Docker 主机侧 volume 已切换到 ./var/...
  • 容器内仍保留旧路径兼容挂载,属于过渡策略,不代表旧根目录运行目录仍是长期目标。
  • infra/docker/ 已成为 Docker / compose 唯一 canonical 目录,根目录同名文件已在 T-521 删除。
  • vendor/mediacrawler/ 已成为外部 MediaCrawler 子模块的 canonical 目录。
  • Insight 多语言情感模型运行目录已通过 INSIGHT_SENTIMENT_MODEL_DIR 配置化,默认值已切到 var/models/insight_weibo_multilingual,根目录旧路径仅保留兼容/示例用途。
  • 根目录后续目标应只保留源码、装配层、文档、配置和基础设施文件,不继续承载运行时数据与临时产物。

3. 分类总览

3.1 可立即删除的临时残留

项目 当前状态 建议动作 原因
.codex-tmp-mediacrawler/ 已删除(T-105 无需后续动作 已按清单完成物理删除
.codex-tmp-mediacrawler2/ 已删除(T-105 无需后续动作 已按清单完成物理删除
.codex-tmp-mediacrawler.zip 已删除(T-105 无需后续动作 已按清单完成物理删除
__pycache__/(全仓) 已删除(T-109 无需后续动作 已清理 106 个 Python 编译缓存与 pytest 缓存目录,避免仓库继续混入本地运行残留
.pytest_cache/ 已删除(T-109 无需后续动作 已作为测试缓存统一清理

处理要求:

  1. T-105 已完成物理删除。
  2. 继续保留 .gitignore.codex-tmp-* 的忽略规则,防止再次回流。
  3. T-109 已完成全仓 Python / pytest 缓存清理;后续若再次运行测试或脚本,可继续按同样规则清理 __pycache__/.pytest_cache/

3.2 需迁移或归档后再删除的旧运行目录

这些目录已经不应作为主运行路径,但目录中的内容可能仍有参考价值,因此需要先按“核对用途 -> 迁移或归档 -> 删除根目录目录”的顺序处理。

目录 文件数 体积(MB) 建议归属 处理策略
logs/ 0 0.00 var/logs/ 已完成迁移;活跃日志与状态文件已迁入 var/logs/,示例日志已归档到 var/logs/archive/legacy-root/20260407/,根目录目录已删除
final_reports/ 0 0.00 var/reports/final/ 已完成迁移;报告产物已迁入 var/reports/final/,根目录目录已删除
insight_engine_streamlit_reports/ 0 0.00 var/reports/engines/insight/ 已完成迁移;引擎输出已迁入 var/reports/engines/insight/,根目录目录已删除
media_engine_streamlit_reports/ 0 0.00 var/reports/engines/media/ 已完成迁移;引擎输出已迁入 var/reports/engines/media/,根目录目录已删除
query_engine_streamlit_reports/ 0 0.00 var/reports/engines/query/ 已完成迁移;引擎输出已迁入 var/reports/engines/query/,根目录目录已删除
crawler_browser_data/ 0 0.00 var/crawler/browser_data/ 已完成冷迁移;源数据已复制到 var/crawler/browser_data/,根目录旧目录已删除,冷备份位于 var/backups/runtime-migration/20260407/t108/crawler_browser_data/
db_data/ 0 0.00 var/db/postgres/ 已完成冷迁移;源数据已复制到 var/db/postgres/,根目录旧目录已删除,冷备份位于 var/backups/runtime-migration/20260407/t108/db_data/
output/ 0 0.00 var/output/ 已完成迁移;导出与截图产物已迁入 var/output/,根目录目录已删除

处理顺序建议:

  1. T-106 已完成轻量目录迁移与删除:logs/final_reports/、三个 *_streamlit_reports/output/
  2. T-108 已完成高风险目录冷迁移:crawler_browser_data/db_data/ 已迁入 var/ 并删除根目录旧目录。
  3. 每完成一类目录收口,都要验证是否仍有代码或容器挂载写回根目录旧路径。

2026-04-07 / T-107 高风险目录复核结论

  • docker-compose.ymlinfra/docker/docker-compose.yml 当前都已经只挂载 ./var/crawler/browser_data./var/db/postgres,说明根目录 crawler_browser_data/db_data/ 已不再是 canonical 运行目录。
  • var/crawler/browser_data/var/db/postgres/ 当前都只有 .gitkeep,而根目录仍分别保留 5013 个文件 / 337.49 MB1462 个文件 / 47.78 MB 的旧数据,属于“结构已收口、数据尚未冷迁移”的遗留状态。
  • crawler_browser_data/ 目前主要由多个 Chromium 用户目录组成,其中 dy_user_data_dir194.53 MBxhs_user_data_dir59.53 MBtieba_user_data_dir28.09 MB,绝大部分体积来自浏览器缓存;迁移时应优先保留登录态与必要站点数据,再决定是否保留整份缓存。
  • db_data/ 是完整 PostgreSQL 数据目录,包含 PG_VERSIONbase/global/pg_wal/postmaster.pid;这类目录只能在停容器窗口下冷迁移或先做备份后重建,禁止运行中直接覆盖到 var/db/postgres/
  • 因此下一步不建议直接删除这两个根目录,而应先执行一次带停进程前置检查的 T-108 冷迁移/归档任务。

T-108 建议执行步骤

  1. 执行前检查:
    • docker ps --format "table {{.Names}}\t{{.Status}}" 确认不存在正在运行的 bettafish / bettafish-db 容器。
    • 若存在 BettaFish 相关容器,先执行 docker compose -f infra/docker/docker-compose.yml -f infra/docker/docker-compose.override.yml down,确认数据库与爬虫相关进程全部停止。
  2. 先做冷备份:
    • crawler_browser_data/db_data/ 先做一份只读备份,推荐落到 var/ 下专用备份目录或仓库外安全位置,再开始任何迁移。
    • 备份完成前,不删除根目录原始目录,也不直接覆盖 var/ 目标目录。
  3. 迁移浏览器用户数据:
    • 移除 var/crawler/browser_data/.gitkeep 后,将根目录 crawler_browser_data/ 的用户目录整体复制到 var/crawler/browser_data/
    • 若希望缩小体积,可在复制后单独评估各 profile 下的 Cache/Code Cache/GPUCache/ 等缓存目录是否删除,但 CookiesLocal StorageSession StorageLogin Data 等登录态相关数据应优先保留。
  4. 迁移 PostgreSQL 数据目录:
    • 移除 var/db/postgres/.gitkeep 后,将根目录 db_data/ 的完整内容冷复制到 var/db/postgres/
    • 由于这是宿主机 bind mount 的真实 PostgreSQL 数据目录,迁移时必须保留原目录结构,不做挑拣式复制。
  5. 最小验证:
    • 先启动数据库服务,确认 pg_isready 或 compose healthcheck 通过。
    • 再启动 BettaFish 应用服务,确认新运行产物继续写入 var/crawler/browser_data/var/db/postgres/,而根目录旧目录没有新增文件。
  6. 完成收口:
    • 只有在备份存在、服务可启动且 var/ 路径验证通过后,才删除根目录 crawler_browser_data/db_data/
    • 删除后同步更新本清单、task 文档与 memory 文档,把 T-108 状态切到 done

2026-04-07 / T-108 执行结果

  • 已将根目录 crawler_browser_data/db_data/ 分别冷备份到 var/backups/runtime-migration/20260407/t108/
  • 已将两份目录完整复制到 var/crawler/browser_data/var/db/postgres/,并完成文件数、文件集合与总字节数逐项对账。
  • 已删除旧的退出容器 bettafishbettafish-db,因为它们仍绑定到旧根目录 crawler_browser_data/db_data/ 等路径;随后按当前 compose 配置重建容器。
  • 已确认新 bettafish-db 挂载的是 var/db/postgres 且健康检查通过,新 bettafish 挂载的是 var/logsvar/reports/*var/outputvar/crawler/browser_data
  • 已确认根目录 crawler_browser_data/db_data/ 在迁移完成后没有被重新创建。

3.3 需要跟踪的兼容入口与过渡文件

以下内容要么仍需暂时保留,要么刚完成删除验证;统一保留在此处,避免后续对根目录残留状态产生误判:

项目 当前角色 当前状态 / 备注 计划收口任务
crawler_web.py 已删除的根目录 crawler shim 已在 T-520 删除;crawler Web 的 canonical 导出固定为 backend.crawler T-405,T-520
export_pdf.py 根目录导出脚本 wrapper 已在 T-519 删除,统一切到 tools.reports.export_pdf T-501,T-519
app.py 已删除的根目录 Web API shim 已在 T-525 删除;canonical Python 入口固定为 apps/web_api/app.py / python -m apps.web_api T-205,T-524,T-525
start_local.bat Windows 一键启动兼容入口 真实启动逻辑已收口到 scripts/dev/start_local_stack.ps1,此文件继续保留为用户向薄入口 T-509
config.py 已删除的根目录共享配置 shim 已在 T-520 删除;共享配置的 canonical 导入面固定为 services.shared.config T-304,T-520
openai_compat.py 已删除的根目录 OpenAI 兼容 shim 已在 T-520 删除;统一改为 utils.openai_compat T-504,T-520
report_engine_only.py 根目录报告命令行 wrapper 已在 T-519 删除,统一切到 tools.reports.report_engine_only T-501,T-519
regenerate_latest_html.py 根目录 HTML 重建 wrapper 已在 T-519 删除,统一切到 tools.reports.regenerate_latest_html T-501,T-519
regenerate_latest_md.py 根目录 Markdown 重建 wrapper 已在 T-519 删除,统一切到 tools.reports.regenerate_latest_md T-501,T-519
regenerate_latest_pdf.py 根目录 PDF 重建 wrapper 已在 T-519 删除,统一切到 tools.reports.regenerate_latest_pdf T-501,T-519
frontend/ 根目录前端兼容壳 真实前端已迁到 apps/web_ui/,此目录仅转发旧命令 T-205
SingleEngineApp/ 根目录引擎控制台兼容壳 真实脚本已迁到 apps/engine_console/,此目录仅保留旧入口 wrapper,并已在 T-110 补齐 README 说明 T-205,T-110
ForumEngine/InsightEngine/MediaEngine/QueryEngine/ReportEngine/ 根目录旧包名兼容包 真实引擎包已迁到 services/engines/*T-110 已统一收口为共享 helper + 惰性导出实现 T-305,T-110
SentimentAnalysisModel/ 根目录研究资产兼容说明目录 研究模型主体已迁到 research/sentiment_models/,当前仅保留 WeiboMultilingualSentiment/ wrapper 与迁移说明;T-111 已确认 SentimentAnalysisModel/WeiboMultilingualSentiment/predict.py 暂时冻结保留 T-605,T-111
MindSpider/ 根目录主爬虫兼容壳 真实 MindSpider 代码已迁到 services/crawler/mindspider/,真实 MediaCrawler 代码已迁到 vendor/mediacrawler/T-112 后当前保留的是 main.py / config.py / README 与子目录 wrapper T-407,T-111,T-112
Dockerfile 已删除的根目录 Docker 构建入口 已在 T-521 删除;唯一 canonical 文件为 infra/docker/Dockerfile T-502,T-521
docker-compose.yml 已删除的根目录 compose 入口 已在 T-521 删除;唯一 canonical 文件为 infra/docker/docker-compose.yml T-502,T-521
docker-compose.override.yml 已删除的根目录 override compose 入口 已在 T-521 删除;唯一 canonical 文件为 infra/docker/docker-compose.override.yml T-502,T-521

附加说明:

  • T-106 已完成 services/engines/report/utils/config.pyutils/forum_reader.py 的默认路径收口,报告与论坛日志默认值不再依赖根目录 final_reports/logs/
  • 后续真正剩余的高风险目录问题,已经集中到 crawler_browser_data/db_data/ 的冷迁移,而不是继续修改轻量路径默认值。
  • T-110 已新增 docs/root-compatibility-shim-inventory.md,并将五大根目录引擎兼容包统一到共享 helper + 惰性导出实现;当前兼容壳问题的重点已收敛到目录级兼容壳,而不是单文件 thin shim。
  • T-111 曾将 repo-root Docker / Compose 文件列为阶段性冻结保留对象;该过渡策略已在 T-521 结束,当前 Docker 入口统一切到 infra/docker/
  • T-506 已把主 README 的默认启动方式切到纯本地,并建立 .env.local.example + scripts/dev/start_local.pyT-521 进一步把根目录 Docker 兼容副本一并回收。
  • 本轮验证后再次执行了一轮缓存清理,仓内新生成的 __pycache__/.pytest_cache/ 已删除。
  • T-112 已完成删除试点,Dockerfile.runtime-hotfixMindSpider/config.py.exampleMindSpider/requirements.txt 已从仓库移除。
  • 本轮空目录扫描命中的均为 var/ 下运行时目录与冷备份内部目录,当前未发现新的源码树空垃圾目录。
  • T-113 已新增 docs/runtime-retention-assessment.md,并明确:t108 冷备份继续保留,var/output/chrome-headless/ 是更适合优先评估的空间回收对象。
  • T-114 已完成运行态复核与受控清理:在确认活跃 Chrome / Playwright 进程未使用仓内 profile 后,var/output/chrome-headless/ 已物理删除,var/output/ 当前仅剩 screens/.gitkeep

3.4 运行时冷备份与空目录评估(T-113

评估结论摘要:

  • var/backups/runtime-migration/20260407/t108/6475 个文件,约 385.27 MB,继续保留
  • var/crawler/browser_data/5013 个文件,约 337.49 MB,属于登录态与浏览器缓存目录,继续保留
  • var/db/postgres/17890 个文件,约 1.12 GB,属于真实数据库卷,继续保留
  • var/output/4 个文件,约 2.49 MBchrome-headless scratch 已完成回收,当前仅保留截图产物

本轮结论:

  • db/postgres/crawler/browser_data/reports/final/logs/ 的空目录属于结构性空目录,不应单独删除。
  • t108 冷备份当前仍有回滚价值,不应直接删除。
  • T-114 已验证:第一优先级应放在 var/output/chrome-headless/ 这类 scratch 目录,而不是数据库卷或浏览器登录态目录。

2026-04-09 / T-114 执行结果

  • 已复核 5000 端口当前由 python -m apps.web_api 提供服务,scripts.dev.start_local 监控进程仍在运行,因此本轮不采用停服式清理。
  • 已复核活跃 Chrome / Playwright 进程使用的是用户目录下的 ms-playwright profile,而不是仓内 var/output/chrome-headless/
  • 已删除 var/output/chrome-headless/ 整棵 scratch 子树,并确认删除后路径不存在。
  • 已确认 var/output/ 删除后仅剩 screens/ 截图产物与 .gitkeep,当前总量约 2.49 MB

3.5 当前应保留并继续作为目标态演进基础的目录

下列目录不属于本次根目录清理对象,应继续作为当前和未来结构优化的承接点:

  • backend/
  • apps/
  • services/
  • tools/
  • docs/
  • scripts/
  • tests/
  • utils/
  • vendor/
  • var/
  • 五大引擎与相关服务目录:InsightEngine/MediaEngine/QueryEngine/ReportEngine/ForumEngine/

说明:

  • 这些目录后续仍可能继续迁移到 apps/services/vendor/research/,但不属于“立即清理的根目录垃圾”。
  • T-104 的目的,是先把“噪音和残留”与“仍在承接功能的目录”区分开。
  • SentimentAnalysisModel/ 已在 T-602 后完成主体迁移、在 T-603 中解除代码硬编码依赖、在 T-604 中把默认运行时缓存切到 var/,并在 T-605 中把 WeiboMultilingualSentiment 正式示例迁入 research/;长期目标态仍是由 research/sentiment_models/ 承接研究模型,根目录仅暂留 wrapper/兼容壳。

4. 处理策略

4.1 执行原则

  • 先删纯临时产物,再迁移历史运行目录,最后收口兼容入口。
  • 先完成目录归属统一,再做代码入口和导入路径收口。
  • 涉及浏览器数据和数据库卷时,先停进程/停容器,再处理文件。
  • 若目录内容存在调试、登录态或历史报告价值,优先归档到 var/ 下的归档子目录,而不是直接丢弃。

4.2 推荐执行顺序

  1. 已完成 T-105.codex-tmp-mediacrawler/.codex-tmp-mediacrawler2/.codex-tmp-mediacrawler.zip 已删除。
  2. 已完成 T-106 配套归档目录补齐,例如 var/logs/archive/legacy-root/20260407/ 已承接根目录历史日志。
  3. 已完成 T-106,轻量旧运行目录已迁移或清理。
  4. 已完成 T-107crawler_browser_data/db_data/ 的高风险迁移约束已复核。
  5. 已完成 T-201 ~ T-205,应用层入口已迁到 apps/ 并保留兼容层。
  6. 已完成 T-501 / T-502,根目录报告脚本与 Docker / compose 文件已分别收口到 tools/infra/docker/
  7. 已完成 T-402,MindSpider 主爬虫真实代码已迁到 services/crawler/mindspider/
  8. 已完成 T-403 ~ T-405MediaCrawler 调用边界与 crawler_web.py 兼容入口已完成本阶段收口。
  9. 已完成 T-406T-407,根目录 MindSpider/ 的 README / CLI / 路径说明、requirements.txtconfig.py.example 已切到明确兼容结构;后续继续评估是否删除这两个兼容文件。
  10. 已完成 T-506,默认启动方式已切到纯本地;.env.local.examplescripts/dev/start_local.py 已成为当前 canonical 本地启动资产。
  11. 已完成 T-112Dockerfile.runtime-hotfixMindSpider/config.py.exampleMindSpider/requirements.txt 等低风险兼容文件已删除。
  12. 已完成 T-113,运行时冷备份与空目录的保留边界已明确。
  13. 已完成 T-520,根目录 config.pycrawler_web.pyopenai_compat.py 已删除。
  14. 已完成 T-114var/output/chrome-headless/ 已在运行态复核后受控删除。
  15. 已完成 T-521,根目录 Dockerfiledocker-compose.ymldocker-compose.override.yml 已删除,Docker 入口统一切到 infra/docker/
  16. 已完成 T-524:根目录 app.py 的保留评估已确认仓内代码无真实依赖,建议在同步清理旧文档与外部命令后进入删除窗口;start_local.bat 仍建议继续作为 Windows 一键入口保留。
  17. 已完成 T-525:根目录 app.py 已删除,README、兼容清单与收尾文档已统一切换到 python -m apps.web_apipython -m scripts.dev.start_local

5. 风险与验证

5.1 主要风险

  • 某些历史脚本仍可能把文件写回根目录旧目录。
  • var/crawler/browser_data/ 中仍保留浏览器登录态与平台缓存,后续若做体积优化,必须避免误删会话数据。
  • var/db/postgres/ 现在已经成为真实数据库卷目录,后续任何手工复制、清理或备份动作都必须在停容器窗口下执行。
  • var/backups/runtime-migration/20260407/t108/ 保留了一份冷备份,会带来额外磁盘占用;删除前必须确认不再需要回滚。
  • T-525 删除根目录 app.py 后,仓外自动化或个人脚本如果仍执行 python app.py 将直接失效,需统一切换到 python -m apps.web_apipython -m scripts.dev.start_local
  • T-403 完成后,若仍有脚本硬编码 MindSpider/DeepSentimentCrawling/MediaCrawler/,将直接失效,因此后续清理时要继续依赖统一 helper 或适配层收口旧路径引用。
  • var/backups/runtime-migration/20260407/t108/ 当前仍保留完整冷备份,删除前必须明确回滚窗口是否结束。
  • 当前扫描到的空目录主要位于运行态浏览器数据、PostgreSQL 数据目录和冷备份内部,不能按“源码空目录”直接清理。

5.2 每次清理后的验证清单

  1. 执行对应入口或脚本,确认新产物写入 var/
  2. 检查根目录旧运行目录没有重新生成新文件。
  3. 若涉及 Docker,执行 docker compose ... config 或最小启动验证。
  4. 若涉及报告导出或爬虫链路,至少跑一次最小功能验证。

6. 本任务结论

T-104 的结论不是“已经删除全部根目录残留”,而是:

  • 已经明确了根目录残留的分类边界。
  • 已经形成可执行的处理顺序和风险控制策略。
  • 已经为后续 T-201 应用层重组提供了更清晰的清场前提。

该清单已经为 T-201T-202 提供了清场基础,后续继续服务于 T-203 ~ T-205 的应用层收口。