Files
Hotel-Booking/Backend/seeders/user_seeder.py
Iliyan Angelov 5a8ca3c475 updates
2025-12-06 03:27:35 +02:00

199 lines
6.1 KiB
Python

"""
User and Role Seeder
Creates default roles and an admin user
"""
import sys
from pathlib import Path
from datetime import datetime, timezone
import bcrypt
# Add parent directory to path to import modules
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from sqlalchemy.orm import Session
from src.shared.config.database import SessionLocal
# Import all models to ensure relationships are properly initialized
from src.models import *
from src.auth.models.role import Role
from src.auth.models.user import User
from src.shared.config.logging_config import get_logger
logger = get_logger(__name__)
def get_roles_data():
"""Generate default roles data"""
return [
{
'name': 'admin',
'description': 'Full system access with all administrative privileges'
},
{
'name': 'staff',
'description': 'Hotel staff with operational access'
},
{
'name': 'customer',
'description': 'Regular customer/guest user'
},
{
'name': 'accountant',
'description': 'Financial management and accounting access'
},
{
'name': 'housekeeping',
'description': 'Housekeeping and room management access'
}
]
def seed_roles(db: Session):
"""Seed roles into the database"""
try:
roles_data = get_roles_data()
created_count = 0
updated_count = 0
role_map = {}
for role_data in roles_data:
existing = db.query(Role).filter(Role.name == role_data['name']).first()
if existing:
logger.info(f'Role already exists: {role_data["name"]}')
role_map[role_data['name']] = existing
else:
logger.info(f'Creating role: {role_data["name"]}')
role = Role(**role_data)
db.add(role)
db.flush() # Flush to get the ID
role_map[role_data['name']] = role
created_count += 1
db.commit()
logger.info(f'Role seeding completed! Created: {created_count}, Existing: {len(roles_data) - created_count}')
return role_map
except Exception as e:
logger.error(f'Error seeding roles: {str(e)}', exc_info=True)
db.rollback()
raise
def seed_admin_user(db: Session, admin_role: Role, email: str = 'admin@hotel.com', password: str = 'admin123', full_name: str = 'Admin User'):
"""Seed admin user into the database"""
try:
# Check if admin user already exists
existing = db.query(User).filter(User.email == email).first()
if existing:
logger.info(f'Admin user already exists: {email}')
# Update role if needed
if existing.role_id != admin_role.id:
existing.role_id = admin_role.id
existing.updated_at = datetime.now(timezone.utc)
db.commit()
logger.info(f'Updated admin user role: {email}')
return existing
# Create new admin user
logger.info(f'Creating admin user: {email}')
password_bytes = password.encode('utf-8')
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password_bytes, salt).decode('utf-8')
admin_user = User(
email=email,
password=hashed_password,
full_name=full_name,
role_id=admin_role.id,
is_active=True,
phone=None,
address=None
)
db.add(admin_user)
db.commit()
db.refresh(admin_user)
logger.info(f'Admin user created successfully: {email}')
return admin_user
except Exception as e:
logger.error(f'Error seeding admin user: {str(e)}', exc_info=True)
db.rollback()
raise
def seed_users_and_roles(db: Session, admin_email: str = 'admin@hotel.com', admin_password: str = 'admin123', admin_name: str = 'Admin User'):
"""Seed roles and admin user"""
try:
# First, seed roles
role_map = seed_roles(db)
# Get admin role
admin_role = role_map.get('admin')
if not admin_role:
raise ValueError('Admin role not found after seeding')
# Seed admin user
admin_user = seed_admin_user(db, admin_role, admin_email, admin_password, admin_name)
return role_map, admin_user
except Exception as e:
logger.error(f'Error seeding users and roles: {str(e)}', exc_info=True)
raise
def main():
"""Main function to run the seeder"""
import argparse
parser = argparse.ArgumentParser(description='Seed roles and admin user')
parser.add_argument(
'--email',
default='admin@hotel.com',
help='Admin user email (default: admin@hotel.com)'
)
parser.add_argument(
'--password',
default='admin123',
help='Admin user password (default: admin123)'
)
parser.add_argument(
'--name',
default='Admin User',
help='Admin user full name (default: Admin User)'
)
args = parser.parse_args()
logger.info('Starting user and role seeder...')
db = SessionLocal()
try:
role_map, admin_user = seed_users_and_roles(
db,
admin_email=args.email,
admin_password=args.password,
admin_name=args.name
)
logger.info(f'User and role seeder completed successfully!')
logger.info(f'Admin user: {admin_user.email} (ID: {admin_user.id})')
logger.info(f'Roles created: {len(role_map)}')
print(f'\n✓ Admin user created successfully!')
print(f' Email: {admin_user.email}')
print(f' Password: {args.password}')
print(f' Role: admin')
print(f'\n⚠️ IMPORTANT: Change the default password after first login!')
except Exception as e:
logger.error(f'Failed to seed users and roles: {str(e)}', exc_info=True)
sys.exit(1)
finally:
db.close()
if __name__ == '__main__':
main()