refactor(storage): remove duplicate watchlist query

This commit is contained in:
leefer
2026-07-30 12:07:05 +08:00
parent 67e279a1d5
commit e0b065e38b
4 changed files with 17 additions and 19 deletions
+3 -2
View File
@@ -66,6 +66,7 @@ def build_container(settings: Settings) -> ApplicationContainer:
credentials = SystemCredentialService(database, credential_repository, cipher) credentials = SystemCredentialService(database, credential_repository, cipher)
tushare = TushareProvider(lambda: credentials.get("tushare_token")) tushare = TushareProvider(lambda: credentials.get("tushare_token"))
market_repository = MarketRepository() market_repository = MarketRepository()
review_repository = ReviewRepository()
gateway = DataGateway( gateway = DataGateway(
database, database,
market_repository, market_repository,
@@ -82,7 +83,7 @@ def build_container(settings: Settings) -> ApplicationContainer:
market = MarketService( market = MarketService(
gateway, gateway,
MarketSnapshotService(database, market_repository, gateway), MarketSnapshotService(database, market_repository, gateway),
MarketInsightService(database, market_repository, gateway), MarketInsightService(database, market_repository, review_repository, gateway),
) )
accounts = AccountService(database, account_repository, PasswordHasher(), cipher) accounts = AccountService(database, account_repository, PasswordHasher(), cipher)
memberships = MembershipService(database, account_repository) memberships = MembershipService(database, account_repository)
@@ -110,7 +111,7 @@ def build_container(settings: Settings) -> ApplicationContainer:
llm, llm,
PROJECT_ROOT / "config" / "heaven" / "iching_zh.json", PROJECT_ROOT / "config" / "heaven" / "iching_zh.json",
) )
review = ReviewService(database, ReviewRepository(), gateway, screener, llm) review = ReviewService(database, review_repository, gateway, screener, llm)
jobs = JobService(database, JobRepository()) jobs = JobService(database, JobRepository())
events = MarketEventService(database, market_repository, gateway) events = MarketEventService(database, market_repository, gateway)
operations = OperationsService( operations = OperationsService(
-13
View File
@@ -480,19 +480,6 @@ class MarketRepository:
(seat_name, alias_name, updated_at, updated_by), (seat_name, alias_name, updated_at, updated_by),
) )
def watchlist(
self, connection: sqlite3.Connection, user_id: int
) -> tuple[sqlite3.Row, ...]:
return tuple(
connection.execute(
"""
SELECT identifier, name, sector FROM watchlist_entries
WHERE user_id = ? ORDER BY created_at, identifier
""",
(user_id,),
).fetchall()
)
def save_chart( def save_chart(
self, self,
connection: sqlite3.Connection, connection: sqlite3.Connection,
@@ -50,6 +50,7 @@ from backend.features.market.insights.support import (
valid_date as _date, valid_date as _date,
) )
from backend.features.market.insights.themes import build_theme_detail, build_theme_library from backend.features.market.insights.themes import build_theme_detail, build_theme_library
from backend.features.review.repository import ReviewRepository
SHANGHAI = ZoneInfo("Asia/Shanghai") SHANGHAI = ZoneInfo("Asia/Shanghai")
@@ -60,10 +61,15 @@ class MarketInsightError(RuntimeError):
class MarketInsightService: class MarketInsightService:
def __init__( def __init__(
self, database: Database, repository: MarketRepository, gateway: DataGateway self,
database: Database,
repository: MarketRepository,
watchlists: ReviewRepository,
gateway: DataGateway,
) -> None: ) -> None:
self._database = database self._database = database
self._repository = repository self._repository = repository
self._watchlists = watchlists
self._gateway = gateway self._gateway = gateway
def workspace( def workspace(
@@ -211,7 +217,7 @@ class MarketInsightService:
market_rows = list(result.pop("_market_rows", ())) market_rows = list(result.pop("_market_rows", ()))
with self._database.read() as connection: with self._database.read() as connection:
watchlist = tuple( watchlist = tuple(
dict(row) for row in self._repository.watchlist(connection, user_id) dict(row) for row in self._watchlists.watchlist(connection, user_id)
) )
result["watchlist_rows"] = build_watchlist_rows( result["watchlist_rows"] = build_watchlist_rows(
market_rows, market_rows,
+6 -2
View File
@@ -17,6 +17,7 @@ from backend.features.market.insights.dragon import build_dragon_list
from backend.features.market.insights.popularity import build_popularity from backend.features.market.insights.popularity import build_popularity
from backend.features.market.insights.service import MarketInsightService from backend.features.market.insights.service import MarketInsightService
from backend.features.market.insights.themes import build_theme_detail, build_theme_library from backend.features.market.insights.themes import build_theme_detail, build_theme_library
from backend.features.review.repository import ReviewRepository
SHANGHAI = ZoneInfo("Asia/Shanghai") SHANGHAI = ZoneInfo("Asia/Shanghai")
@@ -106,7 +107,7 @@ def test_watchlist_rows_are_built_only_from_current_account_entries() -> None:
def test_watchlist_repository_isolates_accounts(tmp_path) -> None: def test_watchlist_repository_isolates_accounts(tmp_path) -> None:
database = Database(tmp_path / "watchlists.db") database = Database(tmp_path / "watchlists.db")
MigrationRunner(database).upgrade(MIGRATIONS) MigrationRunner(database).upgrade(MIGRATIONS)
repository = MarketRepository() repository = ReviewRepository()
with database.transaction() as connection: with database.transaction() as connection:
for user_id, username in ((1, "account-a"), (2, "account-b")): for user_id, username in ((1, "account-a"), (2, "account-b")):
connection.execute( connection.execute(
@@ -342,7 +343,10 @@ def insight_service(tmp_path, dynamic_available: bool = True) -> MarketInsightSe
payload=prior, payload=prior,
) )
return MarketInsightService( return MarketInsightService(
database, repository, AuctionGateway(dynamic_available) # type: ignore[arg-type] database,
repository,
ReviewRepository(),
AuctionGateway(dynamic_available), # type: ignore[arg-type]
) )