123 lines
4.3 KiB
Python
123 lines
4.3 KiB
Python
from fastapi import APIRouter, Depends
|
|
from sqlmodel import Session, select, func
|
|
from app.core.database import get_session
|
|
from app.models.analytics import AnalyticsEvent
|
|
from app.models.user import User
|
|
from typing import Optional, Dict
|
|
from datetime import datetime, timedelta
|
|
from app.api.deps import get_current_user_optional
|
|
|
|
router = APIRouter()
|
|
|
|
@router.post("/event")
|
|
async def log_event(
|
|
event: Dict,
|
|
session: Session = Depends(get_session),
|
|
current_user: Optional[User] = Depends(get_current_user_optional)
|
|
):
|
|
user_id = current_user.id if current_user else None
|
|
|
|
new_event = AnalyticsEvent(
|
|
event_name=event.get("event_name"),
|
|
user_id=user_id,
|
|
screen_name=event.get("screen_name"),
|
|
item_id=event.get("item_id"),
|
|
properties=event.get("properties", {})
|
|
)
|
|
session.add(new_event)
|
|
session.commit()
|
|
return {"status": "ok"}
|
|
|
|
@router.get("/strategic")
|
|
async def get_strategic_analysis(
|
|
session: Session = Depends(get_session)
|
|
):
|
|
"""Deep analysis of how businesses and shuttles are performing."""
|
|
|
|
# 1. SHUTTLE PERFORMANCE
|
|
shuttle_previews = session.exec(
|
|
select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id))
|
|
.where(AnalyticsEvent.event_name == "shuttle_view")
|
|
.group_by(AnalyticsEvent.item_id)
|
|
).all()
|
|
|
|
shuttle_contacts = session.exec(
|
|
select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id))
|
|
.where(AnalyticsEvent.event_name == "shuttle_contact")
|
|
.group_by(AnalyticsEvent.item_id)
|
|
).all()
|
|
|
|
shuttle_map = {r[0]: {"views": r[1], "contacts": 0} for r in shuttle_previews if r[0]}
|
|
for r in shuttle_contacts:
|
|
if r[0] in shuttle_map:
|
|
shuttle_map[r[0]]["contacts"] = r[1]
|
|
else:
|
|
shuttle_map[r[0]] = {"views": 0, "contacts": r[1]}
|
|
|
|
# 2. BUSINESS PERFORMANCE
|
|
biz_views = session.exec(
|
|
select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id))
|
|
.where(AnalyticsEvent.event_name == "business_view")
|
|
.group_by(AnalyticsEvent.item_id)
|
|
).all()
|
|
|
|
promo_clicks = session.exec(
|
|
select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id))
|
|
.where(AnalyticsEvent.event_name == "promo_click")
|
|
.group_by(AnalyticsEvent.item_id)
|
|
).all()
|
|
|
|
biz_map = {r[0]: {"views": r[1], "promos": 0} for r in biz_views if r[0]}
|
|
for r in promo_clicks:
|
|
if r[0] in biz_map:
|
|
biz_map[r[0]]["promos"] = r[1]
|
|
else:
|
|
biz_map[r[0]] = {"views": 0, "promos": r[1]}
|
|
|
|
# 3. TOP STOPS (CASETAS CON MÁS GENTE)
|
|
top_stops = session.exec(
|
|
select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id))
|
|
.where(AnalyticsEvent.event_name == "stop_selected")
|
|
.group_by(AnalyticsEvent.item_id)
|
|
.order_by(func.count(AnalyticsEvent.id).desc())
|
|
.limit(10)
|
|
).all()
|
|
|
|
# 4. ACTIVE USERS
|
|
total_active_users = session.exec(select(func.count(func.distinct(AnalyticsEvent.user_id))).where(AnalyticsEvent.user_id != None)).one()
|
|
|
|
# 5. PEAK HOURS BY USER TYPE
|
|
hour_expr = func.extract('hour', AnalyticsEvent.timestamp)
|
|
reg_usage = session.exec(select(hour_expr, func.count(AnalyticsEvent.id)).where(AnalyticsEvent.user_id != None).group_by(hour_expr)).all()
|
|
guest_usage = session.exec(select(hour_expr, func.count(AnalyticsEvent.id)).where(AnalyticsEvent.user_id == None).group_by(hour_expr)).all()
|
|
|
|
usage_patterns = {
|
|
"registered": {int(h): c for h, c in reg_usage},
|
|
"guests": {int(h): c for h, c in guest_usage}
|
|
}
|
|
|
|
return {
|
|
"shuttles": shuttle_map,
|
|
"businesses": biz_map,
|
|
"top_stops": [{"id": r[0], "count": r[1]} for r in top_stops],
|
|
"users": {
|
|
"registered_active": total_active_users,
|
|
"patterns": usage_patterns
|
|
},
|
|
"summary": {
|
|
"total_shuttle_contacts": sum(sh[1] for sh in shuttle_contacts),
|
|
"total_promo_clicks": sum(p[1] for p in promo_clicks),
|
|
"total_biz_views": sum(b[1] for b in biz_views)
|
|
}
|
|
}
|
|
|
|
@router.get("/dashboard/stats")
|
|
async def get_dashboard_stats(
|
|
session: Session = Depends(get_session)
|
|
):
|
|
# Base dashboard stats for general overview
|
|
total_events = session.exec(select(func.count(AnalyticsEvent.id))).one()
|
|
return {
|
|
"total_events": total_events
|
|
}
|