""" Authentication-related persistence models """ from datetime import datetime, timezone from typing import Optional from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, UniqueConstraint from sqlalchemy.orm import relationship from app.models.base import BaseModel from sqlalchemy import Text from app.models.audit import LoginAttempt as _AuditLoginAttempt class RefreshToken(BaseModel): """Persisted refresh tokens for revocation and auditing.""" __tablename__ = "refresh_tokens" id = Column(Integer, primary_key=True, autoincrement=True, index=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True) jti = Column(String(64), nullable=False, unique=True, index=True) user_agent = Column(String(255), nullable=True) ip_address = Column(String(45), nullable=True) issued_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False) expires_at = Column(DateTime(timezone=True), nullable=False, index=True) revoked = Column(Boolean, default=False, nullable=False) revoked_at = Column(DateTime(timezone=True), nullable=True) # relationships user = relationship("User") __table_args__ = ( UniqueConstraint("jti", name="uq_refresh_tokens_jti"), ) """ Expose `LoginAttempt` from `app.models.audit` here for backward compatibility. """ LoginAttempt = _AuditLoginAttempt