"""底层安全访问日志模型""" from __future__ import annotations import uuid from datetime import datetime from typing import Optional from sqlalchemy import JSON, DateTime, Float, Index, Integer, String from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.sql import func from app.db.base_class import Base JSONB_TYPE = JSON().with_variant(JSONB, "postgresql") class SecurityAccessLog(Base): __tablename__ = "security_access_logs" __table_args__ = ( Index("ix_security_log_created_at", "created_at"), Index("ix_security_log_ip_created", "client_ip", "created_at"), Index("ix_security_log_status_created", "status_code", "created_at"), Index("ix_security_log_auth_created", "auth_status", "created_at"), Index("ix_security_log_request_id", "request_id"), Index("ix_security_log_category_created", "category", "created_at"), Index("ix_security_log_severity_created", "severity", "created_at"), ) id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) method: Mapped[str] = mapped_column(String(12), nullable=False) path: Mapped[str] = mapped_column(String(500), nullable=False) status_code: Mapped[int] = mapped_column(Integer, nullable=False) elapsed_ms: Mapped[float] = mapped_column(Float, nullable=False) client_ip: Mapped[Optional[str]] = mapped_column(String(45), nullable=True) user_agent: Mapped[Optional[str]] = mapped_column(String(500), nullable=True) client_type: Mapped[Optional[str]] = mapped_column(String(16), nullable=True) client_version: Mapped[Optional[str]] = mapped_column(String(32), nullable=True) client_platform: Mapped[Optional[str]] = mapped_column(String(16), nullable=True) build_channel: Mapped[Optional[str]] = mapped_column(String(16), nullable=True) build_commit: Mapped[Optional[str]] = mapped_column(String(64), nullable=True) request_headers: Mapped[Optional[dict]] = mapped_column(JSONB_TYPE, nullable=True) request_snapshot: Mapped[Optional[dict]] = mapped_column(JSONB_TYPE, nullable=True) auth_status: Mapped[str] = mapped_column(String(30), nullable=False) user_identifier: Mapped[Optional[str]] = mapped_column(String(80), nullable=True) request_id: Mapped[Optional[str]] = mapped_column(String(36), nullable=True) category: Mapped[Optional[str]] = mapped_column(String(30), nullable=True) severity: Mapped[Optional[str]] = mapped_column(String(16), nullable=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now() )