96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
from fastapi import APIRouter
|
|
from typing import Optional, List, Dict, Any
|
|
from pydantic import BaseModel, Field
|
|
from datetime import date
|
|
|
|
from common.log.module_logger import ModuleLogger
|
|
from backend.services.registration_analytics_service import RegistrationService
|
|
|
|
|
|
class RegistrationDataPoint(BaseModel):
|
|
"""Single data point in registration time series."""
|
|
date: str = Field(..., description="Date in YYYY-MM-DD format")
|
|
value: int = Field(..., description="Number of registered users")
|
|
product_id: str = Field(..., description="Product identifier")
|
|
|
|
|
|
class RegistrationTimeSeriesResponse(BaseModel):
|
|
"""Response model for registration time series data."""
|
|
metric_name: str = Field(..., description="Name of the queried metric")
|
|
data_points: List[RegistrationDataPoint] = Field(..., description="List of data points")
|
|
total_points: int = Field(..., description="Total number of data points")
|
|
time_range: Dict[str, str] = Field(..., description="Start and end date of the query")
|
|
total_registrations: int = Field(..., description="Total number of registrations in the period")
|
|
|
|
|
|
class RegistrationQueryRequest(BaseModel):
|
|
"""Request model for registration query."""
|
|
product_id: str = Field("freeleaps", description="Product ID to identify which product's data to query")
|
|
start_date: str = Field(..., description="Start date in YYYY-MM-DD format")
|
|
end_date: str = Field(..., description="End date in YYYY-MM-DD format")
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
# Initialize service and logger
|
|
registration_service = RegistrationService()
|
|
module_logger = ModuleLogger(__file__)
|
|
|
|
|
|
@router.post("/starrocks/dru_query", response_model=RegistrationTimeSeriesResponse)
|
|
async def metrics_query(
|
|
request: RegistrationQueryRequest
|
|
):
|
|
"""
|
|
Query registration time series data.
|
|
|
|
Returns XY curve data (time series) for user registrations within the given date range.
|
|
"""
|
|
await module_logger.log_info(
|
|
f"Querying registration data for product '{request.product_id}' from {request.start_date} to {request.end_date}")
|
|
|
|
# Parse dates - handle both YYYY-M-D and YYYY-MM-DD formats
|
|
def parse_date(date_str: str) -> date:
|
|
try:
|
|
return date.fromisoformat(date_str)
|
|
except ValueError:
|
|
# Try to parse YYYY-M-D format and convert to YYYY-MM-DD
|
|
parts = date_str.split('-')
|
|
if len(parts) == 3:
|
|
year, month, day = parts
|
|
return date(int(year), int(month), int(day))
|
|
raise ValueError(f"Invalid date format: {date_str}")
|
|
|
|
start_date = parse_date(request.start_date)
|
|
end_date = parse_date(request.end_date)
|
|
|
|
# Query the registration data
|
|
result = registration_service.get_daily_registered_users(
|
|
start_date=start_date,
|
|
end_date=end_date,
|
|
product_id=request.product_id
|
|
)
|
|
|
|
# Format response
|
|
response = RegistrationTimeSeriesResponse(
|
|
metric_name="daily_registered_users",
|
|
data_points=[
|
|
RegistrationDataPoint(
|
|
date=date_str,
|
|
value=count,
|
|
product_id=request.product_id
|
|
)
|
|
for date_str, count in zip(result.dates, result.counts)
|
|
],
|
|
total_points=len(result.dates),
|
|
time_range={
|
|
"start": request.start_date,
|
|
"end": request.end_date
|
|
},
|
|
total_registrations=result.total_registrations
|
|
)
|
|
|
|
await module_logger.log_info(
|
|
f"Successfully queried registration data with {len(result.dates)} data points, total registrations: {result.total_registrations}")
|
|
return response
|