DocDoeAI / app /models /user_usage_monthly.py
asnannp's picture
Deploy backend cd4237ff: support routes + rate limit + exam_date nullable + upload 413 fix
7c6ffa6
Raw
History Blame Contribute Delete
1.98 kB
"""Monthly per-user usage tracking model.
One row per user per calendar month. Tracks granular counts for each
billable metric so the usage endpoint and admin dashboard can report
accurate numbers.
"""
from __future__ import annotations
from datetime import datetime
from sqlalchemy import DateTime, Float, Integer, String, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column
from app.core.database import Base
from app.utils.ids import prefixed_id
class UserUsageMonthly(Base):
__tablename__ = "user_usage_monthly"
__table_args__ = (
UniqueConstraint("user_id", "month", name="uq_user_usage_monthly_user_month"),
)
id: Mapped[str] = mapped_column(
String(40),
primary_key=True,
default=lambda: prefixed_id("usg"),
)
user_id: Mapped[str] = mapped_column(
String(40),
index=True,
nullable=False,
)
month: Mapped[str] = mapped_column(
String(7), # YYYY-MM
nullable=False,
)
documents_uploaded_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
generations_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
quizzes_generated_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
flashcards_generated_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
videos_generated_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
audio_minutes_generated: Mapped[float] = mapped_column(Float, default=0.0, nullable=False)
storage_bytes_used: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
server_default=func.now(),
nullable=False,
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)