Files
xiaobaifupan/docs/migration/重建迁移章程.md
T

213 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 小白复盘重建迁移章程
> 状态:执行中
> 建立日期:2026-07-30
> 产品真相源:`docs/product/小白复盘-完整产品规格说明书.md`
## 1. 唯一目标
在当前仓库的`next/`目录内,从零重建小白复盘。新系统必须完整实现产品规格说明书定义的功能、权限、数据口径、交互状态、视觉和终端行为,同时显著减少重复实现、补丁层和隐式依赖,使后续人工维护可操作。
迁移不是对旧系统继续重构,也不是增加新产品功能。旧系统在迁移期间保持可运行,只用于读取业务事实、算法、必要数据和视觉资产。
## 2. 不可违反的约束
1. 产品规格说明书中的“已确认产品标准”优先于旧代码现状。
2. 旧系统文件不移动、不批量改名、不作为新系统运行时依赖。
3. 新系统开发数据库独立,不直接写入旧系统数据库。
4. 不整文件复制旧`server.py``app.js`、样式覆盖层或巨型业务模块。
5. 每项业务规则只保留一个权威实现。
6. 全站只有一个浏览器API出口、一个数据网关、一个LLM网关、一个弹窗管理器和一套设计令牌。
7. 页面只负责取数、组织状态和组合组件,不拥有跨页面业务计算。
8. 外部数据源只能通过数据网关访问;公开网页源不得进入正式计算。
9. LLM只解释或编译受控公式,不参与确定性行情、情绪、选股和问天计算。
10. 用户私有数据的所有读写必须在服务端验证账号所有权。
11. 兼容层只能用于迁移,必须登记删除条件;最终交付不得保留双实现。
12. 不以“测试通过”替代产品验收;测试必须实际覆盖对应规格。
13. 不以“目录已建立”或“接口已预留”宣称功能迁移完成。
14. 不自动替换NAS生产容器;最终切换在全量验收后单独确认。
## 3. 技术与结构决策
### 3.1 技术栈
- 后端:Python、FastAPI、Pydantic。
- 数据库:SQLite,显式Repository与有序Migration,不引入ORM双重抽象。
- 前端:Vue 3、TypeScript、Vite、Pinia。
- 单元与集成测试:pytest。
- 浏览器验收:Playwright。
- 部署:多阶段Docker构建,运行时保持单容器模块化单体。
### 3.2 目标一级结构
```text
next/
frontend/
src/
shared/
pages/
app/
backend/
bootstrap/
http/
features/
data/
database/
jobs/
llm/
config/
tests/
tools/
docs/
```
只预建稳定的一级边界。二、三级业务目录随纵向切片建立,不创建无真实职责的空目录树。
### 3.3 依赖方向
```text
浏览器页面 -> 前端共享层 -> HTTP接口
HTTP/后台任务 -> 业务服务 -> Repository/DataGateway/LLMGateway -> 基础设施
```
禁止反向依赖、跨功能直接读表、页面直接访问外部数据源,以及Controller中编写评分和持久化逻辑。
## 4. “做减法”验收标准
每个迁移切片必须证明:
- 旧系统同一行为的多个实现已经在新系统收敛为一个。
- 没有为了快速兼容复制第二份公式、请求逻辑或CSS组件。
- 新增共享抽象至少有两个真实调用方,或明确消除一个高风险全局出口。
- 页面专属样式不修改其他页面和全局Shell。
- 临时代码有明确删除条件,不使用永久`legacy``v2-fix``override-final`式补丁层。
- 重建后的文件按职责可读,不用巨型文件重新制造旧问题。
- 仅统计代码行数下降不能证明成功;功能等价、唯一职责和可删除旧实现同时成立才算减法。
建议性文件规模门禁:
- 前端页面容器目标不超过400行,超出时按稳定子组件拆分。
- 后端业务服务目标不超过500行,复杂确定性算法可独立成纯计算模块。
- 单个CSS文件目标不超过600行,按令牌、Shell、共享组件、页面、移动端分层。
- 超过门禁必须在本章程记录原因,不能静默放宽。
## 5. 迁移方法
采用纵向切片。每个切片同时交付:
1. 产品行为与状态。
2. 权限和账号数据边界。
3. 后端接口与Schema。
4. 业务计算与数据访问。
5. 前端页面、日间/夜间和响应式行为。
6. 单元、契约、集成和浏览器测试。
7. 与旧系统和产品规格的差异报告。
8. Git提交和远端回档节点。
禁止先迁移全部HTML、再迁移全部接口、最后补业务逻辑。这会产生长期空壳和无法验收的中间状态。
## 6. 执行阶段
| 阶段 | 内容 | 完成证据 | 状态 |
|---:|---|---|---|
| 0 | 产品规格、迁移章程、旧系统只读基线 | 文档检查、Git节点 | 已完成 |
| 1 | `next/`最小可运行骨架与工具链 | 前后端启动、健康检查、基础测试 | 已完成 |
| 2 | 配置、错误、日志、数据库迁移、Repository基础 | 迁移回退和错误契约测试 | 已完成 |
| 3 | 账户、会话、权限、会员和系统配置 | 权限矩阵与跨账号测试 | 已完成 |
| 4 | 前端Shell、路由、状态、API、弹窗、主题和令牌 | 1080P/4K/390px Shell截图 | 已完成 |
| 5 | 数据网关、日期、快照、图表和搜索 | 来源/时间/缺失/降级测试 | 已完成 |
| 6 | 情绪周期与五类股池 | 算法固定样本、页面E2E | 未开始 |
| 7 | 涨停表现、市场天梯和板块轮动 | 结构统计与展开滚动验收 | 未开始 |
| 8 | 集合竞价、题材库、人气热榜和龙虎榜 | 生命周期、口径和空态验收 | 未开始 |
| 9 | 智能选股、36套策略、自定义选股和持续跟踪 | 109因子、确定性和隔离测试 | 未开始 |
| 10 | 问师、模型Skill、LLM流式网关 | 上下文路由、去重和回退测试 | 未开始 |
| 11 | 问天观势、观气、观心 | 公式、安全门、动画和历史验收 | 未开始 |
| 12 | 我的复盘、提醒和复盘助手 | 私有数据、汇总和弹窗验收 | 未开始 |
| 13 | 全站移动端重组和无障碍 | 320/390/430/768/横屏验收 | 未开始 |
| 14 | 数据迁移、Docker、备份恢复和性能安全 | 旧库副本迁移、回滚演练 | 未开始 |
| 15 | 全量验收、减法审计和切换准备 | 规格覆盖矩阵、最终报告 | 未开始 |
阶段编号不会因为上下文压缩重新规划。只有发现产品规格自身矛盾时,才记录决策并调整阶段内容;不得通过新增阶段掩盖未完成工作。
## 7. 每阶段质量门禁
每次提交前至少执行:
1. 格式、类型和静态检查。
2. 受影响模块的单元测试。
3. API契约和账号边界测试。
4. 数据库迁移前进/回退测试(涉及数据库时)。
5. Playwright关键流程(涉及运行时或前端时)。
6. 日间/夜间和目标视口截图(涉及视觉时)。
7. 浏览器控制台无未处理错误。
8. 密钥、Token、日志和生成物扫描。
9. 与产品规格固定验收案例的可追溯检查。
10. `git diff --check`和工作区来源确认。
## 8. Git与回档
- 当前`main`保留旧系统可运行状态和新系统迁移过程。
- 每个阶段至少一个独立提交,提交信息使用`rebuild(stage-N): ...`
- 阶段门禁通过后推送Gitea。
- 不重写已推送历史,不使用破坏性重置。
- 大阶段内可有多个小提交,但最终必须有明确阶段完成节点。
- 规格说明书和本章程的变更与相应行为变更同提交或先提交。
## 9. 数据迁移与最终切换
- 开发期间只使用旧数据库的只读副本或脱敏样本。
- 迁移工具可重复运行,并输出逐表数量、校验和、跳过项和失败项。
- 首次完整迁移后进行账号、权限、共享快照和私有数据抽样比对。
- 最终切换前停止旧系统写入,执行最终增量迁移,再启动新容器。
- 保留旧镜像、旧数据库一致性备份和加密密钥,验证回退路径。
- 未经最终确认,不停止或替换NAS现有容器。
## 10. 持续状态记录
每完成一个阶段,在本节追加:
- 提交哈希和推送状态。
- 实际完成证据。
- 删除或避免的重复代码。
- 未完成项和残余风险。
- 下一阶段入口条件。
### 当前状态
- 阶段0已完成:产品规格说明书和迁移章程通过结构、表格和密钥扫描。
- 产品规格说明书包含16个工作区、36套策略、109个因子和85个固定验收案例。
- 旧系统保持原状。
- 阶段1已完成,代码提交为`603e73d`:建立隔离的FastAPI与Vue 3/TypeScript/Vite骨架、唯一前端API客户端、统一安全错误外壳、设计令牌起点及前后端基础测试。
- 后端门禁:Ruff通过,pytest为2项通过;存在1项FastAPI 0.141测试客户端上游弃用警告,阶段2改用显式ASGI传输层消除。
- 前端门禁:类型检查通过,Vitest为1个文件/2项通过,Vite生产构建通过;依赖安装审计为0个已知漏洞。
- 运行验收:`8780/api/health`返回开发环境健康状态,`5173`代理访问成功;1280x720浏览器实测无控制台错误、无横向溢出。
- 减法证据:删除未使用的`jsdom`及37个传递依赖;禁止TypeScript生成重复JavaScript测试产物;未复制旧`server.py``app.js`或CSS覆盖层。
- 阶段2已完成,代码提交为`d969d2c`:配置从环境唯一加载,SQLite连接启用WAL/外键/忙等待,迁移支持前进、显式回退、原子失败、校验和和连续历史校验。
- Repository基础只建立被健康检查真实使用的数据库状态Repository,未创建通用CRUD或空业务目录;数据库维护CLI支持状态、升级及需二次确认的回退。
- HTTP错误统一为`code/message/request_id`,404、验证错误、业务错误和未知异常均通过安全契约;请求编号同时写入响应头,未知异常不向前端泄露原文。
- 日志采用结构化JSON、`Asia/Shanghai`时间、10MB/3份轮转和嵌套/字符串敏感值脱敏;运行健康检查可区分进程和数据库状态。
- 阶段2门禁:Ruff通过,pytest为20项通过,前端2项测试、类型检查和生产构建通过;真实服务健康响应、请求编号及`+08:00`启动日志通过运行验收。
- 阶段3已完成,代码提交为`f69972c`并已推送:首个注册账号成为管理员,后续账号为普通用户;管理员权限与会员状态独立,管理员开通会员后同时具有管理员和会员标识。
- 会话Cookie为HttpOnlyCSRF使用Cookie与请求头双重校验;服务端只保存会话和CSRF哈希。修改密码保留当前会话并撤销其他会话,账号出生资料和系统凭据均加密落库且按权限隔离。
- 会员管理支持1个月、3个月、12个月、3年和永久,续期从有效到期日继续计算;会员每日智能调用上限进入会员配置。管理员无需伪装成会员即可使用智能功能,普通非会员被服务端拒绝。
- 模型池限制20个模型,首个模型自动成为主模型,支持独立选择主模型和辅助模型;选中模型不可删除,密钥不会通过管理接口返回。模型连通测试明确留给阶段10的唯一LLM网关,系统管理不建立第二个模型调用出口。
- 减法证据:HTTP Schema从路由中拆出,路由由412行降至314行;系统凭据职责从账户服务拆出,最长业务服务由429行降至382行。未建立通用CRUD、旧账号兼容层、第二套权限判断或明文密钥读取接口。
- 阶段3门禁:Ruff通过,pytest为40项通过;前端2项测试、类型检查和生产构建继续通过;数据库版本1和2的前进及倒序回退通过,真实账号密码和已提供令牌未进入`next/`
- 阶段3残余边界:账号与系统管理的前端交互属于阶段4;LLM成功调用计次和模型连通性属于阶段10,不在阶段3提前实现。
- 阶段4已完成,代码提交为`3b75bf2`并已推送:登录注册、16项工作区注册表、PC/移动Shell、顶栏、摘要条、固定状态栏、主题、日期、账户菜单和系统管理前端均已接入。
- 账户五项菜单独立可达;浏览器实际保存并重读个人出生资料。会员状态完整显示开通状态、到期、剩余时长、今日用量、今日剩余、功能对比和暂不可用加油包。
- 管理员可按分类维护平台凭据、模型池、主辅模型与会员;非管理员不显示后台刷新和系统管理,直达管理路由会返回情绪周期,智能工作区保留同结构会员锁定态。
- 前端只有一个工作区注册表、API客户端、会话Store、主题Store、弹窗Host和Toast Host。响应式规则从五处分散媒体查询收敛到唯一`mobile.css`;最长前端文件332行,组件样式未出现令牌文件之外的色值。
- 阶段4门禁:Ruff和40项pytest通过;Vue类型检查、2个文件5项Vitest、Vite生产构建通过;2项Playwright覆盖管理员/普通用户、真实写入、Ctrl+K、主题持久化、弹窗、系统管理和多视口。
- 视觉证据已保存于`next/docs/evidence/stage-4/`:日间/夜间1920×1080、夜间3840×2160和390×844;实测无横向溢出、弹窗居中、Shell尺寸与内容边距符合规范。
- 阶段4残余边界:行情摘要值、真实搜索结果、后台刷新和各工作区业务内容属于阶段5及后续阶段;移动端逐页业务重组属于阶段13,未用占位页冒充完成。
- 阶段5已完成,代码提交为`cf0ab70`并已推送:建立唯一`DataGateway`、四源职责策略、观测元信息、失败关闭质量门,以及交易日历、标的目录、行情摘要和图表序列的版本3数据库结构。
- Tushare只承担权威交易日历、股票目录和日线入口;iFinD优先承担日K与分时展示,并支持顶层表格响应和Access Token失效后的Refresh Token重试;东方财富只允许作为展示分时兜底,策略层禁止其进入正式计算。腾讯职责已在策略中登记,但尚无本阶段真实消费者,因此未创建空Provider。
- 日期契约区分请求日期、实际数据日期和观测时间;盘前空今日K线会被剔除,沿用最近真实快照时明确返回真实日期和说明,从未同步时不生成模拟数据。
- 全局搜索按股票、板块、题材、指数固定分组,具备160毫秒防抖、键盘循环选择和明确状态;搜索预览与行情详情共用同一图表组件,日K上涨空心且影线不穿实体,分时范围固定9:30至15:00并包含昨收零轴和均价线。
- 管理员行情管理增加交易日历和股票目录的真实同步入口;普通用户响应不显示供应商工程名称。完整行情后台任务、情绪摘要写入和各实体业务详情仍属于后续阶段,没有用本阶段基础页冒充完成。
- 阶段5门禁:Ruff通过,pytest为46项通过;Vue类型检查、2个文件5项Vitest和Vite生产构建通过;3项Playwright覆盖既有Shell回归、摘要、搜索、日K/分时、日夜主题、1920×1080和390×844视口。组件CSS无令牌外色值,已提供密码和令牌未进入`next/`
- 减法证据:未复制旧`TushareClient``IfindHttpClient``MarketChartClient`或供应商缓存堆叠;所有外部访问收敛到一个网关和一份策略,搜索预览与详情没有重复图表实现;新增后端最长文件379行,低于章程400行目标。
- 新系统进入阶段6:使用阶段5的交易日期、摘要存储和质量门迁移情绪周期与五类股池的确定性公式、固定样本和页面。
- 生产切换明确保留为最终人工确认项。