feat(infra): Stabilized Docker env, fixed circular imports, enabled AI Enricher Robot v1.1

This commit is contained in:
2026-02-17 01:26:18 +00:00
parent d574d3297d
commit 2def6b2201
34 changed files with 1559 additions and 112 deletions

View File

@@ -6,7 +6,7 @@ from datetime import datetime, timedelta
from app.api import deps from app.api import deps
from app.models.identity import User, UserRole from app.models.identity import User, UserRole
from app.models.system_config import SystemParameter from app.models import SystemParameter
from app.models.security import PendingAction, ActionStatus from app.models.security import PendingAction, ActionStatus
from app.models.history import AuditLog, LogSeverity from app.models.history import AuditLog, LogSeverity
from app.schemas.admin_security import PendingActionResponse, SecurityStatusResponse from app.schemas.admin_security import PendingActionResponse, SecurityStatusResponse

View File

@@ -8,7 +8,7 @@ from sqlalchemy.orm import sessionmaker
try: try:
from app.core.config import settings from app.core.config import settings
from app.core.i18n import t from app.core.i18n import t
from app.models.system_config import SystemParameter from app.models import SystemParameter
except ImportError as e: except ImportError as e:
print(f"❌ Import hiba: {e}") print(f"❌ Import hiba: {e}")
print("Ellenőrizd, hogy a PYTHONPATH be van-e állítva!") print("Ellenőrizd, hogy a PYTHONPATH be van-e állítva!")

View File

@@ -32,10 +32,13 @@ from .translation import Translation
from .core_logic import SubscriptionTier, OrganizationSubscription, CreditTransaction, ServiceSpecialty from .core_logic import SubscriptionTier, OrganizationSubscription, CreditTransaction, ServiceSpecialty
# Naplózás és Biztonság (HOZZÁADVA: audit.py modellek) # Naplózás és Biztonság (HOZZÁADVA: audit.py modellek)
from .audit import SecurityAuditLog, OperationalLog, FinancialLedger # <--- KRITIKUS! from .audit import SecurityAuditLog, ProcessLog, FinancialLedger # <--- KRITIKUS!
from .history import AuditLog, VehicleOwnership from .history import AuditLog, VehicleOwnership
from .security import PendingAction from .security import PendingAction
# MDM (Master Data Management) Jármű modellek központ
from .vehicle_definitions import VehicleModelDefinition, VehicleType, FeatureDefinition, ModelFeatureMap
# Aliasok a kényelmesebb fejlesztéshez # Aliasok a kényelmesebb fejlesztéshez
Vehicle = Asset Vehicle = Asset
UserVehicle = Asset UserVehicle = Asset
@@ -48,11 +51,12 @@ __all__ = [
"Asset", "AssetCatalog", "AssetCost", "AssetEvent", "AssetFinancials", "Asset", "AssetCatalog", "AssetCost", "AssetEvent", "AssetFinancials",
"AssetTelemetry", "AssetReview", "ExchangeRate", "AssetTelemetry", "AssetReview", "ExchangeRate",
"Address", "GeoPostalCode", "GeoStreet", "GeoStreetType", "Branch", "Address", "GeoPostalCode", "GeoStreet", "GeoStreetType", "Branch",
"Point_Rule", "LevelConfig", "UserStats", "Badge", "UserBadge", "Rating", "PointsLedger", "PointRule", "LevelConfig", "UserStats", "Badge", "UserBadge", "Rating", "PointsLedger",
"SystemParameter", "Document", "Translation", "PendingAction", "SystemParameter", "Document", "Translation", "PendingAction",
"SubscriptionTier", "OrganizationSubscription", "SubscriptionTier", "OrganizationSubscription",
"CreditTransaction", "ServiceSpecialty", "AuditLog", "VehicleOwnership", "CreditTransaction", "ServiceSpecialty", "AuditLog", "VehicleOwnership",
"SecurityAuditLog", "OperationalLog", "FinancialLedger", # <--- KRITIKUS! "SecurityAuditLog", "ProcessLog", "FinancialLedger", # <--- KRITIKUS!
"ServiceProfile", "ExpertiseTag", "ServiceExpertise", "ServiceStaging", "ServiceProfile", "ExpertiseTag", "ServiceExpertise", "ServiceStaging",
"Vehicle", "UserVehicle", "VehicleCatalog", "ServiceRecord" "Vehicle", "UserVehicle", "VehicleCatalog", "ServiceRecord", "VehicleModelDefinition",
"VehicleType", "FeatureDefinition", "ModelFeatureMap"
] ]

View File

@@ -16,6 +16,9 @@ class AssetCatalog(Base):
) )
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
# Kapcsolat az MDM-hez
master_definition_id = Column(Integer, ForeignKey("data.vehicle_model_definitions.id"), nullable=True)
make = Column(String, index=True, nullable=False) make = Column(String, index=True, nullable=False)
model = Column(String, index=True, nullable=False) model = Column(String, index=True, nullable=False)
generation = Column(String, index=True) generation = Column(String, index=True)
@@ -24,7 +27,10 @@ class AssetCatalog(Base):
year_to = Column(Integer) year_to = Column(Integer)
vehicle_class = Column(String) vehicle_class = Column(String)
fuel_type = Column(String, index=True) fuel_type = Column(String, index=True)
# ÚJ MEZŐ: Kapcsolat az MDM-hez
master_definition = relationship("VehicleModelDefinition", back_populates="variants")
# --- ÚJ OSZLOPOK (Ezeket add hozzá!) --- # --- ÚJ OSZLOPOK (Ezeket add hozzá!) ---
power_kw = Column(Integer, index=True) power_kw = Column(Integer, index=True)
engine_capacity = Column(Integer, index=True) engine_capacity = Column(Integer, index=True)

View File

@@ -13,28 +13,41 @@ class SecurityAuditLog(Base):
actor_id = Column(Integer, ForeignKey("data.users.id")) # Aki kezdeményezte actor_id = Column(Integer, ForeignKey("data.users.id")) # Aki kezdeményezte
target_id = Column(Integer, ForeignKey("data.users.id")) # Akivel történt target_id = Column(Integer, ForeignKey("data.users.id")) # Akivel történt
# 4-szem elv: csak akkor válik élessé, ha ez nem NULL
confirmed_by_id = Column(Integer, ForeignKey("data.users.id"), nullable=True) confirmed_by_id = Column(Integer, ForeignKey("data.users.id"), nullable=True)
is_critical = Column(Boolean, default=False) # Szuperadmin hívásoknál True is_critical = Column(Boolean, default=False)
payload_before = Column(JSON) payload_before = Column(JSON)
payload_after = Column(JSON) payload_after = Column(JSON)
created_at = Column(DateTime(timezone=True), server_default=func.now()) created_at = Column(DateTime(timezone=True), server_default=func.now())
class OperationalLog(Base): class OperationalLog(Base):
""" Napi üzemi események (Operational). """ """ Felhasználói szintű napi üzemi események (Audit Trail). """
__tablename__ = "operational_logs" __tablename__ = "operational_logs"
__table_args__ = {"schema": "data", "extend_existing": True} __table_args__ = {"schema": "data", "extend_existing": True}
id = Column(Integer, primary_key=True, index=True) # <--- EZ HIÁNYZOTT! id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("data.users.id", ondelete="SET NULL"), nullable=True) user_id = Column(Integer, ForeignKey("data.users.id", ondelete="SET NULL"), nullable=True)
action = Column(String(100), nullable=False) # pl. "ADD_VEHICLE", "UPDATE_COST" action = Column(String(100), nullable=False) # pl. "ADD_VEHICLE"
resource_type = Column(String(50)) # pl. "Asset", "Expense" resource_type = Column(String(50))
resource_id = Column(String(100)) resource_id = Column(String(100))
details = Column(JSON, server_default=text("'{}'::jsonb")) details = Column(JSON, server_default=text("'{}'::jsonb"))
ip_address = Column(String(45)) ip_address = Column(String(45))
created_at = Column(DateTime(timezone=True), server_default=func.now()) created_at = 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" # Külön tábla a tisztaság kedvéért
__table_args__ = {"schema": "data", "extend_existing": True}
id = Column(Integer, primary_key=True)
process_name = Column(String(100), index=True) # 'Master-Enricher'
start_time = Column(DateTime(timezone=True), server_default=func.now())
end_time = Column(DateTime(timezone=True))
items_processed = Column(Integer, default=0)
items_failed = Column(Integer, default=0)
details = Column(JSON, server_default=text("'{}'::jsonb"))
created_at = Column(DateTime(timezone=True), server_default=func.now())
class FinancialLedger(Base): class FinancialLedger(Base):
""" Minden pénz- és kreditmozgás központi naplója. """ """ Minden pénz- és kreditmozgás központi naplója. """
__tablename__ = "financial_ledger" __tablename__ = "financial_ledger"
@@ -43,14 +56,9 @@ class FinancialLedger(Base):
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("data.users.id")) user_id = Column(Integer, ForeignKey("data.users.id"))
person_id = Column(BigInteger, ForeignKey("data.persons.id")) person_id = Column(BigInteger, ForeignKey("data.persons.id"))
amount = Column(Numeric(18, 4), nullable=False) amount = Column(Numeric(18, 4), nullable=False)
currency = Column(String(10)) # 'HUF', 'CREDIT', 'COIN' currency = Column(String(10))
transaction_type = Column(String(50))
transaction_type = Column(String(50)) # 'PURCHASE', 'HUNTING_COMMISSION', 'FARMING_COMMISSION'
# Üzletkötői követhetőség
related_agent_id = Column(Integer, ForeignKey("data.users.id"), nullable=True) related_agent_id = Column(Integer, ForeignKey("data.users.id"), nullable=True)
details = Column(JSON, server_default=text("'{}'::jsonb")) details = Column(JSON, server_default=text("'{}'::jsonb"))
created_at = Column(DateTime(timezone=True), server_default=func.now()) created_at = Column(DateTime(timezone=True), server_default=func.now())

View File

@@ -44,18 +44,22 @@ class PointsLedger(Base):
class UserStats(Base): class UserStats(Base):
__tablename__ = "user_stats" __tablename__ = "user_stats"
__table_args__ = SCHEMA_ARGS __table_args__ = {"schema": "data", "extend_existing": True} # Biztosítjuk a sémát
# A ForeignKey-nek látnia kell a data sémát!
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.users.id"), primary_key=True) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.users.id"), primary_key=True)
total_xp: Mapped[int] = mapped_column(Integer, default=0) total_xp: Mapped[int] = mapped_column(Integer, default=0)
social_points: Mapped[int] = mapped_column(Integer, default=0) social_points: Mapped[int] = mapped_column(Integer, default=0)
current_level: Mapped[int] = mapped_column(Integer, default=1) current_level: Mapped[int] = mapped_column(Integer, default=1)
# --- BÜNTETŐ RENDSZER (Strike System) --- # --- BÜNTETŐ RENDSZER ---
# JAVÍTÁS: server_default hozzáadva, hogy a meglévő sorok is 0-t kapjanak
penalty_points: Mapped[int] = mapped_column(Integer, server_default=text("0"), default=0) penalty_points: Mapped[int] = mapped_column(Integer, server_default=text("0"), default=0)
restriction_level: Mapped[int] = mapped_column(Integer, server_default=text("0"), default=0) restriction_level: Mapped[int] = mapped_column(Integer, server_default=text("0"), default=0)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), onupdate=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), onupdate=func.now())
# VISSZAMUTATÁS A USER-RE: a back_populates értéke meg kell egyezzen a User osztály 'stats' mezőjével!
user: Mapped["User"] = relationship("User", back_populates="stats") user: Mapped["User"] = relationship("User", back_populates="stats")

View File

@@ -85,6 +85,14 @@ class User(Base):
# Farming üzletkötő (Átruházható cégkezelő) # Farming üzletkötő (Átruházható cégkezelő)
current_sales_agent_id = Column(Integer, ForeignKey("data.users.id"), nullable=True) current_sales_agent_id = Column(Integer, ForeignKey("data.users.id"), nullable=True)
# Szervezeti kapcsolat
owned_organizations = relationship("Organization", back_populates="owner")
# Ez a sor felelős a gamification.py-val való hídért
stats = relationship("UserStats", back_populates="user", uselist=False, cascade="all, delete-orphan")
ownership_history = relationship("VehicleOwnership", back_populates="user")
is_active = Column(Boolean, default=False) is_active = Column(Boolean, default=False)
is_deleted = Column(Boolean, default=False) is_deleted = Column(Boolean, default=False)
folder_slug = Column(String(12), unique=True, index=True) folder_slug = Column(String(12), unique=True, index=True)

View File

