refactor(selection): replace concept sector filter with sub-industry

- pin the selection sector vocabulary to industry: the /sectors endpoint
  no longer accepts sector_type, and the port, adapter, and use case all
  resolve counts and member codes with sector_type="industry"
- relabel the results filter to 细分行业 and drop concept-type plumbing
  from the frontend API, query keys, and types
- show only 细分行业 in the signal detail panel; remove the concept-board
  chips and keep the snapshot-date tooltip on the industry line
- update backend and frontend tests to the industry vocabulary and record
  the revised scope in the task PRD
This commit is contained in:
yuxuanhui
2026-09-05 21:04:00 +08:00
parent ade1713e86
commit 68282f5d46
14 changed files with 82 additions and 179 deletions
+3 -29
View File
@@ -59,7 +59,6 @@ class FakeSelectionService:
self.executed = False
self.mode = "ok"
self.last_query: SelectionResultQuery | None = None
self.sector_type_requested: str | None = None
def prepare(
self,
@@ -117,16 +116,13 @@ class FakeSelectionService:
self,
strategy: str,
target_trade_date: date | None = None,
*,
sector_type: str = "concept",
) -> SelectionSectorAggregates | None:
self.sector_type_requested = sector_type
if self.run is None:
return None
return SelectionSectorAggregates(
run=self.run,
snapshot_trade_date=self.run.target_trade_date,
sector_type=sector_type,
sector_type="industry",
sectors=self.sectors,
)
@@ -493,7 +489,7 @@ def test_sectors_returns_aggregated_counts_desc() -> None:
"run_id": "run-http",
"status": "success",
"snapshot_trade_date": "2026-08-08",
"sector_type": "concept",
"sector_type": "industry",
"sectors": [
{"sector_code": "BK0001.DC", "sector_name": "机器人", "stock_count": 3},
{"sector_code": "BK0003.DC", "sector_name": "数字经济", "stock_count": 2},
@@ -501,19 +497,6 @@ def test_sectors_returns_aggregated_counts_desc() -> None:
}
def test_sectors_forwards_sector_type() -> None:
service = FakeSelectionService(_run("run-http", "success"))
response = _client(service).get(
"/api/v1/selection/sectors",
params={"sector_type": "industry"},
)
assert response.status_code == 200
assert service.sector_type_requested == "industry"
assert response.json()["sector_type"] == "industry"
def test_sectors_without_run_returns_no_data() -> None:
response = _client(FakeSelectionService()).get("/api/v1/selection/sectors")
@@ -524,20 +507,11 @@ def test_sectors_without_run_returns_no_data() -> None:
"run_id": None,
"status": "no_data",
"snapshot_trade_date": None,
"sector_type": "concept",
"sector_type": "industry",
"sectors": [],
}
def test_sectors_rejects_unknown_sector_type() -> None:
response = _client(FakeSelectionService()).get(
"/api/v1/selection/sectors",
params={"sector_type": "macro"},
)
assert response.status_code == 422
def test_chart_returns_bounded_qfq_contract() -> None:
chart_service = FakeChartService()