refactor: establish standalone application boundary
This commit is contained in:
@@ -74,6 +74,14 @@ def css_layers(html: str) -> list[str]:
|
||||
return re.findall(r'<link[^>]+rel="stylesheet"[^>]+href="([^"]+)"', html)
|
||||
|
||||
|
||||
def frontend_fragments(registry: str) -> list[str]:
|
||||
return re.findall(
|
||||
r'^\s*\["[^"]+", "(/pages/[^"]+/page\.html(?:\?[^"]*)?)", \[',
|
||||
registry,
|
||||
re.MULTILINE,
|
||||
)
|
||||
|
||||
|
||||
def source_metrics(path: Path) -> dict[str, int]:
|
||||
text = path.read_text(encoding="utf-8")
|
||||
return {
|
||||
@@ -85,22 +93,73 @@ def source_metrics(path: Path) -> dict[str, int]:
|
||||
def code_hotspots() -> list[dict[str, Any]]:
|
||||
candidates = [
|
||||
"backend/application.py",
|
||||
"backend/http/dispatch.py",
|
||||
"backend/features/system/service.py",
|
||||
"backend/features/accounts/application.py",
|
||||
"backend/jobs/service.py",
|
||||
"database.py",
|
||||
"backend/features/screener/engine.py",
|
||||
"backend/features/screener/catalog.py",
|
||||
"backend/features/screener/data_sync.py",
|
||||
"backend/features/screener/indicators.py",
|
||||
"backend/features/screener/factors.py",
|
||||
"backend/features/screener/formula.py",
|
||||
"backend/features/screener/regime.py",
|
||||
"backend/features/screener/selection.py",
|
||||
"backend/features/screener/backtest.py",
|
||||
"backend/features/market/insights.py",
|
||||
"backend/features/market/insights_context.py",
|
||||
"backend/features/market/insights_auction_scoring.py",
|
||||
"backend/features/market/insights_auction_data.py",
|
||||
"backend/features/market/insights_auction.py",
|
||||
"backend/features/market/insights_themes.py",
|
||||
"backend/features/market/insights_popularity.py",
|
||||
"backend/data/providers/tushare_client.py",
|
||||
"backend/data/providers/tushare_transport.py",
|
||||
"backend/data/providers/tushare_helpers.py",
|
||||
"backend/data/providers/tushare_dashboard.py",
|
||||
"backend/data/providers/tushare_indices.py",
|
||||
"backend/data/providers/tushare_industries.py",
|
||||
"backend/data/providers/tushare_sectors.py",
|
||||
"backend/data/providers/tushare_dragon_tiger.py",
|
||||
"backend/data/providers/tushare_stocks.py",
|
||||
"backend/data/providers/tushare_daily.py",
|
||||
"backend/features/heaven/service.py",
|
||||
"backend/features/heaven/manual.py",
|
||||
"backend/features/heaven/trend.py",
|
||||
"backend/features/heaven/market_context.py",
|
||||
"backend/features/heaven/readings.py",
|
||||
"backend/features/heaven/engine.py",
|
||||
"frontend/index.html",
|
||||
"frontend/bootstrap.js",
|
||||
"frontend/pages.config.js",
|
||||
"frontend/app.js",
|
||||
"frontend/styles/styles.css",
|
||||
"frontend/styles/redesign-v2.css",
|
||||
"frontend/styles/renovation.css",
|
||||
"frontend/styles/theme.css",
|
||||
"frontend/pages/heaven/page.css",
|
||||
"frontend/shared/context.js",
|
||||
"frontend/shared/application.js",
|
||||
"frontend/shared/feedback.js",
|
||||
"frontend/shared/dashboard.js",
|
||||
"frontend/shared/session.js",
|
||||
"frontend/shared/admin.js",
|
||||
"frontend/shared/theme.js",
|
||||
"frontend/shared/table.js",
|
||||
"frontend/pages/heaven/foundation.css",
|
||||
"frontend/pages/screener/foundation.css",
|
||||
"frontend/pages/auction/foundation.css",
|
||||
"frontend/shared/shell.css",
|
||||
"frontend/pages/heaven/page.js",
|
||||
"frontend/pages/market/runtime.js",
|
||||
]
|
||||
candidates.extend(
|
||||
relative(path)
|
||||
for path in sorted((ROOT / "frontend" / "pages" / "market").glob("*.js"))
|
||||
)
|
||||
candidates.extend(
|
||||
relative(path)
|
||||
for path in sorted((ROOT / "backend" / "features").glob("*/routes.py"))
|
||||
)
|
||||
candidates.extend(
|
||||
relative(path)
|
||||
for path in sorted((ROOT / "frontend" / "pages").glob("*/page.html"))
|
||||
)
|
||||
rows = []
|
||||
for name in candidates:
|
||||
path = ROOT / name
|
||||
@@ -112,7 +171,14 @@ def code_hotspots() -> list[dict[str, Any]]:
|
||||
|
||||
def build() -> dict[str, Any]:
|
||||
html = source("frontend/index.html")
|
||||
server = source("backend/application.py")
|
||||
page_registry = source("frontend/pages.config.js")
|
||||
fragments = frontend_fragments(page_registry)
|
||||
http_sources = [source("backend/http/dispatch.py")]
|
||||
http_sources.extend(
|
||||
path.read_text(encoding="utf-8")
|
||||
for path in sorted((ROOT / "backend" / "features").glob("*/routes.py"))
|
||||
)
|
||||
server = "\n".join(http_sources)
|
||||
database_sources = [source("database.py")]
|
||||
database_sources.extend(
|
||||
path.read_text(encoding="utf-8")
|
||||
@@ -140,27 +206,63 @@ def build() -> dict[str, Any]:
|
||||
"api_prefixes": len(api["prefixes"]),
|
||||
"api_patterns": len(api["patterns"]),
|
||||
"database_tables": len(tables),
|
||||
"frontend_page_fragments": len(fragments),
|
||||
},
|
||||
"pages": pages,
|
||||
"api": api,
|
||||
"database_tables": tables,
|
||||
"background_job_methods": python_functions(
|
||||
"backend/application.py",
|
||||
"backend/jobs/service.py",
|
||||
("_background", "_run_background", "_schedule_", "run_automatic"),
|
||||
),
|
||||
"external_data_adapters": [
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_client.py", "runtime_role": "primary deterministic market data"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_client.py", "runtime_role": "stable client facade for primary deterministic market data"},
|
||||
{"provider": "ifind", "path": "backend/data/providers/ifind_client.py", "runtime_role": "realtime, charts, snapshots, enrichment"},
|
||||
{"provider": "eastmoney", "path": "backend/features/market/charts.py", "runtime_role": "display chart fallback"},
|
||||
{"provider": "eastmoney", "path": "backend/data/realtime.py", "runtime_role": "isolated realtime observation"},
|
||||
{"provider": "tencent", "path": "backend/data/realtime.py", "runtime_role": "index observation fallback"},
|
||||
],
|
||||
"provider_domains": [
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_transport.py", "responsibility": "HTTP transport and provider errors"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_dashboard.py", "responsibility": "market overview and realtime breadth"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_indices.py", "responsibility": "market indices"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_industries.py", "responsibility": "Shenwan membership and industry snapshots"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_sectors.py", "responsibility": "generic sector snapshots"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_dragon_tiger.py", "responsibility": "hot-money directory and dragon-tiger activity"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_stocks.py", "responsibility": "stock detail and intraday bars"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_daily.py", "responsibility": "trading calendar, daily bars, and limit lists"},
|
||||
{"provider": "tushare", "path": "backend/data/providers/tushare_helpers.py", "responsibility": "shared deterministic normalization helpers"},
|
||||
],
|
||||
"provider_construction": [
|
||||
{"client": "TushareClient", "owner": "backend/data/providers/tushare.py", "compatibility_fallback": "backend/features/market/service.py"},
|
||||
{"client": "IfindHttpClient", "owner": "backend/data/gateway.py"},
|
||||
{"client": "MarketChartClient", "owner": "backend/data/gateway.py"},
|
||||
{"client": "WebRealtimeAggregator", "owner": "backend/data/gateway.py"},
|
||||
],
|
||||
"heaven_service_owners": {
|
||||
"facade": "backend/features/heaven/service.py",
|
||||
"manual_validation_and_safety": "backend/features/heaven/manual.py",
|
||||
"trend_orchestration_and_quality": "backend/features/heaven/trend.py",
|
||||
"market_context": "backend/features/heaven/market_context.py",
|
||||
"readings_and_interpretation": "backend/features/heaven/readings.py",
|
||||
},
|
||||
"market_insight_owners": {
|
||||
"facade": "backend/features/market/insights.py",
|
||||
"shared_context": "backend/features/market/insights_context.py",
|
||||
"auction_scoring": "backend/features/market/insights_auction_scoring.py",
|
||||
"auction_data": "backend/features/market/insights_auction_data.py",
|
||||
"auction_orchestration": "backend/features/market/insights_auction.py",
|
||||
"themes": "backend/features/market/insights_themes.py",
|
||||
"popularity": "backend/features/market/insights_popularity.py",
|
||||
},
|
||||
"application_owners": {
|
||||
"composition_root": "backend/application.py",
|
||||
"http_dispatch": "backend/http/dispatch.py",
|
||||
"system_service": "backend/features/system/service.py",
|
||||
"account_bridge": "backend/features/accounts/application.py",
|
||||
"job_lifecycle": "backend/jobs/service.py",
|
||||
"feature_routes": "backend/features/*/routes.py",
|
||||
},
|
||||
"numeric_normalization": [
|
||||
{"function": "finite_number", "path": "backend/data/numbers.py"},
|
||||
{"function": "non_nan_number", "path": "backend/data/numbers.py"},
|
||||
@@ -184,6 +286,32 @@ def build() -> dict[str, Any]:
|
||||
{"function": "send_ndjson_stream", "path": "backend/http/handler.py"},
|
||||
],
|
||||
"css_layers": css_layers(html),
|
||||
"frontend_composition": {
|
||||
"shell": "frontend/index.html",
|
||||
"bootstrap": "frontend/bootstrap.js",
|
||||
"registry": "frontend/pages.config.js",
|
||||
"startup": "frontend/app.js",
|
||||
"runtime_owners": {
|
||||
"context": "frontend/shared/context.js",
|
||||
"application": "frontend/shared/application.js",
|
||||
"feedback": "frontend/shared/feedback.js",
|
||||
"dashboard": "frontend/shared/dashboard.js",
|
||||
"session": "frontend/shared/session.js",
|
||||
"admin": "frontend/shared/admin.js",
|
||||
"theme": "frontend/shared/theme.js",
|
||||
"table": "frontend/shared/table.js",
|
||||
},
|
||||
"market_runtime_owners": {
|
||||
"breadth": "frontend/pages/market/breadth.js",
|
||||
"charts": "frontend/pages/market/charts.js",
|
||||
"entity_detail": "frontend/pages/market/entity-detail.js",
|
||||
"stock_detail": "frontend/pages/market/stock-detail.js",
|
||||
"preview": "frontend/pages/market/preview.js",
|
||||
"search": "frontend/pages/market/search.js",
|
||||
"bindings": "frontend/pages/market/bindings.js",
|
||||
},
|
||||
"fragments": [path.split("?", 1)[0] for path in fragments],
|
||||
},
|
||||
"code_hotspots": code_hotspots(),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user