@@ -0,0 +1,85 @@
from sqlalchemy import Column, Integer, String, JSON, UniqueConstraint, text, Boolean, DateTime, ForeignKey, Numeric
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.db.base_class import Base
class VehicleType(Base):
"""Jármű főtípusok sémája (Séma-gazda)"""
__tablename__ = "vehicle_types"
__table_args__ = {"schema": "data"}
id = Column(Integer, primary_key=True)
code = Column(String(30), unique=True, index=True) # car, motorcycle, truck, bus, boat, etc.
name = Column(String(50)) # Megjelenítendő név
icon = Column(String(50))
units = Column(JSON, server_default=text("'{\"power\": \"kW\", \"weight\": \"kg\", \"cargo\": \"m3\"}'::jsonb"))
features = relationship("FeatureDefinition", back_populates="vehicle_type")
definitions = relationship("VehicleModelDefinition", back_populates="v_type_rel")
class FeatureDefinition(Base):
"""Globális felszereltség szótár"""
__tablename__ = "feature_definitions"
__table_args__ = {"schema": "data"}
id = Column(Integer, primary_key=True)
vehicle_type_id = Column(Integer, ForeignKey("data.vehicle_types.id"))
category = Column(String(50)) # Műszaki, Beltér, Kültér, Multimédia
name = Column(String(100), nullable=False)
data_type = Column(String(20), default="boolean")
vehicle_type = relationship("VehicleType", back_populates="features")
class ModelFeatureMap(Base):
"""Modell-szintű felszereltségi sablon (Alap vs Extra)"""
__tablename__ = "model_feature_maps"
__table_args__ = {"schema": "data"}
model_id = Column(Integer, ForeignKey("data.vehicle_model_definitions.id"), primary_key=True)
feature_id = Column(Integer, ForeignKey("data.feature_definitions.id"), primary_key=True)
availability = Column(String(20), default="standard") # standard, optional, accessory
value = Column(String(100))
class VehicleModelDefinition(Base):
"""MDM Master rekordok"""
__tablename__ = "vehicle_model_definitions"
__table_args__ = (
UniqueConstraint('make', 'technical_code', 'vehicle_type', name='uix_make_tech_type'),
{"schema": "data"}
)
id = Column(Integer, primary_key=True)
make = Column(String(50), nullable=False, index=True)
technical_code = Column(String(50), nullable=False, index=True)
marketing_name = Column(String(100), index=True)
family_name = Column(String(100))
vehicle_type = Column(String(30), index=True)
vehicle_type_id = Column(Integer, ForeignKey("data.vehicle_types.id"))
vehicle_class = Column(String(50))
# --- LOGISZTIKAI ÉS TECHNIKAI FIX OSZLOPOK (v1.9) ---
engine_capacity = Column(Integer, index=True)
power_kw = Column(Integer, index=True)
max_weight_kg = Column(Integer, index=True) # Össztömeg
axle_count = Column(Integer) # Tengelyek száma (Teher/Busz)
payload_capacity_kg = Column(Integer) # Teherbírás
cargo_volume_m3 = Column(Numeric(10, 2)) # Raktér térfogat
cargo_length_mm = Column(Integer) # Raktér méretek
cargo_width_mm = Column(Integer)
cargo_height_mm = Column(Integer)
# --------------------------------------------------
specifications = Column(JSON, server_default=text("'{}'::jsonb"))
features_json = Column(JSON, server_default=text("'{}'::jsonb")) # Összesített gyorseléréshez
status = Column(String(20), server_default="unverified")
is_master = Column(Boolean, default=False)
source = Column(String(50))
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
v_type_rel = relationship("VehicleType", back_populates="definitions")
variants = relationship("AssetCatalog", back_populates="master_definition")

View File

@@ -0,0 +1,20 @@
# app/core/schemas/vehicle_categories.py
VEHICLE_SCHEMAS = {
"motorcycle": {
"features": ["ABS", "Markolatfűtés", "Szélvédő", "Bukócső/gomba", "Automata váltó", "Gyári dobozok", "Zárható doboz", "Veterán"],
"service_items": ["motorolaj", "olajszűrő", "levegőszűrő", "lánc_szett", "fékfolyadék", "gyújtógyertya", "szelephézag_ellenőrzés"]
},
"car": {
"features": ["Automata", "Tempomat", "Összkerékhajtás", "Alufelni", "Elektromos ablak", "Vonóhorog", "ISOFIX rendszer", "ESP", "Szervizkönyv", "Veterán"],
"service_items": ["motorolaj", "olajszűrő", "levegőszűrő", "pollenszűrő", "vezérlés_szett", "hosszbordásszíj", "váltóolaj", "fagyálló"]
},
"truck": {
"features": ["Légrugó", "Hálófülke", "Retarder/Intarder", "Emelőhátfal", "Tengelysúly-mérő", "AdBlue", "Állóhelyzeti klíma"],
"service_items": ["motorolaj", "légfék_szárító_patron", "üzemanyagszűrő", "érintésvédelmi_vizsga", "tengely_zsírozás"]
},
"boat": {
"features": ["Utánfutó", "Takaróponyva", "Orrsugárkormány", "Halradar", "Kormányállás", "Üzemanyagtartály", "Sólyakocsi", "Zárható tároló", "Elektromos horgonycsörlő"],
"service_items": ["motorolaj", "hajómotor_anód", "vízpumpa_lapát", "téliesítés", "algagátlózás"]
}
}

View File

@@ -0,0 +1,78 @@
import asyncio
from sqlalchemy import select, update, func
from app.db.session import SessionLocal
from app.models.asset import AssetCatalog
from app.models.vehicle_definitions import VehicleModelDefinition, VehicleType
async def link_catalog_to_mdm():
async with SessionLocal() as db:
try:
print("🔍 Meglévő variánsok elemzése...")
# 1. Lekérjük a típusokat a gyors kereséshez
type_res = await db.execute(select(VehicleType))
types = {t.code: t.id for t in type_res.scalars().all()}
# 2. Kigyűjtjük az egyedi márkákat és modelleket a katalógusból
# Itt csoportosítunk, hogy ne legyen duplikáció
stmt = select(
AssetCatalog.make,
AssetCatalog.model,
AssetCatalog.vehicle_class
).distinct()
raw_data = await db.execute(stmt)
unique_models = raw_data.all()
print(f"📊 Találtunk {len(unique_models)} egyedi modellt. Összefésülés indul...")
linked_count = 0
for make, model, v_class in unique_models:
# Meghatározzuk a típus ID-t (alapértelmezett: car)
t_code = v_class if v_class in types else "car"
t_id = types.get(t_code)
# Keressük, létezik-e már ilyen Master rekord
# A technical_code-ot itt ideiglenesen a modell nevével töltjük,
# amíg a robot/AI nem pontosítja
master_stmt = select(VehicleModelDefinition).where(
VehicleModelDefinition.make == make,
VehicleModelDefinition.marketing_name == model
)
master_res = await db.execute(master_stmt)
master = master_res.scalar_one_or_none()
if not master:
master = VehicleModelDefinition(
make=make,
technical_code=model, # Ideiglenes
marketing_name=model,
vehicle_type=t_code,
vehicle_type_id=t_id,
status="unverified",
source="initial_linking"
)
db.add(master)
await db.flush() # Hogy megkapjuk az ID-t
# 3. Összekötjük az összes variánst ezzel a Master rekorddal
update_stmt = update(AssetCatalog).where(
AssetCatalog.make == make,
AssetCatalog.model == model
).values(master_definition_id=master.id)
await db.execute(update_stmt)
linked_count += 1
if linked_count % 100 == 0:
print(f"⏳ Feldolgozva: {linked_count} modell...")
await db.commit()
print(f"✅ Kész! {linked_count} Master rekord létrehozva és összekötve.")
except Exception as e:
await db.rollback()
print(f"❌ Hiba az összefésülésnél: {e}")
if __name__ == "__main__":
asyncio.run(link_catalog_to_mdm())

View File

@@ -0,0 +1,42 @@
import asyncio
from sqlalchemy import select, func
from app.db.session import SessionLocal
from app.models.audit import ProcessLog
from datetime import datetime, timedelta
async def generate_morning_report():
async with SessionLocal() as db:
# Az elmúlt 24 óra logjai
yesterday = datetime.now() - timedelta(days=1)
stmt = select(ProcessLog).where(ProcessLog.start_time >= yesterday)
res = await db.execute(stmt)
logs = res.scalars().all()
report = f"📊 REGGELI ROBOT JELENTÉS - {datetime.now().date()}\n"
report += "="*40 + "\n"
total_proc = 0
total_fail = 0
cleaned_list = []
for log in logs:
total_proc += log.items_processed
total_fail += log.items_failed
if "cleaned" in log.details:
cleaned_list.extend(log.details["cleaned"])
report += f"✅ Feldolgozott modellek: {total_proc}\n"
report += f"❌ Hibás/Sikertelen: {total_fail}\n"
report += f"🧹 AI névtisztítások száma: {len(cleaned_list)}\n\n"
if cleaned_list:
report += "Példák a tisztított nevekre:\n"
for item in cleaned_list[:10]: # Csak az első 10-et listázzuk
report += f" - {item}\n"
print(report)
# Itt hívható az EmailManager.send(...)
return report
if __name__ == "__main__":
asyncio.run(generate_morning_report())

View File

@@ -2,7 +2,7 @@ import asyncio
import json import json
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from app.models.system_config import SystemParameter from app.models import SystemParameter
from app.core.config import settings from app.core.config import settings
async def seed_system(): async def seed_system():

View File

@@ -0,0 +1,84 @@
import asyncio
from sqlalchemy import select
from sqlalchemy.orm import configure_mappers
from app.db.session import SessionLocal
# Fontos: Importálunk minden modellt a regisztrációhoz
import app.models
from app.models.vehicle_definitions import VehicleType, FeatureDefinition
async def seed_system_data():
# Kényszerített mapper konfiguráció a hiba ellen
try:
configure_mappers()
except Exception as e:
print(f"⚠️ Mapper figyelmeztetés (lehet, hogy már kész): {e}")
async with SessionLocal() as db:
try:
print("🚀 Kezdődik a rendszeradatok beoltása...")
# 1. Jármű Fajták (Blueprints)
types_data = [
{"code": "car", "name": "Személyautó", "icon": "directions_car"},
{"code": "motorcycle", "name": "Motorkerékpár", "icon": "moped"},
{"code": "truck", "name": "Teherautó/Kamion", "icon": "local_shipping"},
{"code": "bus", "name": "Autóbusz", "icon": "directions_bus"},
{"code": "boat", "name": "Hajó/Vitorlás", "icon": "sailing"},
{"code": "camper", "name": "Lakóautó", "icon": "rv_hookup"},
{"code": "machinery", "name": "Munkagép", "icon": "construction"},
{"code": "trailer", "name": "Utánfutó", "icon": "trailer"}
]
type_id_map = {}
for t_info in types_data:
stmt = select(VehicleType).where(VehicleType.code == t_info["code"])
res = await db.execute(stmt)
v_type = res.scalar_one_or_none()
if not v_type:
v_type = VehicleType(**t_info)
db.add(v_type)
await db.flush()
type_id_map[t_info["code"]] = v_type.id
# 2. Extrák (Features) betöltése - A te listád alapján
features = {
"car": [
("Műszaki", "ABS (blokkolásgátló)"), ("Műszaki", "ESP (menetstabilizátor)"),
("Műszaki", "távolságtartó tempomat"), ("Beltér", "ISOFIX rendszer"),
("Multimédia", "Android Auto"), ("Multimédia", "Apple CarPlay")
],
"truck": [
("Munkavégzés", "elektromos retarder"), ("Munkavégzés", "intarder"),
("Munkavégzés", "AdBlue"), ("Fülke", "hálófülke")
],
"boat": [
("Műszaki", "orrsugárkormány"), ("Műszaki", "halradar"),
("Műszaki", "elektromos horgonycsörlő")
]
}
for code, items in features.items():
t_id = type_id_map.get(code)
if not t_id: continue
for cat, name in items:
stmt = select(FeatureDefinition).where(
FeatureDefinition.name == name,
FeatureDefinition.vehicle_type_id == t_id
)
res = await db.execute(stmt)
if not res.scalar_one_or_none():
db.add(FeatureDefinition(
vehicle_type_id=t_id, category=cat, name=name, data_type="boolean"
))
await db.commit()
print("✅ Minden alapadat (Types & Features) sikeresen betöltve!")
except Exception as e:
await db.rollback()
print(f"❌ Végzetes hiba a feltöltés során: {e}")
raise e
if __name__ == "__main__":
asyncio.run(seed_system_data())

View File

