161 lines
8.8 KiB
Python
Executable File
161 lines
8.8 KiB
Python
Executable File
# /opt/docker/dev/service_finder/backend/app/models/vehicle_definitions.py
|
|
from __future__ import annotations
|
|
from datetime import datetime
|
|
from typing import Optional, List
|
|
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, text, JSON, Index, UniqueConstraint, Text, ARRAY, func, Numeric
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
from sqlalchemy.sql import func
|
|
|
|
# MB 2.0: Egységesített Base import a központi adatbázis motorból
|
|
from app.database import Base
|
|
|
|
class VehicleType(Base):
|
|
""" Jármű kategóriák (pl. Személyautó, Motorkerékpár, Teherautó, Hajó) """
|
|
__tablename__ = "vehicle_types"
|
|
__table_args__ = {"schema": "vehicle"}
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
code: Mapped[str] = mapped_column(String(30), unique=True, index=True)
|
|
name: Mapped[str] = mapped_column(String(50))
|
|
icon: Mapped[Optional[str]] = mapped_column(String(50))
|
|
units: Mapped[dict] = mapped_column(JSONB, server_default=text("'{\"power\": \"kW\", \"weight\": \"kg\"}'::jsonb"))
|
|
|
|
# Kapcsolatok
|
|
features: Mapped[List["FeatureDefinition"]] = relationship("FeatureDefinition", back_populates="vehicle_type")
|
|
definitions: Mapped[List["VehicleModelDefinition"]] = relationship("VehicleModelDefinition", back_populates="v_type_rel")
|
|
|
|
|
|
class FeatureDefinition(Base):
|
|
""" Felszereltségi elemek definíciója (pl. ABS, Klíma, LED fényszóró) """
|
|
__tablename__ = "feature_definitions"
|
|
__table_args__ = {"schema": "vehicle"}
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
vehicle_type_id: Mapped[int] = mapped_column(Integer, ForeignKey("vehicle.vehicle_types.id"))
|
|
code: Mapped[str] = mapped_column(String(50), index=True)
|
|
name: Mapped[str] = mapped_column(String(100))
|
|
category: Mapped[str] = mapped_column(String(50), index=True)
|
|
|
|
vehicle_type: Mapped["VehicleType"] = relationship("VehicleType", back_populates="features")
|
|
model_maps: Mapped[List["ModelFeatureMap"]] = relationship("ModelFeatureMap", back_populates="feature")
|
|
|
|
|
|
class VehicleModelDefinition(Base):
|
|
market: Mapped[str] = mapped_column(String(20), server_default=text("'GLOBAL'"), index=True)
|
|
"""
|
|
Robot v1.1.0 Multi-Tier MDM Master Adattábla.
|
|
Az ökoszisztéma technikai igazságforrása.
|
|
"""
|
|
__tablename__ = "vehicle_model_definitions"
|
|
__table_args__ = {"schema": "vehicle"}
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
|
|
make: Mapped[str] = mapped_column(String(100), index=True)
|
|
marketing_name: Mapped[str] = mapped_column(String(255), index=True) # Nyers név az RDW-ből
|
|
official_marketing_name: Mapped[Optional[str]] = mapped_column(String(255)) # Dúsított, validált név (Robot 2.2)
|
|
|
|
# --- ROBOT LOGIKAI MEZŐK (JAVÍTVA 2.0 STÍLUSBAN) ---
|
|
attempts: Mapped[int] = mapped_column(Integer, default=0, server_default=text("0"))
|
|
last_error: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now())
|
|
priority_score: Mapped[int] = mapped_column(Integer, default=0, server_default=text("0"))
|
|
|
|
# --- PRECISION LOGIC MEZŐK ---
|
|
normalized_name: Mapped[Optional[str]] = mapped_column(String(255), index=True, nullable=True)
|
|
marketing_name_aliases: Mapped[list] = mapped_column(JSONB, server_default=text("'[]'::jsonb"))
|
|
engine_code: Mapped[Optional[str]] = mapped_column(String(50), index=True) # A GLOBÁLIS KAPOCS
|
|
|
|
# --- TECHNIKAI AZONOSÍTÓK ---
|
|
technical_code: Mapped[str] = mapped_column(String(100), index=True) # Holland rendszám (kulcs)
|
|
variant_code: Mapped[Optional[str]] = mapped_column(String(100), index=True)
|
|
version_code: Mapped[Optional[str]] = mapped_column(String(100), index=True)
|
|
|
|
# --- ÚJ PRÉMIUM MŰSZAKI MEZŐK ---
|
|
type_approval_number: Mapped[Optional[str]] = mapped_column(String(100), index=True) # e1*2001/...
|
|
seats: Mapped[Optional[int]] = mapped_column(Integer)
|
|
width: Mapped[Optional[int]] = mapped_column(Integer) # cm
|
|
wheelbase: Mapped[Optional[int]] = mapped_column(Integer) # cm
|
|
list_price: Mapped[Optional[int]] = mapped_column(Integer) # EUR (catalogusprijs)
|
|
max_speed: Mapped[Optional[int]] = mapped_column(Integer) # km/h
|
|
|
|
# Vontatási adatok
|
|
towing_weight_unbraked: Mapped[Optional[int]] = mapped_column(Integer)
|
|
towing_weight_braked: Mapped[Optional[int]] = mapped_column(Integer)
|
|
|
|
# Környezetvédelmi adatok
|
|
fuel_consumption_combined: Mapped[Optional[float]] = mapped_column(Numeric(10, 2), nullable=True)
|
|
co2_emissions_combined: Mapped[Optional[int]] = mapped_column(Integer)
|
|
|
|
|
|
# --- SPECIFIKÁCIÓK ---
|
|
vehicle_type_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("vehicle.vehicle_types.id"))
|
|
vehicle_class: Mapped[Optional[str]] = mapped_column(String(50), index=True)
|
|
body_type: Mapped[Optional[str]] = mapped_column(String(100))
|
|
fuel_type: Mapped[Optional[str]] = mapped_column(String(50), index=True)
|
|
|
|
engine_capacity: Mapped[int] = mapped_column(Integer, default=0, index=True)
|
|
power_kw: Mapped[int] = mapped_column(Integer, default=0, index=True)
|
|
torque_nm: Mapped[Optional[int]] = mapped_column(Integer)
|
|
cylinders: Mapped[Optional[int]] = mapped_column(Integer)
|
|
cylinder_layout: Mapped[Optional[str]] = mapped_column(String(50))
|
|
|
|
curb_weight: Mapped[Optional[int]] = mapped_column(Integer)
|
|
max_weight: Mapped[Optional[int]] = mapped_column(Integer)
|
|
euro_classification: Mapped[Optional[str]] = mapped_column(String(20))
|
|
doors: Mapped[Optional[int]] = mapped_column(Integer)
|
|
transmission_type: Mapped[Optional[str]] = mapped_column(String(50))
|
|
drive_type: Mapped[Optional[str]] = mapped_column(String(50))
|
|
|
|
# --- ÉLETCIKLUS ÉS STÁTUSZ ---
|
|
year_from: Mapped[Optional[int]] = mapped_column(Integer, index=True)
|
|
year_to: Mapped[Optional[int]] = mapped_column(Integer, index=True)
|
|
production_status: Mapped[Optional[str]] = mapped_column(String(50)) # active / discontinued
|
|
|
|
# Státusz szintek: unverified, research_in_progress, awaiting_ai_synthesis, gold_enriched
|
|
status: Mapped[str] = mapped_column(String(50), server_default=text("'unverified'"), index=True)
|
|
is_manual: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
source: Mapped[Optional[str]] = mapped_column(String(100))
|
|
|
|
# --- ADAT-KONTÉNEREK ---
|
|
raw_search_context: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
|
|
research_metadata: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
|
|
specifications: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb")) # Robot 2.2/2.5 Arany adatai
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
last_research_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
|
|
|
|
# --- BEÁLLÍTÁSOK ---
|
|
__table_args__ = (
|
|
UniqueConstraint('make', 'normalized_name', 'variant_code', 'version_code', 'fuel_type', 'market', 'year_from', name='uix_vmd_precision_v2'),
|
|
Index('idx_vmd_lookup_fast', 'make', 'normalized_name'),
|
|
Index('idx_vmd_engine_bridge', 'make', 'engine_code'),
|
|
{"schema": "vehicle"}
|
|
)
|
|
|
|
# KAPCSOLATOK
|
|
v_type_rel: Mapped["VehicleType"] = relationship("VehicleType", back_populates="definitions")
|
|
feature_maps: Mapped[List["ModelFeatureMap"]] = relationship("ModelFeatureMap", back_populates="model_definition")
|
|
|
|
# Hivatkozás az asset.py-ban lévő osztályra
|
|
# Megjegyzés: Ha az AssetCatalog nincs itt importálva, húzzal adjuk meg a neve
|
|
variants: Mapped[List["AssetCatalog"]] = relationship("AssetCatalog", back_populates="master_definition")
|
|
|
|
# TCO költségnapló kapcsolata
|
|
costs: Mapped[List["VehicleCost"]] = relationship("VehicleCost", back_populates="vehicle")
|
|
# Kilométeróra állapot kapcsolata
|
|
odometer_state: Mapped["VehicleOdometerState"] = relationship("VehicleOdometerState", back_populates="vehicle")
|
|
|
|
|
|
class ModelFeatureMap(Base):
|
|
""" Kapcsolótábla a modellek és az alapfelszereltség között """
|
|
__tablename__ = "model_feature_maps"
|
|
__table_args__ = {"schema": "vehicle"}
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
model_definition_id: Mapped[int] = mapped_column(Integer, ForeignKey("vehicle.vehicle_model_definitions.id"))
|
|
feature_id: Mapped[int] = mapped_column(Integer, ForeignKey("vehicle.feature_definitions.id"))
|
|
is_standard: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
|
|
model_definition: Mapped["VehicleModelDefinition"] = relationship("VehicleModelDefinition", back_populates="feature_maps")
|
|
feature: Mapped["FeatureDefinition"] = relationship("FeatureDefinition", back_populates="model_maps") |