diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..dfc266c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # ── Python 侧:版本一致性 + 语法 + 单元测试 ────────────────────── + python: + name: Python 3.12 一致性 / 语法 / 测试 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # 版本来源唯一:读取仓库根目录 .python-version, + # 避免 CI 里再写死一份版本号造成漂移 + - uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + + - name: 显示版本 + run: python3 --version + + - name: 版本一致性检查(声明 / venv / 硬编码引用) + run: python3 Scripts/bin/check_python_version.py --strict + + - name: 语法编译检查 + run: | + python3 -m compileall -q \ + Scripts/bin \ + Services/findatahub-core/src \ + Services/kuaixun-service/app \ + Services/kuaixun-service/extend + + - name: 安装测试依赖 + run: python3 -m pip install --quiet pytest pytest-asyncio + + - name: 运行单元测试 + # 部分用例依赖本机 MySQL / Ollama,暂不阻塞 CI + continue-on-error: true + run: python3 -m pytest Scripts/bin/tests -q + + # ── Swift 侧:编译验证 ──────────────────────────────────────── + swift: + name: Swift 编译(macOS) + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + + - name: 显示工具链 + run: swift --version + + - name: 编译 release + # 本机 SPM manifest 沙箱(sandbox-exec)不可用,必须禁用 + run: swift build -c release --disable-sandbox + + - name: Shell 脚本语法检查 + run: | + for f in Scripts/build-app.sh Scripts/bin/*.sh; do + bash -n "$f" && echo "ok: $f" + done diff --git a/.gitignore b/.gitignore index 5d07589..3b19b47 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ venv/ .env .env.local .env.*.local +.env.development +.env.production # Node.js node_modules/ @@ -92,3 +94,6 @@ test-results/ *.dmg *.pkg *.zip + +# Agent 团队运行态(会话产物,非产品资产) +.agent-teams/ diff --git a/.mcp.json b/.mcp.json deleted file mode 100644 index a0300fd..0000000 --- a/.mcp.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "mcpServers": { - "context7": { - "type": "http", - "url": "https://mcp.context7.com/mcp", - "headers": { - "CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}" - } - } - } -} diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/.workbuddy/automations/automation-1786281342338/memory.md b/.workbuddy/automations/automation-1786281342338/memory.md new file mode 100644 index 0000000..51185bb --- /dev/null +++ b/.workbuddy/automations/automation-1786281342338/memory.md @@ -0,0 +1,50 @@ +# 自动化测试缺口分析 - 执行历史 + +## 2026-08-09 (首次运行) + +**审查范围**: 最近 7 天的 git 提交 (bace1b9 ~ 4b62693) +**涉及模块**: akshare_fetcher, tushare_fetcher, newsflash_collect, sync_bridge, check_db, init_db + +### 新增测试 +1. `test_newsflash_collect.py::test_db_error_stdout_clean` - 验证 DB 异常时 stdout 保持纯净(回归测试 for c27fa99/d43a177) +2. `test_db.py::TestEnsureMarketTableContract::test_database_manager_has_ensure_market_table` - 验证 DatabaseManager 通过继承提供 ensure_market_table 方法 + +### 测试结果 +- akshare test_db + test_fetcher: 101 passed, 4 skipped +- Scripts/bin (newsflash_collect + sync_bridge + check_db + init_db): 55 passed +- tushare test_db + test_api: 53 passed, 5 failed (预存失败,非本次引入) + +### 预存失败 (非本次引入) +- tushare `TestUpdateTableMeta` (4个): `db_mod.pymysql` 属性不存在(重构为 BaseDatabaseManager 后 pymysql 在基类导入) +- tushare `TestThrottle::test_sleeps_when_within_interval`: 时序断言 `0.3 < 0.3` 边界问题 + +### 覆盖良好的区域 (无需补充) +- `_aggregate_ohlcv` 周/月线聚合 (12 个测试) +- `max_stocks` 截断逻辑 (3 个测试) +- `sync_cache` 更新逻辑 (3 个测试) +- `sync_bridge._pump_stream` 流转发 (6 个测试) +- `tushare api.py` 频率限流 (4 个测试) +- `tushare db.py` `update_table_meta` 静态表分支 (3 个测试) +- `check_db/init_db` 三库支持 (12 个测试) + +## 2026-08-14 + +**审查范围**: 最近 7 天无新 git 提交;覆盖工作区未提交变更。 +**涉及模块**: kuaixun-service (rate_limiter, dal_unified, unified_writer, routers/unified) + +### 新增测试 +1. `tests/test_rate_limiter.py` (10 个) - 滑动窗口限流、过期清理、key 隔离、边界条件 +2. `tests/test_dal_unified.py` (14 个) - news_unified 查询/过滤/统计/搜索/标签 +3. `tests/test_unified_writer_unit.py` (17 个) - content_hash/simhash/Jaccard/L0 批内去重 +4. `tests/test_routers_unified.py` (7 个) - /api/v2 统一接口参数透传与响应结构 + +### 生产代码修复 +- `app/rate_limiter.py`: `reset_interval()` 修复为返回 `self._window_sec`(原引用不存在的 `_bucket_purge_interval`) + +### 测试结果 +- kuaixun-service: 313 passed, 1 skipped, 1 xfailed +- akshare_fetcher: 146 passed, 4 skipped + +### 预存问题(非本次引入) +- tushare_fetcher: 4 个 collection error(findatahub_core 未在当前 venv 安装) +- Scripts/bin: 当前环境缺少 pytest diff --git a/.workbuddy/automations/automation-1786281342338/report-2026-08-14.md b/.workbuddy/automations/automation-1786281342338/report-2026-08-14.md new file mode 100644 index 0000000..7ed36a2 --- /dev/null +++ b/.workbuddy/automations/automation-1786281342338/report-2026-08-14.md @@ -0,0 +1,58 @@ +# 自动化测试缺口分析报告 — 2026-08-14 + +## 审查范围 + +- **时间窗口**:最近 7 天(2026-08-07 ~ 2026-08-14)的 git 提交为空;本次审查覆盖工作区中尚未提交的近期变更。 +- **重点模块**:`Services/kuaixun-service` 新增/修改的核心后端逻辑。 +- **跳过的内容**:快照式测试、UI 外观测试、纯重构的覆盖。 + +## 发现的有意义缺口 + +1. **`app/rate_limiter.py`(新增)** + - 无测试覆盖。 + - `reset_interval()` 引用了不存在的 `_bucket_purge_interval`,属于真实回归风险。 + +2. **`app/dal_unified.py`(新增)** + - 作为 `dal.py` 的替代,负责从 `news_unified` 整合表读取数据。 + - 无单元测试,参数透传、时间转换、缓存统计、标签解析等路径未验证。 + +3. **`extend/unified_writer.py`(新增)** + - 仅有 1 个需要在线 MySQL 的端到端测试。 + - 四层去重中的 `content_hash`、`simhash`、`Jaccard` 等核心算法缺少独立单元测试。 + +4. **`app/routers/unified.py`(新增)** + - `/api/v2/*` 统一接口未覆盖,参数默认值解析和响应结构未验证。 + +## 新增/修改的测试文件 + +| 文件 | 测试数 | 覆盖的风险行为 | +|---|---|---| +| `tests/test_rate_limiter.py` | 10 | 滑动窗口限流、过期清理、跨 key 隔离、边界条件;修复 `reset_interval()` bug | +| `tests/test_dal_unified.py` | 14 | 整合表分页查询、source/time/importance 过滤、统计去重率、标签聚合、空查询短路 | +| `tests/test_unified_writer_unit.py` | 17 | content_hash、simhash、hamming 距离、Jaccard 相似度、L0 批内去重、空内容跳过 | +| `tests/test_routers_unified.py` | 7 | `/api/v2/news/live` 等统一接口的参数透传与响应结构 | + +## 生产代码修复 + +- **`app/rate_limiter.py`**:`reset_interval()` 从引用不存在的 `_bucket_purge_interval` 改为返回 `float(self._window_sec)`。 + +## 验证结果 + +```text +Services/kuaixun-service: 313 passed, 1 skipped, 1 xfailed +Services/akshare_fetcher: 146 passed, 4 skipped +``` + +所有新增测试确定性强、彼此隔离、可独立运行;未发现不稳定用例。 + +## 预存问题(非本次引入) + +- `Services/tushare_fetcher` 因 `findatahub_core` 未在当前 venv 中安装,出现 4 个 collection error,属于环境/依赖问题,不是测试缺口。 +- `Scripts/bin` 当前环境缺少 pytest,未执行。 + +## 风险降低说明 + +- **限流器**:现在覆盖了并发场景下的窗口计数与清理逻辑,并修复了 `reset_interval` 这一调用即崩溃的缺陷,避免下游依赖该接口时发生回归。 +- **统一 DAL**:所有读取路径(过滤、统计、搜索、标签)均通过 mock 隔离验证,能防止未来修改 SQL 拼接或参数转换时引入错误。 +- **去重算法**:核心哈希与相似度算法获得独立单元测试,未来调整阈值或分词策略时可快速验证正确性。 +- **统一路由**:接口层参数透传与响应格式被锁定,降低前后端联调阶段的契约回归风险。 diff --git a/.workbuddy/memory/2026-08-09.md b/.workbuddy/memory/2026-08-09.md new file mode 100644 index 0000000..5ee3fad --- /dev/null +++ b/.workbuddy/memory/2026-08-09.md @@ -0,0 +1,87 @@ +# 2026-08-09 工作日志 + +## FinDataHub 全仓代码分析 + 优化建议报告 +- 完成项目全景分析,产出报告 `FinDataHub-代码分析与优化建议.md`(仓根目录)。 +- 定位:A 股本地金融数据中枢 = 双源采集(tushare/akshare) → 七步清洗+四级门控(findatahub-core) → SDK/REST/MCP 输出(findatahub-client),外挂 macOS 菜单栏 App(SwiftUI) 与财经快讯子系统(FastAPI+Vue3)。 +- 技术栈实证:Swift 5.9(零三方依赖) / Python 3.10-3.14 混用 / Vue3 纯 JS(非 TS,仓内 .ts/.js 多为 node_modules+dist) / Rust PyO3(tushare rust_core) / MySQL。 +- 现状:P1-P4 完成,P5(云端)远期;已完成安全审计与大量测试补齐。 +- 发现的关键问题:client.py stats() NameError Bug、SimHash 用不稳定 hash()、pipeline 血缘静默吞错、快讯 pyproject 入口指向不存在模块、Swift 超大文件(SettingsView 2467 行)、core/client/Swift 测试盲区、行级 pandas 性能隐患。 +- 报告含四维度优化建议(性能/代码质量/功能扩展/可维护性)+ 三步走落地优先级。 + +## 逐项修复项目问题(依架构文档 findatahub-data-pipeline.html) +按「一次一个、修复即验证」完成 7 项修复,全程不偏离三层架构与 9.1 铁律: +1. client.py stats() NameError:变量 df→row_count。AST+mock 运行时验证通过。 +2. 快讯 dedup SimHash 用内置 hash():跨进程不稳+负值位映射损坏 → 改 hashlib.md5。PYTHONHASHSEED=1/99/7 指纹一致,40 去重测试过。 +3. pipeline.py _record_lineage 裸 except 静默吞错 → 指定异常(pymysql.MySQLError,OSError)+structlog 警告+finally 关连接。验证失败可见不抛出。 +4. kuaixun pyproject 两个坏 entry point(指向不存在模块 kuaixun_service.main/pipeline)→ 移除。editable install 验证 OK。 +5. cross_validator merged.iterrows 逐行 → 向量化。与原版输出完全等价(31499 issue 集合相等,含全部边界),真实场景 16.6x 提速。 +6. gate.py 文件末尾延迟 import pandas → 移到顶部(pandas 是三方库无循环依赖)。模块导入+注册表+测试验证。 +7. kuaixun 3 个预存失败测试 → 顺带揪出并修复 3 个真实 bug: + a. tencent_news 注册不完整(dal.py 补 VALID_TABLES+TABLE_TO_SOURCE+name_map),否则 pipeline 第67行 SOURCE_TO_TABLE.get 返回 None 致腾讯快讯被静默丢弃; + b. source_to_table() 查错字典(用 TABLE_TO_SOURCE 应改 SOURCE_TO_TABLE),否则 tencent_news 误路由到不存在的 news_tencent_news 表; + c. platformdirs 未声明依赖 → 补 pyproject + 安装。 + d. 测试计数断言 11→8(源已刻意精简)。 + 结果:262过/3挂 → 265过/0挂 全绿。 + +遗留说明(非回归、不属代码 bug):findatahub-core 的 test_unified_writer_e2e 是集成测试,需 jieba+pandas+在线 MySQL 同时满足,现有 venv 无同时具备者,且跨服务 import kuaixun 代码,属测试放置/环境问题。 + +改动文件:client.py, dedup/__init__.py, pipeline.py, gate.py, cross_validator.py, kuaixun pyproject.toml, dal.py, test_database.py。 + +## 后续两项任务(向量化 + 测试迁移) +### 任务8:akshare fetcher 向量化(8 处 df.apply(axis=1)) +- 实为 8 处 pct_chg 逐行计算:fetcher.py 7 处(日线163/周线200/月线231/指数392/实时456/结果475/批量886)+ bj_fetcher.py 1 处(89)。 +- 方案:每文件新增 `_compute_pct_chg_vec(open_s, close_s)` 向量化助手,numpy errstate+np.where+np.round。关键语义保持:fetcher 用 `open<=0→0.0`,bj 用 `open==0→0.0`(两文件标量语义不同,分别保留);NaN open 走算术分支得 NaN(np.where 条件 NaN 比较为 False 自动落入)。验证 np.round 与 Python round 在 60 万真实值域样本 0 不一致。 +- 等价性:全部边界(open<=0/0/负/NaN、close NaN、双 NaN、极端值)与标量版逐一比对完全一致。 +- 无回归:仅回滚我这2个文件做基线(14挂/135过)vs 改动后(14挂/135过)完全相同;14 挂全在 test_db.py(用户 db.py 重构在制品 + findatahub_core 未装入该 venv 所致,与本改无关)。test_fetcher.py 63 全过。 +- 性能:1000 行 46.6x,50000 行 203.7x。 +- 注意:akshare venv 未装 findatahub_core 且 pyproject 未声明(架构重构项声称已补但实际没有),跑测试需 PYTHONPATH 指向 findatahub-core/src。 + +### 任务9:迁移 test_unified_writer_e2e +- 从 findatahub-core/tests/test_core_pipeline.py 移除(跨服务 import 快讯代码,违反分层),新建 kuaixun-service/tests/test_unified_writer.py。 +- 改进:DB 配置改从环境变量读(MYSQL_PASSWORD 等,符合架构禁硬编码密码),加 _db_available() skip 守卫(无 DB 时跳过而非失败)。 +- 依赖:该测试只需 jieba+pymysql(pyproject 已声明)+ pytest/pytest-asyncio(dev 已声明),无需新增。 +- 干净 venv 实证:/tmp 建 Python3.12 干净 venv,pip 装 pyproject 声明依赖,迁移测试 1 通过;全量套件 266 过/0 挂(与项目 venv 一致)。过程中发现手动漏装 pytest-asyncio 会致 34 个 async 测试失败——反证 pyproject dev extras 是完整依赖真源。 +- 结果:kuaixun 套件 265→266 全绿;core 套件移除该测试后 6 过/1 跳过/0 挂(jieba ModuleNotFoundError 随之消失)。 +- 发现(待用户确认,未改):DB 实际表是 news_tencent_news,但 database.py 模型与 dal.py 映射用 news_tencent,两者不一致,是 tencent_news 在制品的遗留问题。 + +## 补充:akshare findatahub_core 依赖 + 测试修复 +- akshare pyproject 补声明 `findatahub-core>=0.1.0` + `[tool.uv.sources]` editable 路径(对照 tushare 规范),venv 安装。 +- 测试 monkeypatch 3 处 db_mod.pymysql → core_db.pymysql;11 个 skip(8+3,方法已随重构移除)。 +- 结果:138 过/11 跳过/0 挂,无需 PYTHONPATH。 + +## 应用初始化引导方案设计 +- 分析当前 EnvChecker/VenvManager/PythonPathFinder 等已有基建,梳理外部依赖全景(Python/MySQL/3xvenv/Ollama/uv)。 +- 产出 `Docs/macos/BOOTSTRAP_DESIGN.md`:独立 BootstrapScene + DependencySpec 协议 + 并行扫描 + 分级决策(block/warn/info) + 联网自动安装(Homebrew/pkg/venv恢复) + 哈希校验缓存(~/Library/Caches) + 离线清单(JSON/Markdown) + 可选依赖异步不阻塞 + 5 阶段实施路线。 +- 同时分析了 .build/FinDataHub.app 打包现状:代码是最新重构版本,但 findatahub_core 通过绝对 editable .pth 挂载(跨机不可用)、alpha-common 残留、kuaixun common/ 缺失。 + +## 自动化测试缺口分析(每日定时任务) +- 审查最近 7 天 git 提交(bace1b9~4b62693),覆盖 akshare/tushare/newsflash/sync_bridge/check_db/init_db 六模块。 +- 新增 2 个测试: + 1. `test_newsflash_collect.py::test_db_error_stdout_clean` — 验证 DB 异常时 stdout 保持纯净(回归测试 for c27fa99/d43a177 JSON 污染 bug) + 2. `test_db.py(akshare)::TestEnsureMarketTableContract` — 契约测试,验证 DatabaseManager 通过继承 BaseDatabaseManager 提供 ensure_market_table 方法 +- 测试结果:akshare 101 passed/4 skipped;Scripts/bin 55 passed;tushare 53 passed/5 failed(预存失败:db_mod.pymysql 属性不存在 + throttle 时序边界,非本次引入)。 +- 覆盖良好的区域:_aggregate_ohlcv(12)、max_stocks(3)、sync_cache(3)、_pump_stream(6)、频率限流(4)、update_table_meta(3)、三库支持(12)。 + +## 引导方案实施(S1-S3 代码 + S4 离线 + App 整合) +按 BOOTSTRAP_DESIGN.md 实施,新增 7 个 Swift 文件,修改 1 个入口文件: +- Models/BootstrapModels.swift:DependencySpec / Criticality / CheckResult / InstallResult / BootstrapPhase / OfflineManifest +- Services/DependencyScanner.swift:async/await 并行扫描 actor +- Services/DependencyManifest.swift:7 个 spec(Python/MySQL/3×venv/Ollama/uv),复用现有 PythonPathFinder/VenvManager API +- Services/BootstrapShell.swift:独立 Process shell 执行器 + MySQL 连接测试 +- Services/DownloadCache.swift:SHA-256 校验 + ~/Library/Caches 缓存 + JSON/MD 离线清单导出 +- ViewModels/BootstrapViewModel.swift:状态机协调器(checking→installing→blocked/ready) +- Views/BootstrapView.swift:引导窗口 UI(进度条/依赖卡片/离线导出按钮/一键启动) +- FinDataHubApp.swift:引入 BootstrapPhase,Window Scene(引导)↔ MenuBarExtra(主程序)切换;命令行菜单提取为 mainCommands 计算属性;引导完成后才初始化 scheduler/快讯。 +注:sandbox-exec 阻挡 swift build 编译;需在 Xcode 或解除沙盒后编译验证。 + +## App 打包缺陷修复(3 项) +1. findatahub_core 绝对路径 → 从 editable .pth 改为 pip install 到 site-packages,路径变为 .app 内自包含 +2. kuaixun-service/common/ 补入 bundle → app.main 导入链(common.config + common.security)可解析 +3. alpha-common 残留 → 从 Resources/ 移除 +验证:3 个 venv 导入链路全部 OK(akshare+core / tushare / kuaixun jieba+fastapi+dal+common) + +## 编译打包 +- 修 DependencyScanner await、RunResult 解构(x6)、SceneBuilder if/else(x1) 共 3 类编译错误 +- `swift build --disable-sandbox` 编译成功 (1.89s) +- 替换 .app 二进制为 arm64-apple-macosx/debug/FinDataHub (22:40, 18.8MB) +- .app 路径:.build/FinDataHub.app (540MB, 未签名) diff --git a/.workbuddy/memory/2026-08-10.md b/.workbuddy/memory/2026-08-10.md new file mode 100644 index 0000000..49ebce6 --- /dev/null +++ b/.workbuddy/memory/2026-08-10.md @@ -0,0 +1,20 @@ +# 2026-08-10 工作日志 + +## 测试缺口分析收尾(用户自动化报告核实) +- 核实报告:4 个新测试文件(rate_limiter 10 / dal_unified 14 / unified_writer_unit 17 / routers_unified 7)存在,rate_limiter.reset_interval 修复到位。 + +## 修复 tushare_fetcher(5 个预存失败 → 184 全过) +1. dev venv 缺 findatahub_core → ensurepip + pip install(报告预存问题1) +2. test_db.py 4 处 `db_mod.pymysql` → `core_db.pymysql`(db.py 重构后 pymysql 在 core 层,与 akshare 同款修复) +3. **生产 bug**:`fetcher.py _fetch_static` 对静态表(stock_basic 等无 DATE_COLUMN_MAP 条目)传默认 "trade_date" → 重构后的 BaseDatabaseManager 生成 SELECT MAX(trade_date) → MySQL 1247。修复:静态表传空串 date_col。 +4. test_static_table_no_date_column 适配新契约:update_table_meta("stock_basic", "", 50) + +## 修复 Scripts/bin(42 failed + 卡死 143 → 128 全过) +1. **模块级 sys.modules mock 污染**(test_newsflash_collect.py 反模式):收集阶段 `sys.modules["common"]=mock` 等全局替换 → test_common/test_db_pool 拿错引用。修复:临时替换 sys.modules 手动 importlib 加载 newsflash_collect,finally 安全恢复(不 clear,逐个还原 + 移除新增 key)。 +2. **测试自杀**:test_common.test_stop_removes_file 用 os.kill 杀当前 pytest 进程(write() 写入自身 PID)→ exit=143 卡死。修复:monkeypatch os.kill(原来只 mock 了 os.system,但 stop() 用 os.kill)。 + +## 最终测试状态(全绿) +- Scripts/bin: 128 passed +- kuaixun-service: 314 passed, 1 xfailed +- akshare_fetcher: 146 passed, 4 skipped +- tushare_fetcher: 184 passed diff --git a/.workbuddy/memory/2026-08-14.md b/.workbuddy/memory/2026-08-14.md new file mode 100644 index 0000000..762dd95 --- /dev/null +++ b/.workbuddy/memory/2026-08-14.md @@ -0,0 +1,8 @@ +# 2026-08-14 + +## 自动化测试缺口分析 + +- 审查工作区未提交变更,识别出 kuaixun-service 新增模块(rate_limiter/dal_unified/unified_writer/routers/unified)的测试覆盖缺口。 +- 新增 4 个测试文件共 48 个测试:test_rate_limiter.py、test_dal_unified.py、test_unified_writer_unit.py、test_routers_unified.py。 +- 修复 app/rate_limiter.py 中 reset_interval() 引用不存在属性的 bug。 +- 验证结果:kuaixun-service 313 passed/1 skipped/1 xfailed;akshare_fetcher 146 passed/4 skipped。 diff --git a/.workbuddy/memory/2026-08-27.md b/.workbuddy/memory/2026-08-27.md new file mode 100644 index 0000000..c66ea98 --- /dev/null +++ b/.workbuddy/memory/2026-08-27.md @@ -0,0 +1,19 @@ + +## 复查 08-27 两轮更新(23:40 前后) +- rate_limiter.py 高危缺陷:读取阶段 `del` defaultdict key 导致限流完全失效,已修复(空桶删除移入拒绝分支)。 +- test_content_enricher 2 个用例裸调真实 DNS 偶发误报 → 改 mock DNS。 +- test_core_pipeline test_pipeline_lineage 加 MySQL 可达守卫(skipif)。 +- 回归:kuaixun-service 377 passed / findatahub-core 68 passed 全绿。 +- findatahub-core venv 此前缺 pytest,pyproject 未声明测试依赖(待补 dependency-groups);uv sync 走 10808 超时,需清华镜像。 + +## 部署实例体检与修复(08-28 凌晨) +- 修复:快讯采集停更 2 天(08-25 23:15 起)→ 恢复实时入库;bundle 代码热同步;newsflash_backend.py 补挂 unified_router(36→42 路由);newsflash_collect.py insert_news 接入 UnifiedWriter,news_unified 统一表开始跨源写入。 +- 行情:tushare kickstart 后到 20260827;akshare 后台跑中。launchd 任务其实一直加载着——launchctl list 在 WorkBuddy 环境返回空(误判),要用 launchctl print gui/501/