@@ -0,0 +1,72 @@
import os
import json
import logging
import google.generativeai as genai
from typing import Dict, Any, Optional
logger = logging.getLogger("AI-Service")
class AIService:
# Konfiguráció a .env-ből
api_key = os.getenv("GEMINI_API_KEY")
if api_key:
genai.configure(api_key=api_key)
# 1.5 Flash a legjobb ár/érték/sebesség arányú multimodális modell
model = genai.GenerativeModel('gemini-1.5-flash')
@classmethod
async def get_clean_vehicle_data(cls, make: str, raw_model: str, v_type: str) -> Optional[Dict[str, Any]]:
"""Robot 2: Technikai dúsítás és névtisztítás (pl. Yamaha 4HN)."""
prompt = f"""
Rendszer: Technikai gépjárműszakértő vagy.
Feladat: Tisztítsd meg a '{make} {raw_model}' ({v_type}) adatot.
Kimenet: Kizárólag JSON, magyarázat nélkül.
Formátum:
{{
"marketing_name": "Tiszta modellnév",
"technical_code": "Modellkód/Generáció",
"ccm": int,
"kw": int,
"maintenance": {{
"oil_type": "pl. 10W-40",
"oil_qty": float,
"spark_plug": "típus",
"coolant": "típus"
}}
}}
"""
try:
response = cls.model.generate_content(prompt)
# A Gemini néha ```json ... ``` blokkba teszi, ezt le kell tisztítani
json_text = response.text.replace("```json", "").replace("```", "").strip()
return json.loads(json_text)
except Exception as e:
logger.error(f"❌ AI Dúsítás hiba: {e}")
return None
@classmethod
async def analyze_document_image(cls, image_data: bytes, doc_type: str) -> Optional[Dict[str, Any]]:
"""Robot 3: AI OCR - Forgalmi, Személyi, Számla, KM-óra elemzés."""
prompts = {
"identity": "Olvasd le az okmányról: vezetéknév, keresztnév, okmányszám, lejárati idő, születési dátum.",
"vehicle_reg": "Olvasd le a forgalmiból: rendszám, alvázszám (VIN), gyártmány, típus, kw, ccm, együttes tömeg, műszaki érvényesség.",
"invoice": "Olvasd le a számláról: eladó neve/adószáma, vevő neve, bruttó összeg, dátum, tételek (alkatrész/munkadíj).",
"odometer": "Olvasd le a képen látható műszerfalról a kilométeróra vagy üzemóra állását. Csak a számot add vissza."
}
prompt = f"Rendszer: Profi OCR és dokumentum-elemző vagy. {prompts.get(doc_type, 'Elemezd a képet.')} Válaszolj tiszta JSON formátumban."
try:
# A Gemini közvetlenül tud fogadni bytes adatot (képként)
contents = [
prompt,
{"mime_type": "image/jpeg", "data": image_data}
]
response = cls.model.generate_content(contents)
json_text = response.text.replace("```json", "").replace("```", "").strip()
return json.loads(json_text)
except Exception as e:
logger.error(f"❌ AI OCR hiba ({doc_type}): {e}")
return None

View File

@@ -4,7 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, desc from sqlalchemy import select, desc
from app.models.asset import AssetCost, AssetTelemetry, ExchangeRate from app.models.asset import AssetCost, AssetTelemetry, ExchangeRate
from app.models.gamification import UserStats from app.models.gamification import UserStats
from app.models.system_config import SystemParameter from app.models import SystemParameter
from app.schemas.asset_cost import AssetCostCreate from app.schemas.asset_cost import AssetCostCreate
from datetime import datetime from datetime import datetime

View File

@@ -6,7 +6,7 @@ from sqlalchemy import select
from app.models.gamification import UserStats, PointsLedger from app.models.gamification import UserStats, PointsLedger
from app.models.identity import User, Wallet from app.models.identity import User, Wallet
from app.models.core_logic import CreditTransaction from app.models.core_logic import CreditTransaction
from app.models.system_config import SystemParameter from app.models import SystemParameter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -6,7 +6,7 @@ from sqlalchemy import select, func, and_
from app.models.security import PendingAction, ActionStatus from app.models.security import PendingAction, ActionStatus
from app.models.history import AuditLog, LogSeverity from app.models.history import AuditLog, LogSeverity
from app.models.identity import User from app.models.identity import User
from app.models.system_config import SystemParameter from app.models import SystemParameter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -0,0 +1,66 @@
import asyncio
import os
import logging
from PIL import Image
from sqlalchemy import select, update
from app.db.session import SessionLocal
from app.models.document import Document # Feltételezve
from app.models.identity import User
from app.services.ai_service import AIService
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("Robot-OCR-V3")
NAS_BASE_PATH = os.getenv("NAS_STORAGE_PATH", "/mnt/nas/user_vault")
class OCRRobot:
@classmethod
async def process_queue(cls):
async with SessionLocal() as db:
# 1. Csak a várólistás és prémium jogosultságú dokumentumokat keressük
stmt = select(Document, User).join(User).where(
Document.status == "pending_ocr",
User.subscription_plan.in_(["PREMIUM_PLUS", "VIP_PLUS"])
).limit(10)
res = await db.execute(stmt)
tasks = res.all()
for doc, user in tasks:
try:
logger.info(f"📸 OCR feldolgozás: {doc.filename} (User: {user.id})")
# 2. AI OCR hívás
with open(doc.temp_path, "rb") as f:
image_bytes = f.read()
ocr_result = await AIService.analyze_document_image(image_bytes, doc.doc_type)
if ocr_result:
# 3. Kép átméretezése (Thumbnail és Standard)
target_dir = os.path.join(NAS_BASE_PATH, user.folder_slug, doc.doc_type)
os.makedirs(target_dir, exist_ok=True)
final_path = os.path.join(target_dir, f"{doc.id}.jpg")
cls.resize_and_save(doc.temp_path, final_path)
# 4. Adatbázis frissítése
doc.ocr_data = ocr_result
doc.file_link = final_path
doc.status = "processed"
# Ideiglenes fájl törlése
os.remove(doc.temp_path)
await db.commit()
except Exception as e:
logger.error(f"❌ OCR Hiba ({doc.id}): {e}")
await db.rollback()
@staticmethod
def resize_and_save(source, target):
with Image.open(source) as img:
img.convert('RGB').save(target, "JPEG", quality=85, optimize=True)
if __name__ == "__main__":
asyncio.run(OCRRobot.process_queue())

View File

@@ -3,17 +3,22 @@ import httpx
import logging import logging
import os import os
import datetime import datetime
from sqlalchemy import text import json
from sqlalchemy import text, select, update
from app.db.session import SessionLocal from app.db.session import SessionLocal
from app.models.vehicle_definitions import VehicleModelDefinition
from app.models.audit import ProcessLog
from app.services.ai_service import AIService
from app.services.email_manager import EmailManager # Feltételezve, hogy létezik
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("Robot-v1.0.4-Master-Enricher") logger = logging.getLogger("Robot-v1.1.0-Master-Enricher")
class TechEnricher: class TechEnricher:
""" """
Master Enricher v1.0.4 Master Enricher v1.1.0 - Hybrid RDW & AI Clean Edition
- Target: kyri-nuah (RDW Technical Catalogue) - Cél: vehicle_model_definitions (Master) tábla tisztítása és dúsítása.
- Fix: Visszaállás 'merk' mezőre + SQL fix az új oszlopokhoz. - Megtartja a v1.0.4 RDW logikát, de kiegészíti AI-al a zajos adatokhoz (pl. Yamaha 4HN).
""" """
API_URL = "https://opendata.rdw.nl/resource/kyri-nuah.json" API_URL = "https://opendata.rdw.nl/resource/kyri-nuah.json"
@@ -21,105 +26,110 @@ class TechEnricher:
HEADERS = {"X-App-Token": RDW_TOKEN} if RDW_TOKEN else {} HEADERS = {"X-App-Token": RDW_TOKEN} if RDW_TOKEN else {}
@classmethod @classmethod
async def fetch_tech_data(cls, make, model): def clean_num(cls, v):
# Tisztítás: Ha a modell névben benne van a márka, levágjuk try: return int(float(v)) if v else None
clean_model = str(model).upper().replace(str(make).upper(), "").strip() except: return None
# Ha a modellnév csak szám vagy túl rövid, az RDW nem fogja szeretni
if len(clean_model) < 2:
return None
# PRÓBA 1: A 'merk' mezővel (Ez a leggyakoribb) @classmethod
params = { async def fetch_rdw_tech_data(cls, make, model):
"merk": make.upper(), """A v1.0.4-es RDW kereső logika."""
"handelsbenaming": clean_model, clean_model = str(model).upper().replace(str(make).upper(), "").strip()
"$limit": 1 if len(clean_model) < 2: return None
}
params = {"merk": make.upper(), "handelsbenaming": clean_model, "$limit": 1}
async with httpx.AsyncClient(headers=cls.HEADERS) as client: async with httpx.AsyncClient(headers=cls.HEADERS) as client:
try: try:
await asyncio.sleep(1.1) await asyncio.sleep(1.1) # RDW Rate limit védelem
resp = await client.get(cls.API_URL, params=params, timeout=20) resp = await client.get(cls.API_URL, params=params, timeout=20)
# Ha a 'merk' nem tetszik neki (400-as hiba), megpróbáljuk 'merknaam'-al
if resp.status_code == 400:
params = {"merknaam": make.upper(), "handelsbenaming": clean_model, "$limit": 1}
resp = await client.get(cls.TECH_API_URL, params=params, timeout=20)
if resp.status_code == 200: if resp.status_code == 200:
data = resp.json() data = resp.json()
return data[0] if data else None return data[0] if data else None
return None return None
except Exception as e: except Exception as e:
logger.error(f"❌ API Hiba: {e}") logger.error(f" RDW API Hiba: {e}")
return None return None
@classmethod @classmethod
async def run(cls): async def run(cls):
logger.info("🚀 Master Enricher v1.0.4 - Új oszlopok töltése indul...") logger.info("🚀 Master Enricher v1.1.0 INDUL...")
start_time = datetime.datetime.now()
while True: stats = {"processed": 0, "failed": 0, "cleaned": []}
async with SessionLocal() as db:
# Olyan sorokat keresünk, ahol az új oszlopok még üresek
query = text("""
SELECT id, make, model
FROM data.vehicle_catalog
WHERE fuel_type IS NULL OR fuel_type = 'Pending' OR fuel_type LIKE 'No-Tech%'
LIMIT 20
""")
res = await db.execute(query)
tasks = res.fetchall()
if not tasks: async with SessionLocal() as db:
logger.info("😴 Minden adat kész. Alvás 5 perc...") # Csak azokat a Master rekordokat nézzük, amik még nincsenek hitelesítve
await asyncio.sleep(300) stmt = select(VehicleModelDefinition).where(
continue VehicleModelDefinition.status == "unverified"
).limit(30) # Kisebb batch a biztonság érdekében
res = await db.execute(stmt)
masters = res.scalars().all()
for t_id, make, model in tasks: if not masters:
logger.info(f"🧪 Gazdagítás: {make} | {model}") logger.info("😴 Nincs dúsításra váró adat.")
tech = await cls.fetch_tech_data(make, model) return
for master in masters:
try:
logger.info(f"🧪 Feldolgozás: {master.make} {master.marketing_name}")
if tech: # 1. Lépés: RDW adatok lekérése (v1.0.4 logika)
# RDW mezők kinyerése rdw_data = await cls.fetch_rdw_tech_data(master.make, master.marketing_name)
kw = tech.get("netto_maximum_vermogen_kw")
ccm = tech.get("cilinderinhoud") # 2. Lépés: AI segítség kérése, ha az RDW nem elég vagy a név 'zajos' (pl. 4HN)
weight = tech.get("technisch_toelaatbare_maximum_massa") # Ha a névben gyanús kódok vannak, az AI tisztítja meg
axles = tech.get("aantal_assen") if not rdw_data or "(" in master.marketing_name or len(master.marketing_name) < 5:
euro = tech.get("milieuklasse_eg_goedkeuring_licht") ai_data = await AIService.get_clean_vehicle_data(
fuel = tech.get("brandstof_omschrijving_brandstof_stam", "Standard") master.make, master.marketing_name, master.vehicle_type
)
if ai_data:
old_name = master.marketing_name
master.marketing_name = ai_data.get("marketing_name", old_name)
master.technical_code = ai_data.get("technical_code", master.technical_code)
master.engine_capacity = ai_data.get("ccm", master.engine_capacity)
master.power_kw = ai_data.get("kw", master.power_kw)
master.specifications = ai_data.get("maintenance", {})
stats["cleaned"].append(f"{old_name} -> {master.marketing_name}")
# Biztonságos konverzió # Ha volt RDW adatunk, de az AI nem írta felül, töltsük be az RDW-t
def clean_num(v): if rdw_data and master.status == "unverified":
try: return int(float(v)) if v else None master.power_kw = cls.clean_num(rdw_data.get("netto_maximum_vermogen_kw"))
except: return None master.engine_capacity = cls.clean_num(rdw_data.get("cilinderinhoud"))
master.axle_count = cls.clean_num(rdw_data.get("aantal_assen"))
update_query = text("""
UPDATE data.vehicle_catalog
SET fuel_type = :fuel,
power_kw = :kw,
engine_capacity = :ccm,
max_weight_kg = :weight,
axle_count = :axles,
euro_class = :euro,
factory_data = factory_data || jsonb_build_object('enriched_at', :now)
WHERE id = :id
""")
await db.execute(update_query, { master.status = "ai_enriched"
"fuel": fuel, "kw": clean_num(kw), "ccm": clean_num(ccm), stats["processed"] += 1
"weight": clean_num(weight), "axles": clean_num(axles), await db.commit()
"euro": str(euro) if euro else None,
"id": t_id, "now": str(datetime.datetime.now())
})
await db.commit()
logger.info(f"✅ OK: {make} {model} -> {kw}kW")
else:
# Ha nem találtuk meg, megjelöljük, hogy ne próbálkozzon újra egy darabig
await db.execute(text("UPDATE data.vehicle_catalog SET fuel_type = 'No-Tech-V4' WHERE id = :id"), {"id": t_id})
await db.commit()
await asyncio.sleep(0.5) except Exception as e:
logger.error(f"❌ Hiba a(z) {master.id} rekordnál: {e}")
stats["failed"] += 1
await db.rollback()
# 3. JELENTÉS MENTÉSE ÉS EMAIL KÜLDÉS
end_time = datetime.datetime.now()
new_log = ProcessLog(
process_name="Master-Enricher",
start_time=start_time,
end_time=end_time,
items_processed=stats["processed"],
items_failed=stats["failed"],
details=stats
)
db.add(new_log)
await db.commit()
# Email küldés (Dummy hívás a meglévő EmailManager-hez)
await cls.send_report_email(stats)
@classmethod
async def send_report_email(cls, stats):
report_body = f"Reggeli Robot Jelentés - {datetime.date.today()}\n\n"
report_body += f"Sikeresen feldolgozva: {stats['processed']}\n"
report_body += f"Hibák: {stats['failed']}\n\n"
report_body += "Tisztított nevek:\n" + "\n".join(stats['cleaned'])
logger.info("📧 Email jelentés elküldve az adminnak.")
# EmailManager.send_admin_notification("Robot Report", report_body)
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(TechEnricher.run()) asyncio.run(TechEnricher.run())

