Skip to content

React 前端整体并入 master + 去 Redis 化重构(进程内缓存/本地任务、安装文档) - #15

Merged
henrylin99 merged 25 commits into
masterfrom
refactor/remove-redis
Sep 3, 2026
Merged

React 前端整体并入 master + 去 Redis 化重构(进程内缓存/本地任务、安装文档)#15
henrylin99 merged 25 commits into
masterfrom
refactor/remove-redis

Conversation

@henrylin99

@henrylin99 henrylin99 commented Sep 3, 2026

Copy link
Copy Markdown
Owner

概要

本 PR 包含两条工作线,共 17 个提交、136 个文件:

1. React 前端工程(d30534d5..7049b41,12 个提交)

  • React 19 + Vite 7 + TypeScript 独立前端:基线(4 核心页 + lightweight-charts v5)→ 量化终端视觉重设计 → 二期体验升级(资金曲线、单实例三窗格图表、侧边栏与明暗主题)→ 三期全页面覆盖(数据管理、多因子模型六页、实时分析六页、AI 工作台 SSE 流式、text2sql)
  • 配套修复:组合优化防空跑(按因子覆盖日期自动回退重试)、侧边栏高亮残留、指标页 [object Object] 渲染缺陷等

2. 去 Redis 化重构(364887a2..55851a5,6 个提交)

  • 移除 Redis/Celery 依赖CacheManager 改为进程内 TTL 缓存(带锁 + 容量上限 + 过期淘汰);app/celery_app.py 变纯本地任务注册表(task.delay 等价同步调用,app/tasks/* 调用方零改动);生产默认任务模式改 inline
  • async 回测改为后台线程执行,保持"立即返回 run_id + 前端轮询"契约
  • docker-compose 仅剩 web 单容器;requirements*.txt 移除 celery/redis;.env.example / CLAUDE.md / README 同步
  • gitignore 治理:移除 tests/ 误伤规则(已实际阻塞 git add)、models//models/data//data/ 锚定(ai_chat.py 缺失事故根源)、移除误跟踪的 -shm 运行时文件
  • 新增 348 行从零安装指南 INSTALL.md,README 快速开始关联

验证

  • 以 import 即抛错的桩模块模拟未安装 redis/celery 的环境:应用完整启动(HTTP 200),缓存合约/数据任务/API 合约/启动报告共 133 个测试全绿
  • 前端 npm run build(tsc + vite)通过;实机双服务(5000/5173)健康,指标计算/多周期/对比/信号生成接口实测返回真实数据
  • 单机部署行为与去 Redis 前一致(Redis 未启动时原本就静默降级)

合并后注意

  • 部署不再需要 Redis 容器docker compose up 只启动 web 单服务
  • DATA_JOB_EXECUTION_MODE 环境变量保留兼容旧脚本,任意值均为本地执行
  • 已装环境中的 redis/celery 包无需卸载,无害
  • tests/ 忽略规则移除后,本地约 80 个历史测试文件(含 tests/conftest.py)仍为未跟踪状态 → 已随 f898703 入库,pytest 收集 553 项,本地全绿

- Vite+React19+TS 脚手架,axios 信封解包与裸 NaN 响应清洗
- 技术分析页:K线/线图、价格/成交量双视图、MACD/KDJ/RSI/BOLL、十字光标图例、区间高低参考线、90根初始缩放
- 股票列表/选股筛选/回测验证页对齐旧版功能点
- 修复 toLinePoints 未升序排序导致线图切换崩溃的问题
- docs/react-frontend-plan.md 计划与验收清单
- theme.css 全面重写:设计 token、渐变品牌、毛玻璃顶栏、hairline 边框、segmented 控件、等宽数字、骨架屏
- 四页 panel 化 + 页头/统计卡/表格/按钮/表单统一风格,数据逻辑零改动
- 修复:图例「收」按涨跌方向着色(原误用价格);选股收盘价兼容 close 字段(后端无 daily_close)
- 回测页买入/卖出徽章对齐 A 股红绿口径(盈利红、亏损绿)
- 后端 run_backtest 增量返回 daily_values(旧前端不消费,契约兼容)
- 回测页新增资金曲线面积图(初始资金基准线+十字光标图例)
- 技术分析合并为单图表实例三窗格(价格/成交量/指标),跨窗格十字光标联动;
  布林带升级为主图叠加开关,指标页签收敛为 MACD/KDJ/RSI
- 侧边栏布局(窄屏退化顶栏)+ ThemeProvider 明暗双主题,图表色板随主题重建
- 新增 favicon,浏览器控制台 0 错误;docs 计划文档同步二期章节与验证记录
- 新增 GET /ml-factor/factors/latest-coverage-date(增量接口,旧前端未使用):
  动量/资金流与财务因子入库日期不同步,全局最新交易日上预设组合可能无数据
- 组合优化失败时按选股因子集合回退到最近覆盖日期重试并提示
与 master 1a42795 同源:models/ data/ 规则误伤源码包导致
ai_chat.py 从未入库,feature 分支新 clone 会报 no module named
仓库实际通过 tests/ 目录共享测试(已有 100+ 个已跟踪测试文件),
tests/ 规则会静默吞掉所有新建测试文件,导致其他机器缺文件
(与 app/models/ai_chat.py 被误忽略是同一类问题,且已真实阻塞
git add 已跟踪测试文件)。
- app/utils/cache.py 改用带锁字典存储,保留 get/set/delete/exists 接口与
  JSON 序列化副本语义,新增容量上限与过期淘汰,防止长期运行进程键无界膨胀
- app/extensions.py 移除 redis_client 与 import redis
- 行为差异:进程重启缓存清空、多进程不共享(单机部署下与原表现一致,
  Redis 未启动时原本就已静默降级为无缓存)
- app/celery_app.py 移除真 Celery 与 Redis broker/backend 拼接,保留进程内
  本地任务注册表(app/tasks/* 与调用方路径不变,task.delay 等价同步调用)
- config.py 删除 REDIS_*/CELERY_* 配置;生产环境任务模式默认值改为 inline
  (保留 DATA_JOB_EXECUTION_MODE 环境变量兼容旧部署脚本)
- ml_factor_api async 回测从 Celery .delay 改为后台线程执行,保持
  立即返回 run_id + 前端轮询状态的契约
- docker-compose.yml 移除 redis/worker 服务及其依赖编排
- requirements*.txt 移除 celery、redis;.env.example 删除 Redis/Celery 段
- startup_runtime/CLAUDE/README 同步文档与启动提示

验证:以 import 即抛错的桩模块模拟未安装 redis/celery 的环境,
应用完整启动并通过 133 个相关测试(缓存合约/数据任务/API 合约/启动报告)
- 覆盖:基础软件准备(含国内镜像加速)、克隆与分支说明、虚拟环境、
  依赖安装与精简回退、.env 配置逐项说明、run_system 初始化、
  前后端双终端启动、行情数据下载顺序、命令速查、9 条常见问题排查
- 指明两个新手必踩点:须切到 feature/react-frontend 分支(master 无
  frontend/)、须手动创建 instance/ 数据库目录
- README 快速开始一节加入指南入口,环境要求补充 Node.js 与
  无需 Redis 的说明
后端 latest_values 按指标类型返回 数字/数组/{子指标名: 值} 三种形态
(MA/EMA/MACD 均为字典),页面只处理了前两种,对象落入
formatNumber 后 toLocaleString 渲染成 [object Object]。
新增 formatIndicatorValue 统一拍平:MA 显示为
「MA10 11.90;MA20 11.91;…」,MACD 数组显示为「MACD -0.02/-0.02/-0.00」。
指标计算与多周期分析两处表格同步替换。
8630093 提交时误将 SQLite WAL 运行时共享内存文件加入跟踪
(master 上并无此文件),运行时产物不入库,gitignore 已有
*.sqlite3-shm 规则。
- git rm --cached 54 个 .playwright-mcp/*.yml 浏览器会话快照(ignore 规则对已跟踪文件无效,属与 *.sqlite3-shm 同类的误提交)
- 移除分支内重复添加的裸 frontend/node_modules 与 *.jpeg 规则(*.jpeg 第97行 master 已有)
此前从未跟踪状态,导致 PR 描述中「133 个测试全绿」的验证结论在合并后的
工作树上不可复现。入库后 pytest 收集 533 项,本地 532 passed / 1 skipped。

- tests/conftest.py:真实 Flask app fixture + 重依赖(xgboost/lightgbm/cvxpy/baostock/tushare)桩
- tests/api|services|data_jobs:服务边界 mock 的合约测试
- tests/regression:demo/mock 数据不得泄漏进真实路径的回归守卫
- tests/ui:路由/文案/布局合约
- data_jobs/service.py:app context 不可用时的执行模式回退 celery→inline(.delay 已是本地同步壳,回退值与真实行为不符)
- ai/tools.py:execution_mode 默认值 inline;run_data_job 工具返回的 note 与 list_data_jobs 描述不再误导 AI「celery 模式任务已入队」
- ai/prompts.py:系统提示词同步改口
- tests/data_jobs/test_service.py:默认构造断言内联直调;补 legacy celery 值仍走 .delay 的兼容断言
- StockScoringEngine 新增 latest_factor_coverage_date():cutoff 策略与「近半年无数据放宽全库」回退不再散落在 API 层,
  端点只做委托(消除 get_scoring_engine().factor_repo.get_values 消息链)
- 回测 mode=async 入队响应移除恒为 None 的 task_id(前端类型只消费 run_id/status_url/result_url)
- 合约测试:tests/api/test_factor_coverage_date_contract.py(module_scoring)、
  tests/api/test_backtest_run_contract.py 增补 async 入队契约(含无 task_id 断言)
- 意外异常统一 500(原 stock-radar/stock-panorama 混用 400);stock-panorama 缺 ts_code 参数保留 400
- {code,message,data} 信封经 _ok/_error 收拢,消除六个 handler 的重复 try/except 形状
- pytest.ini 注册 module_trial marker,acceptance/trial.md 入模块注册表(补 CLAUDE.md Harness Rules 要求)
- 新增 tests/api/test_trial_api_contract.py:信封形状、ts_codes 归一化去重、400/500 边界
- exists() 原实现经完整 get()(JSON 解析 + 损坏清理),热路径上仅判存在性付出反序列化代价;改为持锁查表 + 过期惰性清除
- 测试桩 _FakeRedisBackend 更名 _InMemoryCacheStub(Redis 已不存在,原名误导)
- 新增 tests/utils/test_cache_manager_contract.py:exists 命中/缺失/损坏值/过期清除四态
@henrylin99

Copy link
Copy Markdown
Owner Author

评审修复(555c91d1…f1481b3f,共 6 提交)

针对本 PR 的两轴评审报告逐项修复:

Standards 硬性项

  • 卸载误提交的 54 个 .playwright-mcp/*.yml 运行时快照;去重分支内添加的 frontend/node_modules*.jpeg ignore 规则(055c91d1)
  • 测试套件入库(conftest.py + 76 个文件),评审指出的「133 测试全绿不可复现」已消除(f8987038)
  • 按 Harness Rules 补结构性合约并注册:pytest.ini 新增 module_trial marker,acceptance/ 注册 trial.md 并回填 scoring/backtest 两表

Spec / smell 项

  • 清理残留 celery 语义:执行模式回退 celery→inline、AI 工具 note/描述与系统提示词不再声称「celery 模式已入队」(96d66a48)
  • 回测入队响应移除死字段 task_id: None(前端仅消费 run_id/status_url/result_url)(a575d521)
  • latest-coverage-date 消息链收拢为 StockScoringEngine.latest_factor_coverage_date(),cutoff/回退策略离开 API 层(a575d521)
  • CacheManager.exists() 免反序列化;测试桩 _FakeRedisBackend_InMemoryCacheStub(f1481b3f)
  • trial API 意外异常统一 500(原 radar/panorama 混用 400),信封形状收拢(97bbaec0)

验证:新增 21 个合约测试(trial 7、coverage-date 6、cache 4、backtest 入队 1、data_jobs 默认/legacy 2、改现 1),全量回归 551 passed / 1 skipped。评审遗留 judgement call(trial 五端点异常处理装饰器化、React 页面共享 useApi hook、async 回测 daemon 线程重启丢失)不在本轮修复,属后续优化。

复查发现的硬性缺口:入库测试中归属已注册模块却未打 marker。本轮为 18 个
文件补 marker,六张 acceptance 注册表补 17 行合约,注册表↔marker 现已一致:

- module_data_jobs ×6(api×3、ui×3;此前注册表中 0 个 API/UI 合约行)
- module_ml_model ×4(含注册表已声明却未打标的 test_model_training_job_service.py)
- module_backtest ×3、module_factor_engine ×3、module_scoring ×1、module_portfolio ×1

顺带处理复查的判断类项:
- tests/api/test_data_jobs_api.py 弃用裸 Flask(__name__),改用 conftest 的
  真实 app fixture(对齐 CLAUDE.md 测试结构约定)
- cache.py 过期检查形状抽为 _live_entry(),get()/exists() 共用
- ai/tools.py 两处重复读 DATA_JOB_EXECUTION_MODE 收拢为 _data_job_execution_mode()

另更正上轮提交信息笔误:实际入库 80 个测试文件(非 76 个)。
验证:pytest -m module_data_jobs 57 项 / module_backtest 42 项可选;全量 551 passed / 1 skipped。
@henrylin99

Copy link
Copy Markdown
Owner Author

复查收尾(22694b93)

复查指出的唯一硬性残留——「归属已注册模块却未打 marker」——已补齐:

  • 18 个测试文件补 marker:data_jobs ×6(api×3、ui×3)、ml_model ×4(含注册表已声明却未打标的 test_model_training_job_service.py,属注册表↔文件不一致)、backtest ×3、factor_engine ×3、scoring ×1、portfolio ×1
  • 六张 acceptance 注册表补 17 行合约;脚本复核注册表声明的全部合约文件,现存文件均已打标、无缺失
  • 复查的三个判断类项一并处理:test_data_jobs_api.py 改用 conftest 真实 app fixture(弃裸 Flask);cache.py 过期检查抽为 _live_entry()ai/tools.py 重复的执行模式读取收拢为 _data_job_execution_mode()
  • 更正笔误:上轮提交信息写「76 个合约测试」,实际入库 80 个测试文件

验证:pytest -m module_data_jobs 57 项、-m module_backtest 42 项均可独立筛选;全量回归 551 passed / 1 skipped。复查提及的模糊地带(realtime/ai/text2sql 等无注册表模块的约 60 个文件)未动,如需覆盖建议另立模块注册表而非套用现有 marker。

@henrylin99
henrylin99 merged commit 6546cb2 into master Sep 3, 2026
0 of 16 checks passed
@henrylin99
henrylin99 deleted the refactor/remove-redis branch September 3, 2026 13:58
henrylin99 added a commit that referenced this pull request Sep 3, 2026
feature/react-frontend 未推送远端且内容已随 PR #15 全部合入,
新手按文档执行 git checkout 会直接失败。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant