Files
shopship/apps/telemetry/api/services.py
T

61 lines
2.7 KiB
Python
Raw Normal View History

2026-08-31 15:11:52 +03:30
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"],
)