73 lines
2.0 KiB
Python
73 lines
2.0 KiB
Python
"""Usage sample model - aggregated telemetry data.
|
|
|
|
PRIVACY GUARANTEE: This model contains NO sensitive data fields.
|
|
Only tool names, durations, and counts are stored.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from uuid import UUID
|
|
|
|
from sqlalchemy import DateTime, ForeignKey, Integer, String
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.models.base import Base, UUIDMixin
|
|
|
|
|
|
class UsageSample(UUIDMixin, Base):
|
|
"""
|
|
Aggregated usage statistics for an instance.
|
|
|
|
PRIVACY: This model deliberately has NO fields for:
|
|
- Environment values
|
|
- File contents
|
|
- Request/response payloads
|
|
- Screenshots
|
|
- Credentials
|
|
- Error messages or stack traces
|
|
|
|
Only metadata fields are allowed.
|
|
"""
|
|
|
|
__tablename__ = "usage_samples"
|
|
|
|
# Instance reference
|
|
instance_id: Mapped[UUID] = mapped_column(
|
|
ForeignKey("instances.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
|
|
# Time window
|
|
window_start: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
nullable=False,
|
|
)
|
|
window_end: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
nullable=False,
|
|
)
|
|
window_type: Mapped[str] = mapped_column(
|
|
String(20),
|
|
nullable=False,
|
|
)
|
|
# "minute", "hour", "day"
|
|
|
|
# Tool (ONLY name, never payloads)
|
|
tool_name: Mapped[str] = mapped_column(
|
|
String(255),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
# e.g., "sysadmin.env_update"
|
|
|
|
# Counts (aggregated)
|
|
call_count: Mapped[int] = mapped_column(Integer, default=0)
|
|
success_count: Mapped[int] = mapped_column(Integer, default=0)
|
|
error_count: Mapped[int] = mapped_column(Integer, default=0)
|
|
rate_limited_count: Mapped[int] = mapped_column(Integer, default=0)
|
|
|
|
# Duration stats (milliseconds)
|
|
total_duration_ms: Mapped[int] = mapped_column(Integer, default=0)
|
|
min_duration_ms: Mapped[int] = mapped_column(Integer, default=0)
|
|
max_duration_ms: Mapped[int] = mapped_column(Integer, default=0)
|