átlagos kiegészítséek jó sok

This commit is contained in:
Roo
2026-03-22 11:02:05 +00:00
parent f53e0b53df
commit 5d44339f21
249 changed files with 20922 additions and 2253 deletions

View File

@@ -0,0 +1,12 @@
# system package barrel
from .system import SystemParameter, ParameterScope, InternalNotification, SystemServiceStaging
from .audit import SecurityAuditLog, OperationalLog, ProcessLog, FinancialLedger, WalletType, LedgerStatus, LedgerEntryType
from .document import Document
from .translation import Translation
from .legal import LegalDocument, LegalAcceptance
__all__ = [
"SystemParameter", "InternalNotification", "SystemServiceStaging",
"SecurityAuditLog", "ProcessLog", "FinancialLedger", "WalletType", "LedgerStatus", "LedgerEntryType",
"Document", "Translation", "LegalDocument", "LegalAcceptance"
]

View File

@@ -0,0 +1,115 @@
# /opt/docker/dev/service_finder/backend/app/models/system/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
)

View File

@@ -0,0 +1,42 @@
# /opt/docker/dev/service_finder/backend/app/models/system/document.py
import uuid
from datetime import datetime
from typing import Optional
from sqlalchemy import String, Integer, Boolean, DateTime, ForeignKey, Text
from sqlalchemy.dialects.postgresql import UUID as PG_UUID
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.sql import func
from app.database import Base # MB 2.0: Egységesített Base a szinkronitáshoz
class Document(Base):
""" NAS alapú dokumentumtár metaadatai. """
__tablename__ = "documents"
__table_args__ = {"schema": "system"}
id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
parent_type: Mapped[str] = mapped_column(String(20)) # 'organization' vagy 'asset'
parent_id: Mapped[str] = mapped_column(String(50), index=True)
doc_type: Mapped[Optional[str]] = mapped_column(String(50))
original_name: Mapped[str] = mapped_column(String(255))
file_hash: Mapped[str] = mapped_column(String(64))
file_ext: Mapped[str] = mapped_column(String(10), default="webp")
mime_type: Mapped[str] = mapped_column(String(100), default="image/webp")
file_size: Mapped[Optional[int]] = mapped_column(Integer)
has_thumbnail: Mapped[bool] = mapped_column(Boolean, default=False)
thumbnail_path: Mapped[Optional[str]] = mapped_column(String(255))
uploaded_by: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id"))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
# =========================================================================
# THOUGHT PROCESS & ARCHITECTURE DECISIONS (2026-03-04)
# =========================================================================
# Probléma: Az `ocr_robot.py` (Robot 3) módosítani próbálta a dokumentumok
# állapotát és menteni akarta az AI eredményeket, de a mezők hiányoztak.
# =========================================================================
status: Mapped[str] = mapped_column(String(50), default="uploaded", index=True)
ocr_data: Mapped[Optional[str]] = mapped_column(Text)
error_log: Mapped[Optional[str]] = mapped_column(Text)

View File

@@ -0,0 +1,33 @@
# /opt/docker/dev/service_finder/backend/app/models/system/legal.py
from datetime import datetime
from typing import Optional
from sqlalchemy import Integer, String, Text, DateTime, ForeignKey, Boolean
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.sql import func
from app.db.base_class import Base
class LegalDocument(Base):
__tablename__ = "legal_documents"
__table_args__ = {"schema": "system"}
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
title: Mapped[Optional[str]] = mapped_column(String(255))
content: Mapped[str] = mapped_column(Text)
version: Mapped[str] = mapped_column(String(20))
region_code: Mapped[str] = mapped_column(String(5), default="HU")
language: Mapped[str] = mapped_column(String(5), default="hu")
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
class LegalAcceptance(Base):
__tablename__ = "legal_acceptances"
__table_args__ = {"schema": "identity"}
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"))
document_id: Mapped[int] = mapped_column(Integer, ForeignKey("system.legal_documents.id"))
accepted_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
ip_address: Mapped[Optional[str]] = mapped_column(String(45))
user_agent: Mapped[Optional[str]] = mapped_column(Text)

View File

