migration: establish exact preserved app baseline

This commit is contained in:
leefer
2026-07-30 23:51:48 +08:00
parent 41329943c4
commit 4083dceba3
399 changed files with 129967 additions and 23 deletions
+26
View File
@@ -0,0 +1,26 @@
# Governance Registries
These registries describe the approved product surface during architecture migration.
- `pages.config.json`: primary page identity, navigation group, access expectation, scrolling,
and mobile composition policy.
- `features.config.json`: feature ownership, backend access class, data scope, and availability.
- `api.config.json`: transitional inventory of current routes, generated from `server.py` and
assigned to a feature owner.
- `data-fields.config.json`: canonical data products, provider eligibility, intended use, and
known blocked datasets.
- `data-quality.config.json`: freshness, coverage, units, adjustment, point-in-time, and
fail-closed rules for every canonical data product.
- `jobs.config.json`: background schedules, dependencies, lock keys, retry policy, timeouts,
and output versions.
During Stage 04 these files are contract inputs, not runtime replacements. Backend access in
`api_access.py` remains authoritative until the HTTP governance phase switches it atomically.
Frontend visibility remains a presentation concern and never grants backend access.
Regenerate the transitional API inventory after a route change:
```shell
python tools/build_api_registry.py
python tools/build_api_registry.py --check
```
+524
View File
@@ -0,0 +1,524 @@
{
"schema_version": 1,
"generated_from": "server.py",
"routes": [
{
"method": "DELETE",
"path": "/api/account/birth-profile",
"match": "exact",
"feature": "account",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/account/birth-profile",
"match": "exact",
"feature": "account",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/account/password",
"match": "exact",
"feature": "account",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/account/status",
"match": "exact",
"feature": "account",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/admin/membership",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "POST",
"path": "/api/admin/refresh",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "GET",
"path": "/api/admin/settings",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "POST",
"path": "/api/admin/settings",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "POST",
"path": "/api/admin/settings/test",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "GET",
"path": "/api/alerts",
"match": "exact",
"feature": "alerts",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/alerts",
"match": "exact",
"feature": "alerts",
"access": "authenticated"
},
{
"method": "DELETE",
"path": "/api/alerts/(\\d+)",
"match": "regex",
"feature": "alerts",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/alerts/(\\d+)/read",
"match": "regex",
"feature": "alerts",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/alerts/read-all",
"match": "exact",
"feature": "alerts",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/assistant/chat",
"match": "exact",
"feature": "review",
"access": "member"
},
{
"method": "DELETE",
"path": "/api/assistant/messages",
"match": "exact",
"feature": "review",
"access": "member"
},
{
"method": "GET",
"path": "/api/assistant/messages",
"match": "exact",
"feature": "review",
"access": "member"
},
{
"method": "GET",
"path": "/api/auction",
"match": "exact",
"feature": "auction",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/auth/login",
"match": "exact",
"feature": "auth",
"access": "public"
},
{
"method": "POST",
"path": "/api/auth/logout",
"match": "exact",
"feature": "auth",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/auth/me",
"match": "exact",
"feature": "auth",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/auth/register",
"match": "exact",
"feature": "auth",
"access": "public"
},
{
"method": "POST",
"path": "/api/backfill",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "GET",
"path": "/api/chart/intraday",
"match": "exact",
"feature": "charts",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/dashboard",
"match": "exact",
"feature": "market",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/dragon-tiger",
"match": "exact",
"feature": "dragon_tiger",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/dragon-tiger/profiles",
"match": "exact",
"feature": "dragon_tiger",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/health",
"match": "exact",
"feature": "health",
"access": "public"
},
{
"method": "POST",
"path": "/api/heaven/hexagram",
"match": "exact",
"feature": "heaven",
"access": "member"
},
{
"method": "POST",
"path": "/api/heaven/interpret",
"match": "exact",
"feature": "heaven",
"access": "member"
},
{
"method": "POST",
"path": "/api/heaven/personal",
"match": "exact",
"feature": "heaven",
"access": "member"
},
{
"method": "GET",
"path": "/api/heaven/readings",
"match": "exact",
"feature": "heaven",
"access": "member"
},
{
"method": "DELETE",
"path": "/api/heaven/readings/(\\d+)",
"match": "regex",
"feature": "heaven",
"access": "member"
},
{
"method": "POST",
"path": "/api/heaven/sector-phases",
"match": "exact",
"feature": "heaven",
"access": "admin"
},
{
"method": "DELETE",
"path": "/api/heaven/sector-phases/(.+)",
"match": "regex",
"feature": "heaven",
"access": "admin"
},
{
"method": "GET",
"path": "/api/heaven/setup",
"match": "exact",
"feature": "heaven",
"access": "member"
},
{
"method": "POST",
"path": "/api/mentors/chat",
"match": "exact",
"feature": "mentor",
"access": "member"
},
{
"method": "DELETE",
"path": "/api/mentors/messages",
"match": "exact",
"feature": "mentor",
"access": "member"
},
{
"method": "GET",
"path": "/api/mentors/messages",
"match": "exact",
"feature": "mentor",
"access": "member"
},
{
"method": "POST",
"path": "/api/mentors/preferences",
"match": "exact",
"feature": "mentor",
"access": "member"
},
{
"method": "GET",
"path": "/api/mentors/setup",
"match": "exact",
"feature": "mentor",
"access": "member"
},
{
"method": "GET",
"path": "/api/notes",
"match": "exact",
"feature": "review",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/notes",
"match": "exact",
"feature": "review",
"access": "authenticated"
},
{
"method": "DELETE",
"path": "/api/notes/(\\d+)",
"match": "regex",
"feature": "review",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/popularity",
"match": "exact",
"feature": "popularity",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/realtime-aggregate/health",
"match": "exact",
"feature": "market",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/reasons",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "GET",
"path": "/api/rotation/history",
"match": "exact",
"feature": "rotation",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/rotation/members",
"match": "exact",
"feature": "rotation",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/screener/compile",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "POST",
"path": "/api/screener/run",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "GET",
"path": "/api/screener/setup",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "POST",
"path": "/api/screener/strategies",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "DELETE",
"path": "/api/screener/strategies/(\\d+)",
"match": "regex",
"feature": "screener",
"access": "member"
},
{
"method": "POST",
"path": "/api/screener/sync",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "GET",
"path": "/api/screener/tracking",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "POST",
"path": "/api/screener/tracking",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "DELETE",
"path": "/api/screener/tracking/(\\d+)",
"match": "regex",
"feature": "screener",
"access": "member"
},
{
"method": "POST",
"path": "/api/screener/tracking/refresh",
"match": "exact",
"feature": "screener",
"access": "member"
},
{
"method": "GET",
"path": "/api/search",
"match": "exact",
"feature": "search",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/search/detail",
"match": "exact",
"feature": "search",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/seat-aliases",
"match": "exact",
"feature": "admin",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/seat-aliases",
"match": "exact",
"feature": "admin",
"access": "admin"
},
{
"method": "GET",
"path": "/api/sentiment/history",
"match": "exact",
"feature": "sentiment",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/stock/(\\d{6})",
"match": "regex",
"feature": "market",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/stock/(\\d{6})/preview",
"match": "regex",
"feature": "market",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/themes",
"match": "exact",
"feature": "themes",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/themes/detail",
"match": "exact",
"feature": "themes",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/trades",
"match": "exact",
"feature": "review",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/trades",
"match": "exact",
"feature": "review",
"access": "authenticated"
},
{
"method": "DELETE",
"path": "/api/trades/(\\d+)",
"match": "regex",
"feature": "review",
"access": "authenticated"
},
{
"method": "GET",
"path": "/api/watchlist",
"match": "exact",
"feature": "review",
"access": "authenticated"
},
{
"method": "POST",
"path": "/api/watchlist",
"match": "exact",
"feature": "review",
"access": "authenticated"
},
{
"method": "DELETE",
"path": "/api/watchlist/(\\d{6})",
"match": "regex",
"feature": "review",
"access": "authenticated"
}
]
}
+31
View File
@@ -0,0 +1,31 @@
{
"schema_version": 1,
"providers": {
"tushare": {"class": "licensed", "calculation_allowed": true},
"ifind": {"class": "licensed", "calculation_allowed": true},
"eastmoney": {"class": "public_web", "calculation_allowed": false},
"tencent": {"class": "public_web", "calculation_allowed": false},
"local": {"class": "derived", "calculation_allowed": true},
"unresolved": {"class": "missing", "calculation_allowed": false}
},
"datasets": [
{"id": "market.trade_calendar", "entity": "market", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["trade_date", "is_open", "previous_open_date"]},
{"id": "market.stock_master", "entity": "stock", "frequency": "event", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["ts_code", "name", "industry", "market", "list_date"]},
{"id": "market.stock_daily", "entity": "stock", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "adjustment": "current-unadjusted", "fields": ["open", "high", "low", "close", "pct_chg", "volume_shares", "amount_yuan"]},
{"id": "market.daily_valuation", "entity": "stock", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["turnover_rate_pct", "volume_ratio", "total_mv_10k_yuan", "circ_mv_10k_yuan", "pe_ttm", "pb", "ps_ttm", "dv_ttm_pct"]},
{"id": "market.fundamentals", "entity": "stock", "frequency": "quarterly", "primary": "tushare", "fallbacks": [], "usage": "calculation", "point_in_time": "announcement_date", "fields": ["roe_pct", "roa_pct", "roic_pct", "gross_margin_pct", "net_profit_yoy_pct", "revenue_yoy_pct", "operating_cashflow_quality"]},
{"id": "market.moneyflow", "entity": "stock", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["small_net_yuan", "medium_net_yuan", "large_net_yuan", "extra_large_net_yuan", "total_net_yuan"]},
{"id": "market.industry_sw", "entity": "industry", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["industry_code", "industry_name", "level", "members", "pct_chg", "turnover_rate_pct"]},
{"id": "market.limit_events", "entity": "stock", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["limit_type", "first_time", "last_time", "open_times", "limit_reason", "consecutive_boards"]},
{"id": "market.auction_close", "entity": "stock", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["price", "volume_shares", "amount_yuan", "pre_close", "turnover_rate_pct", "volume_ratio", "float_share"]},
{"id": "market.auction_dynamic", "entity": "stock", "frequency": "snapshot", "primary": "ifind", "fallbacks": [], "usage": "calculation", "freshness_seconds": 10, "fields": ["quote_time", "price", "pct_chg", "volume_shares", "amount_yuan"]},
{"id": "market.popularity", "entity": "stock", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["ths_rank", "dc_rank", "rank_change", "dual_source"]},
{"id": "market.dragon_tiger", "entity": "stock", "frequency": "daily", "primary": "tushare", "fallbacks": [], "usage": "calculation", "fields": ["seat_name", "buy_yuan", "sell_yuan", "net_buy_yuan", "side", "reason"]},
{"id": "chart.stock_daily", "entity": "stock", "frequency": "daily", "primary": "ifind", "fallbacks": [], "usage": "display", "adjustment": "forward1", "fields": ["open", "high", "low", "close", "volume_shares", "amount_yuan"]},
{"id": "chart.intraday", "entity": "stock_or_index_or_board", "frequency": "minute", "primary": "ifind", "fallbacks": ["eastmoney"], "usage": "display", "fields": ["quote_time", "open", "high", "low", "close", "avg_price", "volume_shares", "amount_yuan"]},
{"id": "observation.realtime_indices", "entity": "index", "frequency": "snapshot", "primary": "eastmoney", "fallbacks": ["tencent"], "usage": "display", "fields": ["quote_time", "price", "pct_chg", "amount_yuan"]},
{"id": "derived.sentiment", "entity": "market", "frequency": "daily", "primary": "local", "fallbacks": [], "usage": "calculation", "fields": ["temperature", "stage", "direction", "confidence", "component_scores"]},
{"id": "research.consensus", "entity": "stock", "frequency": "event", "primary": "unresolved", "fallbacks": [], "usage": "blocked", "fields": ["consensus_profit", "forecast_revision", "rating_change", "target_price", "report_count"]},
{"id": "market.level2", "entity": "stock", "frequency": "tick", "primary": "unresolved", "fallbacks": [], "usage": "blocked", "fields": ["order_queue", "unmatched_orders", "tick_trades", "tick_orders", "open_board_depth"]}
]
}
+45
View File
@@ -0,0 +1,45 @@
{
"schema_version": 1,
"timezone": "Asia/Shanghai",
"defaults": {
"calculation": {"missing_policy": "fail_closed", "provenance_required": true, "future_tolerance_seconds": 5},
"display": {"missing_policy": "unavailable", "provenance_required": true, "future_tolerance_seconds": 5}
},
"unit_profiles": {
"none": {},
"calendar": {"trade_date": "date", "is_open": "boolean", "previous_open_date": "date"},
"master": {"list_date": "date"},
"daily_ohlcv": {"open": "CNY/share", "high": "CNY/share", "low": "CNY/share", "close": "CNY/share", "pct_chg": "percent", "volume_shares": "share", "amount_yuan": "CNY"},
"valuation": {"turnover_rate_pct": "percent", "volume_ratio": "ratio", "total_mv_10k_yuan": "10k CNY", "circ_mv_10k_yuan": "10k CNY", "pe_ttm": "ratio", "pb": "ratio", "ps_ttm": "ratio", "dv_ttm_pct": "percent"},
"fundamental": {"roe_pct": "percent", "roa_pct": "percent", "roic_pct": "percent", "gross_margin_pct": "percent", "net_profit_yoy_pct": "percent", "revenue_yoy_pct": "percent", "operating_cashflow_quality": "ratio"},
"moneyflow": {"small_net_yuan": "CNY", "medium_net_yuan": "CNY", "large_net_yuan": "CNY", "extra_large_net_yuan": "CNY", "total_net_yuan": "CNY"},
"industry": {"pct_chg": "percent", "turnover_rate_pct": "percent"},
"limit_event": {"first_time": "datetime", "last_time": "datetime", "open_times": "count", "consecutive_boards": "count"},
"auction": {"price": "CNY/share", "volume_shares": "share", "amount_yuan": "CNY", "pre_close": "CNY/share", "turnover_rate_pct": "percent", "volume_ratio": "ratio", "float_share": "share"},
"popularity": {"ths_rank": "rank", "dc_rank": "rank", "rank_change": "rank", "dual_source": "boolean"},
"dragon_tiger": {"buy_yuan": "CNY", "sell_yuan": "CNY", "net_buy_yuan": "CNY"},
"intraday": {"quote_time": "datetime", "open": "CNY/share", "high": "CNY/share", "low": "CNY/share", "close": "CNY/share", "avg_price": "CNY/share", "volume_shares": "share", "amount_yuan": "CNY"},
"realtime_index": {"quote_time": "datetime", "price": "CNY", "pct_chg": "percent", "amount_yuan": "CNY"},
"sentiment": {"temperature": "score", "confidence": "percent"}
},
"datasets": {
"market.trade_calendar": {"unit_profile": "calendar", "min_coverage_ratio": 1.0},
"market.stock_master": {"unit_profile": "master", "min_coverage_ratio": 0.98},
"market.stock_daily": {"unit_profile": "daily_ohlcv", "min_coverage_ratio": 0.98, "adjustment": "current-unadjusted"},
"market.daily_valuation": {"unit_profile": "valuation", "min_coverage_ratio": 0.95},
"market.fundamentals": {"unit_profile": "fundamental", "min_coverage_ratio": 0.90, "point_in_time": "announcement_date"},
"market.moneyflow": {"unit_profile": "moneyflow", "min_coverage_ratio": 0.90},
"market.industry_sw": {"unit_profile": "industry", "min_coverage_ratio": 0.95},
"market.limit_events": {"unit_profile": "limit_event", "min_coverage_ratio": 1.0},
"market.auction_close": {"unit_profile": "auction", "min_coverage_ratio": 0.90},
"market.auction_dynamic": {"unit_profile": "auction", "min_coverage_ratio": 0.80, "freshness_seconds": 10},
"market.popularity": {"unit_profile": "popularity", "min_coverage_ratio": 0.95},
"market.dragon_tiger": {"unit_profile": "dragon_tiger", "min_coverage_ratio": 0.95},
"chart.stock_daily": {"unit_profile": "daily_ohlcv", "min_coverage_ratio": 1.0, "adjustment": "forward1"},
"chart.intraday": {"unit_profile": "intraday", "min_coverage_ratio": 1.0, "freshness_seconds": 30},
"observation.realtime_indices": {"unit_profile": "realtime_index", "min_coverage_ratio": 1.0, "freshness_seconds": 90},
"derived.sentiment": {"unit_profile": "sentiment", "min_coverage_ratio": 1.0},
"research.consensus": {"unit_profile": "none", "min_coverage_ratio": 0.0, "blocked": true},
"market.level2": {"unit_profile": "none", "min_coverage_ratio": 0.0, "blocked": true}
}
}
+26
View File
@@ -0,0 +1,26 @@
{
"schema_version": 1,
"roles": ["public", "authenticated", "member", "admin"],
"features": [
{"id": "health", "title": "健康检查", "access": "public", "data_scope": "system", "enabled": true},
{"id": "auth", "title": "账户认证", "access": "public", "data_scope": "user", "enabled": true},
{"id": "account", "title": "账户设置", "access": "authenticated", "data_scope": "user", "enabled": true},
{"id": "admin", "title": "系统管理", "access": "admin", "data_scope": "system", "enabled": true},
{"id": "market", "title": "市场总览", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "sentiment", "title": "情绪周期", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "pools", "title": "市场股池", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "ladder", "title": "市场天梯", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "rotation", "title": "板块轮动", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "auction", "title": "集合竞价", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "themes", "title": "题材库", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "popularity", "title": "人气热榜", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "dragon_tiger", "title": "龙虎榜", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "search", "title": "全局搜索", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "charts", "title": "行情图表", "access": "authenticated", "data_scope": "shared", "enabled": true},
{"id": "screener", "title": "智能选股", "access": "member", "data_scope": "mixed", "daily_llm_quota": true, "enabled": true},
{"id": "mentor", "title": "问师", "access": "member", "data_scope": "user", "daily_llm_quota": true, "enabled": true},
{"id": "heaven", "title": "问天", "access": "member", "data_scope": "user", "daily_llm_quota": true, "enabled": true},
{"id": "review", "title": "我的复盘", "access": "authenticated", "data_scope": "user", "enabled": true},
{"id": "alerts", "title": "提醒中心", "access": "authenticated", "data_scope": "user", "enabled": true}
]
}
+35
View File
@@ -0,0 +1,35 @@
{
"schema_version": 1,
"jobs": [
{
"id": "market.refresh",
"schedule": "realtime polling or administrator request",
"input_date_policy": "requested trade date",
"dependencies": ["market provider", "database"],
"lock_key": "market-refresh",
"timeout_seconds": 120,
"max_attempts": 1,
"output_version": "dashboard-v1"
},
{
"id": "screener.automatic",
"schedule": "trading day after 15:10 Asia/Shanghai",
"input_date_policy": "current completed trade date",
"dependencies": ["market.refresh", "factor data", "database"],
"lock_key": "automatic-screener",
"timeout_seconds": 900,
"max_attempts": 1,
"output_version": "screener-library-v8"
},
{
"id": "market.ifind-event-enrichment",
"schedule": "on demand after market close",
"input_date_policy": "completed trade date",
"dependencies": ["ifind", "database"],
"lock_key": "ifind-event-enrichment",
"timeout_seconds": 180,
"max_attempts": 1,
"output_version": "ifind-event-v1"
}
]
}
+21
View File
@@ -0,0 +1,21 @@
{
"schema_version": 1,
"pages": [
{"id": "sentimentCycleView", "title": "情绪周期", "feature": "sentiment", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": true},
{"id": "limitPool", "title": "涨停池", "feature": "pools", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "brokenView", "title": "炸板池", "feature": "pools", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "downView", "title": "跌停板", "feature": "pools", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "yesterdayView", "title": "昨日涨停", "feature": "pools", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "performanceView", "title": "涨停表现", "feature": "pools", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "ladderView", "title": "市场天梯", "feature": "ladder", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "rotationView", "title": "板块轮动", "feature": "rotation", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "auctionView", "title": "集合竞价", "feature": "auction", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "themeLibraryView", "title": "题材库", "feature": "themes", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "popularityView", "title": "人气热榜", "feature": "popularity", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "dragonView", "title": "龙虎榜", "feature": "dragon_tiger", "group": "market", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "screenerView", "title": "智能选股", "feature": "screener", "group": "intelligence", "access": "member", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "mentorView", "title": "问师", "feature": "mentor", "group": "intelligence", "access": "member", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "heavenView", "title": "问天", "feature": "heaven", "group": "intelligence", "access": "member", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false},
{"id": "reviewWorkspaceView", "title": "我的复盘", "feature": "review", "group": "personal", "access": "authenticated", "desktop_scroll": "page", "mobile_layout": "dedicated", "default": false}
]
}