Files
orion/scripts/seed/init_production.py
Samir Boulahtit 820ab1aaa4
Some checks failed
CI / ruff (push) Successful in 11s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
feat(i18n): add multilingual platform descriptions and HostWizard demo data
- Add description_translations JSON column to Platform model + migration
- Add language tabs to platform admin edit form for multilingual descriptions
- Update API schemas to include description_translations in request/response
- Translate pricing section UI labels via _t() macro (monthly/annual/CTA/etc.)
- Add Luxembourgish (lb) support to all platforms (OMS, Main, Loyalty, Hosting)
- Seed description_translations, contact emails, and social links for all platforms
- Add LuxWeb Agency demo merchant with hosting stores, team, and content pages
- Fix language code typo: lu → lb in platform-edit.js availableLanguages
- Fix store content pages to use correct primary platform instead of hardcoded OMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:38:52 +01:00

934 lines
31 KiB
Python

#!/usr/bin/env python3
"""
Production Database Initialization for Orion Platform
This script initializes ESSENTIAL data required for production:
- Platform admin user
- Default store roles and permissions
- Admin settings
- Platform configuration
This is SAFE to run in production and should be run after migrations.
Usage:
make init-prod
This script is idempotent - safe to run multiple times.
"""
import sys
from datetime import UTC, datetime
from pathlib import Path
# Add project root to path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
import contextlib
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.core.config import (
print_environment_info,
settings,
validate_production_settings,
)
from app.core.database import SessionLocal
from app.core.environment import is_production
from app.modules.billing.models.subscription import SubscriptionTier
from app.modules.tenancy.models import AdminSetting, Platform, PlatformModule, User
from app.modules.tenancy.services.permission_discovery_service import (
permission_discovery_service,
)
from middleware.auth import AuthManager
# Register all models with SQLAlchemy so string-based relationships resolve
for _mod in [
"app.modules.billing.models",
"app.modules.inventory.models",
"app.modules.cart.models",
"app.modules.messaging.models",
"app.modules.loyalty.models",
"app.modules.catalog.models",
"app.modules.customers.models",
"app.modules.orders.models",
"app.modules.marketplace.models",
"app.modules.cms.models",
"app.modules.prospecting.models",
"app.modules.hosting.models",
]:
with contextlib.suppress(ImportError):
__import__(_mod)
# =============================================================================
# HELPER FUNCTIONS
# =============================================================================
def print_header(text: str):
"""Print formatted header."""
print("\n" + "=" * 70)
print(f" {text}")
print("=" * 70)
def print_step(step: int, text: str):
"""Print step indicator."""
print(f"\n[{step}] {text}")
def print_success(text: str):
"""Print success message."""
print(f"{text}")
def print_warning(text: str):
"""Print warning message."""
print(f"{text}")
def print_error(text: str):
"""Print error message."""
print(f"{text}")
# =============================================================================
# INITIALIZATION FUNCTIONS
# =============================================================================
def create_admin_user(db: Session, auth_manager: AuthManager) -> User:
"""Create or get the platform admin user."""
# Check if admin already exists
admin = db.execute(
select(User).where(User.email == settings.admin_email)
).scalar_one_or_none()
if admin:
print_warning(f"Admin user already exists: {admin.email}")
return admin
# Create new admin
hashed_password = auth_manager.hash_password(settings.admin_password)
admin = User(
username=settings.admin_username,
email=settings.admin_email,
hashed_password=hashed_password,
role="super_admin",
first_name=settings.admin_first_name,
last_name=settings.admin_last_name,
is_active=True,
is_email_verified=True,
created_at=datetime.now(UTC),
updated_at=datetime.now(UTC),
)
db.add(admin)
db.flush()
print_success(f"Created admin user: {admin.email}")
return admin
def create_platform_admin(
db: Session,
auth_manager: AuthManager,
platform: Platform,
username: str,
email: str,
first_name: str,
) -> User | None:
"""Create a platform admin for a specific platform."""
from app.modules.tenancy.models.admin_platform import AdminPlatform
existing = db.execute(select(User).where(User.email == email)).scalar_one_or_none()
if existing:
print_warning(f"{platform.name} admin already exists: {email}")
return existing
password = "admin123" # noqa: SEC001 Dev default, change in production
admin = User(
username=username,
email=email,
hashed_password=auth_manager.hash_password(password),
role="platform_admin",
first_name=first_name,
last_name="Administrator",
is_active=True,
is_email_verified=True,
)
db.add(admin)
db.flush()
# Assign to platform
assignment = AdminPlatform(
user_id=admin.id,
platform_id=platform.id,
is_active=True,
)
db.add(assignment)
db.flush()
print_success(f"Created {platform.name} admin: {email} (password: {password})") # noqa: SEC021
return admin
def create_loyalty_admin(db: Session, auth_manager: AuthManager, loyalty_platform: Platform) -> User | None:
"""Create a platform admin for the Loyalty+ platform."""
return create_platform_admin(
db, auth_manager, loyalty_platform,
username="loyalty_admin",
email="admin@rewardflow.lu",
first_name="Loyalty",
)
def create_oms_admin(db: Session, auth_manager: AuthManager, oms_platform: Platform) -> User | None:
"""Create a platform admin for the OMS platform."""
return create_platform_admin(
db, auth_manager, oms_platform,
username="oms_admin",
email="admin@omsflow.lu",
first_name="OMS",
)
def create_hostwizard_admin(db: Session, auth_manager: AuthManager, hosting_platform: Platform) -> User | None:
"""Create a platform admin for the HostWizard platform."""
return create_platform_admin(
db, auth_manager, hosting_platform,
username="hosting_admin",
email="admin@hostwizard.lu",
first_name="HostWizard",
)
def create_default_platforms(db: Session) -> list[Platform]:
"""Create all default platforms (OMS, Main, Loyalty+)."""
platform_defs = [
{
"code": "oms",
"name": "OMS",
"description": "Order Management System for multi-store e-commerce",
"description_translations": {
"fr": "Système de gestion des commandes pour le commerce multi-boutiques",
"de": "Bestellverwaltungssystem für Multi-Store-E-Commerce",
"en": "Order Management System for multi-store e-commerce",
"lb": "Bestellverwaltungssystem fir Multi-Store-E-Commerce",
},
"domain": "omsflow.lu",
"path_prefix": "oms",
"default_language": "fr",
"supported_languages": ["fr", "de", "en", "lb"],
"settings": {
"contact_email": "info@omsflow.lu",
"support_email": "support@omsflow.lu",
},
"theme_config": {},
},
{
"code": "main",
"name": "Wizard",
"description": "Main marketing site showcasing all Orion platforms",
"description_translations": {
"fr": "Site marketing principal présentant toutes les plateformes Orion",
"de": "Zentrale Marketingseite für alle Orion-Plattformen",
"en": "Main marketing site showcasing all Orion platforms",
"lb": "Haaptmarketingsäit fir all Orion-Plattformen",
},
"domain": "wizard.lu",
"path_prefix": None,
"default_language": "fr",
"supported_languages": ["fr", "de", "en", "lb"],
"settings": {
"is_marketing_site": True,
"contact_email": "info@wizard.lu",
"support_email": "support@wizard.lu",
},
"theme_config": {
"primary_color": "#2563EB",
"secondary_color": "#3B82F6",
"social": {
"facebook": "https://facebook.com/wizard.lu",
"linkedin": "https://linkedin.com/company/wizard-lu",
},
},
},
{
"code": "loyalty",
"name": "Loyalty",
"description": "Customer loyalty program platform for Luxembourg businesses",
"description_translations": {
"fr": "Plateforme de programme de fidélité pour les entreprises luxembourgeoises",
"de": "Kundenbindungsprogramm-Plattform für luxemburgische Unternehmen",
"en": "Customer loyalty program platform for Luxembourg businesses",
"lb": "Clientsfidélitéitsprogramm-Plattform fir lëtzebuerger Betriber",
},
"domain": "rewardflow.lu",
"path_prefix": "loyalty",
"default_language": "fr",
"supported_languages": ["fr", "de", "en", "lb"],
"settings": {
"features": ["points", "rewards", "tiers", "analytics"],
"contact_email": "info@rewardflow.lu",
"support_email": "support@rewardflow.lu",
},
"theme_config": {
"primary_color": "#8B5CF6",
"secondary_color": "#A78BFA",
},
},
{
"code": "hosting",
"name": "HostWizard",
"description": "Web hosting, domains, email, and website building for Luxembourg businesses",
"description_translations": {
"fr": "Hébergement web, domaines, e-mail et création de sites pour les entreprises luxembourgeoises",
"de": "Webhosting, Domains, E-Mail und Website-Erstellung für luxemburgische Unternehmen",
"en": "Web hosting, domains, email, and website building for Luxembourg businesses",
"lb": "Webhosting, Domainer, E-Mail a Websäit-Erstellung fir lëtzebuerger Betriber",
},
"domain": "hostwizard.lu",
"path_prefix": "hosting",
"default_language": "fr",
"supported_languages": ["fr", "de", "en", "lb"],
"settings": {
"features": ["hosting", "domains", "email", "ssl", "poc_sites"],
"contact_email": "info@hostwizard.lu",
"support_email": "support@hostwizard.lu",
"sales_email": "sales@hostwizard.lu",
},
"theme_config": {
"primary_color": "#0D9488",
"secondary_color": "#14B8A6",
"social": {
"facebook": "https://facebook.com/hostwizard.lu",
"linkedin": "https://linkedin.com/company/hostwizard",
"instagram": "https://instagram.com/hostwizard.lu",
},
},
},
]
platforms = []
for pdef in platform_defs:
existing = db.execute(
select(Platform).where(Platform.code == pdef["code"])
).scalar_one_or_none()
if existing:
print_warning(f"Platform already exists: {existing.name} ({existing.code})")
platforms.append(existing)
continue
platform = Platform(
code=pdef["code"],
name=pdef["name"],
description=pdef["description"],
description_translations=pdef.get("description_translations"),
domain=pdef["domain"],
path_prefix=pdef["path_prefix"],
default_language=pdef["default_language"],
supported_languages=pdef["supported_languages"],
settings=pdef["settings"],
theme_config=pdef["theme_config"],
is_active=True,
is_public=True,
created_at=datetime.now(UTC),
updated_at=datetime.now(UTC),
)
db.add(platform) # noqa: PERF006
db.flush()
platforms.append(platform)
print_success(f"Created platform: {platform.name} ({platform.code})")
return platforms
def create_default_role_templates(db: Session) -> dict:
"""Create default role templates (not tied to any store).
These serve as templates that can be copied when creating store-specific roles.
Note: Actual roles are store-specific and created when stores are onboarded.
"""
print(" Available role presets:")
print(" - Manager: Nearly full access (except team management)")
print(" - Staff: Day-to-day operations")
print(" - Support: Customer service focused")
print(" - Viewer: Read-only access")
print(" - Marketing: Marketing and customer communication")
print_success("Role templates ready for store onboarding")
return {
"manager": list(permission_discovery_service.get_preset_permissions("manager")),
"staff": list(permission_discovery_service.get_preset_permissions("staff")),
"support": list(permission_discovery_service.get_preset_permissions("support")),
"viewer": list(permission_discovery_service.get_preset_permissions("viewer")),
"marketing": list(permission_discovery_service.get_preset_permissions("marketing")),
}
def create_admin_settings(db: Session) -> int:
"""Create essential admin settings."""
settings_created = 0
# Essential platform settings
default_settings = [
{
"key": "platform_name",
"value": settings.project_name,
"value_type": "string",
"description": "Platform name displayed in admin panel",
"is_public": True,
},
{
"key": "platform_url",
"value": f"https://{settings.platform_domain}",
"value_type": "string",
"description": "Main platform URL",
"is_public": True,
},
{
"key": "support_email",
"value": f"support@{settings.platform_domain}",
"value_type": "string",
"description": "Platform support email",
"is_public": True,
},
{
"key": "max_stores_per_user",
"value": str(settings.max_stores_per_user),
"value_type": "integer",
"description": "Maximum stores a user can own",
"is_public": False,
},
{
"key": "max_team_members_per_store",
"value": str(settings.max_team_members_per_store),
"value_type": "integer",
"description": "Maximum team members per store",
"is_public": False,
},
{
"key": "invitation_expiry_days",
"value": str(settings.invitation_expiry_days),
"value_type": "integer",
"description": "Days until team invitation expires",
"is_public": False,
},
{
"key": "require_store_verification",
"value": "true",
"value_type": "boolean",
"description": "Require admin verification for new stores",
"is_public": False,
},
{
"key": "allow_custom_domains",
"value": str(settings.allow_custom_domains).lower(),
"value_type": "boolean",
"description": "Allow stores to use custom domains",
"is_public": False,
},
{
"key": "maintenance_mode",
"value": "false",
"value_type": "boolean",
"description": "Enable maintenance mode",
"is_public": True,
},
# Logging settings
{
"key": "log_level",
"value": "INFO",
"value_type": "string",
"category": "logging",
"description": "Application log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)",
"is_public": False,
},
{
"key": "log_file_max_size_mb",
"value": "10",
"value_type": "integer",
"category": "logging",
"description": "Maximum log file size in MB before rotation",
"is_public": False,
},
{
"key": "log_file_backup_count",
"value": "5",
"value_type": "integer",
"category": "logging",
"description": "Number of rotated log files to keep",
"is_public": False,
},
{
"key": "db_log_retention_days",
"value": "30",
"value_type": "integer",
"category": "logging",
"description": "Number of days to retain logs in database",
"is_public": False,
},
{
"key": "file_logging_enabled",
"value": "true",
"value_type": "boolean",
"category": "logging",
"description": "Enable file-based logging",
"is_public": False,
},
{
"key": "db_logging_enabled",
"value": "true",
"value_type": "boolean",
"category": "logging",
"description": "Enable database logging for critical events",
"is_public": False,
},
]
for setting_data in default_settings:
# Check if setting already exists
existing = db.execute(
select(AdminSetting).where(AdminSetting.key == setting_data["key"])
).scalar_one_or_none()
if not existing:
setting = AdminSetting(
key=setting_data["key"],
value=setting_data["value"],
value_type=setting_data["value_type"],
category=setting_data.get("category"),
description=setting_data.get("description"),
is_public=setting_data.get("is_public", False),
created_at=datetime.now(UTC),
updated_at=datetime.now(UTC),
)
db.add(setting) # noqa: PERF006
settings_created += 1
db.flush()
if settings_created > 0:
print_success(f"Created {settings_created} admin settings")
else:
print_warning("Admin settings already exist")
return settings_created
def create_subscription_tiers(db: Session, platform: Platform) -> int:
"""Create default subscription tiers for a platform."""
tier_defs = [
{
"code": "essential",
"name": "Essential",
"name_translations": {
"en": "Essential", "fr": "Essentiel",
"de": "Basis", "lb": "Basis",
},
"price_monthly_cents": 2900,
"price_annual_cents": 29000,
"is_public": True,
"display_order": 10,
},
{
"code": "professional",
"name": "Professional",
"name_translations": {
"en": "Professional", "fr": "Professionnel",
"de": "Professionell", "lb": "Professionell",
},
"price_monthly_cents": 7900,
"price_annual_cents": 79000,
"is_public": True,
"display_order": 20,
},
{
"code": "business",
"name": "Business",
"name_translations": {
"en": "Business", "fr": "Business",
"de": "Business", "lb": "Business",
},
"price_monthly_cents": 14900,
"price_annual_cents": 149000,
"is_public": True,
"display_order": 30,
},
{
"code": "enterprise",
"name": "Enterprise",
"name_translations": {
"en": "Enterprise", "fr": "Entreprise",
"de": "Enterprise", "lb": "Enterprise",
},
"price_monthly_cents": 29900,
"price_annual_cents": None,
"is_public": False,
"display_order": 40,
},
]
tiers_created = 0
for tdef in tier_defs:
existing = db.execute(
select(SubscriptionTier).where(
SubscriptionTier.code == tdef["code"],
SubscriptionTier.platform_id == platform.id,
)
).scalar_one_or_none()
if existing:
# Backfill name_translations if missing
if existing.name_translations is None and tdef.get("name_translations"):
existing.name_translations = tdef["name_translations"]
print_success(f"Backfilled name_translations: {existing.name} ({existing.code}) for {platform.name}")
else:
print_warning(f"Tier already exists: {existing.name} ({existing.code}) for {platform.name}")
continue
tier = SubscriptionTier(
platform_id=platform.id,
code=tdef["code"],
name=tdef["name"],
name_translations=tdef.get("name_translations"),
price_monthly_cents=tdef["price_monthly_cents"],
price_annual_cents=tdef["price_annual_cents"],
is_public=tdef["is_public"],
display_order=tdef["display_order"],
is_active=True,
)
db.add(tier) # noqa: PERF006
db.flush()
tiers_created += 1
print_success(f"Created tier: {tier.name} ({tier.code})")
return tiers_created
def create_platform_modules(db: Session, platforms: list[Platform]) -> int:
"""Create PlatformModule records for all platforms.
Core modules are enabled for every platform. Optional modules are
selectively enabled per platform. All other modules are created but
disabled (available to toggle on later via the admin API).
"""
from app.modules.registry import MODULES, is_core_module
# Optional modules enabled per platform (core modules always enabled)
PLATFORM_MODULES = {
"oms": ["inventory", "catalog", "orders", "marketplace", "analytics", "cart", "checkout"],
"main": ["analytics", "monitoring", "dev-tools"],
"loyalty": ["loyalty"],
"hosting": ["prospecting", "hosting", "analytics"],
}
now = datetime.now(UTC)
records_created = 0
for platform in platforms:
enabled_extras = set(PLATFORM_MODULES.get(platform.code, []))
for code in MODULES:
existing = db.execute(
select(PlatformModule).where(
PlatformModule.platform_id == platform.id,
PlatformModule.module_code == code,
)
).scalar_one_or_none()
if existing:
continue
enabled = is_core_module(code) or code in enabled_extras
pm = PlatformModule(
platform_id=platform.id,
module_code=code,
is_enabled=enabled,
enabled_at=now if enabled else None,
config={},
)
db.add(pm) # noqa: PERF006
records_created += 1
db.flush()
if records_created > 0:
print_success(f"Created {records_created} platform module records")
else:
print_warning("Platform module records already exist")
return records_created
def verify_rbac_schema(db: Session) -> bool:
"""Verify that RBAC schema is in place."""
try:
from sqlalchemy import inspect
inspector = inspect(db.bind)
tables = inspector.get_table_names()
# Check users table has is_email_verified
if "users" in tables:
user_cols = {col["name"] for col in inspector.get_columns("users")}
if "is_email_verified" not in user_cols:
print_error("Missing 'is_email_verified' column in users table")
return False
# Check store_users has RBAC columns
if "store_users" in tables:
vu_cols = {col["name"] for col in inspector.get_columns("store_users")}
required_cols = {
"invitation_token",
"invitation_sent_at",
"invitation_accepted_at",
}
missing = required_cols - vu_cols
if missing:
print_error(f"Missing columns in store_users: {missing}")
return False
# Check roles table exists
if "roles" not in tables:
print_error("Missing 'roles' table")
return False
print_success("RBAC schema verified")
return True
except Exception as e:
print_error(f"Schema verification failed: {e}")
return False
# =============================================================================
# MAIN INITIALIZATION
# =============================================================================
def initialize_production(db: Session, auth_manager: AuthManager):
"""Initialize production database with essential data."""
print_header("PRODUCTION INITIALIZATION")
# Step 1: Verify RBAC schema
print_step(1, "Verifying RBAC schema...")
if not verify_rbac_schema(db):
print_error("RBAC schema not ready. Run migrations first:")
print(" make migrate-up")
sys.exit(1)
# Step 2: Create admin user
print_step(2, "Creating platform admin...")
create_admin_user(db, auth_manager)
# Step 3: Create default platforms
print_step(3, "Creating default platforms...")
platforms = create_default_platforms(db)
# Step 3b: Create platform admins
print_step("3b", "Creating platform admins...")
oms_platform = next((p for p in platforms if p.code == "oms"), None)
if oms_platform:
create_oms_admin(db, auth_manager, oms_platform)
else:
print_warning("OMS platform not found, skipping OMS admin creation")
loyalty_platform = next((p for p in platforms if p.code == "loyalty"), None)
if loyalty_platform:
create_loyalty_admin(db, auth_manager, loyalty_platform)
else:
print_warning("Loyalty platform not found, skipping loyalty admin creation")
hosting_platform = next((p for p in platforms if p.code == "hosting"), None)
if hosting_platform:
create_hostwizard_admin(db, auth_manager, hosting_platform)
else:
print_warning("Hosting platform not found, skipping hosting admin creation")
# Step 4: Set up default role templates
print_step(4, "Setting up role templates...")
create_default_role_templates(db)
# Step 5: Create admin settings
print_step(5, "Creating admin settings...")
create_admin_settings(db)
# Step 6: Seed subscription tiers for all platforms
print_step(6, "Seeding subscription tiers...")
for platform in platforms:
create_subscription_tiers(db, platform)
# Step 7: Create platform module records
print_step(7, "Creating platform module records...")
create_platform_modules(db, platforms)
# Commit all changes
db.commit()
print_success("All changes committed")
def print_summary(db: Session):
"""Print initialization summary."""
print_header("INITIALIZATION SUMMARY")
# Count records
user_count = db.query(User).filter(
User.role.in_(["super_admin", "platform_admin"])
).count()
setting_count = db.query(AdminSetting).count()
platform_count = db.query(Platform).count()
tier_count = db.query(SubscriptionTier).filter(SubscriptionTier.is_active.is_(True)).count()
module_count = db.query(PlatformModule).count()
print("\n📊 Database Status:")
print(f" Admin users: {user_count}")
print(f" Platforms: {platform_count}")
print(f" Platform mods: {module_count}")
print(f" Admin settings: {setting_count}")
print(f" Sub. tiers: {tier_count}")
# Show platforms
platforms = db.query(Platform).order_by(Platform.code).all()
enabled_counts = {}
for pm in db.query(PlatformModule).filter(PlatformModule.is_enabled.is_(True)).all():
enabled_counts[pm.platform_id] = enabled_counts.get(pm.platform_id, 0) + 1
port = settings.api_port
print("\n" + "" * 70)
print("🌐 PLATFORMS")
print("" * 70)
for p in platforms:
n_enabled = enabled_counts.get(p.id, 0)
if p.code == "main":
dev_url = f"http://localhost:{port}/"
else:
dev_url = f"http://localhost:{port}/platforms/{p.code}/"
print(f" {p.name} ({p.code})")
print(f" Domain: {p.domain}")
print(f" Dev URL: {dev_url}")
print(f" Modules: {n_enabled} enabled")
print("\n" + "" * 70)
print("🔐 ADMIN CREDENTIALS")
print("" * 70)
admin_url = f"http://localhost:{port}/admin/login"
print(" Super Admin (all platforms):")
print(f" URL: {admin_url}")
print(f" Username: {settings.admin_username}")
print(f" Password: {settings.admin_password}") # noqa: SEC021
print()
print(" OMS Platform Admin (oms only):")
print(f" URL: {admin_url}")
print(" Username: oms_admin")
print(" Password: admin123") # noqa: SEC021
print()
print(" Loyalty Platform Admin (loyalty only):")
print(f" URL: {admin_url}")
print(" Username: loyalty_admin")
print(" Password: admin123") # noqa: SEC021
print()
print(" HostWizard Platform Admin (hosting only):")
print(f" URL: {admin_url}")
print(" Username: hosting_admin")
print(" Password: admin123") # noqa: SEC021
print("" * 70)
# Show security warnings if in production
if is_production():
warnings = validate_production_settings()
if warnings:
print("\n⚠️ SECURITY WARNINGS:")
for warning in warnings:
print(f" {warning}")
print("\n Please update your .env file with secure values!")
else:
print("\n⚠️ DEVELOPMENT MODE:")
print(" Default credentials are OK for development")
print(" Change them in production via .env file")
print("\n🚀 NEXT STEPS:")
if is_production():
print(f" 1. Login to admin panel: {admin_url}")
print(" 2. CHANGE DEFAULT PASSWORD IMMEDIATELY!") # noqa: SEC021
print(" 3. Configure admin settings")
print(" 4. Create first store")
else:
print(" 1. Start development: make dev")
print(f" 2. Admin panel: {admin_url}")
print(f" 3. Merchant panel: http://localhost:{port}/merchants/login")
print(" 4. Create demo data: make seed-demo")
# =============================================================================
# MAIN ENTRY POINT
# =============================================================================
def main():
"""Main entry point."""
print("\n" + "" + "" * 68 + "")
print("" + " " * 16 + "PRODUCTION INITIALIZATION" + " " * 27 + "")
print("" + "" * 68 + "")
# Show environment info
print_environment_info()
# Production safety check
if is_production():
warnings = validate_production_settings()
if warnings:
print("\n⚠️ PRODUCTION WARNINGS DETECTED:")
for warning in warnings:
print(f" {warning}")
print("\nUpdate your .env file before continuing!")
response = input("\nContinue anyway? (yes/no): ")
if response.lower() != "yes":
print("Initialization cancelled.")
sys.exit(0)
db = SessionLocal()
auth_manager = AuthManager()
try:
initialize_production(db, auth_manager)
print_summary(db)
print_header("✅ INITIALIZATION COMPLETED")
except KeyboardInterrupt:
db.rollback()
print("\n\n⚠️ Initialization interrupted")
sys.exit(1)
except Exception as e:
db.rollback()
print_header("❌ INITIALIZATION FAILED")
print(f"\nError: {e}\n")
import traceback
traceback.print_exc()
sys.exit(1)
finally:
db.close()
if __name__ == "__main__":
main()