@@ -0,0 +1,44 @@
# 选股页面迭代:布局重构与细分行业筛选
## 需求
1. 选股页面从左右布局改为「上搜索栏 + 左列表 / 右详情」三段式布局。
2. 搜索模块增加细分行业筛选:下拉选项为当次策略结果的细分行业聚合,选项旁展示数量,按数量倒序。
3. 选股模块不展示「板块」(概念板块):列表筛选与详情页均去掉;详情页「行业」口径改称「细分行业」。(2026-09-05 修订,原口径为概念板块)
## 关键决策
- 板块口径:细分行业(sector_type=industry,即东财行业快照),selection 上下文固定为 industry——HTTP `/sectors` 不再接受 sector_type 参数,端口/适配器方法签名不再携带 sector_type,适配器固定传 `SectorType.INDUSTRY` ;「细分行业」仍是 sector 词汇的一种,内部参数名保持 `sector` 不变。
- 详情面板 membership 消费面收窄到 industries:前端 `sector-radar.api.ts` / 类型不再解析 concepts 字段(后端 `/sector-radar/stocks/{ts_code}/membership` 契约仍返回 concepts,供板块雷达等其余消费方使用)。
- 单选下拉;排序按 stock_count 倒序(后端保证),名称升序 tie-break。
- 行业数据不在 selection 表中,按 ADR 0001 通过端口委托 sector_radar 读服务(不跨上下文 join SQL)。
## 实现
后端(zhixing-server):
- sector_radar: `domain/persistence.py` 新增 `SectorCountEntry` + 2 个协议方法;`infrastructure/postgres.py` / `infrastructure/memory.py` 实现 `load_sector_counts` / `load_sector_member_codes` ; `application/read.py` 新增 `sector_counts` / `sector_member_codes` (先解析 last-good publication)。
- selection: `domain/runs.py` 新增 `SelectionSectorReader` 端口、`SelectionSectorCount` / `SelectionSectorMembership` / `SelectionRunIdentity` , `SelectionResultQuery.sector` ; `application/run.py` 新增 `list_sector_counts` (固定 industry),`get_run` /`get_latest` 经 identity → 成员代码 → `sector_stock_codes` 过滤;`infrastructure/postgres_runs.py` `_stock_filter` 支持 `ts_code = ANY(...)` / FALSE; `infrastructure/sector_membership.py` 桥接适配器;`presentation/http.py` 新增 `GET /sectors` , results/runs 增加 `sector` 参数。
前端(zhixing-web):
- `selection.types.ts` / `selection.api.ts` / `selection.query.ts` : `SelectionSectors` ( sector_type 收窄为 "industry")、`getSelectionResultSectors` 、`useSelectionResultSectors` (不传 sector_type),query key 加 sector,结果失效同时失效 sectors。
- `route-tree.tsx` : selection 路由 search 增加 `sector` 。
- `selection-results-page.tsx` :结果查询带 sector,页面调用 sectors hook 并下传 workbench;切策略重置 sector。
- `selection-results-workbench.tsx` :布局重构为上搜索栏 + 下方 320px 列表/详情两栏;细分行业下拉(全部细分行业 + 聚合选项带数量徽标);聚合加载后自动清掉失效 sector。
- `signal-detail-panel.tsx` :展示「细分行业:…」(title 提示成分快照日期),不再展示概念板块 chips。
## 测试
- 后端:`test_read.py` +8、`test_sector_filter.py` 新建 9 个(口径 industry)、`test_selection_http.py` +3(不再有 sector_type 转发/422 用例)。
- 前端:页面测试新增「filters by sub-industry and shows per-industry counts」;详情面板测试改为细分行业断言并删除概念 chips 用例。
## 验收
- [x] 页面布局为上搜索栏 + 左列表右详情(移动端纵向堆叠 搜索→列表→详情)
- [x] 细分行业下拉选项为当次策略结果的细分行业聚合,选项旁展示数量,按数量倒序
- [x] 选择细分行业后结果列表服务端过滤,`筛选结果 N 只` 反映叠加计数
- [x] 详情面板只展示细分行业,不展示概念板块
- [x] 后端 ruff/pyright/pytest 与前端 lint/typecheck/test/build 门禁通过(遗留项均为基线原有)
## 遗留(均为基线原有,非本次引入)
- 后端 pyright 16 个错误(chart.py/gold_brick.py pandas 相关、test_run.py 旧 fake 类型);前端 4 个执行状态抽屉测试失败;前端 format:check 有基线未格式化文件(.playwright-cli、sector-radar 部分文件;signal-detail-panel.tsx 已随本次格式化移除)。