Files
AutonetSellCar/backend/app/models/visitor.py
AutonetSellCar Deploy 1f0dcb1ddb Initial commit: AutonetSellCar platform with deployment system
- Frontend: Next.js 14 with TypeScript
- Backend: FastAPI with SQLAlchemy
- Agent: Carmodoo sync agent
- Deployment: Docker Compose based staging/production setup
- Scripts: Automated deployment with rollback support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 13:24:39 +09:00

112 lines
3.9 KiB
Python

"""
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())