Files
xiaobai-review/backend/application.py
T
施工员andmultica-agent 3eaa36a8d5 feat(HEL-560): 数据中枢接管数据源/模型池/会员,注册改一次性邀请码
主站
- 新增 m0006 invite_codes 迁移;注册强制邀请码(首个管理员除外),消码与建号
  同一事务,并发提交只有一个能成功
- 新增 /api/hub-admin/* 服务端点(共享 HUB_ADMIN_TOKEN,先于鉴权校验),供数据
  中枢桥接读写会话/密码/模型池/会员/邀请码,并提供供应商模型列表拉取
- 前端:注册表单加邀请码(桌面 login、index.html、移动端);「系统管理」改为
  「数据中枢」入口指向 8766,原模型池与会员管理分区移除,仅留「行情管理」;
  随之清理陈旧 CSS

数据中枢
- 取消独立账号:删除 hub_admin/hub_sessions 与登录、改密、锁定逻辑,改为校验
  主站 xiaobai_session,仅管理员可进,CSRF 由会话派生,危险操作二次确认走主站
- 控制台新增数据源凭证可编辑区(原有内容一项不删)、供应商制模型池(自动拉取
  /models,失败退回卡内手动录入)、会员管理与邀请码页
- 日夜双主题:颜色收敛为同名 token 换值,SVG 改用 inline style 以吃到变量

自测
- 主站 verify_baseline 通过(498 项);数据中枢 235 项通过
- tools/verify_datahub_console.py 端到端跑通两服务真实对话;
  tools/verify_datahub_console_ui.py 浏览器跑通门禁/凭证/模型池/会员/主题/1030 窄屏

Co-authored-by: multica-agent <github@multica.ai>
2026-09-16 11:44:09 +08:00

165 lines
6.3 KiB
Python

from __future__ import annotations
import threading
from datetime import datetime
from http.server import BaseHTTPRequestHandler
from api_access import ROUTES
from backend.bootstrap.config import DATA_DIR, MENTOR_SKILLS_DIR, PRIVATE_MENTOR_SKILLS_DIR
from backend.bootstrap.container import build_application_container
from backend.bootstrap.settings import load_runtime_settings
from backend.data.providers.tushare_client import TushareError
from backend.features.accounts.application import AccountApplicationMixin
from backend.features.accounts.http import AccountHttpMixin
from backend.features.accounts.routes import AccountRoutesMixin
from backend.features.accounts.security import SecretVault
from backend.features.accounts.service import AccountService
from backend.features.alerts import AlertHttpMixin, AlertServiceMixin
from backend.features.alerts.routes import AlertRoutesMixin
from backend.features.auction import AuctionServiceMixin
from backend.features.auction.routes import AuctionRoutesMixin
from backend.features.dragon_tiger import DragonTigerServiceMixin
from backend.features.dragon_tiger.routes import DragonTigerRoutesMixin
from backend.features.heaven import HeavenHttpMixin, HeavenServiceMixin, build_personal_field
from backend.features.heaven.routes import HeavenRoutesMixin
from backend.features.market import MarketServiceMixin
from backend.features.market.routes import MarketRoutesMixin
from backend.features.mentor import MentorHttpMixin, MentorServiceMixin
from backend.features.mentor.routes import MentorRoutesMixin
from backend.features.pools import PoolServiceMixin
from backend.features.pools.routes import PoolRoutesMixin
from backend.features.popularity import PopularityServiceMixin
from backend.features.popularity.routes import PopularityRoutesMixin
from backend.features.review import ReviewHttpMixin, ReviewServiceMixin
from backend.features.review.routes import ReviewRoutesMixin
from backend.features.rotation import RotationServiceMixin
from backend.features.rotation.routes import RotationRoutesMixin
from backend.features.screener.routes import ScreenerRoutesMixin
from backend.features.screener.service import (
SCREENER_LIBRARY_VERSION,
ScreenerServiceMixin,
automatic_screener_jobs,
)
from backend.features.sentiment import SentimentServiceMixin
from backend.features.sentiment.routes import SentimentRoutesMixin
from backend.features.system import SystemHttpMixin
from backend.features.system.routes import SystemRoutesMixin
from backend.features.system.service import SystemServiceMixin
from backend.features.themes import ThemeServiceMixin
from backend.features.themes.routes import ThemeRoutesMixin
from backend.http import HttpTransportMixin
from backend.http.dispatch import (
AUTHENTICATED_POST_HANDLERS,
HUB_SERVICE_HANDLERS,
PUBLIC_POST_HANDLERS,
ApplicationHttpDispatchMixin,
)
from backend.http.hubadmin import HubAdminHttpMixin
from backend.jobs.service import JobServiceMixin
from backend.llm import LLMGateway
from backend.llm.http import LLMHttpMixin
from backend.llm.service import LLMServiceMixin
from database import ReviewDatabase
class DashboardService(
SystemServiceMixin,
AccountApplicationMixin,
JobServiceMixin,
MarketServiceMixin,
SentimentServiceMixin,
PoolServiceMixin,
RotationServiceMixin,
AuctionServiceMixin,
ThemeServiceMixin,
PopularityServiceMixin,
DragonTigerServiceMixin,
ScreenerServiceMixin,
MentorServiceMixin,
HeavenServiceMixin,
AlertServiceMixin,
ReviewServiceMixin,
LLMServiceMixin,
):
def __init__(self) -> None:
runtime = load_runtime_settings()
self.vault = SecretVault(runtime.encryption_key)
self.database = ReviewDatabase(DATA_DIR / "review.db")
self.sync_lock = threading.Lock()
self.auth_lock = threading.Lock()
self.system_lock = threading.Lock()
self.auto_screener_lock = threading.Lock()
self._auto_screener_last_attempt: dict[str, datetime] = {}
self._ifind_event_lock = threading.Lock()
self._request_context = threading.local()
self.accounts = AccountService(
database=self.database,
vault=self.vault,
current_user_supplier=lambda: self.current_user_id,
access_supplier=lambda: getattr(self._request_context, "access", {}),
bind_user=self.bind_user,
personal_field_builder=build_personal_field,
auth_lock=self.auth_lock,
)
self._system_credentials = self._load_system_credentials(runtime.initial_credentials)
self.container = build_application_container(
self.database,
self._system_credentials,
MENTOR_SKILLS_DIR,
PRIVATE_MENTOR_SKILLS_DIR,
)
self.data_gateway = self.container.data_gateway
self.ifind = self.container.ifind
self.screener = self.container.screener
self.strategy_tracking = self.container.strategy_tracking
self.alert_service = self.container.alert_service
self.trade_journal = self.container.trade_journal
self.mentor_skills = self.container.mentor_skills
self.realtime_aggregator = self.container.realtime_aggregator
self.chart_data = self.container.chart_data
self.jobs = self.container.jobs
self.llm_gateway = LLMGateway(
database=self.database,
user_id_supplier=lambda: self.current_user_id,
membership_supplier=self.membership,
settings_supplier=lambda: self._system_credentials,
profile_supplier=self._resolved_llm_profile,
)
self.screener.ensure_builtin_strategies()
SERVICE = DashboardService()
class RequestHandler(
SystemRoutesMixin,
AccountRoutesMixin,
AlertRoutesMixin,
ReviewRoutesMixin,
MarketRoutesMixin,
AuctionRoutesMixin,
ThemeRoutesMixin,
PopularityRoutesMixin,
SentimentRoutesMixin,
RotationRoutesMixin,
DragonTigerRoutesMixin,
ScreenerRoutesMixin,
MentorRoutesMixin,
HeavenRoutesMixin,
PoolRoutesMixin,
AccountHttpMixin,
SystemHttpMixin,
MentorHttpMixin,
HeavenHttpMixin,
AlertHttpMixin,
ReviewHttpMixin,
LLMHttpMixin,
HubAdminHttpMixin,
ApplicationHttpDispatchMixin,
HttpTransportMixin,
BaseHTTPRequestHandler,
):
server_version = "XiaobaiReviewWeb/0.8"
application_service = SERVICE
route_registry = ROUTES