admin frontend elkezdése, járművek tisztázása, frontend fejleszts
This commit is contained in:
249
backend/scripts/repair_kyc_user.py
Normal file
249
backend/scripts/repair_kyc_user.py
Normal file
@@ -0,0 +1,249 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Repair script for user gy.krisztina76@gmail.com (ID 100).
|
||||
This user went through light registration + email verification but the KYC
|
||||
completion failed because of two bugs:
|
||||
1. verify_email() used Person.user_id (NULL) instead of User.person_id
|
||||
2. GamificationService.award_points() did internal commit conflicting with outer transaction
|
||||
|
||||
This script manually creates all the missing infrastructure that should have
|
||||
been created by complete_kyc():
|
||||
- Activate Person
|
||||
- Create Organization (personal)
|
||||
- Create Branch
|
||||
- Create OrganizationMember
|
||||
- Create Wallet
|
||||
- Create UserStats
|
||||
- Set user.scope_id
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
# Add the backend directory to the path
|
||||
sys.path.insert(0, '/app/backend')
|
||||
|
||||
from sqlalchemy import select, and_
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
|
||||
from app.core.config import settings
|
||||
|
||||
# Setup logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')
|
||||
logger = logging.getLogger("repair_kyc")
|
||||
|
||||
# Database URL from settings
|
||||
DATABASE_URL = settings.DATABASE_URL
|
||||
logger.info(f"Using database: {DATABASE_URL}")
|
||||
|
||||
# Create engine and session
|
||||
engine = create_async_engine(DATABASE_URL, echo=False)
|
||||
AsyncSessionLocal = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
|
||||
async def repair_user():
|
||||
async with AsyncSessionLocal() as db:
|
||||
try:
|
||||
# 1. Find the user
|
||||
from app.models.identity.identity import User, Person, Wallet
|
||||
from app.models.marketplace.organization import Organization, OrganizationMember, Branch
|
||||
from app.models.gamification.gamification import UserStats, PointsLedger
|
||||
|
||||
stmt = select(User).where(User.email == 'gy.krisztina76@gmail.com')
|
||||
user = (await db.execute(stmt)).scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
logger.error("User not found!")
|
||||
return
|
||||
|
||||
logger.info(f"Found user: ID={user.id}, email={user.email}, person_id={user.person_id}")
|
||||
logger.info(f" is_active={user.is_active}, scope_id={user.scope_id}")
|
||||
|
||||
# 2. Find and activate Person
|
||||
person_stmt = select(Person).where(Person.id == user.person_id)
|
||||
person = (await db.execute(person_stmt)).scalar_one_or_none()
|
||||
|
||||
if person:
|
||||
logger.info(f"Found Person: ID={person.id}, is_active={person.is_active}, user_id={person.user_id}")
|
||||
person.is_active = True
|
||||
person.user_id = user.id
|
||||
logger.info(f" -> Activated Person, set user_id={user.id}")
|
||||
else:
|
||||
logger.warning(f"Person with id={user.person_id} not found!")
|
||||
|
||||
# 3. Check if Organization already exists
|
||||
org_stmt = select(Organization).where(Organization.owner_id == user.id)
|
||||
existing_org = (await db.execute(org_stmt)).scalar_one_or_none()
|
||||
|
||||
if existing_org:
|
||||
logger.info(f"Organization already exists: ID={existing_org.id}, name={existing_org.name}")
|
||||
new_org = existing_org
|
||||
else:
|
||||
# Create personal Organization
|
||||
from app.core.security import generate_secure_slug
|
||||
|
||||
org_name = f"{person.last_name} Flotta" if person else "Personal Flotta"
|
||||
folder_slug = generate_secure_slug(12)
|
||||
|
||||
new_org = Organization(
|
||||
name=org_name,
|
||||
full_name=org_name,
|
||||
display_name=org_name,
|
||||
folder_slug=folder_slug,
|
||||
org_type="individual",
|
||||
status="ACTIVE",
|
||||
is_deleted=False,
|
||||
is_active=True,
|
||||
is_verified=False,
|
||||
is_anonymized=False,
|
||||
default_currency="HUF",
|
||||
country_code="HU",
|
||||
language="hu",
|
||||
subscription_plan="FREE",
|
||||
base_asset_limit=3,
|
||||
purchased_extra_slots=0,
|
||||
notification_settings={},
|
||||
external_integration_config={},
|
||||
visual_settings={},
|
||||
is_ownership_transferable=False,
|
||||
owner_id=user.id,
|
||||
first_registered_at=datetime.now(timezone.utc),
|
||||
current_lifecycle_started_at=datetime.now(timezone.utc),
|
||||
lifecycle_index=1,
|
||||
created_at=datetime.now(timezone.utc)
|
||||
)
|
||||
db.add(new_org)
|
||||
await db.flush()
|
||||
logger.info(f"Created Organization: ID={new_org.id}, name={org_name}")
|
||||
|
||||
# 4. Check if Branch already exists
|
||||
branch_stmt = select(Branch).where(Branch.organization_id == new_org.id)
|
||||
existing_branch = (await db.execute(branch_stmt)).scalar_one_or_none()
|
||||
|
||||
if existing_branch:
|
||||
logger.info(f"Branch already exists: ID={existing_branch.id}, name={existing_branch.name}")
|
||||
else:
|
||||
import uuid
|
||||
branch = Branch(
|
||||
id=uuid.uuid4(),
|
||||
organization_id=new_org.id,
|
||||
name="Home Base",
|
||||
is_main=True,
|
||||
opening_hours={},
|
||||
branch_rating=0.0,
|
||||
status="ACTIVE",
|
||||
is_deleted=False,
|
||||
created_at=datetime.now(timezone.utc)
|
||||
)
|
||||
db.add(branch)
|
||||
await db.flush()
|
||||
logger.info(f"Created Branch: ID={branch.id}")
|
||||
|
||||
# 5. Check if OrganizationMember already exists
|
||||
member_stmt = select(OrganizationMember).where(
|
||||
and_(
|
||||
OrganizationMember.organization_id == new_org.id,
|
||||
OrganizationMember.user_id == user.id
|
||||
)
|
||||
)
|
||||
existing_member = (await db.execute(member_stmt)).scalar_one_or_none()
|
||||
|
||||
if existing_member:
|
||||
logger.info(f"OrganizationMember already exists: ID={existing_member.id}")
|
||||
else:
|
||||
member = OrganizationMember(
|
||||
organization_id=new_org.id,
|
||||
user_id=user.id,
|
||||
role="OWNER",
|
||||
permissions={},
|
||||
is_permanent=True,
|
||||
is_verified=True
|
||||
)
|
||||
db.add(member)
|
||||
await db.flush()
|
||||
logger.info(f"Created OrganizationMember: user_id={user.id}, org_id={new_org.id}")
|
||||
|
||||
# 6. Check if Wallet already exists
|
||||
wallet_stmt = select(Wallet).where(Wallet.user_id == user.id)
|
||||
existing_wallet = (await db.execute(wallet_stmt)).scalar_one_or_none()
|
||||
|
||||
if existing_wallet:
|
||||
logger.info(f"Wallet already exists: ID={existing_wallet.id}")
|
||||
else:
|
||||
wallet = Wallet(
|
||||
user_id=user.id,
|
||||
earned_credits=0,
|
||||
purchased_credits=0,
|
||||
service_coins=0,
|
||||
currency="HUF"
|
||||
)
|
||||
db.add(wallet)
|
||||
await db.flush()
|
||||
logger.info(f"Created Wallet for user_id={user.id}")
|
||||
|
||||
# 7. Check if UserStats already exists
|
||||
stats_stmt = select(UserStats).where(UserStats.user_id == user.id)
|
||||
existing_stats = (await db.execute(stats_stmt)).scalar_one_or_none()
|
||||
|
||||
if existing_stats:
|
||||
logger.info(f"UserStats already exists: user_id={existing_stats.user_id}")
|
||||
else:
|
||||
stats = UserStats(
|
||||
user_id=user.id,
|
||||
total_xp=500, # KYC bonus
|
||||
social_points=0,
|
||||
current_level=1,
|
||||
penalty_points=0,
|
||||
restriction_level=0,
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
penalty_quota_remaining=0,
|
||||
places_discovered=0,
|
||||
places_validated=0
|
||||
)
|
||||
db.add(stats)
|
||||
|
||||
# Add PointsLedger entry for KYC bonus
|
||||
ledger = PointsLedger(
|
||||
user_id=user.id,
|
||||
points=500,
|
||||
reason="KYC_VERIFICATION_REPAIR"
|
||||
)
|
||||
db.add(ledger)
|
||||
await db.flush()
|
||||
logger.info(f"Created UserStats and PointsLedger for user_id={user.id}")
|
||||
|
||||
# 8. Set user.scope_id if not set
|
||||
if not user.scope_id:
|
||||
user.scope_id = str(new_org.id)
|
||||
logger.info(f"Set user.scope_id = {new_org.id}")
|
||||
|
||||
# 9. Ensure user.is_active is True
|
||||
if not user.is_active:
|
||||
user.is_active = True
|
||||
logger.info("Activated user")
|
||||
|
||||
await db.commit()
|
||||
logger.info("=" * 50)
|
||||
logger.info("REPAIR COMPLETED SUCCESSFULLY!")
|
||||
logger.info("=" * 50)
|
||||
|
||||
# Verify
|
||||
logger.info("\n--- Verification ---")
|
||||
logger.info(f"User: ID={user.id}, is_active={user.is_active}, scope_id={user.scope_id}")
|
||||
if person:
|
||||
logger.info(f"Person: ID={person.id}, is_active={person.is_active}, user_id={person.user_id}")
|
||||
logger.info(f"Organization: ID={new_org.id}, name={new_org.name}")
|
||||
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
logger.error(f"Repair failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
await db.close()
|
||||
await engine.dispose()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(repair_user())
|
||||
Reference in New Issue
Block a user