Files
service-finder/backend/app/models/vehicle_definitions.py

155 lines
8.4 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": "data"}
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": "data"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
vehicle_type_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.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):
"""
Robot v1.1.0 Multi-Tier MDM Master Adattábla.
Az ökoszisztéma technikai igazságforrása.
"""
__tablename__ = "vehicle_model_definitions"
__table_args__ = {"schema": "data"}
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("data.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', name='uix_vmd_precision'),
Index('idx_vmd_lookup_fast', 'make', 'normalized_name'),
Index('idx_vmd_engine_bridge', 'make', 'engine_code'),
{"schema": "data"}
)
# 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 nevet
variants: Mapped[List["AssetCatalog"]] = relationship("AssetCatalog", back_populates="master_definition")
class ModelFeatureMap(Base):
""" Kapcsolótábla a modellek és az alapfelszereltség között """
__tablename__ = "model_feature_maps"
__table_args__ = {"schema": "data"}
id: Mapped[int] = mapped_column(Integer, primary_key=True)
model_definition_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.vehicle_model_definitions.id"))
feature_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.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")