Initial commit: AutonetSellCar platform with deployment system
- Frontend: Next.js 14 with TypeScript - Backend: FastAPI with SQLAlchemy - Agent: Carmodoo sync agent - Deployment: Docker Compose based staging/production setup - Scripts: Automated deployment with rollback support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
154
backend/scripts/migrate_performance_check_to_pdf.py
Normal file
154
backend/scripts/migrate_performance_check_to_pdf.py
Normal file
@@ -0,0 +1,154 @@
|
||||
"""
|
||||
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.")
|
||||
Reference in New Issue
Block a user