135 lines
4.2 KiB
Python
135 lines
4.2 KiB
Python
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|