feat: add OMS platform admin and align "Store panel" naming
Some checks failed
CI / ruff (push) Successful in 10s
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / validate (push) Has been cancelled
CI / pytest (push) Has been cancelled

Add create_oms_admin (admin@omsflow.lu) alongside existing loyalty admin,
both using a shared create_platform_admin helper. Rename "Dashboard" and
"Staff login" labels to "Store panel" and "Store login" across seed output.
Add customer login URLs to production-style access section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 12:12:23 +01:00
parent e7f8e61717
commit ed1cccd2de
2 changed files with 55 additions and 17 deletions

View File

@@ -131,23 +131,29 @@ def create_admin_user(db: Session, auth_manager: AuthManager) -> User:
return admin return admin
def create_loyalty_admin(db: Session, auth_manager: AuthManager, loyalty_platform: Platform) -> User | None: def create_platform_admin(
"""Create a platform admin for the Loyalty+ platform.""" 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 from app.modules.tenancy.models.admin_platform import AdminPlatform
email = "admin@rewardflow.lu"
existing = db.execute(select(User).where(User.email == email)).scalar_one_or_none() existing = db.execute(select(User).where(User.email == email)).scalar_one_or_none()
if existing: if existing:
print_warning(f"Loyalty admin already exists: {email}") print_warning(f"{platform.name} admin already exists: {email}")
return existing return existing
password = "admin123" # noqa: SEC001 Dev default, change in production password = "admin123" # noqa: SEC001 Dev default, change in production
admin = User( admin = User(
username="loyalty_admin", username=username,
email=email, email=email,
hashed_password=auth_manager.hash_password(password), hashed_password=auth_manager.hash_password(password),
role="platform_admin", role="platform_admin",
first_name="Loyalty", first_name=first_name,
last_name="Administrator", last_name="Administrator",
is_active=True, is_active=True,
is_email_verified=True, is_email_verified=True,
@@ -155,19 +161,39 @@ def create_loyalty_admin(db: Session, auth_manager: AuthManager, loyalty_platfor
db.add(admin) db.add(admin)
db.flush() db.flush()
# Assign to loyalty platform # Assign to platform
assignment = AdminPlatform( assignment = AdminPlatform(
user_id=admin.id, user_id=admin.id,
platform_id=loyalty_platform.id, platform_id=platform.id,
is_active=True, is_active=True,
) )
db.add(assignment) db.add(assignment)
db.flush() db.flush()
print_success(f"Created loyalty admin: {email} (password: {password})") # noqa: SEC021 print_success(f"Created {platform.name} admin: {email} (password: {password})") # noqa: SEC021
return admin 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_default_platforms(db: Session) -> list[Platform]: def create_default_platforms(db: Session) -> list[Platform]:
"""Create all default platforms (OMS, Main, Loyalty+).""" """Create all default platforms (OMS, Main, Loyalty+)."""
@@ -607,8 +633,14 @@ def initialize_production(db: Session, auth_manager: AuthManager):
print_step(3, "Creating default platforms...") print_step(3, "Creating default platforms...")
platforms = create_default_platforms(db) platforms = create_default_platforms(db)
# Step 3b: Create loyalty platform admin # Step 3b: Create platform admins
print_step("3b", "Creating loyalty platform admin...") 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) loyalty_platform = next((p for p in platforms if p.code == "loyalty"), None)
if loyalty_platform: if loyalty_platform:
create_loyalty_admin(db, auth_manager, loyalty_platform) create_loyalty_admin(db, auth_manager, loyalty_platform)
@@ -688,6 +720,11 @@ def print_summary(db: Session):
print(f" Username: {settings.admin_username}") print(f" Username: {settings.admin_username}")
print(f" Password: {settings.admin_password}") # noqa: SEC021 print(f" Password: {settings.admin_password}") # noqa: SEC021
print() 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(" Loyalty Platform Admin (loyalty only):")
print(f" URL: {admin_url}") print(f" URL: {admin_url}")
print(" Username: loyalty_admin") print(" Username: loyalty_admin")

View File

@@ -1379,10 +1379,10 @@ def print_summary(db: Session):
if merchant and merchant.stores: if merchant and merchant.stores:
for store in merchant.stores: for store in merchant.stores:
print( print(
f" Store: http://localhost:8000/store/{store.store_code}/login" f" Store panel: {base}/store/{store.store_code}/login"
) )
print( print(
f" or http://{store.subdomain}.localhost:8000/store/login" # noqa: SEC034 f" or http://{store.subdomain}.localhost:{port}/store/login" # noqa: SEC034
) )
print() print()
@@ -1450,8 +1450,8 @@ def print_summary(db: Session):
for pc in platform_codes: for pc in platform_codes:
print(f" [{pc}] Storefront: {base}/platforms/{pc}/storefront/{store.store_code}/") print(f" [{pc}] Storefront: {base}/platforms/{pc}/storefront/{store.store_code}/")
print(f" [{pc}] Customer login: {base}/platforms/{pc}/storefront/{store.store_code}/account/login") print(f" [{pc}] Customer login: {base}/platforms/{pc}/storefront/{store.store_code}/account/login")
print(f" [{pc}] Store dashboard: {base}/platforms/{pc}/store/{store.store_code}/") print(f" [{pc}] Store panel: {base}/platforms/{pc}/store/{store.store_code}/")
print(f" [{pc}] Staff login: {base}/platforms/{pc}/store/{store.store_code}/login") print(f" [{pc}] Store login: {base}/platforms/{pc}/store/{store.store_code}/login")
else: else:
print(" (!) No platform assigned") print(" (!) No platform assigned")
@@ -1465,7 +1465,8 @@ def print_summary(db: Session):
pdomain = d["domain"] or f"{d['code']}.example.com" pdomain = d["domain"] or f"{d['code']}.example.com"
suffix = " (custom subdomain)" if d["custom_subdomain"] else "" suffix = " (custom subdomain)" if d["custom_subdomain"] else ""
print(f" [{d['code']}] Storefront: https://{subdomain}.{pdomain}/{suffix}") print(f" [{d['code']}] Storefront: https://{subdomain}.{pdomain}/{suffix}")
print(f" [{d['code']}] Dashboard: https://{subdomain}.{pdomain}/store/dashboard") print(f" [{d['code']}] Customer login: https://{subdomain}.{pdomain}/account/login")
print(f" [{d['code']}] Store panel: https://{subdomain}.{pdomain}/store/")
# Show custom domain if any # Show custom domain if any
custom_domain = ( custom_domain = (
db.query(StoreDomain) db.query(StoreDomain)