from django.db import transaction from apps.account.models import User from apps.telemetry.models import AppSession, ClickEvent, ClientErrorLog, PageView class TelemetryIngestService: @staticmethod @transaction.atomic def ingest(user: User, ip_address: str | None, data: dict) -> None: session, _created = AppSession.objects.get_or_create( id=data["session_id"], defaults={ "user": user, "platform": data.get("platform", ""), "app_version": data.get("app_version", ""), "ip_address": ip_address, "started_at": data["events"][0]["at"], }, ) # اگر آی‌پی از قبل ثبت نشده یا عوض شده، آخرین مقدار را نگه می‌داریم — # همان چیزی که «لیست آی‌پی‌هایی که کاربر باهاش اومده» را می‌سازد (از # طریق تجمیعِ همه‌ی session های همان کاربر، نه فقط این یکی). if ip_address and session.ip_address != ip_address: session.ip_address = ip_address session.save(update_fields=["ip_address"]) for event in data["events"]: event_type = event["type"] if event_type == "session_start": if session.started_at != event["at"]: session.started_at = min(session.started_at, event["at"]) session.save(update_fields=["started_at"]) elif event_type == "session_end": session.ended_at = event["at"] session.save(update_fields=["ended_at"]) elif event_type == "page_view": PageView.objects.create( session=session, screen_name=event.get("screen", ""), entered_at=event["at"], duration_seconds=event.get("duration_seconds"), ) elif event_type == "click": ClickEvent.objects.create( session=session, screen_name=event.get("screen", ""), element=event.get("element", ""), x=event.get("x"), y=event.get("y"), created_at=event["at"], ) elif event_type == "error": ClientErrorLog.objects.create( session=session, screen_name=event.get("screen", ""), message=event.get("message", ""), stack_trace=event.get("stack", ""), created_at=event["at"], )