File size: 1,909 Bytes
2563309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""
Performance Monitoring Models
"""

import uuid

from sqlalchemy import Boolean, Column, DateTime, Float, Index, String

from core.models.base import Base, utc_now


class PerformanceMetric(Base):
    """
    Performance Metrics Model
    Stores frontend Web Vitals and other performance indicators.
    """

    __tablename__ = "performance_metrics"

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    timestamp = Column(DateTime, default=utc_now, nullable=False)

    # Context
    user_id = Column(String, nullable=True, index=True)
    url = Column(String, nullable=False, index=True)
    user_agent = Column(String, nullable=False)

    # Web Vitals (all in milliseconds except CLS)
    lcp = Column(Float, nullable=True)  # Largest Contentful Paint
    fid = Column(Float, nullable=True)  # First Input Delay
    cls = Column(Float, nullable=True)  # Cumulative Layout Shift
    fcp = Column(Float, nullable=True)  # First Contentful Paint
    ttfb = Column(Float, nullable=True) # Time to First Byte

    # Additional Metrics
    dom_content_loaded = Column(Float, nullable=True)
    load_complete = Column(Float, nullable=True)
    dom_interactive = Column(Float, nullable=True)

    # Analysis
    is_violation = Column(Boolean, default=False, nullable=False)
    violation_details = Column(String, nullable=True)

    __table_args__ = (
        Index("idx_perf_timestamp", "timestamp"),
        Index("idx_perf_url_timestamp", "url", "timestamp"),
    )

    def to_dict(self):
        return {
            "id": self.id,
            "timestamp": self.timestamp.isoformat(),
            "url": self.url,
            "metrics": {
                "lcp": self.lcp,
                "fid": self.fid,
                "cls": self.cls,
                "fcp": self.fcp,
                "ttfb": self.ttfb
            },
            "is_violation": self.is_violation
        }