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
)