Initial commit: Robot ökoszisztéma v2.0 - Stabilizált jármű és szerviz robotok
This commit is contained in:
0
backend/app/tests_internal/seeds/__init__.py
Executable file
0
backend/app/tests_internal/seeds/__init__.py
Executable file
98
backend/app/tests_internal/seeds/seed_catalog.py
Executable file
98
backend/app/tests_internal/seeds/seed_catalog.py
Executable file
@@ -0,0 +1,98 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/tests_internal/seeds/seed_catalog.py
|
||||
"""
|
||||
🌱 MB2.0 KATALÓGUS ÉS ROBOT SEEDER
|
||||
----------------------------------
|
||||
CÉL: A járműkatalógus alapadatainak és a robotok munkalistájának feltöltése.
|
||||
|
||||
FUNKCIÓK:
|
||||
1. DiscoveryParameter: Azon városok rögzítése, ahol a Scout robot keresni fog.
|
||||
2. CatalogDiscovery: Azon márkák rögzítése, amiket a Robot 0/1 fel fog dolgozni.
|
||||
3. AssetCatalog: 'Arany' (már validált) technikai rekordok beszúrása.
|
||||
|
||||
JAVÍTÁSOK:
|
||||
- 'last_error' oszlop eltávolítva (mivel az adatbázisban nem létezik).
|
||||
- 'attempts' mező kényszerített 0 értékkel (NOT NULL kényszer miatt).
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.models.asset import AssetCatalog, CatalogDiscovery
|
||||
from app.models.staged_data import DiscoveryParameter
|
||||
|
||||
# Logolás beállítása
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] Sentinel-Seed: %(message)s')
|
||||
logger = logging.getLogger("Seed-Catalog")
|
||||
|
||||
async def quick_seed():
|
||||
""" Katalógus és Discovery adatok inicializálása. """
|
||||
async with AsyncSessionLocal() as db:
|
||||
logger.info("🚀 Katalógus alapozás indítása...")
|
||||
|
||||
try:
|
||||
# 1. Felderítendő Városok (DiscoveryParameter)
|
||||
# A Scout robot ezekben a városokban kezdi meg a szervizek kutatását.
|
||||
cities = [
|
||||
("BUDAPEST", "HU"),
|
||||
("DEBRECEN", "HU"),
|
||||
("GYŐR", "HU"),
|
||||
("SZEGED", "HU")
|
||||
]
|
||||
|
||||
for city_name, country in cities:
|
||||
db.add(DiscoveryParameter(
|
||||
city=city_name,
|
||||
country_code=country,
|
||||
is_active=True
|
||||
))
|
||||
|
||||
# 2. Felderítendő Márkák és Típusok (CatalogDiscovery)
|
||||
# Ezeket a rekordokat fogja a Robot 0 és Robot 1 feldolgozni a háttérben.
|
||||
discovery_queue = [
|
||||
("SUZUKI", "ALL"),
|
||||
("TOYOTA", "ALL"),
|
||||
("HONDA", "ALL"),
|
||||
("SKODA", "ALL"),
|
||||
("YAMAHA", "ALL")
|
||||
]
|
||||
|
||||
for m, mod in discovery_queue:
|
||||
# Az attempts=0 kötelező a DB kényszer miatt
|
||||
db.add(CatalogDiscovery(
|
||||
make=m,
|
||||
model=mod,
|
||||
status="pending",
|
||||
attempts=0
|
||||
))
|
||||
|
||||
# 3. Arany rekordok (AssetCatalog / vehicle_catalog tábla)
|
||||
# Példa adatok, amik már átmentek a validációs folyamaton.
|
||||
gold_data = [
|
||||
AssetCatalog(
|
||||
make="SUZUKI",
|
||||
model="VITARA",
|
||||
generation="LY (2015-)",
|
||||
fuel_type="petrol",
|
||||
factory_data={"segment": "SUV", "origin": "Hungary"}
|
||||
),
|
||||
AssetCatalog(
|
||||
make="SKODA",
|
||||
model="OCTAVIA",
|
||||
generation="IV (2020-)",
|
||||
fuel_type="diesel",
|
||||
factory_data={"segment": "Sedan/Combi"}
|
||||
)
|
||||
]
|
||||
db.add_all(gold_data)
|
||||
|
||||
# Mentés végrehajtása
|
||||
await db.commit()
|
||||
logger.info("✨ Katalógus és Discovery paraméterek sikeresen rögzítve!")
|
||||
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
logger.error(f"❌ HIBA a katalógus feltöltésekor: {e}")
|
||||
raise e
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(quick_seed())
|
||||
106
backend/app/tests_internal/seeds/seed_data.py
Executable file
106
backend/app/tests_internal/seeds/seed_data.py
Executable file
@@ -0,0 +1,106 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/seed_data.py
|
||||
import asyncio
|
||||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from sqlalchemy import text, select
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.models.identity import User, Person, UserRole
|
||||
from app.models.social import ServiceProvider, Vote, ModerationStatus, Competition
|
||||
from app.services.social_service import SocialService
|
||||
from app.core.security import get_password_hash
|
||||
|
||||
async def run_simulation():
|
||||
async with AsyncSessionLocal() as db:
|
||||
print("--- 1. TAKARÍTÁS (MB2.0 Séma-tisztítás) ---")
|
||||
# Szigorú sorrend a kényszerek miatt (Cascade)
|
||||
await db.execute(text("TRUNCATE identity.users, identity.persons, data.service_providers, data.votes, data.competitions RESTART IDENTITY CASCADE"))
|
||||
await db.commit()
|
||||
|
||||
print("\n--- 2. SZEREPLŐK LÉTREHOZÁSA (Person + User) ---")
|
||||
users_to_create = [
|
||||
("admin@test.com", "Adminisztrátor", UserRole.superadmin),
|
||||
("good@test.com", "Rendes Srác", UserRole.user),
|
||||
("bad@test.com", "Spammer Aladár", UserRole.user),
|
||||
("voter@test.com", "Szavazó Gép", UserRole.user)
|
||||
]
|
||||
|
||||
created_users = {}
|
||||
for email, name, role in users_to_create:
|
||||
p = Person(id_uuid=uuid.uuid4(), first_name=name.split()[0], last_name=name.split()[1], is_active=True)
|
||||
db.add(p)
|
||||
await db.flush()
|
||||
|
||||
u = User(
|
||||
email=email,
|
||||
hashed_password=get_password_hash("test1234"),
|
||||
person_id=p.id,
|
||||
role=role,
|
||||
is_active=True,
|
||||
reputation_score=5 if "good" in email else (-8 if "bad" in email else 0)
|
||||
)
|
||||
db.add(u)
|
||||
await db.flush()
|
||||
created_users[email] = u
|
||||
|
||||
await db.commit()
|
||||
|
||||
print("\n--- 3. VERSENY INDÍTÁSA ---")
|
||||
race = Competition(
|
||||
name="Téli Szervizvadászat",
|
||||
start_date=datetime.now(timezone.utc) - timedelta(days=1),
|
||||
end_date=datetime.now(timezone.utc) + timedelta(days=30),
|
||||
is_active=True
|
||||
)
|
||||
db.add(race)
|
||||
await db.commit()
|
||||
|
||||
# Szereplők kiemelése a szimulációhoz
|
||||
good_user = created_users["good@test.com"]
|
||||
bad_user = created_users["bad@test.com"]
|
||||
voter = created_users["voter@test.com"]
|
||||
|
||||
print("\n--- 4. SZCENÁRIÓ A: POZITÍV VALIDÁCIÓ ---")
|
||||
# Rendes srác beküld egy szervizt
|
||||
shop = ServiceProvider(
|
||||
name="Profi Gumis",
|
||||
address="Budapest, Váci út 10.",
|
||||
added_by_user_id=good_user.id,
|
||||
status=ModerationStatus.pending
|
||||
)
|
||||
db.add(shop)
|
||||
await db.flush()
|
||||
|
||||
# Szavazatok szimulálása (SocialService használatával a pontszámítás miatt)
|
||||
print(f"Szavazás a '{shop.name}'-re...")
|
||||
# Szimulálunk 5 pozitív szavazatot különböző "virtuális" szavazóktól
|
||||
for _ in range(5):
|
||||
await SocialService.vote_for_provider(db, voter.id, shop.id, 1)
|
||||
|
||||
await db.refresh(good_user)
|
||||
print(f"Jó felhasználó hírneve: {good_user.reputation_score}")
|
||||
|
||||
print("\n--- 5. SZCENÁRIÓ B: AUTO-BAN (SPAM SZŰRÉS) ---")
|
||||
fake_shop = ServiceProvider(
|
||||
name="KAMU SZERVIZ",
|
||||
address="Nincs ilyen utca 0.",
|
||||
added_by_user_id=bad_user.id,
|
||||
status=ModerationStatus.pending
|
||||
)
|
||||
db.add(fake_shop)
|
||||
await db.flush()
|
||||
|
||||
# Leszavazás (Kell -3 a bukáshoz)
|
||||
print("Spam jelentése...")
|
||||
await SocialService.vote_for_provider(db, voter.id, fake_shop.id, -1)
|
||||
await SocialService.vote_for_provider(db, voter.id, fake_shop.id, -1)
|
||||
await SocialService.vote_for_provider(db, voter.id, fake_shop.id, -1)
|
||||
|
||||
await db.refresh(bad_user)
|
||||
print(f"Rossz felhasználó hírneve: {bad_user.reputation_score}")
|
||||
print(f"Fiók státusza: {'KITILTVA' if not bad_user.is_active else 'AKTÍV'}")
|
||||
|
||||
if not bad_user.is_active:
|
||||
print("✅ SIKER: A Sentinel automatikusan leállította a spammert!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_simulation())
|
||||
65
backend/app/tests_internal/seeds/seed_expertises.py
Executable file
65
backend/app/tests_internal/seeds/seed_expertises.py
Executable file
@@ -0,0 +1,65 @@
|
||||
import asyncio
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.models.service import ExpertiseTag
|
||||
from sqlalchemy import text
|
||||
|
||||
async def seed_expertises():
|
||||
tags = [
|
||||
# --- ALAPSZOLGÁLTATÁSOK (MECHANICS) ---
|
||||
('OIL_SERVICE', 'Időszakos szerviz / Olajcsere', 'MECHANICS'),
|
||||
('BRAKE_REPAIR', 'Fékrendszer javítás', 'MECHANICS'),
|
||||
('SUSPENSION', 'Futómű javítás és beállítás', 'MECHANICS'),
|
||||
('EXHAUST', 'Kipufogó szerviz', 'MECHANICS'),
|
||||
('CLUTCH', 'Kuplung és kettőstömegű csere', 'MECHANICS'),
|
||||
|
||||
# --- MOTOR ÉS VÁLTÓ (ENGINE_DRIVETRAIN) ---
|
||||
('ENGINE_REBUILD', 'Motorfelújítás', 'ENGINE_DRIVETRAIN'),
|
||||
('TIMING_BELT', 'Vezérlés csere', 'ENGINE_DRIVETRAIN'),
|
||||
('AUTO_GEARBOX', 'Automata váltó javítás/olajcsere', 'ENGINE_DRIVETRAIN'),
|
||||
('TURBO_REPAIR', 'Turbófeltöltő felújítás', 'ENGINE_DRIVETRAIN'),
|
||||
('INJECTOR', 'Dízel injektor / Adagoló javítás', 'ENGINE_DRIVETRAIN'),
|
||||
('DPF_CLEAN', 'DPF / Részecskeszűrő tisztítás', 'ENGINE_DRIVETRAIN'),
|
||||
|
||||
# --- ELEKTRONIKA (ELECTRICAL) ---
|
||||
('DIAGNOSTICS', 'Számítógépes diagnosztika', 'ELECTRICAL'),
|
||||
('AC_REPAIR', 'Klíma javítás és töltés', 'ELECTRICAL'),
|
||||
('BATTERY', 'Akkumulátor szerviz', 'ELECTRICAL'),
|
||||
('HYBRID_EV', 'Hibrid és Elektromos autó szerviz', 'ELECTRICAL'),
|
||||
('CHIP_TUNING', 'Szoftveres optimalizálás / Tuning', 'ELECTRICAL'),
|
||||
('ADAS', 'Vezetéstámogató rendszerek kalibrálása', 'ELECTRICAL'),
|
||||
|
||||
# --- GUMI ÉS KERÉK (TYRES) ---
|
||||
('TYRE_CHANGE', 'Gumiszerelés és centírozás', 'TYRES'),
|
||||
('WHEEL_REPAIR', 'Alufelni javítás / Görgőzés', 'TYRES'),
|
||||
|
||||
# --- KAROSSZÉRIA (BODY) ---
|
||||
('BODY_REPAIR', 'Karosszéria lakatolás', 'BODY'),
|
||||
('PAINTING', 'Autófényezés', 'BODY'),
|
||||
('GLASS_REPAIR', 'Szélvédő javítás és csere', 'BODY'),
|
||||
('PDR', 'Jégkár és horpadásjavítás (PDR)', 'BODY'),
|
||||
|
||||
# --- SEGÉLY ÉS SZÁLLÍTÁS (EMERGENCY) ---
|
||||
('TOWING', 'Autómentés / Vontatás', 'EMERGENCY'),
|
||||
('ROADSIDE_ASSIST', 'Segélyszolgálat / Helyszíni javítás', 'EMERGENCY'),
|
||||
('LOCKSMITH', 'Autózár szerviz / Kulcsmásolás', 'EMERGENCY'),
|
||||
|
||||
# --- EGYÉB JÁRMŰVEK (VEHICLE_TYPES) ---
|
||||
('MOTO_SERVICE', 'Motorkerékpár szerviz', 'VEHICLE_TYPES'),
|
||||
('TRUCK_SERVICE', 'Tehergépjármű szerviz', 'VEHICLE_TYPES'),
|
||||
('AGRI_SERVICE', 'Mezőgazdasági gép szerviz', 'VEHICLE_TYPES'),
|
||||
]
|
||||
|
||||
async with AsyncSessionLocal() as db:
|
||||
print("🌱 Szakmai címkék feltöltése...")
|
||||
for key, name, cat in tags:
|
||||
stmt = text("""
|
||||
INSERT INTO data.expertise_tags (key, name_hu, category, is_official)
|
||||
VALUES (:k, :n, :c, true)
|
||||
ON CONFLICT (key) DO UPDATE SET name_hu = EXCLUDED.name_hu, category = EXCLUDED.category
|
||||
""")
|
||||
await db.execute(stmt, {"k": key, "n": name, "c": cat})
|
||||
await db.commit()
|
||||
print(f"✅ {len(tags)} címke rögzítve.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(seed_expertises())
|
||||
74
backend/app/tests_internal/seeds/seed_honda.py
Executable file
74
backend/app/tests_internal/seeds/seed_honda.py
Executable file
@@ -0,0 +1,74 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/seed_honda.py
|
||||
import asyncio
|
||||
import logging
|
||||
from sqlalchemy import select
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.models.asset import AssetCatalog
|
||||
from app.models.staged_data import DiscoveryParameter
|
||||
|
||||
# Logolás beállítása
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] Sentinel-Seed: %(message)s')
|
||||
logger = logging.getLogger("Honda-Seeder")
|
||||
|
||||
async def seed_honda():
|
||||
"""
|
||||
Honda specifikus alapozás az MB2.0 MDM (Master Data Management) szerint.
|
||||
Létrehozza a katalógus-vázat és a robot-feladatokat.
|
||||
"""
|
||||
async with AsyncSessionLocal() as db:
|
||||
logger.info("🚀 Honda márka-ökoszisztéma inicializálása...")
|
||||
|
||||
# 1. LOGIKA: Robot Discovery feladatok rögzítése
|
||||
# Ezzel mondjuk meg a Hunter robotnak, hogy keressen rá minden Honda variánsra
|
||||
discovery_tasks = [
|
||||
DiscoveryParameter(make="HONDA", vehicle_class="car", city="BUDAPEST", keyword="repair", is_active=True),
|
||||
DiscoveryParameter(make="HONDA", vehicle_class="motorcycle", city="BUDAPEST", keyword="service", is_active=True)
|
||||
]
|
||||
|
||||
for task in discovery_tasks:
|
||||
# Megnézzük, van-e már ilyen feladat
|
||||
stmt = select(DiscoveryParameter).where(
|
||||
DiscoveryParameter.make == task.make,
|
||||
DiscoveryParameter.vehicle_class == task.vehicle_class
|
||||
)
|
||||
exists = (await db.execute(stmt)).scalar_one_or_none()
|
||||
if not exists:
|
||||
db.add(task)
|
||||
|
||||
# 2. LOGIKA: Népszerű modellek (Arany Rekordok) betöltése
|
||||
# Ezek a "Starter" adatok, amik azonnal elérhetők a felhasználóknak
|
||||
honda_models = [
|
||||
# Személyautók
|
||||
{"model": "CIVIC", "gen": "X (2015-2021)", "class": "car"},
|
||||
{"model": "ACCORD", "gen": "X (2017-)", "class": "car"},
|
||||
{"model": "CR-V", "gen": "V (2016-)", "class": "car"},
|
||||
{"model": "JAZZ", "gen": "IV (2020-)", "class": "car"},
|
||||
# Motorkerékpárok
|
||||
{"model": "CB500X", "gen": "PC64 (2019-)", "class": "motorcycle"},
|
||||
{"model": "AFRICA TWIN", "gen": "CRF1100L", "class": "motorcycle"},
|
||||
{"model": "NC750X", "gen": "RH09 (2021-)", "class": "motorcycle"}
|
||||
]
|
||||
|
||||
for m in honda_models:
|
||||
# Ellenőrizzük az AssetCatalog-ban (MDM tábla)
|
||||
stmt = select(AssetCatalog).where(
|
||||
AssetCatalog.make == "HONDA",
|
||||
AssetCatalog.model == m["model"],
|
||||
AssetCatalog.generation == m["gen"]
|
||||
)
|
||||
exists = (await db.execute(stmt)).scalar_one_or_none()
|
||||
|
||||
if not exists:
|
||||
db.add(AssetCatalog(
|
||||
make="HONDA",
|
||||
model=m["model"],
|
||||
generation=m["gen"],
|
||||
vehicle_class=m["class"],
|
||||
factory_data={"source": "manual_priority_seed"} # MDM metaadat
|
||||
))
|
||||
|
||||
await db.commit()
|
||||
logger.info("✅ Honda (Autó & Motor) katalógus váz sikeresen felépítve!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(seed_honda())
|
||||
79
backend/app/tests_internal/seeds/seed_system.py
Executable file
79
backend/app/tests_internal/seeds/seed_system.py
Executable file
@@ -0,0 +1,79 @@
|
||||
# /app/tests_internal/seeds/seed_system.py
|
||||
import asyncio
|
||||
import logging
|
||||
import uuid
|
||||
from sqlalchemy import select
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.models.identity import User, Person, UserRole
|
||||
from app.models.system import SystemParameter
|
||||
# JAVÍTOTT IMPORTOK: A grep alapján szétválasztva
|
||||
from app.models.gamification import PointRule, LevelConfig, UserStats
|
||||
from app.models.core_logic import SubscriptionTier
|
||||
from app.core.security import get_password_hash
|
||||
from app.core.config import settings
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] Sentinel-Seed: %(message)s')
|
||||
logger = logging.getLogger("System-Seeder")
|
||||
|
||||
async def seed_data():
|
||||
""" Rendszer alapadatok inicializálása a megfelelő modellekből. """
|
||||
async with AsyncSessionLocal() as db:
|
||||
logger.info("🚀 Rendszer-alapozás indítása (MB2.0 Standard)...")
|
||||
|
||||
admin_email = settings.INITIAL_ADMIN_EMAIL
|
||||
admin_password = settings.INITIAL_ADMIN_PASSWORD
|
||||
|
||||
if not admin_email or not admin_password:
|
||||
logger.error("❌ HIBA: Admin hitelesítési adatok hiányoznak!")
|
||||
return
|
||||
|
||||
# 1. Superadmin és Person kapcsolat
|
||||
stmt = select(User).where(User.email == admin_email)
|
||||
admin_exists = (await db.execute(stmt)).scalar_one_or_none()
|
||||
|
||||
if not admin_exists:
|
||||
new_person = Person(
|
||||
first_name="Rendszer",
|
||||
last_name="Adminisztrátor",
|
||||
id_uuid=uuid.uuid4(),
|
||||
is_active=True
|
||||
)
|
||||
db.add(new_person)
|
||||
await db.flush()
|
||||
|
||||
new_admin = User(
|
||||
email=admin_email,
|
||||
hashed_password=get_password_hash(admin_password),
|
||||
role=UserRole.superadmin,
|
||||
is_active=True,
|
||||
person_id=new_person.id
|
||||
)
|
||||
db.add(new_admin)
|
||||
await db.flush()
|
||||
|
||||
# Statisztikai rekord (Gamification)
|
||||
db.add(UserStats(user_id=new_admin.id, total_xp=0, current_level=1))
|
||||
logger.info(f"✅ Superadmin létrehozva: {admin_email}")
|
||||
|
||||
# 2. Rendszerparaméterek (JSONB értékekkel)
|
||||
params = [
|
||||
("SECURITY_MAX_RECORDS_PER_HOUR", {"limit": 50}, "Biztonsági limit"),
|
||||
("VEHICLE_LIMIT", {"default": 5}, "Alapértelmezett jármű limit")
|
||||
]
|
||||
for key, val, desc in params:
|
||||
stmt_p = select(SystemParameter).where(SystemParameter.key == key)
|
||||
if not (await db.execute(stmt_p)).scalar_one_or_none():
|
||||
db.add(SystemParameter(key=key, value=val, description=desc))
|
||||
|
||||
# 3. Gamification Szabályok (gamification.py-ból)
|
||||
rules = [("ASSET_REGISTER", 100), ("ASSET_REVIEW", 75)]
|
||||
for key, pts in rules:
|
||||
stmt_r = select(PointRule).where(PointRule.action_key == key)
|
||||
if not (await db.execute(stmt_r)).scalar_one_or_none():
|
||||
db.add(PointRule(action_key=key, points=pts))
|
||||
|
||||
await db.commit()
|
||||
logger.info("✨ Rendszer alapadatok rögzítve.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(seed_data())
|
||||
120
backend/app/tests_internal/seeds/seed_test_scenario.py
Executable file
120
backend/app/tests_internal/seeds/seed_test_scenario.py
Executable file
@@ -0,0 +1,120 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/seed_test_scenario.py
|
||||
import asyncio
|
||||
import uuid
|
||||
import logging
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from sqlalchemy import select
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
from app.models.organization import Organization, OrganizationMember, OrgType
|
||||
from app.models.asset import (
|
||||
Asset, AssetCatalog, AssetTelemetry,
|
||||
AssetFinancials, AssetCost
|
||||
)
|
||||
|
||||
# Sentinel naplózás
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] Sentinel-Scenario: %(message)s')
|
||||
logger = logging.getLogger("Test-Scenario")
|
||||
|
||||
async def seed_test_scenario():
|
||||
async with AsyncSessionLocal() as db:
|
||||
logger.info("🚀 MB2.0 Teszt ökoszisztéma felépítése indul...")
|
||||
|
||||
# 1. LOGIKA: Admin (Superuser) lekérése az identity sémából
|
||||
res = await db.execute(select(User).where(User.is_active == True))
|
||||
admin = res.scalars().first()
|
||||
|
||||
if not admin:
|
||||
logger.error("❌ Hiba: Nincs aktív felhasználó a rendszerben. Futtasd a seed_system.py-t!")
|
||||
return
|
||||
|
||||
# 2. LOGIKA: Szervezeti struktúra felállítása
|
||||
# Privát garázs
|
||||
private_org = Organization(
|
||||
name="Kincses Privát",
|
||||
full_name="Kincses Magánflotta és Garázs",
|
||||
org_type=OrgType.individual,
|
||||
owner_id=admin.id,
|
||||
folder_slug="kincses-privat-vault"
|
||||
)
|
||||
# Üzleti flotta
|
||||
company_org = Organization(
|
||||
name="ProfiBot Fleet",
|
||||
full_name="ProfiBot Software Solutions Kft.",
|
||||
org_type=OrgType.business,
|
||||
owner_id=admin.id,
|
||||
folder_slug="profibot-fleet-vault"
|
||||
)
|
||||
# Szolgáltatók (Szerviz és Üzemanyag)
|
||||
service_org = Organization(
|
||||
name="Mester Szerviz",
|
||||
org_type=OrgType.service,
|
||||
owner_id=admin.id,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
db.add_all([private_org, company_org, service_org])
|
||||
await db.flush()
|
||||
|
||||
# Tagsági viszonyok rögzítése
|
||||
db.add(OrganizationMember(user_id=admin.id, organization_id=company_org.id, role="owner"))
|
||||
|
||||
# 3. LOGIKA: Tesla Model 3 - Digitális Iker (Digital Twin)
|
||||
# Előbb a katalógus (Gold Data)
|
||||
catalog = AssetCatalog(
|
||||
make="TESLA", model="MODEL 3", generation="Long Range (2021-)",
|
||||
fuel_type="electric",
|
||||
factory_data={
|
||||
"battery": "75 kWh", "power_kw": 366,
|
||||
"tire_size": "235/45 R18", "ac_charge": "11kW"
|
||||
}
|
||||
)
|
||||
db.add(catalog)
|
||||
await db.flush()
|
||||
|
||||
# Majd a konkrét jármű (Asset)
|
||||
vehicle = Asset(
|
||||
vin=f"5YJ3E1EB8LF{uuid.uuid4().hex[:6].upper()}",
|
||||
license_plate="TES-777-EV",
|
||||
name="Céges Tesla",
|
||||
year_of_manufacture=2021,
|
||||
catalog_id=catalog.id,
|
||||
owner_org_id=company_org.id,
|
||||
status="active"
|
||||
)
|
||||
db.add(vehicle)
|
||||
await db.flush()
|
||||
|
||||
# Telemetria és Pénzügyi alapok
|
||||
db.add(AssetTelemetry(asset_id=vehicle.id, current_mileage=45200, vqi_score=100.0))
|
||||
db.add(AssetFinancials(asset_id=vehicle.id, acquisition_price=18500000, currency="HUF"))
|
||||
|
||||
# 4. LOGIKA: A 9 költségtípus szimulálása
|
||||
costs_data = [
|
||||
("FUEL", 12500, "Supercharger töltés"),
|
||||
("MAINTENANCE", 85000, "Pollenszűrő és átvizsgálás"),
|
||||
("TIRES", 280000, "Téli gumi szett"),
|
||||
("INSURANCE", 32000, "Havi CASCO"),
|
||||
("TAX", 15000, "Cégautóadó (szimulált)"),
|
||||
("TOLL", 6500, "Éves matrica"),
|
||||
("CLEANING", 4500, "Külső-belső takarítás"),
|
||||
("PARKING", 1200, "Belvárosi zóna"),
|
||||
("OTHER", 2500, "Szélvédőmosó folyadék")
|
||||
]
|
||||
|
||||
for c_type, amount, desc in costs_data:
|
||||
db.add(AssetCost(
|
||||
asset_id=vehicle.id,
|
||||
organization_id=company_org.id,
|
||||
cost_type=c_type,
|
||||
amount=amount,
|
||||
currency="HUF",
|
||||
date=datetime.now(timezone.utc) - timedelta(days=2),
|
||||
specifications={"description": desc}
|
||||
))
|
||||
|
||||
await db.commit()
|
||||
logger.info("✅ Siker! A teljes flotta-ökoszisztéma üzemkész.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(seed_test_scenario())
|
||||
Reference in New Issue
Block a user