项目架构与开发约束

更新:2026-08-01

1. 当前边界

客户端只维护一条主链路:

蛋卷数据 → 证据归一化 → SQLite 快照 → 规则/AI 研究
  → 关注/每日信号 → 用户确认的定投计划

定投计划已经接在研究链路之后,没有另建第二套数据采集和研究体系。打开定投页只读 SQLite,不隐式访问蛋卷或 DeepSeek。

2. 代码分层

Main

  • src/main/data-sources/danjuan/client.ts:HTTP 与响应校验。
  • src/main/data-sources/danjuan/selection.ts:宽基、行业、主题、全球、策略的数据适配与三阶段执行壳。
  • src/main/data-sources/danjuan/radar.ts:估值雷达数据适配与三阶段执行壳;原始证据、逐项 AI 摘要和最终汇总互不隐式触发。
  • src/main/data-sources/danjuan/run-control.ts:批次控制。
  • src/main/storage/research-db.ts:研究快照。
  • src/main/storage/dca-repository.ts:SQLite v6 四级关注度、计划和每日信号;旧关注/排除表仅用于幂等迁移。
  • src/main/dca/dca-service.ts:本地研究转候选、倍率、预算与历史信号。
  • src/main/storage/file-cache.ts:接口缓存。
  • src/main/ai/deepseek.ts:AI 配置、提示和结果解析。
  • src/main/index.ts:窗口与 IPC 组合根。

Shared

  • src/shared/types.ts:Main、Preload、Renderer 的公共契约。
  • src/shared/index-scoring.ts:指数/基金规则分。
  • src/shared/ai-action-schema.ts:AI 行动协议。
  • src/shared/default-fund-selection.ts:从候选审计结果选择默认研究基金。
  • src/shared/fund-candidate-comparison.ts:合并完整/精选基金池并生成全候选浅层工具分、缺失证据和入选/落选理由;资产规模只使用可解析的 scale 金额,tot_share 作为份额字段保留说明但不参与金额阈值评分。
  • src/shared/research-run-state.ts:两个执行壳实际调用的纯函数领域内核,统一范围、状态分类、续跑、失效与汇总门禁。
  • src/shared/dca-plan.ts:0–6 倍、有效分位、证据上限与计划领域模型。

Renderer

  • IndexSelectionView.vue:五大类共用研究入口与阶段调度。
  • DanjuanIndexValuationView.vue:估值雷达入口,与分类页使用同一阶段协议。
  • components/index-research/ResearchWorkflowSteps.vue:六个入口共用的三阶段流程与暂停入口。
  • components/index-research/*:共享表格、详情和图表。
  • DcaPlanView.vuecomponents/dca/*:定投候选、计划、证据链和历史信号。
  • SettingsView.vue:本地配置状态。

3. 已移除的架构分支

  • 东方财富数据源与行业/股票估值页面。
  • 本地基金筛选和蛋卷在线基金筛选。
  • Mock 行业、基金列表和七步详情页。
  • 旧低估指数基金研究聚合页。
  • 乌龟量化:未发现独立实现。

这些分支不得因旧文档或旧路由再次进入当前主流程。需要恢复时从 Git 创建独立设计任务。

4. 复杂度判断

当前主要复杂度不在页面,而在三个地方:

  1. 长批次可恢复性:几十个指数涉及多接口和 AI;必须先完成可审查的原始数据检查点,再按人工筛选范围逐项 AI,最后独立汇总,三个阶段都不能互相隐式补跑。
  2. 证据口径:缺失、0、不可适用、历史不足不能混为一类。
  3. 状态一致性:同一指数跨大类、估值雷达、关注和定投计划必须使用同一主键和同一最新快照。

不应增加的复杂度:

  • 为每个页面复制一套 API 和评分代码。
  • 在 Vue 组件里直接请求数据或拼业务规则。
  • 同时维护文件缓存、SQLite 和组件状态三套互相矛盾的真相。
  • 为未来可能用到的交易、持仓、账户功能提前建完整系统。

5. 架构规则

单一标识

  • 指数主键使用规范化 indexCode/symbol
  • 基金主键使用 fundCode
  • 同一指数跨分类只保存一份当日证据,分类关系单独记录。

数据分层

RawEvidence      原始接口证据
NormalizedFacts  归一化事实
RuleResult       确定性评分/倍率
AiAssessment     AI 解释与上限
UserPlan         用户确认的计划
ExecutionRecord  用户手工登记的执行

后一层可以引用前一层,不能改写前一层。

缓存与数据库

  • HTTP 文件缓存解决重复请求与 304。
  • SQLite 是研究状态和 UI 恢复的唯一持久化真相。
  • 六个指数入口的原始证据、逐项 AI 摘要与最终汇总是三个独立检查点;刷新证据必须把旧 AI 标记为待更新,后续阶段不得隐式补拉前序数据。
  • 原始数据覆盖选定目录内全部一至三级指数,不受名称、状态、结论、动作或分页过滤影响;AI 使用显式筛选范围,汇总必须精确匹配成功摘要范围。
  • UI 本地状态只保存筛选、分页、展开和选中项。
  • 新表通过幂等迁移增加,不删除旧研究表或用户数据。

IPC

  • Preload 只暴露业务动作,例如“读取计划”“刷新指数”“保存关注”。
  • Renderer 不接触文件路径、数据库句柄、密钥或任意网络请求。
  • IPC 返回结构化错误和状态,不把异常吞成空数组。

6. 页面设计原则

  • Element Plus 为唯一组件体系。
  • 表格优先表达可比较信息;详情用标签页,不平铺所有模块。
  • 状态必须同时使用文字和颜色,不能只靠颜色。
  • 表头提示说明定义、作用、适用范围和分界,不只展开缩写。
  • 图表必须有横纵坐标、十字准星、日期/数值提示和可见的数据窗口。
  • 返回页面时恢复分页、筛选、选中项、折叠和滚动位置。

7. 测试门槛

每轮实现至少运行:

npm run typecheck
npm test
npm run build

重点测试:

  • API 响应归一化和缺失字段。
  • 批次暂停、续跑、同日恢复和失败项重试。
  • 评分及倍率边界。
  • SQLite 迁移与 CRUD。
  • AI 失败时的确定性降级。

真实接口冒烟测试必须低频执行,不作为每次单元测试的依赖。

8. 文档治理

  • PLAN.md 只做入口。
  • plan/ 只保留当前计划。
  • docs/文档索引.md 区分活跃文档和退役档案。
  • 旧实现与旧计划依赖 Git 追溯,不在仓库工作区重复保留。