19 KiB
市场结构与成交额趋势实施计划
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 为综合概览增加行业/题材排行、资金流向排行和全市场成交额趋势,并保持现有指数、市场宽度和短线情绪模块的独立失败隔离。
Architecture: 在现有 market-overview 模块内增加一个连续可读的 structure 业务边界。TDX 负责已验证的指数与成交额能力,AKTools 只通过固定白名单适配行业、题材和资金接口;Nest 输出三个独立 HTTP API,Vue 通过 Axios 和 composable 并行消费,任何未验证的数据源都返回明确状态而不生成占位数据。
Tech Stack: NestJS、TypeScript、Vue 3、Axios、TDX HTTP 桥接、AKTools HTTP、OpenAPI/openapi-typescript、Vitest/Node test、Playwright。
Spec: docs/superpowers/specs/2026-08-25-market-structure-and-turnover-design.md
Global Constraints
- Node 使用
22.x系列;MySQL 使用5.7.x,本切片不启用 MySQL、Redis、RocketMQ。 - 数据库若被治理命令读取,只允许
APP_ENV=development的a_share_analysis_dev,字符集utf8mb4、排序规则utf8mb4_general_ci。 - 浏览器不得直连 TDX 或 AKTools;所有请求经过
web/src/utils/request.ts和 Nest 服务端固定适配器。 - TDX/AKTools 地址、账号、密钥、家庭网络信息、原始行情载荷不得进入仓库、日志或 HTTP 响应。
- API 参数必须白名单校验;排序、分类、数量和时间粒度拒绝未知值及超出范围值。
- 成交额统一以亿元输出;资金净流入只能使用上游明确字段,不得从涨跌或成交额推导。
- 模块状态只能使用
fresh、delayed、partial、unavailable;不可用时禁止离线样本和伪造值。 - 修改任何函数、类、方法前先运行 GitNexus 影响分析;提交前运行
gitnexus_detect_changes。 - 每次提交使用带功能编号的中文 Conventional Commit,并立即推送当前分支到项目 Gitea。
Task 1: 治理基线与数据源能力探针
Files:
- Create:
docs/features/FEAT-MO-005-market-structure-turnover/manifest.yaml - Create:
docs/features/FEAT-MO-005-market-structure-turnover/prd.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/requirements.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/design.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/test-plan.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/rollback.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/data-source-probe.md - Create:
tools/probes/market-structure-capability.mjs
Interfaces:
-
Consumes: local TDX bridge configuration and
http://127.0.0.1:8080/api/public/{interface}. -
Produces: a redacted capability table consumed by Tasks 2–4; each endpoint is classified as
usable,partial, orunavailable. -
Step 1: Capture the development schema baseline before starting the version.
Run:
npm run schema:baseline
npm run schema:verify
Expected: the commands either capture a valid development-only baseline or produce the repository-approved not_applicable/captured_empty evidence; no production host is contacted.
- Step 2: Start the governance record and refresh GitNexus.
Run:
npm run governance:start -- FEAT-MO-005 market-structure-turnover
Expected: docs/features/FEAT-MO-005-market-structure-turnover/gitnexus/before.md and impact-plan.md exist and record the baseline commit, schema evidence and current index.
- Step 3: Implement the probe as a read-only script.
The script must call these fixed candidates and output only status, elapsed time, row count, keys, first/last timestamp and a short error class:
const candidates = [
'stock_board_industry_spot_em',
'stock_board_concept_spot_em',
'stock_sector_fund_flow_rank',
'stock_market_fund_flow',
'stock_zh_a_spot_em',
];
For TDX, call get_market_data for 000001.SH, 399001.SZ, and 899050.BJ with period values 1m, 5m, 15m, and 1d; report whether Date and Amount are aligned and whether timestamps are intraday.
- Step 4: Run the probe twice after market close and once during a trading session.
Run:
node tools/probes/market-structure-capability.mjs --base-url http://127.0.0.1:8080
Expected: the report distinguishes “收盘后最后一条记录” from actual盘中 freshness, records HTTP 500/timeout separately, and does not store raw rows or URLs beyond the configured local base URL.
- Step 5: Decide source mapping in the feature record.
Write one of these explicit outcomes for each metric: TDX primary, AKTools supplement, derived from validated snapshots, or deferred as unavailable. Do not begin Tasks 2–4 until the mapping and field definitions are recorded.
- Step 6: Commit the probe and governance documents.
git add docs/features/FEAT-MO-005-market-structure-turnover tools/probes/market-structure-capability.mjs
git commit -m "docs(FEAT-MO-005): 建立市场结构数据源探针"
git push origin HEAD
Task 2: 建立结构领域类型、映射和来源客户端
Files:
- Create:
server/apps/api/src/market-overview/structure/market-structure.types.ts - Create:
server/apps/api/src/market-overview/structure/market-structure.mapper.ts - Create:
server/apps/api/src/market-overview/structure/market-structure.mapper.test.ts - Create:
server/apps/api/src/market-overview/structure/aktools-structure.client.ts - Create:
server/apps/api/src/market-overview/structure/aktools-structure.client.test.ts - Modify:
server/apps/api/src/market-overview/market-overview.dto.ts - Modify:
server/apps/api/src/market-overview/tdx/tdx.types.tsonly if the probe confirms an intraday TDX response shape.
Interfaces:
-
Consumes: Task 1 source mapping and raw TDX/AKTools rows.
-
Produces:
SectorRankingRecord,CapitalFlowRecord,TurnoverPoint,MarketStructureSourceClient, and pure mappers that reject invalid dates, negative amounts, duplicate timestamps and unknown categories. -
Step 1: Run symbol-level GitNexus impact before editing shared DTOs.
Run impact analysis for MarketOverviewMetaDto, MarketOverviewService, and createAktoolsClient with upstream direction. Record direct callers and affected flows in gitnexus/impact-plan.md; if risk is HIGH or CRITICAL, stop and obtain explicit scope confirmation.
- Step 2: Write failing mapper tests.
Cover these exact cases:
expect(mapSectorRanking({ category: 'industry', name: '半导体', changePercent: '2.5' })).toMatchObject({ changePercent: 2.5 });
expect(mapSectorRanking({ category: 'unknown', name: 'X' })).toBeNull();
expect(mapTurnoverPoints([{ time: '2026-08-25 09:35', amount: '10' }, { time: '2026-08-25 09:30', amount: '8' }])).toEqual({ points: [], invalidCount: 2 });
expect(mapCapitalFlow({ netInflow: 'N/A' }).netInflow).toBeNull();
- Step 3: Implement source clients with fixed endpoint allowlists.
AktoolsStructureClient may call only endpoints classified usable by Task 1. It must apply the existing timeout, response-size limit, JSON validation and error redaction pattern. It must not accept an arbitrary interface name from a request query.
- Step 4: Implement pure mappers and source-specific unit tests.
Convert provider field names to domain fields, normalize amounts to亿元, preserve source, tradeDate and asOf, and return null for unknown money definitions instead of zero.
- Step 5: Run focused tests and commit.
pnpm --filter @a-share-analysis/server test -- market-structure.mapper aktools-structure.client
git add server/apps/api/src/market-overview/structure server/apps/api/src/market-overview/market-overview.dto.ts
git commit -m "feat(FEAT-MO-005): 建立市场结构数据映射边界"
git push origin HEAD
Task 3: 实现行业、题材和板块排行 API
Files:
- Create:
server/apps/api/src/market-overview/structure/market-structure.dto.ts - Create:
server/apps/api/src/market-overview/structure/market-structure.service.ts - Create:
server/apps/api/src/market-overview/structure/market-structure.controller.ts - Create:
server/apps/api/src/market-overview/structure/market-structure.service.test.ts - Modify:
server/apps/api/src/market-overview/market-overview.module.ts
Interfaces:
-
Consumes:
MarketStructureSourceClientand Task 2 mappers. -
Produces:
GET /api/v1/market-overview/sector-rankings?category=industry|concept|board&sort=rise|fall|turnover&limit=1..100. -
Step 1: Add controller validation tests for category, sort and limit.
Reject category=stock, sort=unknown, limit=0, limit=101 and non-integer limits with a 400 response; accept industry, concept, board, rise, fall, turnover and limits 1–100.
- Step 2: Add service tests for sorting and status.
Verify descending rise/fall/turnover order, top-N truncation, partial when one category source fails, unavailable when all rows fail, and delayed when the latest trade date is not the current Shanghai trading date.
- Step 3: Implement DTOs and service.
Return category, code, name, changePercent, turnoverAmount, advancingCount, decliningCount, leader, and tradeDate; omit fields that the source cannot substantiate rather than filling zeros.
- Step 4: Register the structure controller/provider and run the server suite.
pnpm --filter @a-share-analysis/server test
pnpm --filter @a-share-analysis/server typecheck
- Step 5: Commit the endpoint.
git add server/apps/api/src/market-overview
git commit -m "feat(FEAT-MO-005): 增加行业题材板块排行接口"
git push origin HEAD
Task 4: 实现资金流向 API
Files:
- Modify:
server/apps/api/src/market-overview/structure/market-structure.dto.ts - Modify:
server/apps/api/src/market-overview/structure/market-structure.service.ts - Modify:
server/apps/api/src/market-overview/structure/market-structure.controller.ts - Modify:
server/apps/api/src/market-overview/structure/market-structure.service.test.ts
Interfaces:
-
Consumes: Task 1 confirmed fund-flow endpoint and Task 2
CapitalFlowRecord. -
Produces:
GET /api/v1/market-overview/capital-flow?category=industry|concept|board&sort=inflow|outflow&limit=1..100. -
Step 1: Add failing tests for explicit money definitions.
Assert that a row without a documented net-flow field returns netInflow=null, flowDefinition='unavailable'; assert that the API never derives net flow from changePercent or turnoverAmount.
- Step 2: Implement field mapping and sorting.
Sort only validated numeric fields, preserve null at the end, and include the provider definition text in flowDefinition.
- Step 3: Add partial and unavailable behavior tests.
One failed category request must preserve other category data with partial; all failed requests return data=null and unavailable.
- Step 4: Run focused server tests and commit.
pnpm --filter @a-share-analysis/server test -- market-structure.service
git add server/apps/api/src/market-overview/structure
git commit -m "feat(FEAT-MO-005): 增加行业题材资金流向接口"
git push origin HEAD
Task 5: 实现全市场成交额趋势 API
Files:
- Modify:
server/apps/api/src/market-overview/structure/market-structure.dto.ts - Modify:
server/apps/api/src/market-overview/structure/market-structure.service.ts - Modify:
server/apps/api/src/market-overview/structure/market-structure.controller.ts - Modify:
server/apps/api/src/market-overview/structure/market-structure.service.test.ts - Modify:
server/apps/api/src/market-overview/tdx/tdx.types.tsandserver/apps/api/src/market-overview/tdx/tdx.mapper.tsonly when Task 1 confirms TDX intraday Amount.
Interfaces:
-
Consumes: validated TDX intraday Amount or the explicitly approved AKTools fallback.
-
Produces:
GET /api/v1/market-overview/turnover-trend?interval=5|15&tradeDate=YYYYMMDDwithTurnoverPoint[]. -
Step 1: Add failing tests for point integrity.
Cover aligned timestamps, 5/15-minute interval validation, cumulative amount calculation, negative values, duplicate timestamps, date mismatch, and close-after-market handling.
- Step 2: Implement trend mapping.
Sort points by time, reject invalid points, calculate cumulativeAmount from accepted interval amounts, and report invalidPointCount through a warning rather than silently repairing data.
- Step 3: Implement API status rules.
Return fresh only when the latest point is within the validated trading-session freshness window; after close, use the latest trading date and expose the final timestamp without calling it delayed solely because the market is closed.
- Step 4: Run server tests and commit.
pnpm --filter @a-share-analysis/server test -- market-structure
git add server/apps/api/src/market-overview
git commit -m "feat(FEAT-MO-005): 增加全市场成交额趋势接口"
git push origin HEAD
Task 6: 生成契约并接入前端数据层
Files:
- Modify:
server/openapi/openapi.json - Modify:
web/src/api/generated/schema.ts - Create:
web/src/api/market-overview/structure.ts - Modify:
web/src/api/market-overview/index.ts - Modify:
web/src/types/market-overview.ts - Modify:
web/src/views/market-overview/useMarketOverview.ts - Test:
web/src/api/market-overview/structure.test.ts - Test:
web/src/views/market-overview/useMarketOverview.test.ts
Interfaces:
-
Consumes: Tasks 3–5 OpenAPI routes and DTOs.
-
Produces: typed
getSectorRankings,getCapitalFlow,getTurnoverTrendmethods and composable states with independent loading/error handling. -
Step 1: Regenerate contracts instead of hand-editing generated files.
pnpm check:contracts
Expected: OpenAPI and generated TypeScript schema match; boundary verification passes.
- Step 2: Add Axios API wrappers.
Each wrapper must call /api/v1/market-overview/... through request.ts, pass only typed query parameters, and never expose the AKTools base URL.
- Step 3: Extend
useMarketOverview.
Add independent sectorRankings, capitalFlow, and turnoverTrend states; include them in isLoading, setLoading, and refresh without coupling their errors to existing sectors or funds states.
- Step 4: Add API and composable tests.
Assert query serialization, typed response assignment, parallel loading, and one-module failure isolation.
- Step 5: Commit the contract/data-layer change.
git add server/openapi web/src/api web/src/types web/src/views/market-overview/useMarketOverview.ts
git commit -m "feat(FEAT-MO-005): 接入市场结构前端数据层"
git push origin HEAD
Task 7: 实现首屏排行与成交额趋势组件
Files:
- Create:
web/src/views/market-overview/components/SectorRankingPanel.vue - Create:
web/src/views/market-overview/components/CapitalFlowPanel.vue - Create:
web/src/views/market-overview/components/TurnoverTrendPanel.vue - Modify:
web/src/views/market-overview/MarketOverviewPage.vue - Modify:
web/src/styles/index.scss - Test:
web/src/views/market-overview/components/MarketStructurePanels.test.ts
Interfaces:
-
Consumes: Task 6 composable states and generated response types.
-
Produces: scan-friendly category tabs, sortable rankings, click-through detail events, and a responsive amount trend chart.
-
Step 1: Write component tests before implementation.
Cover loading, empty, unavailable, partial and delayed states; category switching; rise/fall/inflow/outflow sorting controls; 亿元 labels; and no rendering of unsupported null money values as zero.
- Step 2: Implement ranking panels.
Show a bounded top/bottom list on the overview, provide an accessible “查看全部” command, and emit a detail event only for validated code and category values.
- Step 3: Implement the turnover trend chart.
Use the existing lightweight chart conventions in the repository; draw interval amount and cumulative amount with stable dimensions, visible units and no SVG/network dependency that introduces a new package.
- Step 4: Integrate panels without nesting cards.
Keep the page sections full-width within the existing overview grid, preserve the current index/breadth/short-term panels, and avoid a single card containing multiple framed cards.
- Step 5: Run front-end tests and typecheck.
pnpm --filter @a-share-analysis/web test
pnpm --filter @a-share-analysis/web typecheck
- Step 6: Commit the UI change.
git add web/src/views/market-overview
git commit -m "feat(FEAT-MO-005): 展示市场结构与成交额趋势"
git push origin HEAD
Task 8: 端到端验证、Review 与治理收尾
Files:
- Modify:
docs/features/FEAT-MO-005-market-structure-turnover/test-plan.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/review/code-review.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/review/standards-review.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/development-summary.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/release-notes.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/qa-report.md - Create:
docs/features/FEAT-MO-005-market-structure-turnover/gitnexus/after.md
Interfaces:
-
Consumes: all implementation tasks, probe report and generated contracts.
-
Produces: repeatable verification evidence, two passed Reviews, final GitNexus comparison and a releasable feature record.
-
Step 1: Run focused and full verification.
pnpm lint
pnpm typecheck
pnpm test
pnpm build
pnpm verify:e2e
- Step 2: Verify the HTTP contract and real service states.
During one trading session and once after close, call the three new routes and record status, row count, trade date, last timestamp, warning count and response duration without saving raw payloads.
- Step 3: Run visual verification.
Use Playwright at desktop and 390px mobile widths. Assert the page is nonblank, no page-level horizontal overflow exists, ranking text fits, and the trend chart has nonzero SVG/canvas pixels.
- Step 4: Run GitNexus final detection and refresh.
npx gitnexus analyze
npx gitnexus status
Run gitnexus_detect_changes({ scope: "staged" }), compare affected flows with gitnexus/before.md, and record any unexpected module impact before Review.
- Step 5: Complete both Reviews.
Code Review must inspect source allowlists, status rules, field口径, error isolation, performance and tests. Standards Review must inspect Chinese comments, API folder boundaries, security evidence, performance evidence, documentation traceability and commit/push history. Both documents must end with passed only after issues are resolved.
- Step 6: Finish governance and push the final record.
npm run governance:finish -- FEAT-MO-005 market-structure-turnover
git add docs/features/FEAT-MO-005-market-structure-turnover
git commit -m "docs(FEAT-MO-005): 完成市场结构功能治理收尾"
git push origin HEAD
Expected: feature record is complete, final GitNexus report is saved, and no required task remains undocumented.