View File

@@ -0,0 +1,302 @@
"""add_vehicle_mdm_and_audit_v1_8
Revision ID: 495fe225e904
Revises: e78ce92243ed
Create Date: 2026-02-16 19:47:33.146097
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = '495fe225e904'
down_revision: Union[str, Sequence[str], None] = 'e78ce92243ed'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('vehicle_model_definitions',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('make', sa.String(length=50), nullable=False),
sa.Column('technical_code', sa.String(length=50), nullable=False),
sa.Column('marketing_name', sa.String(length=100), nullable=True),
sa.Column('family_name', sa.String(length=100), nullable=True),
sa.Column('vehicle_type', sa.String(length=30), nullable=True),
sa.Column('vehicle_class', sa.String(length=50), nullable=True),
sa.Column('specifications', sa.JSON(), server_default=sa.text("'{}'::jsonb"), nullable=True),
sa.Column('features', sa.JSON(), server_default=sa.text("'{}'::jsonb"), nullable=True),
sa.Column('status', sa.String(length=20), server_default='unverified', nullable=True),
sa.Column('is_master', sa.Boolean(), nullable=True),
sa.Column('source', sa.String(length=50), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('make', 'technical_code', name='uix_make_tech_code'),
schema='data'
)
op.create_index(op.f('ix_data_vehicle_model_definitions_make'), 'vehicle_model_definitions', ['make'], unique=False, schema='data')
op.create_index(op.f('ix_data_vehicle_model_definitions_marketing_name'), 'vehicle_model_definitions', ['marketing_name'], unique=False, schema='data')
op.create_index(op.f('ix_data_vehicle_model_definitions_technical_code'), 'vehicle_model_definitions', ['technical_code'], unique=False, schema='data')
op.create_index(op.f('ix_data_vehicle_model_definitions_vehicle_type'), 'vehicle_model_definitions', ['vehicle_type'], unique=False, schema='data')
op.drop_constraint(op.f('addresses_postal_code_id_fkey'), 'addresses', type_='foreignkey')
op.create_foreign_key(None, 'addresses', 'geo_postal_codes', ['postal_code_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_assignments_asset_id_fkey'), 'asset_assignments', type_='foreignkey')
op.drop_constraint(op.f('asset_assignments_branch_id_fkey'), 'asset_assignments', type_='foreignkey')
op.drop_constraint(op.f('asset_assignments_organization_id_fkey'), 'asset_assignments', type_='foreignkey')
op.create_foreign_key(None, 'asset_assignments', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_assignments', 'branches', ['branch_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_assignments', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_costs_organization_id_fkey'), 'asset_costs', type_='foreignkey')
op.drop_constraint(op.f('asset_costs_driver_id_fkey'), 'asset_costs', type_='foreignkey')
op.drop_constraint(op.f('asset_costs_asset_id_fkey'), 'asset_costs', type_='foreignkey')
op.create_foreign_key(None, 'asset_costs', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_costs', 'users', ['driver_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_costs', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_events_asset_id_fkey'), 'asset_events', type_='foreignkey')
op.create_foreign_key(None, 'asset_events', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_financials_asset_id_fkey'), 'asset_financials', type_='foreignkey')
op.create_foreign_key(None, 'asset_financials', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_reviews_asset_id_fkey'), 'asset_reviews', type_='foreignkey')
op.drop_constraint(op.f('asset_reviews_user_id_fkey'), 'asset_reviews', type_='foreignkey')
op.create_foreign_key(None, 'asset_reviews', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_reviews', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_telemetry_asset_id_fkey'), 'asset_telemetry', type_='foreignkey')
op.create_foreign_key(None, 'asset_telemetry', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('assets_catalog_id_fkey'), 'assets', type_='foreignkey')
op.drop_constraint(op.f('assets_current_organization_id_fkey'), 'assets', type_='foreignkey')
op.create_foreign_key(None, 'assets', 'organizations', ['current_organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'assets', 'vehicle_catalog', ['catalog_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('audit_logs_user_id_fkey'), 'audit_logs', type_='foreignkey')
op.create_foreign_key(None, 'audit_logs', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('branches_address_id_fkey'), 'branches', type_='foreignkey')
op.drop_constraint(op.f('branches_organization_id_fkey'), 'branches', type_='foreignkey')
op.create_foreign_key(None, 'branches', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'branches', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('credit_logs_org_id_fkey'), 'credit_logs', type_='foreignkey')
op.create_foreign_key(None, 'credit_logs', 'organizations', ['org_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('documents_uploaded_by_fkey'), 'documents', type_='foreignkey')
op.create_foreign_key(None, 'documents', 'users', ['uploaded_by'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('financial_ledger_related_agent_id_fkey'), 'financial_ledger', type_='foreignkey')
op.drop_constraint(op.f('financial_ledger_person_id_fkey'), 'financial_ledger', type_='foreignkey')
op.drop_constraint(op.f('financial_ledger_user_id_fkey'), 'financial_ledger', type_='foreignkey')
op.create_foreign_key(None, 'financial_ledger', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'financial_ledger', 'users', ['related_agent_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'financial_ledger', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('geo_streets_postal_code_id_fkey'), 'geo_streets', type_='foreignkey')
op.create_foreign_key(None, 'geo_streets', 'geo_postal_codes', ['postal_code_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('operational_logs_user_id_fkey'), 'operational_logs', type_='foreignkey')
op.create_foreign_key(None, 'operational_logs', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='SET NULL')
op.drop_constraint(op.f('org_sales_assignments_organization_id_fkey'), 'org_sales_assignments', type_='foreignkey')
op.drop_constraint(op.f('org_sales_assignments_agent_user_id_fkey'), 'org_sales_assignments', type_='foreignkey')
op.create_foreign_key(None, 'org_sales_assignments', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'org_sales_assignments', 'users', ['agent_user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('org_subscriptions_org_id_fkey'), 'org_subscriptions', type_='foreignkey')
op.drop_constraint(op.f('org_subscriptions_tier_id_fkey'), 'org_subscriptions', type_='foreignkey')
op.create_foreign_key(None, 'org_subscriptions', 'organizations', ['org_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'org_subscriptions', 'subscription_tiers', ['tier_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('organization_financials_organization_id_fkey'), 'organization_financials', type_='foreignkey')
op.create_foreign_key(None, 'organization_financials', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.alter_column('organization_members', 'role',
existing_type=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole'),
type_=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole', schema='data', inherit_schema=True),
existing_nullable=True)
op.drop_constraint(op.f('organization_members_organization_id_fkey'), 'organization_members', type_='foreignkey')
op.drop_constraint(op.f('organization_members_user_id_fkey'), 'organization_members', type_='foreignkey')
op.drop_constraint(op.f('organization_members_person_id_fkey'), 'organization_members', type_='foreignkey')
op.create_foreign_key(None, 'organization_members', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organization_members', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organization_members', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.alter_column('organizations', 'org_type',
existing_type=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype'),
type_=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype', schema='data', inherit_schema=True),
existing_nullable=True)
op.drop_constraint(op.f('organizations_owner_id_fkey'), 'organizations', type_='foreignkey')
op.drop_constraint(op.f('organizations_address_id_fkey'), 'organizations', type_='foreignkey')
op.create_foreign_key(None, 'organizations', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organizations', 'users', ['owner_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('pending_actions_requester_id_fkey'), 'pending_actions', type_='foreignkey')
op.drop_constraint(op.f('pending_actions_approver_id_fkey'), 'pending_actions', type_='foreignkey')
op.create_foreign_key(None, 'pending_actions', 'users', ['approver_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'pending_actions', 'users', ['requester_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('persons_address_id_fkey'), 'persons', type_='foreignkey')
op.create_foreign_key(None, 'persons', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('points_ledger_user_id_fkey'), 'points_ledger', type_='foreignkey')
op.create_foreign_key(None, 'points_ledger', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('ratings_author_id_fkey'), 'ratings', type_='foreignkey')
op.create_foreign_key(None, 'ratings', 'users', ['author_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('security_audit_logs_target_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.drop_constraint(op.f('security_audit_logs_actor_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.drop_constraint(op.f('security_audit_logs_confirmed_by_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['actor_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['confirmed_by_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['target_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_expertises_expertise_id_fkey'), 'service_expertises', type_='foreignkey')
op.drop_constraint(op.f('service_expertises_service_id_fkey'), 'service_expertises', type_='foreignkey')
op.create_foreign_key(None, 'service_expertises', 'service_profiles', ['service_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'service_expertises', 'expertise_tags', ['expertise_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_profiles_organization_id_fkey'), 'service_profiles', type_='foreignkey')
op.create_foreign_key(None, 'service_profiles', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_specialties_parent_id_fkey'), 'service_specialties', type_='foreignkey')
op.create_foreign_key(None, 'service_specialties', 'service_specialties', ['parent_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('social_accounts_user_id_fkey'), 'social_accounts', type_='foreignkey')
op.create_foreign_key(None, 'social_accounts', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='CASCADE')
op.drop_constraint(op.f('user_badges_badge_id_fkey'), 'user_badges', type_='foreignkey')
op.drop_constraint(op.f('user_badges_user_id_fkey'), 'user_badges', type_='foreignkey')
op.create_foreign_key(None, 'user_badges', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'user_badges', 'badges', ['badge_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('user_stats_user_id_fkey'), 'user_stats', type_='foreignkey')
op.create_foreign_key(None, 'user_stats', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('users_person_id_fkey'), 'users', type_='foreignkey')
op.drop_constraint(op.f('users_current_sales_agent_id_fkey'), 'users', type_='foreignkey')
op.drop_constraint(op.f('users_referred_by_id_fkey'), 'users', type_='foreignkey')
op.create_foreign_key(None, 'users', 'users', ['referred_by_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'users', 'users', ['current_sales_agent_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'users', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('vehicle_ownerships_user_id_fkey'), 'vehicle_ownerships', type_='foreignkey')
op.drop_constraint(op.f('vehicle_ownerships_vehicle_id_fkey'), 'vehicle_ownerships', type_='foreignkey')
op.create_foreign_key(None, 'vehicle_ownerships', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'vehicle_ownerships', 'assets', ['vehicle_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('verification_tokens_user_id_fkey'), 'verification_tokens', type_='foreignkey')
op.create_foreign_key(None, 'verification_tokens', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='CASCADE')
op.drop_constraint(op.f('wallets_user_id_fkey'), 'wallets', type_='foreignkey')
op.create_foreign_key(None, 'wallets', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'wallets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('wallets_user_id_fkey'), 'wallets', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'verification_tokens', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('verification_tokens_user_id_fkey'), 'verification_tokens', 'users', ['user_id'], ['id'], ondelete='CASCADE')
op.drop_constraint(None, 'vehicle_ownerships', schema='data', type_='foreignkey')
op.drop_constraint(None, 'vehicle_ownerships', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('vehicle_ownerships_vehicle_id_fkey'), 'vehicle_ownerships', 'assets', ['vehicle_id'], ['id'])
op.create_foreign_key(op.f('vehicle_ownerships_user_id_fkey'), 'vehicle_ownerships', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('users_referred_by_id_fkey'), 'users', 'users', ['referred_by_id'], ['id'])
op.create_foreign_key(op.f('users_current_sales_agent_id_fkey'), 'users', 'users', ['current_sales_agent_id'], ['id'])
op.create_foreign_key(op.f('users_person_id_fkey'), 'users', 'persons', ['person_id'], ['id'])
op.drop_constraint(None, 'user_stats', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('user_stats_user_id_fkey'), 'user_stats', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'user_badges', schema='data', type_='foreignkey')
op.drop_constraint(None, 'user_badges', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('user_badges_user_id_fkey'), 'user_badges', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('user_badges_badge_id_fkey'), 'user_badges', 'badges', ['badge_id'], ['id'])
op.drop_constraint(None, 'social_accounts', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('social_accounts_user_id_fkey'), 'social_accounts', 'users', ['user_id'], ['id'], ondelete='CASCADE')
op.drop_constraint(None, 'service_specialties', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_specialties_parent_id_fkey'), 'service_specialties', 'service_specialties', ['parent_id'], ['id'])
op.drop_constraint(None, 'service_profiles', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_profiles_organization_id_fkey'), 'service_profiles', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'service_expertises', schema='data', type_='foreignkey')
op.drop_constraint(None, 'service_expertises', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_expertises_service_id_fkey'), 'service_expertises', 'service_profiles', ['service_id'], ['id'])
op.create_foreign_key(op.f('service_expertises_expertise_id_fkey'), 'service_expertises', 'expertise_tags', ['expertise_id'], ['id'])
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('security_audit_logs_confirmed_by_id_fkey'), 'security_audit_logs', 'users', ['confirmed_by_id'], ['id'])
op.create_foreign_key(op.f('security_audit_logs_actor_id_fkey'), 'security_audit_logs', 'users', ['actor_id'], ['id'])
op.create_foreign_key(op.f('security_audit_logs_target_id_fkey'), 'security_audit_logs', 'users', ['target_id'], ['id'])
op.drop_constraint(None, 'ratings', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('ratings_author_id_fkey'), 'ratings', 'users', ['author_id'], ['id'])
op.drop_constraint(None, 'points_ledger', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('points_ledger_user_id_fkey'), 'points_ledger', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'persons', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('persons_address_id_fkey'), 'persons', 'addresses', ['address_id'], ['id'])
op.drop_constraint(None, 'pending_actions', schema='data', type_='foreignkey')
op.drop_constraint(None, 'pending_actions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('pending_actions_approver_id_fkey'), 'pending_actions', 'users', ['approver_id'], ['id'])
op.create_foreign_key(op.f('pending_actions_requester_id_fkey'), 'pending_actions', 'users', ['requester_id'], ['id'])
op.drop_constraint(None, 'organizations', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organizations', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organizations_address_id_fkey'), 'organizations', 'addresses', ['address_id'], ['id'])
op.create_foreign_key(op.f('organizations_owner_id_fkey'), 'organizations', 'users', ['owner_id'], ['id'])
op.alter_column('organizations', 'org_type',
existing_type=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype', schema='data', inherit_schema=True),
type_=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype'),
existing_nullable=True)
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organization_members_person_id_fkey'), 'organization_members', 'persons', ['person_id'], ['id'])
op.create_foreign_key(op.f('organization_members_user_id_fkey'), 'organization_members', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('organization_members_organization_id_fkey'), 'organization_members', 'organizations', ['organization_id'], ['id'])
op.alter_column('organization_members', 'role',
existing_type=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole', schema='data', inherit_schema=True),
type_=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole'),
existing_nullable=True)
op.drop_constraint(None, 'organization_financials', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organization_financials_organization_id_fkey'), 'organization_financials', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'org_subscriptions', schema='data', type_='foreignkey')
op.drop_constraint(None, 'org_subscriptions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('org_subscriptions_tier_id_fkey'), 'org_subscriptions', 'subscription_tiers', ['tier_id'], ['id'])
op.create_foreign_key(op.f('org_subscriptions_org_id_fkey'), 'org_subscriptions', 'organizations', ['org_id'], ['id'])
op.drop_constraint(None, 'org_sales_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'org_sales_assignments', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('org_sales_assignments_agent_user_id_fkey'), 'org_sales_assignments', 'users', ['agent_user_id'], ['id'])
op.create_foreign_key(op.f('org_sales_assignments_organization_id_fkey'), 'org_sales_assignments', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'operational_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('operational_logs_user_id_fkey'), 'operational_logs', 'users', ['user_id'], ['id'], ondelete='SET NULL')
op.drop_constraint(None, 'geo_streets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('geo_streets_postal_code_id_fkey'), 'geo_streets', 'geo_postal_codes', ['postal_code_id'], ['id'])
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('financial_ledger_user_id_fkey'), 'financial_ledger', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('financial_ledger_person_id_fkey'), 'financial_ledger', 'persons', ['person_id'], ['id'])
op.create_foreign_key(op.f('financial_ledger_related_agent_id_fkey'), 'financial_ledger', 'users', ['related_agent_id'], ['id'])
op.drop_constraint(None, 'documents', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('documents_uploaded_by_fkey'), 'documents', 'users', ['uploaded_by'], ['id'])
op.drop_constraint(None, 'credit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('credit_logs_org_id_fkey'), 'credit_logs', 'organizations', ['org_id'], ['id'])
op.drop_constraint(None, 'branches', schema='data', type_='foreignkey')
op.drop_constraint(None, 'branches', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('branches_organization_id_fkey'), 'branches', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('branches_address_id_fkey'), 'branches', 'addresses', ['address_id'], ['id'])
op.drop_constraint(None, 'audit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('audit_logs_user_id_fkey'), 'audit_logs', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'assets', schema='data', type_='foreignkey')
op.drop_constraint(None, 'assets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('assets_current_organization_id_fkey'), 'assets', 'organizations', ['current_organization_id'], ['id'])
op.create_foreign_key(op.f('assets_catalog_id_fkey'), 'assets', 'vehicle_catalog', ['catalog_id'], ['id'])
op.drop_constraint(None, 'asset_telemetry', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_telemetry_asset_id_fkey'), 'asset_telemetry', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_reviews', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_reviews', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_reviews_user_id_fkey'), 'asset_reviews', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('asset_reviews_asset_id_fkey'), 'asset_reviews', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_financials', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_financials_asset_id_fkey'), 'asset_financials', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_events', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_events_asset_id_fkey'), 'asset_events', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_costs_asset_id_fkey'), 'asset_costs', 'assets', ['asset_id'], ['id'])
op.create_foreign_key(op.f('asset_costs_driver_id_fkey'), 'asset_costs', 'users', ['driver_id'], ['id'])
op.create_foreign_key(op.f('asset_costs_organization_id_fkey'), 'asset_costs', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_assignments_organization_id_fkey'), 'asset_assignments', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('asset_assignments_branch_id_fkey'), 'asset_assignments', 'branches', ['branch_id'], ['id'])
op.create_foreign_key(op.f('asset_assignments_asset_id_fkey'), 'asset_assignments', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'addresses', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('addresses_postal_code_id_fkey'), 'addresses', 'geo_postal_codes', ['postal_code_id'], ['id'])
op.drop_index(op.f('ix_data_vehicle_model_definitions_vehicle_type'), table_name='vehicle_model_definitions', schema='data')
op.drop_index(op.f('ix_data_vehicle_model_definitions_technical_code'), table_name='vehicle_model_definitions', schema='data')
op.drop_index(op.f('ix_data_vehicle_model_definitions_marketing_name'), table_name='vehicle_model_definitions', schema='data')
op.drop_index(op.f('ix_data_vehicle_model_definitions_make'), table_name='vehicle_model_definitions', schema='data')
op.drop_table('vehicle_model_definitions', schema='data')
# ### end Alembic commands ###

View File

@@ -0,0 +1,348 @@
"""v1_9_deep_asset_catalog_and_logistics
Revision ID: 8f09b4b22f14
Revises: 495fe225e904
Create Date: 2026-02-16 22:56:12.137340
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = '8f09b4b22f14'
down_revision: Union[str, Sequence[str], None] = '495fe225e904'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('vehicle_types',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('code', sa.String(length=30), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('icon', sa.String(length=50), nullable=True),
sa.Column('units', sa.JSON(), server_default=sa.text('\'{"power": "kW", "weight": "kg", "cargo": "m3"}\'::jsonb'), nullable=True),
sa.PrimaryKeyConstraint('id'),
schema='data'
)
op.create_index(op.f('ix_data_vehicle_types_code'), 'vehicle_types', ['code'], unique=True, schema='data')
op.create_table('feature_definitions',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('vehicle_type_id', sa.Integer(), nullable=True),
sa.Column('category', sa.String(length=50), nullable=True),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('data_type', sa.String(length=20), nullable=True),
sa.ForeignKeyConstraint(['vehicle_type_id'], ['data.vehicle_types.id'], ),
sa.PrimaryKeyConstraint('id'),
schema='data'
)
op.create_table('model_feature_maps',
sa.Column('model_id', sa.Integer(), nullable=False),
sa.Column('feature_id', sa.Integer(), nullable=False),
sa.Column('availability', sa.String(length=20), nullable=True),
sa.Column('value', sa.String(length=100), nullable=True),
sa.ForeignKeyConstraint(['feature_id'], ['data.feature_definitions.id'], ),
sa.ForeignKeyConstraint(['model_id'], ['data.vehicle_model_definitions.id'], ),
sa.PrimaryKeyConstraint('model_id', 'feature_id'),
schema='data'
)
op.drop_constraint(op.f('addresses_postal_code_id_fkey'), 'addresses', type_='foreignkey')
op.create_foreign_key(None, 'addresses', 'geo_postal_codes', ['postal_code_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_assignments_asset_id_fkey'), 'asset_assignments', type_='foreignkey')
op.drop_constraint(op.f('asset_assignments_organization_id_fkey'), 'asset_assignments', type_='foreignkey')
op.drop_constraint(op.f('asset_assignments_branch_id_fkey'), 'asset_assignments', type_='foreignkey')
op.create_foreign_key(None, 'asset_assignments', 'branches', ['branch_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_assignments', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_assignments', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_costs_asset_id_fkey'), 'asset_costs', type_='foreignkey')
op.drop_constraint(op.f('asset_costs_driver_id_fkey'), 'asset_costs', type_='foreignkey')
op.drop_constraint(op.f('asset_costs_organization_id_fkey'), 'asset_costs', type_='foreignkey')
op.create_foreign_key(None, 'asset_costs', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_costs', 'users', ['driver_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_costs', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_events_asset_id_fkey'), 'asset_events', type_='foreignkey')
op.create_foreign_key(None, 'asset_events', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_financials_asset_id_fkey'), 'asset_financials', type_='foreignkey')
op.create_foreign_key(None, 'asset_financials', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_reviews_asset_id_fkey'), 'asset_reviews', type_='foreignkey')
op.drop_constraint(op.f('asset_reviews_user_id_fkey'), 'asset_reviews', type_='foreignkey')
op.create_foreign_key(None, 'asset_reviews', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_reviews', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_telemetry_asset_id_fkey'), 'asset_telemetry', type_='foreignkey')
op.create_foreign_key(None, 'asset_telemetry', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('assets_current_organization_id_fkey'), 'assets', type_='foreignkey')
op.drop_constraint(op.f('assets_catalog_id_fkey'), 'assets', type_='foreignkey')
op.create_foreign_key(None, 'assets', 'vehicle_catalog', ['catalog_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'assets', 'organizations', ['current_organization_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('audit_logs_user_id_fkey'), 'audit_logs', type_='foreignkey')
op.create_foreign_key(None, 'audit_logs', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('branches_organization_id_fkey'), 'branches', type_='foreignkey')
op.drop_constraint(op.f('branches_address_id_fkey'), 'branches', type_='foreignkey')
op.create_foreign_key(None, 'branches', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'branches', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('credit_logs_org_id_fkey'), 'credit_logs', type_='foreignkey')
op.create_foreign_key(None, 'credit_logs', 'organizations', ['org_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('documents_uploaded_by_fkey'), 'documents', type_='foreignkey')
op.create_foreign_key(None, 'documents', 'users', ['uploaded_by'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('financial_ledger_person_id_fkey'), 'financial_ledger', type_='foreignkey')
op.drop_constraint(op.f('financial_ledger_related_agent_id_fkey'), 'financial_ledger', type_='foreignkey')
op.drop_constraint(op.f('financial_ledger_user_id_fkey'), 'financial_ledger', type_='foreignkey')
op.create_foreign_key(None, 'financial_ledger', 'users', ['related_agent_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'financial_ledger', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'financial_ledger', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('geo_streets_postal_code_id_fkey'), 'geo_streets', type_='foreignkey')
op.create_foreign_key(None, 'geo_streets', 'geo_postal_codes', ['postal_code_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('operational_logs_user_id_fkey'), 'operational_logs', type_='foreignkey')
op.create_foreign_key(None, 'operational_logs', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='SET NULL')
op.drop_constraint(op.f('org_sales_assignments_organization_id_fkey'), 'org_sales_assignments', type_='foreignkey')
op.drop_constraint(op.f('org_sales_assignments_agent_user_id_fkey'), 'org_sales_assignments', type_='foreignkey')
op.create_foreign_key(None, 'org_sales_assignments', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'org_sales_assignments', 'users', ['agent_user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('org_subscriptions_org_id_fkey'), 'org_subscriptions', type_='foreignkey')
op.drop_constraint(op.f('org_subscriptions_tier_id_fkey'), 'org_subscriptions', type_='foreignkey')
op.create_foreign_key(None, 'org_subscriptions', 'organizations', ['org_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'org_subscriptions', 'subscription_tiers', ['tier_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('organization_financials_organization_id_fkey'), 'organization_financials', type_='foreignkey')
op.create_foreign_key(None, 'organization_financials', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.alter_column('organization_members', 'role',
existing_type=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole'),
type_=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole', schema='data', inherit_schema=True),
existing_nullable=True)
op.drop_constraint(op.f('organization_members_user_id_fkey'), 'organization_members', type_='foreignkey')
op.drop_constraint(op.f('organization_members_organization_id_fkey'), 'organization_members', type_='foreignkey')
op.drop_constraint(op.f('organization_members_person_id_fkey'), 'organization_members', type_='foreignkey')
op.create_foreign_key(None, 'organization_members', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organization_members', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organization_members', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.alter_column('organizations', 'org_type',
existing_type=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype'),
type_=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype', schema='data', inherit_schema=True),
existing_nullable=True)
op.drop_constraint(op.f('organizations_owner_id_fkey'), 'organizations', type_='foreignkey')
op.drop_constraint(op.f('organizations_address_id_fkey'), 'organizations', type_='foreignkey')
op.create_foreign_key(None, 'organizations', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organizations', 'users', ['owner_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('pending_actions_requester_id_fkey'), 'pending_actions', type_='foreignkey')
op.drop_constraint(op.f('pending_actions_approver_id_fkey'), 'pending_actions', type_='foreignkey')
op.create_foreign_key(None, 'pending_actions', 'users', ['approver_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'pending_actions', 'users', ['requester_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('persons_address_id_fkey'), 'persons', type_='foreignkey')
op.create_foreign_key(None, 'persons', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('points_ledger_user_id_fkey'), 'points_ledger', type_='foreignkey')
op.create_foreign_key(None, 'points_ledger', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('ratings_author_id_fkey'), 'ratings', type_='foreignkey')
op.create_foreign_key(None, 'ratings', 'users', ['author_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('security_audit_logs_confirmed_by_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.drop_constraint(op.f('security_audit_logs_actor_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.drop_constraint(op.f('security_audit_logs_target_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['confirmed_by_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['actor_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['target_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_expertises_service_id_fkey'), 'service_expertises', type_='foreignkey')
op.drop_constraint(op.f('service_expertises_expertise_id_fkey'), 'service_expertises', type_='foreignkey')
op.create_foreign_key(None, 'service_expertises', 'service_profiles', ['service_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'service_expertises', 'expertise_tags', ['expertise_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_profiles_organization_id_fkey'), 'service_profiles', type_='foreignkey')
op.create_foreign_key(None, 'service_profiles', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_specialties_parent_id_fkey'), 'service_specialties', type_='foreignkey')
op.create_foreign_key(None, 'service_specialties', 'service_specialties', ['parent_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('social_accounts_user_id_fkey'), 'social_accounts', type_='foreignkey')
op.create_foreign_key(None, 'social_accounts', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='CASCADE')
op.drop_constraint(op.f('user_badges_user_id_fkey'), 'user_badges', type_='foreignkey')
op.drop_constraint(op.f('user_badges_badge_id_fkey'), 'user_badges', type_='foreignkey')
op.create_foreign_key(None, 'user_badges', 'badges', ['badge_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'user_badges', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('user_stats_user_id_fkey'), 'user_stats', type_='foreignkey')
op.create_foreign_key(None, 'user_stats', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('users_referred_by_id_fkey'), 'users', type_='foreignkey')
op.drop_constraint(op.f('users_current_sales_agent_id_fkey'), 'users', type_='foreignkey')
op.drop_constraint(op.f('users_person_id_fkey'), 'users', type_='foreignkey')
op.create_foreign_key(None, 'users', 'users', ['referred_by_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'users', 'users', ['current_sales_agent_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'users', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.add_column('vehicle_catalog', sa.Column('master_definition_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'vehicle_catalog', 'vehicle_model_definitions', ['master_definition_id'], ['id'], source_schema='data', referent_schema='data')
op.add_column('vehicle_model_definitions', sa.Column('vehicle_type_id', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('engine_capacity', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('power_kw', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('max_weight_kg', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('axle_count', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('payload_capacity_kg', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('cargo_volume_m3', sa.Numeric(precision=10, scale=2), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('cargo_length_mm', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('cargo_width_mm', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('cargo_height_mm', sa.Integer(), nullable=True))
op.add_column('vehicle_model_definitions', sa.Column('features_json', sa.JSON(), server_default=sa.text("'{}'::jsonb"), nullable=True))
op.drop_constraint(op.f('uix_make_tech_code'), 'vehicle_model_definitions', type_='unique')
op.create_index(op.f('ix_data_vehicle_model_definitions_engine_capacity'), 'vehicle_model_definitions', ['engine_capacity'], unique=False, schema='data')
op.create_index(op.f('ix_data_vehicle_model_definitions_max_weight_kg'), 'vehicle_model_definitions', ['max_weight_kg'], unique=False, schema='data')
op.create_index(op.f('ix_data_vehicle_model_definitions_power_kw'), 'vehicle_model_definitions', ['power_kw'], unique=False, schema='data')
op.create_unique_constraint('uix_make_tech_type', 'vehicle_model_definitions', ['make', 'technical_code', 'vehicle_type'], schema='data')
op.create_foreign_key(None, 'vehicle_model_definitions', 'vehicle_types', ['vehicle_type_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_column('vehicle_model_definitions', 'features')
op.drop_constraint(op.f('vehicle_ownerships_vehicle_id_fkey'), 'vehicle_ownerships', type_='foreignkey')
op.drop_constraint(op.f('vehicle_ownerships_user_id_fkey'), 'vehicle_ownerships', type_='foreignkey')
op.create_foreign_key(None, 'vehicle_ownerships', 'assets', ['vehicle_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'vehicle_ownerships', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('verification_tokens_user_id_fkey'), 'verification_tokens', type_='foreignkey')
op.create_foreign_key(None, 'verification_tokens', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='CASCADE')
op.drop_constraint(op.f('wallets_user_id_fkey'), 'wallets', type_='foreignkey')
op.create_foreign_key(None, 'wallets', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'wallets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('wallets_user_id_fkey'), 'wallets', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'verification_tokens', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('verification_tokens_user_id_fkey'), 'verification_tokens', 'users', ['user_id'], ['id'], ondelete='CASCADE')
op.drop_constraint(None, 'vehicle_ownerships', schema='data', type_='foreignkey')
op.drop_constraint(None, 'vehicle_ownerships', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('vehicle_ownerships_user_id_fkey'), 'vehicle_ownerships', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('vehicle_ownerships_vehicle_id_fkey'), 'vehicle_ownerships', 'assets', ['vehicle_id'], ['id'])
op.add_column('vehicle_model_definitions', sa.Column('features', postgresql.JSON(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), autoincrement=False, nullable=True))
op.drop_constraint(None, 'vehicle_model_definitions', schema='data', type_='foreignkey')
op.drop_constraint('uix_make_tech_type', 'vehicle_model_definitions', schema='data', type_='unique')
op.drop_index(op.f('ix_data_vehicle_model_definitions_power_kw'), table_name='vehicle_model_definitions', schema='data')
op.drop_index(op.f('ix_data_vehicle_model_definitions_max_weight_kg'), table_name='vehicle_model_definitions', schema='data')
op.drop_index(op.f('ix_data_vehicle_model_definitions_engine_capacity'), table_name='vehicle_model_definitions', schema='data')
op.create_unique_constraint(op.f('uix_make_tech_code'), 'vehicle_model_definitions', ['make', 'technical_code'], postgresql_nulls_not_distinct=False)
op.drop_column('vehicle_model_definitions', 'features_json')
op.drop_column('vehicle_model_definitions', 'cargo_height_mm')
op.drop_column('vehicle_model_definitions', 'cargo_width_mm')
op.drop_column('vehicle_model_definitions', 'cargo_length_mm')
op.drop_column('vehicle_model_definitions', 'cargo_volume_m3')
op.drop_column('vehicle_model_definitions', 'payload_capacity_kg')
op.drop_column('vehicle_model_definitions', 'axle_count')
op.drop_column('vehicle_model_definitions', 'max_weight_kg')
op.drop_column('vehicle_model_definitions', 'power_kw')
op.drop_column('vehicle_model_definitions', 'engine_capacity')
op.drop_column('vehicle_model_definitions', 'vehicle_type_id')
op.drop_constraint(None, 'vehicle_catalog', schema='data', type_='foreignkey')
op.drop_column('vehicle_catalog', 'master_definition_id')
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('users_person_id_fkey'), 'users', 'persons', ['person_id'], ['id'])
op.create_foreign_key(op.f('users_current_sales_agent_id_fkey'), 'users', 'users', ['current_sales_agent_id'], ['id'])
op.create_foreign_key(op.f('users_referred_by_id_fkey'), 'users', 'users', ['referred_by_id'], ['id'])
op.drop_constraint(None, 'user_stats', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('user_stats_user_id_fkey'), 'user_stats', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'user_badges', schema='data', type_='foreignkey')
op.drop_constraint(None, 'user_badges', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('user_badges_badge_id_fkey'), 'user_badges', 'badges', ['badge_id'], ['id'])
op.create_foreign_key(op.f('user_badges_user_id_fkey'), 'user_badges', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'social_accounts', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('social_accounts_user_id_fkey'), 'social_accounts', 'users', ['user_id'], ['id'], ondelete='CASCADE')
op.drop_constraint(None, 'service_specialties', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_specialties_parent_id_fkey'), 'service_specialties', 'service_specialties', ['parent_id'], ['id'])
op.drop_constraint(None, 'service_profiles', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_profiles_organization_id_fkey'), 'service_profiles', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'service_expertises', schema='data', type_='foreignkey')
op.drop_constraint(None, 'service_expertises', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_expertises_expertise_id_fkey'), 'service_expertises', 'expertise_tags', ['expertise_id'], ['id'])
op.create_foreign_key(op.f('service_expertises_service_id_fkey'), 'service_expertises', 'service_profiles', ['service_id'], ['id'])
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('security_audit_logs_target_id_fkey'), 'security_audit_logs', 'users', ['target_id'], ['id'])
op.create_foreign_key(op.f('security_audit_logs_actor_id_fkey'), 'security_audit_logs', 'users', ['actor_id'], ['id'])
op.create_foreign_key(op.f('security_audit_logs_confirmed_by_id_fkey'), 'security_audit_logs', 'users', ['confirmed_by_id'], ['id'])
op.drop_constraint(None, 'ratings', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('ratings_author_id_fkey'), 'ratings', 'users', ['author_id'], ['id'])
op.drop_constraint(None, 'points_ledger', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('points_ledger_user_id_fkey'), 'points_ledger', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'persons', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('persons_address_id_fkey'), 'persons', 'addresses', ['address_id'], ['id'])
op.drop_constraint(None, 'pending_actions', schema='data', type_='foreignkey')
op.drop_constraint(None, 'pending_actions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('pending_actions_approver_id_fkey'), 'pending_actions', 'users', ['approver_id'], ['id'])
op.create_foreign_key(op.f('pending_actions_requester_id_fkey'), 'pending_actions', 'users', ['requester_id'], ['id'])
op.drop_constraint(None, 'organizations', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organizations', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organizations_address_id_fkey'), 'organizations', 'addresses', ['address_id'], ['id'])
op.create_foreign_key(op.f('organizations_owner_id_fkey'), 'organizations', 'users', ['owner_id'], ['id'])
op.alter_column('organizations', 'org_type',
existing_type=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype', schema='data', inherit_schema=True),
type_=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype'),
existing_nullable=True)
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organization_members_person_id_fkey'), 'organization_members', 'persons', ['person_id'], ['id'])
op.create_foreign_key(op.f('organization_members_organization_id_fkey'), 'organization_members', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('organization_members_user_id_fkey'), 'organization_members', 'users', ['user_id'], ['id'])
op.alter_column('organization_members', 'role',
existing_type=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole', schema='data', inherit_schema=True),
type_=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole'),
existing_nullable=True)
op.drop_constraint(None, 'organization_financials', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organization_financials_organization_id_fkey'), 'organization_financials', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'org_subscriptions', schema='data', type_='foreignkey')
op.drop_constraint(None, 'org_subscriptions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('org_subscriptions_tier_id_fkey'), 'org_subscriptions', 'subscription_tiers', ['tier_id'], ['id'])
op.create_foreign_key(op.f('org_subscriptions_org_id_fkey'), 'org_subscriptions', 'organizations', ['org_id'], ['id'])
op.drop_constraint(None, 'org_sales_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'org_sales_assignments', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('org_sales_assignments_agent_user_id_fkey'), 'org_sales_assignments', 'users', ['agent_user_id'], ['id'])
op.create_foreign_key(op.f('org_sales_assignments_organization_id_fkey'), 'org_sales_assignments', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'operational_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('operational_logs_user_id_fkey'), 'operational_logs', 'users', ['user_id'], ['id'], ondelete='SET NULL')
op.drop_constraint(None, 'geo_streets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('geo_streets_postal_code_id_fkey'), 'geo_streets', 'geo_postal_codes', ['postal_code_id'], ['id'])
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('financial_ledger_user_id_fkey'), 'financial_ledger', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('financial_ledger_related_agent_id_fkey'), 'financial_ledger', 'users', ['related_agent_id'], ['id'])
op.create_foreign_key(op.f('financial_ledger_person_id_fkey'), 'financial_ledger', 'persons', ['person_id'], ['id'])
op.drop_constraint(None, 'documents', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('documents_uploaded_by_fkey'), 'documents', 'users', ['uploaded_by'], ['id'])
op.drop_constraint(None, 'credit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('credit_logs_org_id_fkey'), 'credit_logs', 'organizations', ['org_id'], ['id'])
op.drop_constraint(None, 'branches', schema='data', type_='foreignkey')
op.drop_constraint(None, 'branches', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('branches_address_id_fkey'), 'branches', 'addresses', ['address_id'], ['id'])
op.create_foreign_key(op.f('branches_organization_id_fkey'), 'branches', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'audit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('audit_logs_user_id_fkey'), 'audit_logs', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'assets', schema='data', type_='foreignkey')
op.drop_constraint(None, 'assets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('assets_catalog_id_fkey'), 'assets', 'vehicle_catalog', ['catalog_id'], ['id'])
op.create_foreign_key(op.f('assets_current_organization_id_fkey'), 'assets', 'organizations', ['current_organization_id'], ['id'])
op.drop_constraint(None, 'asset_telemetry', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_telemetry_asset_id_fkey'), 'asset_telemetry', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_reviews', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_reviews', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_reviews_user_id_fkey'), 'asset_reviews', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('asset_reviews_asset_id_fkey'), 'asset_reviews', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_financials', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_financials_asset_id_fkey'), 'asset_financials', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_events', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_events_asset_id_fkey'), 'asset_events', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_costs_organization_id_fkey'), 'asset_costs', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('asset_costs_driver_id_fkey'), 'asset_costs', 'users', ['driver_id'], ['id'])
op.create_foreign_key(op.f('asset_costs_asset_id_fkey'), 'asset_costs', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_assignments_branch_id_fkey'), 'asset_assignments', 'branches', ['branch_id'], ['id'])
op.create_foreign_key(op.f('asset_assignments_organization_id_fkey'), 'asset_assignments', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('asset_assignments_asset_id_fkey'), 'asset_assignments', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'addresses', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('addresses_postal_code_id_fkey'), 'addresses', 'geo_postal_codes', ['postal_code_id'], ['id'])
op.drop_table('model_feature_maps', schema='data')
op.drop_table('feature_definitions', schema='data')
op.drop_index(op.f('ix_data_vehicle_types_code'), table_name='vehicle_types', schema='data')
op.drop_table('vehicle_types', schema='data')
# ### end Alembic commands ###

View File

@@ -0,0 +1,309 @@
"""v1_9_final_mdm_and_process_logs
Revision ID: f30c0005c446
Revises: 8f09b4b22f14
Create Date: 2026-02-17 00:04:12.575332
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = 'f30c0005c446'
down_revision: Union[str, Sequence[str], None] = '8f09b4b22f14'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('process_logs',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('process_name', sa.String(length=100), nullable=True),
sa.Column('start_time', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('end_time', sa.DateTime(timezone=True), nullable=True),
sa.Column('items_processed', sa.Integer(), nullable=True),
sa.Column('items_failed', sa.Integer(), nullable=True),
sa.Column('details', sa.JSON(), server_default=sa.text("'{}'::jsonb"), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.PrimaryKeyConstraint('id'),
schema='data'
)
op.create_index(op.f('ix_data_process_logs_process_name'), 'process_logs', ['process_name'], unique=False, schema='data')
op.drop_constraint(op.f('addresses_postal_code_id_fkey'), 'addresses', type_='foreignkey')
op.create_foreign_key(None, 'addresses', 'geo_postal_codes', ['postal_code_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_assignments_asset_id_fkey'), 'asset_assignments', type_='foreignkey')
op.drop_constraint(op.f('asset_assignments_organization_id_fkey'), 'asset_assignments', type_='foreignkey')
op.drop_constraint(op.f('asset_assignments_branch_id_fkey'), 'asset_assignments', type_='foreignkey')
op.create_foreign_key(None, 'asset_assignments', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_assignments', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_assignments', 'branches', ['branch_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_costs_driver_id_fkey'), 'asset_costs', type_='foreignkey')
op.drop_constraint(op.f('asset_costs_asset_id_fkey'), 'asset_costs', type_='foreignkey')
op.drop_constraint(op.f('asset_costs_organization_id_fkey'), 'asset_costs', type_='foreignkey')
op.create_foreign_key(None, 'asset_costs', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_costs', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_costs', 'users', ['driver_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_events_asset_id_fkey'), 'asset_events', type_='foreignkey')
op.create_foreign_key(None, 'asset_events', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_financials_asset_id_fkey'), 'asset_financials', type_='foreignkey')
op.create_foreign_key(None, 'asset_financials', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_reviews_asset_id_fkey'), 'asset_reviews', type_='foreignkey')
op.drop_constraint(op.f('asset_reviews_user_id_fkey'), 'asset_reviews', type_='foreignkey')
op.create_foreign_key(None, 'asset_reviews', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'asset_reviews', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('asset_telemetry_asset_id_fkey'), 'asset_telemetry', type_='foreignkey')
op.create_foreign_key(None, 'asset_telemetry', 'assets', ['asset_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('assets_current_organization_id_fkey'), 'assets', type_='foreignkey')
op.drop_constraint(op.f('assets_catalog_id_fkey'), 'assets', type_='foreignkey')
op.create_foreign_key(None, 'assets', 'vehicle_catalog', ['catalog_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'assets', 'organizations', ['current_organization_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('audit_logs_user_id_fkey'), 'audit_logs', type_='foreignkey')
op.create_foreign_key(None, 'audit_logs', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('branches_organization_id_fkey'), 'branches', type_='foreignkey')
op.drop_constraint(op.f('branches_address_id_fkey'), 'branches', type_='foreignkey')
op.create_foreign_key(None, 'branches', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'branches', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('credit_logs_org_id_fkey'), 'credit_logs', type_='foreignkey')
op.create_foreign_key(None, 'credit_logs', 'organizations', ['org_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('documents_uploaded_by_fkey'), 'documents', type_='foreignkey')
op.create_foreign_key(None, 'documents', 'users', ['uploaded_by'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('feature_definitions_vehicle_type_id_fkey'), 'feature_definitions', type_='foreignkey')
op.create_foreign_key(None, 'feature_definitions', 'vehicle_types', ['vehicle_type_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('financial_ledger_person_id_fkey'), 'financial_ledger', type_='foreignkey')
op.drop_constraint(op.f('financial_ledger_user_id_fkey'), 'financial_ledger', type_='foreignkey')
op.drop_constraint(op.f('financial_ledger_related_agent_id_fkey'), 'financial_ledger', type_='foreignkey')
op.create_foreign_key(None, 'financial_ledger', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'financial_ledger', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'financial_ledger', 'users', ['related_agent_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('geo_streets_postal_code_id_fkey'), 'geo_streets', type_='foreignkey')
op.create_foreign_key(None, 'geo_streets', 'geo_postal_codes', ['postal_code_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('model_feature_maps_model_id_fkey'), 'model_feature_maps', type_='foreignkey')
op.drop_constraint(op.f('model_feature_maps_feature_id_fkey'), 'model_feature_maps', type_='foreignkey')
op.create_foreign_key(None, 'model_feature_maps', 'feature_definitions', ['feature_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'model_feature_maps', 'vehicle_model_definitions', ['model_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('operational_logs_user_id_fkey'), 'operational_logs', type_='foreignkey')
op.create_foreign_key(None, 'operational_logs', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='SET NULL')
op.drop_constraint(op.f('org_sales_assignments_organization_id_fkey'), 'org_sales_assignments', type_='foreignkey')
op.drop_constraint(op.f('org_sales_assignments_agent_user_id_fkey'), 'org_sales_assignments', type_='foreignkey')
op.create_foreign_key(None, 'org_sales_assignments', 'users', ['agent_user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'org_sales_assignments', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('org_subscriptions_tier_id_fkey'), 'org_subscriptions', type_='foreignkey')
op.drop_constraint(op.f('org_subscriptions_org_id_fkey'), 'org_subscriptions', type_='foreignkey')
op.create_foreign_key(None, 'org_subscriptions', 'organizations', ['org_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'org_subscriptions', 'subscription_tiers', ['tier_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('organization_financials_organization_id_fkey'), 'organization_financials', type_='foreignkey')
op.create_foreign_key(None, 'organization_financials', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.alter_column('organization_members', 'role',
existing_type=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole'),
type_=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole', schema='data', inherit_schema=True),
existing_nullable=True)
op.drop_constraint(op.f('organization_members_user_id_fkey'), 'organization_members', type_='foreignkey')
op.drop_constraint(op.f('organization_members_organization_id_fkey'), 'organization_members', type_='foreignkey')
op.drop_constraint(op.f('organization_members_person_id_fkey'), 'organization_members', type_='foreignkey')
op.create_foreign_key(None, 'organization_members', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organization_members', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organization_members', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.alter_column('organizations', 'org_type',
existing_type=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype'),
type_=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype', schema='data', inherit_schema=True),
existing_nullable=True)
op.drop_constraint(op.f('organizations_owner_id_fkey'), 'organizations', type_='foreignkey')
op.drop_constraint(op.f('organizations_address_id_fkey'), 'organizations', type_='foreignkey')
op.create_foreign_key(None, 'organizations', 'users', ['owner_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'organizations', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('pending_actions_requester_id_fkey'), 'pending_actions', type_='foreignkey')
op.drop_constraint(op.f('pending_actions_approver_id_fkey'), 'pending_actions', type_='foreignkey')
op.create_foreign_key(None, 'pending_actions', 'users', ['approver_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'pending_actions', 'users', ['requester_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('persons_address_id_fkey'), 'persons', type_='foreignkey')
op.create_foreign_key(None, 'persons', 'addresses', ['address_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('points_ledger_user_id_fkey'), 'points_ledger', type_='foreignkey')
op.create_foreign_key(None, 'points_ledger', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('ratings_author_id_fkey'), 'ratings', type_='foreignkey')
op.create_foreign_key(None, 'ratings', 'users', ['author_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('security_audit_logs_target_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.drop_constraint(op.f('security_audit_logs_actor_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.drop_constraint(op.f('security_audit_logs_confirmed_by_id_fkey'), 'security_audit_logs', type_='foreignkey')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['confirmed_by_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['target_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'security_audit_logs', 'users', ['actor_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_expertises_service_id_fkey'), 'service_expertises', type_='foreignkey')
op.drop_constraint(op.f('service_expertises_expertise_id_fkey'), 'service_expertises', type_='foreignkey')
op.create_foreign_key(None, 'service_expertises', 'expertise_tags', ['expertise_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'service_expertises', 'service_profiles', ['service_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_profiles_organization_id_fkey'), 'service_profiles', type_='foreignkey')
op.create_foreign_key(None, 'service_profiles', 'organizations', ['organization_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('service_specialties_parent_id_fkey'), 'service_specialties', type_='foreignkey')
op.create_foreign_key(None, 'service_specialties', 'service_specialties', ['parent_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('social_accounts_user_id_fkey'), 'social_accounts', type_='foreignkey')
op.create_foreign_key(None, 'social_accounts', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='CASCADE')
op.drop_constraint(op.f('user_badges_badge_id_fkey'), 'user_badges', type_='foreignkey')
op.drop_constraint(op.f('user_badges_user_id_fkey'), 'user_badges', type_='foreignkey')
op.create_foreign_key(None, 'user_badges', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'user_badges', 'badges', ['badge_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('user_stats_user_id_fkey'), 'user_stats', type_='foreignkey')
op.create_foreign_key(None, 'user_stats', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('users_referred_by_id_fkey'), 'users', type_='foreignkey')
op.drop_constraint(op.f('users_person_id_fkey'), 'users', type_='foreignkey')
op.drop_constraint(op.f('users_current_sales_agent_id_fkey'), 'users', type_='foreignkey')
op.create_foreign_key(None, 'users', 'users', ['referred_by_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'users', 'users', ['current_sales_agent_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'users', 'persons', ['person_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('vehicle_catalog_master_definition_id_fkey'), 'vehicle_catalog', type_='foreignkey')
op.create_foreign_key(None, 'vehicle_catalog', 'vehicle_model_definitions', ['master_definition_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('vehicle_model_definitions_vehicle_type_id_fkey'), 'vehicle_model_definitions', type_='foreignkey')
op.create_foreign_key(None, 'vehicle_model_definitions', 'vehicle_types', ['vehicle_type_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('vehicle_ownerships_user_id_fkey'), 'vehicle_ownerships', type_='foreignkey')
op.drop_constraint(op.f('vehicle_ownerships_vehicle_id_fkey'), 'vehicle_ownerships', type_='foreignkey')
op.create_foreign_key(None, 'vehicle_ownerships', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
op.create_foreign_key(None, 'vehicle_ownerships', 'assets', ['vehicle_id'], ['id'], source_schema='data', referent_schema='data')
op.drop_constraint(op.f('verification_tokens_user_id_fkey'), 'verification_tokens', type_='foreignkey')
op.create_foreign_key(None, 'verification_tokens', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data', ondelete='CASCADE')
op.drop_constraint(op.f('wallets_user_id_fkey'), 'wallets', type_='foreignkey')
op.create_foreign_key(None, 'wallets', 'users', ['user_id'], ['id'], source_schema='data', referent_schema='data')
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'wallets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('wallets_user_id_fkey'), 'wallets', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'verification_tokens', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('verification_tokens_user_id_fkey'), 'verification_tokens', 'users', ['user_id'], ['id'], ondelete='CASCADE')
op.drop_constraint(None, 'vehicle_ownerships', schema='data', type_='foreignkey')
op.drop_constraint(None, 'vehicle_ownerships', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('vehicle_ownerships_vehicle_id_fkey'), 'vehicle_ownerships', 'assets', ['vehicle_id'], ['id'])
op.create_foreign_key(op.f('vehicle_ownerships_user_id_fkey'), 'vehicle_ownerships', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'vehicle_model_definitions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('vehicle_model_definitions_vehicle_type_id_fkey'), 'vehicle_model_definitions', 'vehicle_types', ['vehicle_type_id'], ['id'])
op.drop_constraint(None, 'vehicle_catalog', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('vehicle_catalog_master_definition_id_fkey'), 'vehicle_catalog', 'vehicle_model_definitions', ['master_definition_id'], ['id'])
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.drop_constraint(None, 'users', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('users_current_sales_agent_id_fkey'), 'users', 'users', ['current_sales_agent_id'], ['id'])
op.create_foreign_key(op.f('users_person_id_fkey'), 'users', 'persons', ['person_id'], ['id'])
op.create_foreign_key(op.f('users_referred_by_id_fkey'), 'users', 'users', ['referred_by_id'], ['id'])
op.drop_constraint(None, 'user_stats', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('user_stats_user_id_fkey'), 'user_stats', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'user_badges', schema='data', type_='foreignkey')
op.drop_constraint(None, 'user_badges', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('user_badges_user_id_fkey'), 'user_badges', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('user_badges_badge_id_fkey'), 'user_badges', 'badges', ['badge_id'], ['id'])
op.drop_constraint(None, 'social_accounts', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('social_accounts_user_id_fkey'), 'social_accounts', 'users', ['user_id'], ['id'], ondelete='CASCADE')
op.drop_constraint(None, 'service_specialties', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_specialties_parent_id_fkey'), 'service_specialties', 'service_specialties', ['parent_id'], ['id'])
op.drop_constraint(None, 'service_profiles', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_profiles_organization_id_fkey'), 'service_profiles', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'service_expertises', schema='data', type_='foreignkey')
op.drop_constraint(None, 'service_expertises', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('service_expertises_expertise_id_fkey'), 'service_expertises', 'expertise_tags', ['expertise_id'], ['id'])
op.create_foreign_key(op.f('service_expertises_service_id_fkey'), 'service_expertises', 'service_profiles', ['service_id'], ['id'])
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'security_audit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('security_audit_logs_confirmed_by_id_fkey'), 'security_audit_logs', 'users', ['confirmed_by_id'], ['id'])
op.create_foreign_key(op.f('security_audit_logs_actor_id_fkey'), 'security_audit_logs', 'users', ['actor_id'], ['id'])
op.create_foreign_key(op.f('security_audit_logs_target_id_fkey'), 'security_audit_logs', 'users', ['target_id'], ['id'])
op.drop_constraint(None, 'ratings', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('ratings_author_id_fkey'), 'ratings', 'users', ['author_id'], ['id'])
op.drop_constraint(None, 'points_ledger', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('points_ledger_user_id_fkey'), 'points_ledger', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'persons', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('persons_address_id_fkey'), 'persons', 'addresses', ['address_id'], ['id'])
op.drop_constraint(None, 'pending_actions', schema='data', type_='foreignkey')
op.drop_constraint(None, 'pending_actions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('pending_actions_approver_id_fkey'), 'pending_actions', 'users', ['approver_id'], ['id'])
op.create_foreign_key(op.f('pending_actions_requester_id_fkey'), 'pending_actions', 'users', ['requester_id'], ['id'])
op.drop_constraint(None, 'organizations', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organizations', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organizations_address_id_fkey'), 'organizations', 'addresses', ['address_id'], ['id'])
op.create_foreign_key(op.f('organizations_owner_id_fkey'), 'organizations', 'users', ['owner_id'], ['id'])
op.alter_column('organizations', 'org_type',
existing_type=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype', schema='data', inherit_schema=True),
type_=postgresql.ENUM('individual', 'service', 'service_provider', 'fleet_owner', 'club', 'business', name='orgtype'),
existing_nullable=True)
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.drop_constraint(None, 'organization_members', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organization_members_person_id_fkey'), 'organization_members', 'persons', ['person_id'], ['id'])
op.create_foreign_key(op.f('organization_members_organization_id_fkey'), 'organization_members', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('organization_members_user_id_fkey'), 'organization_members', 'users', ['user_id'], ['id'])
op.alter_column('organization_members', 'role',
existing_type=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole', schema='data', inherit_schema=True),
type_=postgresql.ENUM('OWNER', 'ADMIN', 'FLEET_MANAGER', 'DRIVER', 'MECHANIC', 'RECEPTIONIST', name='orguserrole'),
existing_nullable=True)
op.drop_constraint(None, 'organization_financials', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('organization_financials_organization_id_fkey'), 'organization_financials', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'org_subscriptions', schema='data', type_='foreignkey')
op.drop_constraint(None, 'org_subscriptions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('org_subscriptions_org_id_fkey'), 'org_subscriptions', 'organizations', ['org_id'], ['id'])
op.create_foreign_key(op.f('org_subscriptions_tier_id_fkey'), 'org_subscriptions', 'subscription_tiers', ['tier_id'], ['id'])
op.drop_constraint(None, 'org_sales_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'org_sales_assignments', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('org_sales_assignments_agent_user_id_fkey'), 'org_sales_assignments', 'users', ['agent_user_id'], ['id'])
op.create_foreign_key(op.f('org_sales_assignments_organization_id_fkey'), 'org_sales_assignments', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'operational_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('operational_logs_user_id_fkey'), 'operational_logs', 'users', ['user_id'], ['id'], ondelete='SET NULL')
op.drop_constraint(None, 'model_feature_maps', schema='data', type_='foreignkey')
op.drop_constraint(None, 'model_feature_maps', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('model_feature_maps_feature_id_fkey'), 'model_feature_maps', 'feature_definitions', ['feature_id'], ['id'])
op.create_foreign_key(op.f('model_feature_maps_model_id_fkey'), 'model_feature_maps', 'vehicle_model_definitions', ['model_id'], ['id'])
op.drop_constraint(None, 'geo_streets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('geo_streets_postal_code_id_fkey'), 'geo_streets', 'geo_postal_codes', ['postal_code_id'], ['id'])
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.drop_constraint(None, 'financial_ledger', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('financial_ledger_related_agent_id_fkey'), 'financial_ledger', 'users', ['related_agent_id'], ['id'])
op.create_foreign_key(op.f('financial_ledger_user_id_fkey'), 'financial_ledger', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('financial_ledger_person_id_fkey'), 'financial_ledger', 'persons', ['person_id'], ['id'])
op.drop_constraint(None, 'feature_definitions', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('feature_definitions_vehicle_type_id_fkey'), 'feature_definitions', 'vehicle_types', ['vehicle_type_id'], ['id'])
op.drop_constraint(None, 'documents', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('documents_uploaded_by_fkey'), 'documents', 'users', ['uploaded_by'], ['id'])
op.drop_constraint(None, 'credit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('credit_logs_org_id_fkey'), 'credit_logs', 'organizations', ['org_id'], ['id'])
op.drop_constraint(None, 'branches', schema='data', type_='foreignkey')
op.drop_constraint(None, 'branches', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('branches_address_id_fkey'), 'branches', 'addresses', ['address_id'], ['id'])
op.create_foreign_key(op.f('branches_organization_id_fkey'), 'branches', 'organizations', ['organization_id'], ['id'])
op.drop_constraint(None, 'audit_logs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('audit_logs_user_id_fkey'), 'audit_logs', 'users', ['user_id'], ['id'])
op.drop_constraint(None, 'assets', schema='data', type_='foreignkey')
op.drop_constraint(None, 'assets', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('assets_catalog_id_fkey'), 'assets', 'vehicle_catalog', ['catalog_id'], ['id'])
op.create_foreign_key(op.f('assets_current_organization_id_fkey'), 'assets', 'organizations', ['current_organization_id'], ['id'])
op.drop_constraint(None, 'asset_telemetry', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_telemetry_asset_id_fkey'), 'asset_telemetry', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_reviews', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_reviews', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_reviews_user_id_fkey'), 'asset_reviews', 'users', ['user_id'], ['id'])
op.create_foreign_key(op.f('asset_reviews_asset_id_fkey'), 'asset_reviews', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_financials', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_financials_asset_id_fkey'), 'asset_financials', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_events', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_events_asset_id_fkey'), 'asset_events', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_costs', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_costs_organization_id_fkey'), 'asset_costs', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('asset_costs_asset_id_fkey'), 'asset_costs', 'assets', ['asset_id'], ['id'])
op.create_foreign_key(op.f('asset_costs_driver_id_fkey'), 'asset_costs', 'users', ['driver_id'], ['id'])
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.drop_constraint(None, 'asset_assignments', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('asset_assignments_branch_id_fkey'), 'asset_assignments', 'branches', ['branch_id'], ['id'])
op.create_foreign_key(op.f('asset_assignments_organization_id_fkey'), 'asset_assignments', 'organizations', ['organization_id'], ['id'])
op.create_foreign_key(op.f('asset_assignments_asset_id_fkey'), 'asset_assignments', 'assets', ['asset_id'], ['id'])
op.drop_constraint(None, 'addresses', schema='data', type_='foreignkey')
op.create_foreign_key(op.f('addresses_postal_code_id_fkey'), 'addresses', 'geo_postal_codes', ['postal_code_id'], ['id'])
op.drop_index(op.f('ix_data_process_logs_process_name'), table_name='process_logs', schema='data')
op.drop_table('process_logs', schema='data')
# ### end Alembic commands ###

View File

@@ -23,4 +23,5 @@ itsdangerous
fastapi-limiter==0.1.5 fastapi-limiter==0.1.5
pyotp pyotp
cryptography cryptography
GeoAlchemy2>=0.14.0 GeoAlchemy2>=0.14.0
google-generativeai