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, PUBLIC_POST_HANDLERS, ApplicationHttpDispatchMixin, ) 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 LEGACY_SECRET_KEYS = { "TUSHARE_TOKEN", "IFIND_REFRESH_TOKEN", "IFIND_ACCESS_TOKEN", "LLM_API_KEY", "LLM_BASE_URL", "LLM_MODEL", "LLM_PRIMARY_API_KEY", "LLM_PRIMARY_BASE_URL", "LLM_PRIMARY_MODEL", "LLM_FALLBACK_API_KEY", "LLM_FALLBACK_BASE_URL", "LLM_FALLBACK_MODEL", } 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, lambda: self.token, ) 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, ApplicationHttpDispatchMixin, HttpTransportMixin, BaseHTTPRequestHandler, ): server_version = "XiaobaiReviewWeb/0.8" application_service = SERVICE route_registry = ROUTES