Files
service-finder/backend/app/models/audit.py
2026-03-13 10:22:41 +00:00

115 lines
5.5 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# /opt/docker/dev/service_finder/backend/app/models/audit.py
import enum
import uuid
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 sqlalchemy.dialects.postgresql import UUID as PG_UUID, ENUM as PG_ENUM
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"
__table_args__ = {"schema": "audit"}
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"
__table_args__ = {"schema": "audit"}
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"
__table_args__ = {"schema": "audit"}
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 LedgerEntryType(str, enum.Enum):
DEBIT = "DEBIT"
CREDIT = "CREDIT"
class WalletType(str, enum.Enum):
EARNED = "EARNED"
PURCHASED = "PURCHASED"
SERVICE_COINS = "SERVICE_COINS"
VOUCHER = "VOUCHER"
class LedgerStatus(str, enum.Enum):
PENDING = "PENDING"
SUCCESS = "SUCCESS"
FAILED = "FAILED"
REFUNDED = "REFUNDED"
REFUND = "REFUND"
class FinancialLedger(Base):
""" Minden pénz- és kreditmozgás központi naplója. Billing Engine alapja. """
__tablename__ = "financial_ledger"
__table_args__ = {"schema": "audit"}
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())
# Új mezők doubleentry és okos levonáshoz
entry_type: Mapped[LedgerEntryType] = mapped_column(
PG_ENUM(LedgerEntryType, name="ledger_entry_type", schema="audit"),
nullable=False
)
balance_after: Mapped[Optional[float]] = mapped_column(Numeric(18, 4))
wallet_type: Mapped[Optional[WalletType]] = mapped_column(
PG_ENUM(WalletType, name="wallet_type", schema="audit")
)
# Economy 1: számlázási mezők
issuer_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("finance.issuers.id"), nullable=True)
invoice_status: Mapped[Optional[str]] = mapped_column(String(50), default="PENDING")
tax_amount: Mapped[Optional[float]] = mapped_column(Numeric(18, 4))
gross_amount: Mapped[Optional[float]] = mapped_column(Numeric(18, 4))
net_amount: Mapped[Optional[float]] = mapped_column(Numeric(18, 4))
transaction_id: Mapped[uuid.UUID] = mapped_column(
PG_UUID(as_uuid=True), default=uuid.uuid4, nullable=False, index=True
)
status: Mapped[LedgerStatus] = mapped_column(
PG_ENUM(LedgerStatus, name="ledger_status", schema="audit"),
default=LedgerStatus.SUCCESS,
nullable=False
)