Clarify scan terminal service boundaries

The scan terminal service had accumulated cache, payload, filtering, AI prompt, AI merge, METAR gate, ranking, and city-row construction details in one file. This splits those stable responsibilities into focused modules while preserving the endpoint payload shape and existing behavior.

Constraint: User-visible behavior and release version must remain unchanged for this internal refactor

Rejected: Rewrite the terminal scan flow around a new abstraction | too risky while production behavior is being stabilized

Confidence: high

Scope-risk: moderate

Directive: Keep scan_terminal_service.py as orchestration; add detailed rule changes to the focused modules instead of re-growing the service file

Tested: py_compile for extracted modules; ruff check .; pytest tests/test_scan_terminal_modules.py tests/test_web_observability.py; full pytest; npm run test:business; npm run build; git diff --cached --check
This commit is contained in:
2569718930@qq.com
2026-04-28 17:13:45 +08:00
parent b122e7cbae
commit 20516000a2
11 changed files with 1696 additions and 1309 deletions
+6 -5
View File
@@ -3,8 +3,9 @@ from fastapi.testclient import TestClient
from web.app import app
import web.routes as routes
import web.scan_terminal_cache as scan_terminal_cache
import web.scan_terminal_service as scan_terminal_service
from web.scan_terminal_service import _scan_terminal_cache_key
from web.scan_terminal_cache import scan_terminal_cache_key
from src.database.db_manager import DBManager
from src.database.runtime_state import TruthRecordRepository, TrainingFeatureRecordRepository
@@ -737,7 +738,7 @@ def test_ops_truth_history_returns_filtered_rows(monkeypatch):
def test_scan_terminal_service_returns_stale_payload_after_failed_refresh(monkeypatch):
filters = {"scan_mode": "tradable", "limit": 5}
normalized_filters = scan_terminal_service._normalize_scan_terminal_filters(filters)
scan_terminal_service._SCAN_TERMINAL_CACHE.clear()
scan_terminal_cache._SCAN_TERMINAL_CACHE.clear()
monkeypatch.setattr(
scan_terminal_service,
@@ -778,7 +779,7 @@ def test_scan_terminal_service_returns_stale_payload_after_failed_refresh(monkey
def test_scan_terminal_service_returns_failed_without_success_snapshot(monkeypatch):
filters = {"scan_mode": "tradable", "limit": 5}
scan_terminal_service._SCAN_TERMINAL_CACHE.clear()
scan_terminal_cache._SCAN_TERMINAL_CACHE.clear()
def _explode(*_args, **_kwargs):
raise RuntimeError("network down")
@@ -837,14 +838,14 @@ def test_scan_terminal_endpoint_forwards_filters(monkeypatch):
def test_scan_terminal_cache_key_includes_filter_dimensions():
first = _scan_terminal_cache_key(
first = scan_terminal_cache_key(
{
"scan_mode": "tradable",
"time_range": "today",
"limit": 25,
}
)
second = _scan_terminal_cache_key(
second = scan_terminal_cache_key(
{
"scan_mode": "trend",
"time_range": "week",