Files
service-finder/backend/app/scripts/verify_migration.py

79 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Verify the results of the Great Garage & Vehicle Migration."""
import asyncio
import asyncpg
DATABASE_URL = "postgresql://service_finder_app:AppSafePass_2026@shared-postgres:5432/service_finder"
async def verify():
conn = await asyncpg.connect(DATABASE_URL)
print("=== VERIFICATION REPORT ===")
print()
# 1. Users without personal garages
r = await conn.fetchval("""
SELECT COUNT(*) FROM identity.users u
JOIN identity.persons p ON p.id = u.person_id
WHERE u.is_deleted = false AND u.is_active = true
AND NOT EXISTS (
SELECT 1 FROM fleet.organizations o
WHERE o.owner_id = u.id AND o.org_type = 'individual' AND o.is_deleted = false
)
""")
print(f"1. Users still WITHOUT personal garage: {r} (expected: 0)")
# 2. Total personal garages
r = await conn.fetchval("""
SELECT COUNT(*) FROM fleet.organizations
WHERE org_type = 'individual' AND is_deleted = false
""")
print(f"2. Total personal garages (INDIVIDUAL): {r}")
# 3. Users with NULL scope_id
r = await conn.fetchval("""
SELECT COUNT(*) FROM identity.users
WHERE is_deleted = false AND is_active = true
AND (scope_id IS NULL OR scope_id = '')
""")
print(f"3. Users with NULL/empty scope_id: {r}")
# 4. Organization members with OWNER role
r = await conn.fetchval("""
SELECT COUNT(*) FROM fleet.organization_members WHERE role = 'OWNER'
""")
print(f"4. Organization members with OWNER role: {r}")
# 5. Orphaned vehicles remaining
r = await conn.fetchval("""
SELECT COUNT(*) FROM vehicle.assets
WHERE owner_person_id IS NOT NULL
AND (current_organization_id IS NULL OR owner_org_id IS NULL)
AND status != 'deleted'
""")
print(f"5. Orphaned vehicles remaining: {r} (expected: 0)")
# 6. Detail of all personal garages
rows = await conn.fetch("""
SELECT o.id, o.name, u.email, u.scope_id
FROM fleet.organizations o
JOIN identity.users u ON u.id = o.owner_id
WHERE o.org_type = 'individual' AND o.is_deleted = false
ORDER BY o.id
""")
print(f"\n6. Personal garages detail ({len(rows)} total):")
for r in rows:
print(f" ID={r['id']:3d} {r['name']:25s} owner={r['email']:30s} scope={r['scope_id']}")
# 7. Count all vehicles and their org assignments
r = await conn.fetchval("SELECT COUNT(*) FROM vehicle.assets WHERE status != 'deleted'")
r2 = await conn.fetchval("""
SELECT COUNT(*) FROM vehicle.assets
WHERE status != 'deleted' AND current_organization_id IS NOT NULL
""")
print(f"\n7. Vehicles: {r} total, {r2} with organization assigned")
await conn.close()
asyncio.run(verify())