164 lines
12 KiB
Markdown
164 lines
12 KiB
Markdown
# 指数与板块详情分析页实施计划
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** 在市场综合概览中实现可点击的指数详情页,并在同一外壳上接入一级行业板块详情;只展示经过 TDX 校验的事实数据和规则计算结果。
|
||
|
||
**Architecture:** 后端新增详情业务模块,复用现有 TDX Client 和概览元数据,但不把详情数据拼入首页接口。详情 Controller 负责参数白名单与查询上限,Service 按指数/板块分别读取和映射日 K 线,Web 通过独立 Axios API 和共享详情页面外壳展示状态、K 线与可用视图;分时能力只有在探测报告通过后才启用。
|
||
|
||
**Tech Stack:** NestJS 11、TypeScript 5.9、Vue 3、Vue Router 4、Axios、Naive UI、原生 SVG/Canvas(除非依赖评估证明需要新增图表库)、TDX JSON-RPC。
|
||
|
||
**Spec:** `docs/superpowers/specs/2026-08-24-index-sector-detail-design.md`
|
||
|
||
## Global Constraints
|
||
|
||
- Node 使用 `22.x`,MySQL 仅保留 `5.7.x` 兼容约束,排序规则为 `utf8mb4_general_ci`。
|
||
- 详情接口只读 TDX,不启用 MySQL、Redis、RocketMQ、AI 或用户体系。
|
||
- TDX 原始地址、请求体、凭据和原始异常不得进入 Web 响应;错误必须分类并脱敏。
|
||
- API 响应 `asOf` 保持 UTC ISO,Web 统一按 `Asia/Shanghai` 展示。
|
||
- 每个详情请求最多返回 120 个 K 线点;`period` 仅接受已验证的 `1d`。
|
||
- 不提交密钥、密码、`.env`、生产数据或 `.gitnexus/`;继续使用项目级 Gitea。
|
||
- 修改代码前完成 GitNexus upstream impact;提交前运行 `gitnexus_detect_changes`。
|
||
- 中文 Conventional Commit,提交验证通过后立即推送远程。
|
||
|
||
## 文件边界
|
||
|
||
### 新增
|
||
|
||
- `server/apps/api/src/market-overview/detail/market-detail.dto.ts`:详情响应、报价、K 线点和可用视图 OpenAPI DTO。
|
||
- `server/apps/api/src/market-overview/detail/market-detail.mapper.ts`:指数/板块 K 线的安全字段映射、日期排序、数量裁剪和状态辅助。
|
||
- `server/apps/api/src/market-overview/detail/market-detail.service.ts`:详情查询、业务代码白名单、TDX 错误降级和指数/板块口径分流。
|
||
- `server/apps/api/src/market-overview/detail/market-detail.controller.ts`:两个详情路由、查询参数校验和 Swagger 声明。
|
||
- `server/apps/api/src/market-overview/detail/market-detail.service.test.ts`、`market-detail.mapper.test.ts`:服务与映射单元测试。
|
||
- `server/apps/api/test/market-detail.e2e-spec.ts`:HTTP 参数、响应状态和脱敏测试。
|
||
- `web/src/api/market-overview/detail.ts`:详情 API Axios 封装。
|
||
- `web/src/views/market-overview/detail/MarketDetailPage.vue`:共享详情页外壳和加载/错误/延迟状态。
|
||
- `web/src/views/market-overview/detail/MarketDetailChart.vue`:固定尺寸的轻量 SVG K 线图和不可用边界。
|
||
- `web/src/views/market-overview/detail/market-detail.ts`:前端详情响应类型适配与展示辅助。
|
||
- `web/src/views/market-overview/detail/MarketDetailPage.test.ts`、`MarketDetailChart.test.ts`:路由状态、时区和图表输入测试。
|
||
- `docs/features/FEAT-MO-004-index-sector-detail/`:PRD、需求、设计、计划、测试、回退、开发总结、GitNexus、Review 和 QA 证据。
|
||
|
||
### 修改
|
||
|
||
- `server/apps/api/src/market-overview/market-overview.module.ts`:注册详情 Controller/Service。
|
||
- `server/apps/api/src/market-overview/tdx/tdx.types.ts`:仅在探测确认后补充分时响应类型;日 K 线已有类型保持兼容。
|
||
- `web/src/app/router.ts`:新增 `/market-overview/indices/:code` 与 `/market-overview/sectors/:code` 路由。
|
||
- `web/src/views/market-overview/MarketOverviewPage.vue`:把指数/板块选择事件改为真实路由导航。
|
||
- `server/openapi/openapi.json`、`web/src/api/generated/schema.ts`:通过既有生成脚本更新契约,不手写漂移。
|
||
|
||
## 实施任务
|
||
|
||
### Task 1:建立功能档案、基线与影响分析
|
||
|
||
**Files:**
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/manifest.yaml`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/prd.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/requirements.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/design.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/rollback.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/gitnexus/impact-plan.md`
|
||
|
||
- [ ] 运行 `npm run schema:baseline`、`npm run schema:verify`;如果开发库为空,记录 `captured_empty`,不得伪造 SQL。
|
||
- [ ] 运行 `npm run governance:start -- FEAT-MO-004 index-sector-detail`,确认基线已提交、已推送且 GitNexus up-to-date。
|
||
- [ ] 对 `MarketOverviewController`、`MarketOverviewService`、`createTdxClient`、`createAppRouter` 和 `MarketOverviewPage` 执行 upstream impact,记录直接调用方、执行流、模块影响和风险。
|
||
- [ ] 将 HTTP/OpenAPI、Web API、消息、数据库、Redis、Scheduler、Worker、部署、测试和文档的同步判断写入 `gitnexus/impact-plan.md`。
|
||
|
||
### Task 2:TDX 能力探测和脱敏证据
|
||
|
||
**Files:**
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/tdx-capability-probe.md`
|
||
- Test: `server/apps/api/src/market-overview/tdx/tdx.client.test.ts`(只补充固定方法/参数边界测试,如确有必要)
|
||
|
||
- [ ] 使用当前开发环境 TDX 隧道探测 `get_market_data` 的日 K 线、候选分时方法、时间字段、响应上限和一级行业代码历史 K 线。
|
||
- [ ] 记录方法名、参数形状、返回字段、耗时、是否可重复和脱敏失败原因;禁止把地址、请求体凭据或原始异常写入文档。
|
||
- [ ] 若分时协议或字段完整性未通过,只登记 `intraday=false`,不改造协议、不生成假数据。
|
||
|
||
### Task 3:先写详情 Mapper 失败测试并实现安全 K 线映射
|
||
|
||
**Files:**
|
||
- Create: `server/apps/api/src/market-overview/detail/market-detail.mapper.test.ts`
|
||
- Create: `server/apps/api/src/market-overview/detail/market-detail.mapper.ts`
|
||
- Create: `server/apps/api/src/market-overview/detail/market-detail.dto.ts`
|
||
|
||
**Interfaces:**
|
||
- `mapDetailSeries(series: TdxKlineSeries, count: number): DetailSeriesPoint[]`
|
||
- `mapDetailQuote(series: TdxKlineSeries, definition: DetailInstrumentDefinition): DetailQuoteDto | null`
|
||
- `trimAndSortSeries(points: DetailSeriesPoint[], count: number): DetailSeriesPoint[]`
|
||
|
||
- [ ] 为空序列、日期非法、字段长度不一致、倒序日期、缺少金额/成交量、超过 120 条和相邻收盘价为零编写失败测试。
|
||
- [ ] 实现只读取 `Date/Open/High/Low/Close/Amount/Volume`,按合法交易日期升序排序,单点字段缺失时返回 `null` 或降级状态,不抛出原始数据。
|
||
- [ ] 实现价格、涨跌幅和方向计算;板块报价只暴露设计中确认的强弱字段。
|
||
- [ ] 运行 mapper 定向测试并确认通过。
|
||
|
||
### Task 4:实现详情 Service、Controller 和 OpenAPI DTO
|
||
|
||
**Files:**
|
||
- Create: `server/apps/api/src/market-overview/detail/market-detail.service.ts`
|
||
- Create: `server/apps/api/src/market-overview/detail/market-detail.controller.ts`
|
||
- Create: `server/apps/api/src/market-overview/detail/market-detail.service.test.ts`
|
||
- Modify: `server/apps/api/src/market-overview/market-overview.module.ts`
|
||
|
||
**Interfaces:**
|
||
- `MarketDetailService.getIndexDetail(code: string, period: DetailPeriod, count: number): Promise<IndexDetailResponseDto>`
|
||
- `MarketDetailService.getSectorDetail(code: string, period: DetailPeriod, count: number): Promise<SectorDetailResponseDto>`
|
||
- `GET /api/v1/market-overview/indices/:code/detail?period=1d&count=120`
|
||
- `GET /api/v1/market-overview/sectors/:code/detail?period=1d&count=120`
|
||
|
||
- [ ] 先写成功、非法代码、非法 period/count、TDX 超时、协议错误、空序列、部分字段缺失和延迟交易日测试。
|
||
- [ ] Controller 只接受白名单指数/一级行业代码、`period=1d` 和 `1..120` 的整数 count;非法参数由 Nest 标准 400 返回。
|
||
- [ ] Service 调用固定 `get_market_data`,不把方法名或原始 params 从 HTTP 传入;指数和板块使用独立定义表和 warning 文案。
|
||
- [ ] 以 `fresh/delayed/partial/unavailable` 生成元数据;详情失败只影响本次请求,不影响首页接口。
|
||
- [ ] 注册模块并生成 OpenAPI;运行 API 单元测试和 E2E 定向测试。
|
||
|
||
### Task 5:接入 Web 路由、Axios API 和共享详情页面
|
||
|
||
**Files:**
|
||
- Create: `web/src/api/market-overview/detail.ts`
|
||
- Create: `web/src/views/market-overview/detail/market-detail.ts`
|
||
- Create: `web/src/views/market-overview/detail/MarketDetailPage.vue`
|
||
- Create: `web/src/views/market-overview/detail/MarketDetailChart.vue`
|
||
- Create: `web/src/views/market-overview/detail/MarketDetailPage.test.ts`
|
||
- Create: `web/src/views/market-overview/detail/MarketDetailChart.test.ts`
|
||
- Modify: `web/src/app/router.ts`
|
||
- Modify: `web/src/views/market-overview/MarketOverviewPage.vue`
|
||
- Modify: `web/src/styles/index.scss`
|
||
|
||
**Interfaces:**
|
||
- `createMarketDetailApi(requestClient): { getIndexDetail(code, params), getSectorDetail(code, params) }`
|
||
- `MarketDetailPage` consumes route `type/code`, calls only the Axios API wrapper, and renders `instrument/quote/series/availableViews`.
|
||
|
||
- [ ] 先写路由参数、加载、空、错误、延迟、上海时区和 390px 视口测试。
|
||
- [ ] 实现页面固定结构:返回概览、名称/代码/来源/更新时间、核心行情、K 线、数据质量和事实型复盘摘要。
|
||
- [ ] 实现轻量 SVG 图表,固定容器尺寸,点数多于 120 时不额外扩张;`intraday=false` 只显示边界说明。
|
||
- [ ] 修改概览点击事件使用 `router.push`,不在页面直接调用 Axios 或 TDX。
|
||
- [ ] 运行 Web 定向测试、typecheck 和生产构建;确认移动端无横向溢出。
|
||
|
||
### Task 6:契约、全量验证与 Review
|
||
|
||
**Files:**
|
||
- Modify: `server/openapi/openapi.json`
|
||
- Modify: `web/src/api/generated/schema.ts`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/test-plan.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/implementation-plan.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/development-summary.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/review/code-review.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/review/standards-review.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/qa/test-results.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/qa/visual-qa.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/gitnexus/after.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/gitnexus/detected-changes.md`
|
||
- Create: `docs/features/FEAT-MO-004-index-sector-detail/gitnexus/comparison.md`
|
||
|
||
- [ ] 运行 `npm run check:contracts`,确认后端 DTO、OpenAPI 和 Web 类型一致。
|
||
- [ ] 运行定向测试、`npm run verify`、开发服务器 Playwright 桌面/390px 截图和非空图表检查。
|
||
- [ ] 执行代码 Review、开发规范符合性 Review,记录发现、处置和残余风险。
|
||
- [ ] 运行 `npm run governance:finish -- FEAT-MO-004 index-sector-detail`,刷新 GitNexus 并保存前后对比。
|
||
- [ ] 运行 `gitnexus_detect_changes`,确认只影响详情模块、路由、契约和预期文档。
|
||
- [ ] 使用中文 Conventional Commit 提交并立即推送项目 Gitea;推送失败不得标记完成。
|
||
|
||
## 计划自检
|
||
|
||
- 设计覆盖:指数/板块双切片、TDX 能力门、状态降级、路由、契约、时区、安全、性能、测试、回退均有对应任务。
|
||
- 占位检查:没有以 TBD/TODO 或“适当处理”代替具体行为;分时未验证时明确返回 `intraday=false`。
|
||
- 类型一致性:Service 参数、DTO 字段、Web API 方法和页面消费字段与设计文档一致。
|