""" Seed POS role permissions script. Populates MongoDB with POS module permissions for retail_owner role. Usage: python scripts/seed_permissions.py Or with custom role: python scripts/seed_permissions.py --role "role_custom" """ import asyncio import argparse import sys from pathlib import Path from datetime import datetime # Add parent directory to path to import app modules sys.path.insert(0, str(Path(__file__).parent.parent)) from app.nosql import connect_to_mongo, close_mongo_connection, get_database from app.core.config import settings # POS Role Permissions POS_ROLES = { "role_retail_owner": { "role_id": "role_retail_owner", "role_name": "retail Owner", "description": "retail/Spa owner with full access to POS operations", "permissions": { "retail_staff": ["view", "create", "update", "delete"], "retail_catalogue": ["view", "create", "update", "delete"], "retail_customers": ["view", "create", "update", "delete"], "retail_sales": ["view", "create", "update", "delete"], "retail_appointments": ["view", "create", "update", "delete"], } }, "role_retail_manager": { "role_id": "role_retail_manager", "role_name": "retail Manager", "description": "retail manager with operational access", "permissions": { "retail_staff": ["view", "create", "update"], "retail_catalogue": ["view"], "retail_customers": ["view", "create", "update"], "retail_sales": ["view", "create"], "retail_appointments": ["view", "create", "update"], } }, "role_staff_member": { "role_id": "role_staff_member", "role_name": "Staff Member", "description": "Regular staff member with limited access", "permissions": { "retail_staff": ["view"], "retail_catalogue": ["view"], "retail_customers": ["view"], "retail_sales": ["view"], "retail_appointments": ["view", "create", "update"], } }, "admin": { "role_id": "admin", "role_name": "Admin", "description": "System admin (bypasses permission checks)", "permissions": { "retail_staff": ["view", "create", "update", "delete"], "retail_catalogue": ["view", "create", "update", "delete"], "retail_customers": ["view", "create", "update", "delete"], "retail_sales": ["view", "create", "update", "delete"], "retail_appointments": ["view", "create", "update", "delete"], } }, "super_admin": { "role_id": "super_admin", "role_name": "Super Admin", "description": "Super admin (bypasses permission checks)", "permissions": { "retail_staff": ["view", "create", "update", "delete"], "retail_catalogue": ["view", "create", "update", "delete"], "retail_customers": ["view", "create", "update", "delete"], "retail_sales": ["view", "create", "update", "delete"], "retail_appointments": ["view", "create", "update", "delete"], } }, } async def seed_permissions(role_id: str = None): """Seed POS role permissions.""" db = get_database() if db is None: print("āŒ MongoDB not connected. Cannot seed permissions.") return False collection = db["scm_access_roles"] print("\nšŸ“‹ Seeding POS Role Permissions...") roles_to_seed = [role_id] if role_id else POS_ROLES.keys() created_count = 0 updated_count = 0 for rid in roles_to_seed: if rid not in POS_ROLES: print(f" āš ļø Unknown role: {rid}") continue role_config = POS_ROLES[rid] # Check if role already exists existing = await collection.find_one({"role_id": rid}) now = datetime.utcnow() doc = { "role_id": rid, "role_name": role_config["role_name"], "description": role_config["description"], "permissions": role_config["permissions"], "is_active": True, "created_at": existing.get("created_at") if existing else now, "updated_at": now } if existing: # Update existing role await collection.replace_one({"role_id": rid}, doc) print(f" ā™»ļø Updated: {role_config['role_name']} ({rid})") updated_count += 1 else: # Insert new role await collection.insert_one(doc) print(f" āœ… Created: {role_config['role_name']} ({rid})") created_count += 1 # Print permissions perms = role_config["permissions"] for module, actions in perms.items(): print(f" └─ {module}: {', '.join(actions)}") print(f"\n šŸ“Š Permissions: {created_count} created, {updated_count} updated") return True async def main(role_id: str = None): """Main seed function.""" print("="*60) print("šŸ” POS Microservice - Seed Permissions Script") print("="*60) if role_id: print(f"\nšŸ“ Seeding role: {role_id}") else: print(f"\nšŸ“ Seeding all {len(POS_ROLES)} roles") print(f"šŸ“ MongoDB: {settings.MONGODB_DB_NAME}") # Connect to MongoDB try: await connect_to_mongo() except Exception as e: print(f"\nāŒ Failed to connect to MongoDB: {e}") print("\nšŸ’” Make sure MongoDB is running:") print(" docker run -d --name mongo -p 27017:27017 mongo:6") return # Seed permissions try: success = await seed_permissions(role_id) if success: print("\n" + "="*60) print("āœ… Permission seeding completed successfully!") print("="*60) if not role_id: print("\nšŸ”‘ Seeded Roles:") for rid, config in POS_ROLES.items(): print(f" • {config['role_name']} ({rid})") perms = config["permissions"] modules = ", ".join(perms.keys()) print(f" Modules: {modules}") print("\nšŸ’” Roles can now access POS endpoints with proper permissions") else: print("\nāš ļø Permission seeding completed with issues") except Exception as e: print(f"\nāŒ Error during seeding: {e}") import traceback traceback.print_exc() finally: await close_mongo_connection() if __name__ == "__main__": parser = argparse.ArgumentParser(description="Seed POS microservice role permissions") parser.add_argument( "--role", type=str, default=None, help=f"Specific role to seed. Available: {', '.join(POS_ROLES.keys())}" ) args = parser.parse_args() asyncio.run(main(args.role))