diff options
| author | Christian Cleberg <[email protected]> | 2026-04-11 13:58:01 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-11 13:58:01 -0500 |
| commit | 6149ca9c394df7d316f80db05ad0fc2aea6c550d (patch) | |
| tree | 11f6cebc445e14b4a79adae648eb46d4be710071 /src/srht_contrib/services/aggregator.py | |
| parent | b6d1348abf907b8b9c16ab87487eb9384dc4cc89 (diff) | |
| download | hutch-stats-6149ca9c394df7d316f80db05ad0fc2aea6c550d.tar.gz hutch-stats-6149ca9c394df7d316f80db05ad0fc2aea6c550d.tar.bz2 hutch-stats-6149ca9c394df7d316f80db05ad0fc2aea6c550d.zip | |
feat: add lazy actor indexing for contribution lookups
Diffstat (limited to 'src/srht_contrib/services/aggregator.py')
| -rw-r--r-- | src/srht_contrib/services/aggregator.py | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/srht_contrib/services/aggregator.py b/src/srht_contrib/services/aggregator.py index 800329a..90ef93b 100644 --- a/src/srht_contrib/services/aggregator.py +++ b/src/srht_contrib/services/aggregator.py @@ -6,8 +6,13 @@ from datetime import date from sqlalchemy import func, select from sqlalchemy.orm import Session -from srht_contrib.models import ContributionEvent -from srht_contrib.schemas import ContributionCalendarResponse, ContributionDay, ContributionStatsResponse +from srht_contrib.models import ContributionEvent, TrackedActor +from srht_contrib.schemas import ( + ContributionCalendarResponse, + ContributionDay, + ContributionIndexMetadata, + ContributionStatsResponse, +) from srht_contrib.utils.dates import date_range, date_to_utc_bounds @@ -30,7 +35,14 @@ class ContributionAggregator: ) for day in date_range(start, end) ] - return ContributionCalendarResponse(actor=actor, from_date=start, to_date=end, days=days) + metadata = self._index_metadata(db, actor) + return ContributionCalendarResponse( + actor=actor, + from_date=start, + to_date=end, + days=days, + **metadata.model_dump(), + ) def build_stats(self, db: Session, actor: str, start: date, end: date) -> ContributionStatsResponse: calendar = self.build_calendar(db, actor, start, end) @@ -47,6 +59,28 @@ class ContributionAggregator: active_days=len(active_days), longest_streak=max(streaks, default=0), current_streak=current_streak, + is_indexed=calendar.is_indexed, + last_polled_at=calendar.last_polled_at, + indexing_state=calendar.indexing_state, + ) + + def _index_metadata(self, db: Session, actor: str) -> ContributionIndexMetadata: + tracked_actor = db.scalar(select(TrackedActor).where(TrackedActor.actor == actor)) + has_indexed_events = db.scalar(select(ContributionEvent.id).where(ContributionEvent.actor == actor).limit(1)) is not None + last_poll_status = tracked_actor.last_poll_status if tracked_actor is not None else None + is_indexed = has_indexed_events or (tracked_actor is not None and tracked_actor.last_polled_at is not None) + + if last_poll_status == "error": + indexing_state = "error" + elif is_indexed: + indexing_state = "indexed" + else: + indexing_state = "pending" + + return ContributionIndexMetadata( + is_indexed=is_indexed, + last_polled_at=tracked_actor.last_polled_at if tracked_actor is not None else None, + indexing_state=indexing_state, ) def _query_daily_aggregates(self, db: Session, actor: str, start: date, end: date) -> list[DailyAggregate]: |
