""" Visitor tracking models for analytics """ from sqlalchemy import Column, Integer, String, DateTime, Text, Index from sqlalchemy.sql import func from ..database import Base class VisitorLog(Base): """ Raw visitor log - tracks every page visit IP addresses are hashed for privacy """ __tablename__ = "visitor_logs" id = Column(Integer, primary_key=True, index=True) # Visitor identification (hashed for privacy) visitor_hash = Column(String(64), nullable=False, index=True) # SHA256 hash of IP + User-Agent ip_hash = Column(String(64), nullable=False) # SHA256 hash of IP only # Session tracking session_id = Column(String(64), nullable=True, index=True) # Cookie-based session ID user_id = Column(Integer, nullable=True, index=True) # If logged in # Page information page_path = Column(String(500), nullable=False, index=True) page_title = Column(String(200), nullable=True) referrer = Column(String(1000), nullable=True) referrer_domain = Column(String(200), nullable=True, index=True) # Device information device_type = Column(String(20), nullable=True, index=True) # mobile, desktop, tablet browser = Column(String(50), nullable=True, index=True) browser_version = Column(String(20), nullable=True) os = Column(String(50), nullable=True) os_version = Column(String(20), nullable=True) # Geographic information (from IP geolocation) country = Column(String(50), nullable=True, index=True) country_code = Column(String(5), nullable=True) city = Column(String(100), nullable=True) region = Column(String(100), nullable=True) # UTM parameters utm_source = Column(String(100), nullable=True) utm_medium = Column(String(100), nullable=True) utm_campaign = Column(String(100), nullable=True) # Timestamp visited_at = Column(DateTime(timezone=True), server_default=func.now(), index=True) class VisitorDailyStats(Base): """ Aggregated daily statistics for faster queries Pre-computed by a scheduled task """ __tablename__ = "visitor_daily_stats" id = Column(Integer, primary_key=True, index=True) stat_date = Column(String(10), nullable=False, unique=True, index=True) # YYYY-MM-DD # Visitor counts total_visits = Column(Integer, default=0) unique_visitors = Column(Integer, default=0) # Device breakdown (JSON string) device_breakdown = Column(Text) # {"mobile": 100, "desktop": 200, "tablet": 20} # Browser breakdown (JSON string) browser_breakdown = Column(Text) # {"Chrome": 150, "Safari": 100, ...} # Country breakdown (JSON string) country_breakdown = Column(Text) # {"MN": 200, "RU": 50, "KR": 30} # Top pages (JSON string) top_pages = Column(Text) # [{"path": "/", "views": 500}, ...] # Top referrers (JSON string) top_referrers = Column(Text) # [{"domain": "google.com", "visits": 100}, ...] # Timestamps created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) class VisitorSession(Base): """ Track visitor sessions for better analytics """ __tablename__ = "visitor_sessions" id = Column(Integer, primary_key=True, index=True) session_id = Column(String(64), unique=True, nullable=False, index=True) visitor_hash = Column(String(64), nullable=False, index=True) user_id = Column(Integer, nullable=True) # Session info first_page = Column(String(500)) last_page = Column(String(500)) page_count = Column(Integer, default=1) # Device/geo info (copied from first visit) device_type = Column(String(20)) browser = Column(String(50)) country = Column(String(50)) # Timestamps started_at = Column(DateTime(timezone=True), server_default=func.now(), index=True) last_activity_at = Column(DateTime(timezone=True), server_default=func.now())