from __future__ import annotations from datetime import datetime from sqlalchemy import DateTime, Index, SmallInteger, String, func, text from sqlalchemy.dialects.postgresql import CIDR from sqlalchemy.orm import Mapped, mapped_column from app.models.db import Base STATUS_ACTIVE = 1 STATUS_BANNED = 2 class TokenBinding(Base): __tablename__ = "token_bindings" __table_args__ = ( Index("idx_token_bindings_hash", "token_hash"), Index("idx_token_bindings_ip", "bound_ip", postgresql_using="gist", postgresql_ops={"bound_ip": "inet_ops"}), ) id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) token_hash: Mapped[str] = mapped_column(String(64), unique=True, nullable=False) token_display: Mapped[str] = mapped_column(String(20), nullable=False) bound_ip: Mapped[str] = mapped_column(CIDR, nullable=False) status: Mapped[int] = mapped_column( SmallInteger, nullable=False, default=STATUS_ACTIVE, server_default=text("1"), ) first_used_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), ) last_used_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), )