@@ -0,0 +1,91 @@
# /opt/docker/dev/service_finder/backend/app/models/system/system.py
import uuid
from datetime import datetime, date
from enum import Enum
from typing import Optional
from sqlalchemy import String, Integer, Boolean, DateTime, text, UniqueConstraint, ForeignKey, Text, Enum as SQLEnum, Date
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.sql import func
from app.database import Base
class ParameterScope(str, Enum):
GLOBAL = "global"
COUNTRY = "country"
REGION = "region"
USER = "user"
class SystemParameter(Base):
""" Dinamikus konfigurációs motor (Global -> Org -> User). """
__tablename__ = "system_parameters"
__table_args__ = (
UniqueConstraint('key', 'scope_level', 'scope_id', name='uix_param_scope'),
{"schema": "system", "extend_existing": True}
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
key: Mapped[str] = mapped_column(String, index=True)
category: Mapped[str] = mapped_column(String, server_default="general", index=True)
value: Mapped[dict] = mapped_column(JSONB, nullable=False)
scope_level: Mapped[ParameterScope] = mapped_column(SQLEnum(ParameterScope, name="parameter_scope", schema="system"), server_default=ParameterScope.GLOBAL.value, index=True)
scope_id: Mapped[Optional[str]] = mapped_column(String(50))
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
description: Mapped[Optional[str]] = mapped_column(String)
last_modified_by: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now())
class InternalNotification(Base):
"""
Belső értesítési központ.
Ezek az üzenetek várják a felhasználót belépéskor.
"""
__tablename__ = "internal_notifications"
__table_args__ = ({"schema": "system", "extend_existing": True})
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id: Mapped[int] = mapped_column(ForeignKey("identity.users.id", ondelete="CASCADE"), nullable=False, index=True)
title: Mapped[str] = mapped_column(String(255), nullable=False)
message: Mapped[str] = mapped_column(Text, nullable=False)
category: Mapped[str] = mapped_column(String(50), server_default="info")
priority: Mapped[str] = mapped_column(String(20), server_default="medium")
read_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
data: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True)
is_read: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
class SystemServiceStaging(Base):
""" Robot 1.3 (Scout) által talált nyers szerviz adatok. """
__tablename__ = "service_staging"
__table_args__ = {"schema": "system"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
name: Mapped[str] = mapped_column(String(255), index=True)
source: Mapped[str] = mapped_column(String(50))
external_id: Mapped[Optional[str]] = mapped_column(String(100), index=True)
fingerprint: Mapped[str] = mapped_column(String(64), unique=True, index=True)
postal_code: Mapped[Optional[str]] = mapped_column(String(20), index=True)
city: Mapped[str] = mapped_column(String(100), index=True)
full_address: Mapped[Optional[str]] = mapped_column(String(500))
contact_phone: Mapped[Optional[str]] = mapped_column(String(50))
website: Mapped[Optional[str]] = mapped_column(String(255))
contact_email: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
raw_data: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
status: Mapped[str] = mapped_column(String(20), default="pending", index=True)
trust_score: Mapped[int] = mapped_column(Integer, default=30)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), onupdate=func.now())
# JAVÍTÁS: Ezeket az oszlopokat vissza kell tenni, mert az audit szerint
# az adatbázisban léteznek a system.service_staging táblában.
read_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
data: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True)

View File

@@ -0,0 +1,27 @@
# /opt/docker/dev/service_finder/backend/app/models/system/translation.py
from sqlalchemy import String, Integer, Text, Boolean, text
from sqlalchemy.orm import Mapped, mapped_column
# MB 2.0: A központi aszinkron adatbázis motorból húzzuk be a Base-t
from app.database import Base
class Translation(Base):
"""
Többnyelvűséget támogató tábla a felületi elemekhez és dinamikus tartalmakhoz.
"""
__tablename__ = "translations"
__table_args__ = {"schema": "system"}
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
# A fordítandó kulcs (pl. 'NAV_DASHBOARD' vagy 'ERR_USER_NOT_FOUND')
key: Mapped[str] = mapped_column(String(255), index=True)
# Nyelvi kód (pl: 'hu', 'en', 'de')
lang: Mapped[str] = mapped_column(String(5), index=True)
# A tényleges fordított szöveg
value: Mapped[str] = mapped_column(Text)
# --- JAVÍTÁS: A diagnosztika által hiányolt publikációs állapot ---
is_published: Mapped[bool] = mapped_column(Boolean, default=True, server_default=text("true"))