Source code for app.services.user_points_analytics_service

"""
Analytics service for user points.

Aggregations, temporal queries and metrics over ``user_points`` records.
Extracted from ``UserPointsService`` so CRUD/write paths and analytic queries
have separate, focused services.

These methods are thin pass-throughs over ``UserPointsRepository`` analytics
queries; they are consumed primarily by strategy engines (``app/engine``) to
compute rewards based on historical user behaviour.
"""

from typing import Any

from app.repository.user_points_repository import UserPointsRepository
from app.services.base_service import BaseService


[docs] class UserPointsAnalyticsService(BaseService): def __init__(self, user_points_repository: UserPointsRepository) -> None: self.user_points_repository = user_points_repository super().__init__(user_points_repository)
[docs] async def count_measurements_by_external_task_id(self, external_task_id) -> Any: """Count all points rows recorded for an external task.""" return await self.user_points_repository.count_measurements_by_external_task_id( external_task_id )
[docs] async def get_user_task_measurements_count( self, externalTaskId, externalUserId ) -> Any: """Count a user's awards on a given external task.""" return await self.user_points_repository.get_user_task_measurements_count( externalTaskId, externalUserId )
[docs] async def get_user_task_measurements_count_the_last_seconds( self, externalTaskId, externalUserId, seconds ) -> Any: """Count a user's awards on a task within the last ``seconds``.""" return await self.user_points_repository.get_user_task_measurements_count_the_last_seconds( externalTaskId, externalUserId, seconds )
[docs] async def get_avg_time_between_tasks_by_user_and_game_task( self, externalGameId, externalTaskId, externalUserId ) -> Any: """Average seconds between a user's consecutive awards on a task (``-1`` with fewer than two awards).""" return await self.user_points_repository.get_avg_time_between_tasks_by_user_and_game_task( # noqa externalGameId, externalTaskId, externalUserId )
[docs] async def get_avg_time_between_tasks_for_all_users( self, externalGameId, externalTaskId ) -> Any: """Average seconds between consecutive awards on a task across all users (``-1`` with fewer than two awards).""" return await self.user_points_repository.get_avg_time_between_tasks_for_all_users( # noqa externalGameId, externalTaskId )
[docs] async def get_last_window_time_diff(self, externalTaskId, externalUserId) -> Any: """Seconds between a user's two most recent awards on a task.""" return await self.user_points_repository.get_last_window_time_diff( externalTaskId, externalUserId )
[docs] async def get_new_last_window_time_diff( self, externalTaskId, externalUserId, externalGameId ) -> Any: """Seconds elapsed since a user's most recent award on a task.""" return await self.user_points_repository.get_new_last_window_time_diff( externalTaskId, externalUserId, externalGameId )
[docs] async def get_user_task_measurements(self, externalTaskId, externalUserId) -> Any: """Return the ordered timestamps of a user's awards on a task.""" return await self.user_points_repository.get_user_task_measurements( externalTaskId, externalUserId )
[docs] async def count_personal_records_by_external_game_id( self, external_game_id, externalUserId ) -> Any: """Count the number of records for a user in a game.""" return await self.user_points_repository.count_personal_records_by_external_game_id( external_game_id, externalUserId )
[docs] async def user_has_record_before_in_externalTaskId_last_min( self, externalTaskId, externalUserId, minutes ) -> Any: """Check if a user has a record in the task in the last `minutes` minutes.""" return await self.user_points_repository.user_has_record_before_in_externalTaskId_last_min( externalTaskId, externalUserId, minutes )
[docs] async def get_global_avg_by_external_game_id(self, external_game_id) -> Any: """ Get the global average time rewarded. Ignores entries with 0 minutes. """ return await self.user_points_repository.get_global_avg_by_external_game_id( external_game_id )
[docs] async def get_personal_avg_by_external_game_id( self, external_game_id, externalUserId ) -> Any: """ Get the personal average time rewarded. Ignores entries with 0 minutes. """ return await self.user_points_repository.get_personal_avg_by_external_game_id( external_game_id, externalUserId )