feat: Asset Catalog system, PostGIS integration and RobotScout V1
This commit is contained in:
@@ -6,42 +6,57 @@ from sqlalchemy.sql import func
|
||||
from app.db.base_class import Base
|
||||
|
||||
class AssetCatalog(Base):
|
||||
"""Globális járműkatalógus (Márka -> Típus -> Generáció -> Motor)."""
|
||||
__tablename__ = "vehicle_catalog"
|
||||
__table_args__ = {"schema": "data"}
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
make = Column(String, index=True, nullable=False)
|
||||
model = Column(String, index=True, nullable=False)
|
||||
generation = Column(String)
|
||||
make = Column(String, index=True, nullable=False) # 1. Szint: Audi
|
||||
model = Column(String, index=True, nullable=False) # 2. Szint: A4
|
||||
generation = Column(String, index=True) # 3. Szint: B8 (2008-2015)
|
||||
engine_variant = Column(String) # 4. Szint: 2.0 TDI (150 LE)
|
||||
|
||||
year_from = Column(Integer)
|
||||
year_to = Column(Integer)
|
||||
vehicle_class = Column(String)
|
||||
fuel_type = Column(String)
|
||||
engine_code = Column(String)
|
||||
factory_data = Column(JSON, server_default=text("'{}'::jsonb"))
|
||||
factory_data = Column(JSON, server_default=text("'{}'::jsonb")) # Technikai specifikációk
|
||||
|
||||
assets = relationship("Asset", back_populates="catalog")
|
||||
|
||||
class Asset(Base):
|
||||
"""Egyedi jármű (Asset) példány - Az ökoszisztéma magja."""
|
||||
__tablename__ = "assets"
|
||||
__table_args__ = {"schema": "data"}
|
||||
|
||||
id = Column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
vin = Column(String(17), unique=True, index=True, nullable=False)
|
||||
license_plate = Column(String(20), index=True)
|
||||
name = Column(String)
|
||||
year_of_manufacture = Column(Integer)
|
||||
|
||||
# --- BIZTONSÁGI ÉS JOGOSULTSÁGI IZOLÁCIÓ ---
|
||||
# A current_organization_id biztosítja a gyors, adatbázis-szintű Scoped RBAC védelmet.
|
||||
current_organization_id = Column(Integer, ForeignKey("data.organizations.id"), nullable=True)
|
||||
|
||||
catalog_id = Column(Integer, ForeignKey("data.vehicle_catalog.id"))
|
||||
is_verified = Column(Boolean, default=False)
|
||||
verification_method = Column(String(20)) # 'robot', 'ocr', 'manual'
|
||||
status = Column(String(20), default="active")
|
||||
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
|
||||
# Kapcsolatok (Digital Twin Modules)
|
||||
catalog = relationship("AssetCatalog", back_populates="assets")
|
||||
current_org = relationship("Organization")
|
||||
financials = relationship("AssetFinancials", back_populates="asset", uselist=False)
|
||||
telemetry = relationship("AssetTelemetry", back_populates="asset", uselist=False)
|
||||
assignments = relationship("AssetAssignment", back_populates="asset")
|
||||
events = relationship("AssetEvent", back_populates="asset")
|
||||
costs = relationship("AssetCost", back_populates="asset")
|
||||
reviews = relationship("AssetReview", back_populates="asset")
|
||||
ownership_history = relationship("VehicleOwnership", back_populates="vehicle")
|
||||
|
||||
class AssetFinancials(Base):
|
||||
__tablename__ = "asset_financials"
|
||||
@@ -77,9 +92,10 @@ class AssetReview(Base):
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
asset = relationship("Asset", back_populates="reviews")
|
||||
user = relationship("User") # <--- JAVÍTÁS: Hozzáadva
|
||||
user = relationship("User")
|
||||
|
||||
class AssetAssignment(Base):
|
||||
"""Jármű flotta-történetének nyilvántartása."""
|
||||
__tablename__ = "asset_assignments"
|
||||
__table_args__ = {"schema": "data"}
|
||||
id = Column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
@@ -90,7 +106,7 @@ class AssetAssignment(Base):
|
||||
status = Column(String(30), default="active")
|
||||
|
||||
asset = relationship("Asset", back_populates="assignments")
|
||||
organization = relationship("Organization") # <--- KRITIKUS JAVÍTÁS: Ez okozta a login hibát
|
||||
organization = relationship("Organization")
|
||||
|
||||
class AssetEvent(Base):
|
||||
__tablename__ = "asset_events"
|
||||
@@ -113,16 +129,13 @@ class AssetCost(Base):
|
||||
amount_local = Column(Numeric(18, 2), nullable=False)
|
||||
currency_local = Column(String(3), nullable=False)
|
||||
amount_eur = Column(Numeric(18, 2), nullable=True)
|
||||
net_amount_local = Column(Numeric(18, 2))
|
||||
vat_rate = Column(Numeric(5, 2))
|
||||
exchange_rate_used = Column(Numeric(18, 6))
|
||||
date = Column(DateTime(timezone=True), server_default=func.now())
|
||||
mileage_at_cost = Column(Integer)
|
||||
data = Column(JSON, server_default=text("'{}'::jsonb"))
|
||||
|
||||
asset = relationship("Asset", back_populates="costs")
|
||||
organization = relationship("Organization") # <--- JAVÍTÁS: Hozzáadva
|
||||
driver = relationship("User") # <--- JAVÍTÁS: Hozzáadva
|
||||
organization = relationship("Organization")
|
||||
driver = relationship("User")
|
||||
|
||||
class ExchangeRate(Base):
|
||||
__tablename__ = "exchange_rates"
|
||||
@@ -131,5 +144,4 @@ class ExchangeRate(Base):
|
||||
base_currency = Column(String(3), default="EUR")
|
||||
target_currency = Column(String(3), unique=True)
|
||||
rate = Column(Numeric(18, 6), nullable=False)
|
||||
rate_date = Column(DateTime, server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
Reference in New Issue
Block a user