""" Migration script: Generate PDFs for existing performance check records This script: 1. Finds all CarPerformanceCheck records that have check_number but no pdf_path 2. Generates PDF for each using Playwright 3. Updates the pdf_path in the database Usage: cd backend python scripts/migrate_performance_check_to_pdf.py Requirements: pip install playwright playwright install chromium """ import asyncio import sys import os # Add parent directory to path for imports sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from app.database import Base from app.models import CarPerformanceCheck from app.services.pdf_service import capture_performance_check_pdf, PLAYWRIGHT_AVAILABLE # Database connection DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./autonetsellcar.db") async def migrate_performance_checks(): """Migrate existing performance checks to PDF format""" if not PLAYWRIGHT_AVAILABLE: print("ERROR: Playwright is not installed. Please run:") print(" pip install playwright") print(" playwright install chromium") return # Create database session engine = create_engine(DATABASE_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) db = SessionLocal() try: # Find all performance checks without PDF records = db.query(CarPerformanceCheck).filter( CarPerformanceCheck.check_number.isnot(None), CarPerformanceCheck.check_number != "", (CarPerformanceCheck.pdf_path.is_(None)) | (CarPerformanceCheck.pdf_path == "") ).all() total = len(records) print(f"Found {total} performance check records to migrate") if total == 0: print("No records to migrate. Done.") return success_count = 0 error_count = 0 for i, record in enumerate(records, 1): print(f"\n[{i}/{total}] Processing car_id={record.car_id}, check_number={record.check_number}") try: pdf_path = await capture_performance_check_pdf( record.check_number, record.car_id ) if pdf_path: record.pdf_path = pdf_path db.commit() print(f" SUCCESS: {pdf_path}") success_count += 1 else: print(f" FAILED: PDF generation returned None") error_count += 1 except Exception as e: print(f" ERROR: {e}") error_count += 1 db.rollback() # Small delay to avoid overwhelming the server await asyncio.sleep(1) print(f"\n{'='*50}") print(f"Migration completed!") print(f" Total: {total}") print(f" Success: {success_count}") print(f" Errors: {error_count}") finally: db.close() async def check_status(): """Check current migration status""" engine = create_engine(DATABASE_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) db = SessionLocal() try: total = db.query(CarPerformanceCheck).count() with_check_num = db.query(CarPerformanceCheck).filter( CarPerformanceCheck.check_number.isnot(None), CarPerformanceCheck.check_number != "" ).count() with_pdf = db.query(CarPerformanceCheck).filter( CarPerformanceCheck.pdf_path.isnot(None), CarPerformanceCheck.pdf_path != "" ).count() print(f"Performance Check Status:") print(f" Total records: {total}") print(f" With check_number: {with_check_num}") print(f" With PDF: {with_pdf}") print(f" Pending migration: {with_check_num - with_pdf}") finally: db.close() if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Migrate performance checks to PDF") parser.add_argument("--status", action="store_true", help="Show current status only") parser.add_argument("--dry-run", action="store_true", help="Show what would be done without making changes") args = parser.parse_args() if args.status: asyncio.run(check_status()) else: print("Starting performance check PDF migration...") print("This will generate PDFs for all existing performance check records.") print() if args.dry_run: print("DRY RUN - No changes will be made") asyncio.run(check_status()) else: confirm = input("Continue? (y/n): ") if confirm.lower() == 'y': asyncio.run(migrate_performance_checks()) else: print("Cancelled.")