201 előtti mentés

This commit is contained in:
Roo
2026-03-26 07:09:44 +00:00
parent 89668a9beb
commit 03258db091
124 changed files with 13619 additions and 13347 deletions

View File

@@ -0,0 +1,355 @@
#!/usr/bin/env python3
"""
Service Finder Integration Data Seeding Script
Populates PostgreSQL DB with real test data for frontend integration.
Inserts:
1. User: tester_pro@profibot.hu (Password: Tester123!, Role: admin)
2. Organization: "Profibot Test Fleet" in fleet.organizations
3. Vehicles: 4 real vehicles (BMW, Audi, Mercedes, Tesla) in vehicle.assets
4. Logs: Initial logs in audit.process_logs
"""
import asyncio
import sys
from datetime import datetime, timedelta
from typing import List, Tuple
import uuid
from sqlalchemy import select, delete, text
from sqlalchemy.dialects.postgresql import insert
from app.db.session import AsyncSessionLocal
from app.models.identity.identity import User, Person, UserRole, Wallet
from app.models.marketplace.organization import Organization
from app.models.vehicle.asset import Asset
from app.models.audit import ProcessLog
from app.core.security import get_password_hash
# Environment safety check
ENVIRONMENT = "development"
async def cleanup_existing_integration_data(db):
"""Clean up previously seeded integration data (only in non-production environments)."""
if ENVIRONMENT == "production":
print("⚠️ Production environment detected - skipping cleanup.")
return
print("🧹 Cleaning up previously seeded integration data...")
# We need to delete in the correct order due to foreign key constraints:
# There's a circular reference between User and Person:
# - User has person_id (foreign key to Person)
# - Person has user_id (foreign key to User, but optional)
# So we need to break the circular reference by setting person.user_id = NULL first
# 1. Delete integration test vehicles (by VIN pattern)
result = await db.execute(
delete(Asset).where(Asset.vin.like("INTEG%"))
)
print(f" Deleted {result.rowcount} integration test vehicles")
# 2. Delete integration test organization
result = await db.execute(
delete(Organization).where(Organization.name == "Profibot Test Fleet")
)
print(f" Deleted {result.rowcount} integration test organization")
# 3. Find integration test users and break circular references
user_stmt = select(User).where(
(User.email == "tester_pro@profibot.hu") |
(User.email == "superadmin@profibot.hu")
)
user_result = await db.execute(user_stmt)
integration_users = user_result.scalars().all()
for user in integration_users:
# Find the person associated with this user
person_stmt = select(Person).where(Person.user_id == user.id)
person_result = await db.execute(person_stmt)
person = person_result.scalar_one_or_none()
if person:
# Break the circular reference: set person.user_id = NULL
person.user_id = None
person.active_user_account = None
await db.flush()
print(f" Broke circular reference for person {person.id}")
# 4. Delete wallets for integration test users
for user in integration_users:
wallet_stmt = select(Wallet).where(Wallet.user_id == user.id)
wallet_result = await db.execute(wallet_stmt)
wallet = wallet_result.scalar_one_or_none()
if wallet:
await db.execute(delete(Wallet).where(Wallet.id == wallet.id))
print(f" Deleted wallet for user {user.email}")
# 5. Now delete the users
result = await db.execute(
delete(User).where(
(User.email == "tester_pro@profibot.hu") |
(User.email == "superadmin@profibot.hu")
)
)
print(f" Deleted {result.rowcount} integration test users")
# 6. Delete the persons (now that user references are broken)
# Find persons that were associated with the deleted users
# We need to join with users to find persons based on user email
person_stmt = select(Person).join(User, Person.user_id == User.id).where(
(User.email == "tester_pro@profibot.hu") |
(User.email == "superadmin@profibot.hu")
)
person_result = await db.execute(person_stmt)
integration_persons = person_result.scalars().all()
for person in integration_persons:
# Double-check that no user references this person
user_check_stmt = select(User).where(User.person_id == person.id)
user_check_result = await db.execute(user_check_stmt)
remaining_users = user_check_result.scalars().all()
if remaining_users:
print(f"⚠️ Person {person.id} still referenced by users: {[u.email for u in remaining_users]}")
# Try to break the reference by setting user.person_id = NULL
for user in remaining_users:
user.person_id = None
await db.flush()
await db.execute(delete(Person).where(Person.id == person.id))
print(f" Deleted person {person.first_name} {person.last_name}")
# 7. Delete integration test logs
result = await db.execute(
delete(ProcessLog).where(ProcessLog.process_name == "integration_seeding")
)
print(f" Deleted {result.rowcount} integration test logs")
async def seed_integration_data():
"""Main seeding function for integration test data."""
print("🚀 Starting integration data seeding...")
async with AsyncSessionLocal() as db:
try:
# Clean up old integration data first
await cleanup_existing_integration_data(db)
# 1. Create Person for the tester
print("👤 Creating Person for tester...")
person = Person(
first_name="Test",
last_name="User",
phone="+36123456789",
is_active=True,
lifetime_xp=1000,
penalty_points=0,
social_reputation=4.5
)
db.add(person)
await db.flush() # Get the person ID
# 2. Create User with admin role (tester)
print("👤 Creating User tester_pro@profibot.hu...")
user = User(
email="tester_pro@profibot.hu",
hashed_password=get_password_hash("Tester123!"),
role=UserRole.admin,
person_id=person.id,
is_active=True,
subscription_plan="PREMIUM",
subscription_expires_at=datetime.now() + timedelta(days=365),
is_vip=True,
preferred_language="hu",
region_code="HU",
preferred_currency="HUF",
scope_level="organization",
custom_permissions={},
created_at=datetime.now()
)
db.add(user)
await db.flush() # Get the user ID
# Update person with active user reference
person.user_id = user.id
person.active_user_account = user
# 2b. Create superadmin user (separate person)
print("👑 Creating superadmin user superadmin@profibot.hu...")
superadmin_person = Person(
first_name="Super",
last_name="Admin",
phone="+36123456788",
is_active=True,
lifetime_xp=5000,
penalty_points=0,
social_reputation=5.0
)
db.add(superadmin_person)
await db.flush()
superadmin_user = User(
email="superadmin@profibot.hu",
hashed_password=get_password_hash("Superadmin123!"),
role=UserRole.superadmin,
person_id=superadmin_person.id,
is_active=True,
subscription_plan="ENTERPRISE",
subscription_expires_at=datetime.now() + timedelta(days=365),
is_vip=True,
preferred_language="hu",
region_code="HU",
preferred_currency="HUF",
scope_level="system",
custom_permissions={},
created_at=datetime.now()
)
db.add(superadmin_user)
await db.flush()
superadmin_person.user_id = superadmin_user.id
superadmin_person.active_user_account = superadmin_user
# 3. Create Organization
print("🏢 Creating Organization 'Profibot Test Fleet'...")
organization = Organization(
name="Profibot Test Fleet",
full_name="Profibot Test Fleet Kft.",
owner_id=user.id,
legal_owner_id=person.id,
default_currency="HUF",
country_code="HU",
language="hu",
folder_slug="profibot",
first_registered_at=datetime.now(),
current_lifecycle_started_at=datetime.now(),
subscription_plan="PREMIUM",
base_asset_limit=10,
purchased_extra_slots=0,
notification_settings={"notify_owner": True, "alert_days_before": [30, 15, 7, 1]},
external_integration_config={},
org_type="fleet_owner",
status="active",
is_active=True,
is_verified=True,
created_at=datetime.now(),
is_ownership_transferable=True
)
db.add(organization)
await db.flush()
# 4. Create 4 real vehicles
print("🚗 Creating 4 real vehicles...")
vehicles_data = [
{
"vin": "INTEGBMW123456", # 13 chars
"license_plate": "ABC-123",
"name": "BMW X5",
"year_of_manufacture": 2022,
"owner_person_id": person.id,
"owner_org_id": organization.id,
"current_organization_id": organization.id,
"status": "active",
"current_mileage": 45000,
"currency": "EUR",
"individual_equipment": {},
"created_at": datetime.now()
},
{
"vin": "INTEGAUDI789012", # 14 chars
"license_plate": "DEF-456",
"name": "Audi A6",
"year_of_manufacture": 2021,
"owner_person_id": person.id,
"owner_org_id": organization.id,
"current_organization_id": organization.id,
"status": "active",
"current_mileage": 32000,
"currency": "EUR",
"individual_equipment": {},
"created_at": datetime.now()
},
{
"vin": "INTEGMB345678", # 12 chars
"license_plate": "GHI-789",
"name": "Mercedes E-Class",
"year_of_manufacture": 2023,
"owner_person_id": person.id,
"owner_org_id": organization.id,
"current_organization_id": organization.id,
"status": "active",
"current_mileage": 15000,
"currency": "EUR",
"individual_equipment": {},
"created_at": datetime.now()
},
{
"vin": "INTEGTESLA90123", # 15 chars
"license_plate": "JKL-012",
"name": "Tesla Model 3",
"year_of_manufacture": 2023,
"owner_person_id": person.id,
"owner_org_id": organization.id,
"current_organization_id": organization.id,
"status": "active",
"current_mileage": 25000,
"currency": "EUR",
"individual_equipment": {},
"created_at": datetime.now()
}
]
for i, vehicle_data in enumerate(vehicles_data, 1):
vehicle = Asset(**vehicle_data)
db.add(vehicle)
print(f" Created vehicle {i}: {vehicle_data['name']}")
# 5. Create initial process logs
print("📝 Creating initial process logs...")
# Create a single process log for the entire seeding process
log = ProcessLog(
process_name="integration_seeding",
start_time=datetime.now(),
end_time=datetime.now(),
items_processed=7, # 1 user + 1 org + 4 vehicles + 1 log
items_failed=0,
details={
"user_email": "tester_pro@profibot.hu",
"organization": "Profibot Test Fleet",
"vehicle_count": 4,
"makes": ["BMW", "Audi", "Mercedes-Benz", "Tesla"]
}
)
db.add(log)
# Commit all changes
await db.commit()
print("✅ Integration data seeding completed successfully!")
# Print summary
print("\n📊 Seeding Summary:")
print(f" • User: tester_pro@profibot.hu (Password: Tester123!)")
print(f" • Organization: Profibot Test Fleet")
print(f" • Vehicles: 4 real vehicles (BMW X5, Audi A6, Mercedes E-Class, Tesla Model 3)")
print(f" • Logs: 3 process logs created")
except Exception as e:
await db.rollback()
print(f"❌ Error during integration data seeding: {e}")
raise
async def main():
"""Entry point for the seeding script."""
try:
await seed_integration_data()
except Exception as e:
print(f"💥 Fatal error: {e}")
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())