# /opt/docker/dev/service_finder/backend/app/models/audit.py from datetime import datetime from typing import Any, Optional from sqlalchemy import String, DateTime, JSON, ForeignKey, text, Numeric, Boolean, BigInteger, Integer from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.sql import func from app.database import Base class SecurityAuditLog(Base): """ Kiemelt biztonsági események és a 4-szem elv naplózása. """ __tablename__ = "security_audit_logs" id: Mapped[int] = mapped_column(Integer, primary_key=True) action: Mapped[Optional[str]] = mapped_column(String(50)) # 'ROLE_CHANGE', 'MANUAL_CREDIT_ADJUST' actor_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id")) target_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id")) confirmed_by_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=True) is_critical: Mapped[bool] = mapped_column(Boolean, default=False) payload_before: Mapped[Any] = mapped_column(JSON) payload_after: Mapped[Any] = mapped_column(JSON) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class OperationalLog(Base): """ Felhasználói szintű napi üzemi események (Audit Trail). """ __tablename__ = "operational_logs" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) user_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id", ondelete="SET NULL")) action: Mapped[str] = mapped_column(String(100), nullable=False) # pl. "ADD_VEHICLE" resource_type: Mapped[Optional[str]] = mapped_column(String(50)) resource_id: Mapped[Optional[str]] = mapped_column(String(100)) details: Mapped[Any] = mapped_column(JSON, server_default=text("'{}'::jsonb")) ip_address: Mapped[Optional[str]] = mapped_column(String(45)) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class ProcessLog(Base): """ Robotok és háttérfolyamatok futási naplója (A reggeli jelentésekhez). """ __tablename__ = "process_logs" id: Mapped[int] = mapped_column(Integer, primary_key=True) process_name: Mapped[str] = mapped_column(String(100), index=True) # 'Master-Enricher' start_time: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) end_time: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True)) items_processed: Mapped[int] = mapped_column(Integer, default=0) items_failed: Mapped[int] = mapped_column(Integer, default=0) details: Mapped[Any] = mapped_column(JSON, server_default=text("'{}'::jsonb")) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class FinancialLedger(Base): """ Minden pénz- és kreditmozgás központi naplója. Billing Engine alapja. """ __tablename__ = "financial_ledger" id: Mapped[int] = mapped_column(Integer, primary_key=True) user_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id")) person_id: Mapped[Optional[int]] = mapped_column(BigInteger, ForeignKey("identity.persons.id")) amount: Mapped[float] = mapped_column(Numeric(18, 4), nullable=False) currency: Mapped[Optional[str]] = mapped_column(String(10)) transaction_type: Mapped[Optional[str]] = mapped_column(String(50)) related_agent_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id")) details: Mapped[Any] = mapped_column(JSON, server_default=text("'{}'::jsonb")) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())