from typing import List, Dict, Any from datetime import date, timedelta from loguru import logger from backend.infra.starrocks_client import StarRocksClient from backend.models.registered_users import UserRegistrationResponse, DailyRegisteredUsers class RegistrationService: """Service for handling user registration data queries""" def __init__(self): self.starrocks_client = StarRocksClient() def get_daily_registered_users( self, start_date: date, end_date: date, product_id: str = "freeleaps" ) -> UserRegistrationResponse: """ Get daily registered users count for a date range Args: start_date: Start date for the query end_date: End date for the query product_id: Product identifier (default: freeleaps) Returns: UserRegistrationResponse with dates and counts """ try: # Query data from StarRocks raw_data = self.starrocks_client.get_daily_registered_users( start_date, end_date, product_id ) # Convert to DailyRegisteredUsers objects daily_data = [ DailyRegisteredUsers( date_id=row['date_id'], product_id=row['product_id'], registered_cnt=row['registered_cnt'], updated_at=row.get('updated_at') ) for row in raw_data ] # Create date-to-count mapping data_dict = {str(item.date_id): item.registered_cnt for item in daily_data} # Generate complete date range dates = [] counts = [] current_date = start_date while current_date <= end_date: date_str = str(current_date) dates.append(date_str) counts.append(data_dict.get(date_str, 0)) current_date += timedelta(days=1) # Calculate total registrations total_registrations = sum(counts) logger.info( f"Retrieved registration data for {len(dates)} days, " f"total registrations: {total_registrations}" ) return UserRegistrationResponse( dates=dates, counts=counts, total_registrations=total_registrations, query_period=f"{start_date} to {end_date}" ) except Exception as e: logger.error(f"Failed to get daily registered users: {e}") raise e def get_registration_summary( self, start_date: date, end_date: date, product_id: str = "freeleaps" ) -> Dict[str, Any]: """ Get summary statistics for user registrations Args: start_date: Start date for the query end_date: End date for the query product_id: Product identifier Returns: Dictionary with summary statistics """ try: response = self.get_daily_registered_users(start_date, end_date, product_id) if not response.counts: return { "total_registrations": 0, "average_daily": 0, "max_daily": 0, "min_daily": 0, "days_with_registrations": 0, "total_days": len(response.dates) } counts = response.counts non_zero_counts = [c for c in counts if c > 0] return { "total_registrations": response.total_registrations, "average_daily": round(sum(counts) / len(counts), 2), "max_daily": max(counts), "min_daily": min(counts), "days_with_registrations": len(non_zero_counts), "total_days": len(response.dates) } except Exception as e: logger.error(f"Failed to get registration summary: {e}") raise e