Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| Standalone sync script for POS seed data. | |
| Syncs MongoDB data to PostgreSQL for Cuatro Beauty Ltd. | |
| """ | |
| import asyncio | |
| import logging | |
| import sys | |
| import os | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| # Add current directory to Python path | |
| current_dir = Path(__file__).parent | |
| sys.path.insert(0, str(current_dir)) | |
| # Load environment variables | |
| load_dotenv() | |
| # Setup logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| MERCHANT_ID = "company_cuatro_beauty_ltd" | |
| async def sync_customers(): | |
| """Sync customers from MongoDB to PostgreSQL""" | |
| try: | |
| from app.nosql import get_database | |
| from app.sync.handler import POSSyncHandler | |
| from app.customers.models.model import CustomerModel | |
| logger.info("π Syncing customers...") | |
| # Get MongoDB data | |
| db = get_database() | |
| if db is None: | |
| raise RuntimeError("MongoDB not available") | |
| customers_collection = db.customers | |
| customers = await customers_collection.find({"merchant_id": MERCHANT_ID}).to_list(length=None) | |
| if not customers: | |
| logger.warning("No customers found to sync") | |
| return {"synced": 0, "errors": 0} | |
| synced_count = 0 | |
| error_count = 0 | |
| for customer_doc in customers: | |
| try: | |
| customer_model = CustomerModel(**customer_doc) | |
| success = await POSSyncHandler.handle_customer_created(customer_model) | |
| if success: | |
| synced_count += 1 | |
| else: | |
| error_count += 1 | |
| except Exception as e: | |
| logger.error(f"Error syncing customer {customer_doc.get('customer_id')}: {e}") | |
| error_count += 1 | |
| logger.info(f"β Customers sync completed: {synced_count} synced, {error_count} errors") | |
| return {"synced": synced_count, "errors": error_count} | |
| except Exception as e: | |
| logger.error(f"Error in customer sync: {e}") | |
| raise | |
| async def sync_staff(): | |
| """Sync staff from MongoDB to PostgreSQL""" | |
| try: | |
| from app.nosql import get_database | |
| from app.sync.handler import POSSyncHandler | |
| logger.info("π Syncing staff...") | |
| # Get MongoDB data | |
| db = get_database() | |
| if db is None: | |
| raise RuntimeError("MongoDB not available") | |
| staff_collection = db.staff | |
| staff_list = await staff_collection.find({"merchant_id": MERCHANT_ID}).to_list(length=None) | |
| if not staff_list: | |
| logger.warning("No staff found to sync") | |
| return {"synced": 0, "errors": 0} | |
| synced_count = 0 | |
| error_count = 0 | |
| for staff_doc in staff_list: | |
| try: | |
| success = await POSSyncHandler.handle_staff_created(staff_doc) | |
| if success: | |
| synced_count += 1 | |
| else: | |
| error_count += 1 | |
| except Exception as e: | |
| logger.error(f"Error syncing staff {staff_doc.get('_id')}: {e}") | |
| error_count += 1 | |
| logger.info(f"β Staff sync completed: {synced_count} synced, {error_count} errors") | |
| return {"synced": synced_count, "errors": error_count} | |
| except Exception as e: | |
| logger.error(f"Error in staff sync: {e}") | |
| raise | |
| async def sync_catalogue_services(): | |
| """Sync catalogue services from MongoDB to PostgreSQL""" | |
| try: | |
| from app.nosql import get_database | |
| from app.sync.handler import POSSyncHandler | |
| logger.info("π Syncing catalogue services...") | |
| # Get MongoDB data | |
| db = get_database() | |
| if db is None: | |
| raise RuntimeError("MongoDB not available") | |
| services_collection = db.catalogue_services | |
| services = await services_collection.find({"merchant_id": MERCHANT_ID}).to_list(length=None) | |
| if not services: | |
| logger.warning("No catalogue services found to sync") | |
| return {"synced": 0, "errors": 0} | |
| synced_count = 0 | |
| error_count = 0 | |
| for service_doc in services: | |
| try: | |
| success = await POSSyncHandler.handle_catalogue_service_created(service_doc) | |
| if success: | |
| synced_count += 1 | |
| else: | |
| error_count += 1 | |
| except Exception as e: | |
| logger.error(f"Error syncing service {service_doc.get('_id')}: {e}") | |
| error_count += 1 | |
| logger.info(f"β Catalogue services sync completed: {synced_count} synced, {error_count} errors") | |
| return {"synced": synced_count, "errors": error_count} | |
| except Exception as e: | |
| logger.error(f"Error in catalogue services sync: {e}") | |
| raise | |
| async def check_sync_health(): | |
| """Check sync system health""" | |
| try: | |
| from app.sync.handler import POSSyncHandler | |
| logger.info("π Checking sync health...") | |
| health = await POSSyncHandler.check_sync_health() | |
| if health.get("overall_health"): | |
| logger.info("β Sync system is healthy") | |
| else: | |
| logger.warning("β οΈ Sync system has issues") | |
| return health | |
| except Exception as e: | |
| logger.error(f"Error checking sync health: {e}") | |
| return {"overall_health": False, "error": str(e)} | |
| async def main(): | |
| """Main sync function""" | |
| logger.info("=" * 60) | |
| logger.info("POS SEED DATA SYNC TO POSTGRESQL") | |
| logger.info("=" * 60) | |
| logger.info(f"Merchant ID: {MERCHANT_ID}") | |
| try: | |
| # Check sync health first | |
| health = await check_sync_health() | |
| if not health.get("overall_health"): | |
| logger.error("β Sync system is not healthy. Please check configuration.") | |
| return False | |
| # Sync all entities | |
| logger.info("\nπ Starting sync operations...") | |
| # Sync customers | |
| customer_result = await sync_customers() | |
| # Sync staff | |
| staff_result = await sync_staff() | |
| # Sync catalogue services | |
| service_result = await sync_catalogue_services() | |
| # Summary | |
| logger.info("\n" + "=" * 60) | |
| logger.info("SYNC SUMMARY") | |
| logger.info("=" * 60) | |
| logger.info(f"Customers: {customer_result['synced']} synced, {customer_result['errors']} errors") | |
| logger.info(f"Staff: {staff_result['synced']} synced, {staff_result['errors']} errors") | |
| logger.info(f"Services: {service_result['synced']} synced, {service_result['errors']} errors") | |
| total_synced = customer_result['synced'] + staff_result['synced'] + service_result['synced'] | |
| total_errors = customer_result['errors'] + staff_result['errors'] + service_result['errors'] | |
| logger.info(f"Total: {total_synced} synced, {total_errors} errors") | |
| if total_errors == 0: | |
| logger.info("π All data synced successfully!") | |
| else: | |
| logger.warning(f"β οΈ {total_errors} items failed to sync") | |
| logger.info("=" * 60) | |
| return total_errors == 0 | |
| except Exception as e: | |
| logger.error(f"β Sync failed: {e}") | |
| return False | |
| if __name__ == "__main__": | |
| # Check if we're in the right directory | |
| if not (Path.cwd() / "app").exists(): | |
| print("β Please run this script from the cuatrolabs-pos-ms directory") | |
| print("Usage: cd cuatrolabs-pos-ms && python sync_seed_data.py") | |
| exit(1) | |
| success = asyncio.run(main()) | |
| exit(0 if success else 1) |