feat: add SQL query tool, platform debug, loyalty settings, and multi-module improvements
Some checks failed
Some checks failed
- Add admin SQL query tool with saved queries, schema explorer presets, and collapsible category sections (dev_tools module) - Add platform debug tool for admin diagnostics - Add loyalty settings page with owner-only access control - Fix loyalty settings owner check (use currentUser instead of window.__userData) - Replace HTTPException with AuthorizationException in loyalty routes - Expand loyalty module with PIN service, Apple Wallet, program management - Improve store login with platform detection and multi-platform support - Update billing feature gates and subscription services - Add store platform sync improvements and remove is_primary column - Add unit tests for loyalty (PIN, points, stamps, program services) - Update i18n translations across dev_tools locales Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -422,7 +422,7 @@ class MenuService:
|
||||
Get the primary platform ID for a merchant's visibility config.
|
||||
|
||||
Resolution order:
|
||||
1. Platform from the store marked is_primary in StorePlatform
|
||||
1. First active StorePlatform for the merchant's stores (by joined_at)
|
||||
2. First active subscription's platform (fallback)
|
||||
|
||||
Args:
|
||||
@@ -445,7 +445,7 @@ class MenuService:
|
||||
|
||||
# Try primary store platform first
|
||||
for store in stores:
|
||||
pid = platform_service.get_primary_platform_id_for_store(db, store.id)
|
||||
pid = platform_service.get_first_active_platform_id_for_store(db, store.id)
|
||||
if pid is not None:
|
||||
# Verify merchant has active subscription on this platform
|
||||
active_pids = subscription_service.get_active_subscription_platform_ids(
|
||||
@@ -460,16 +460,16 @@ class MenuService:
|
||||
)
|
||||
return active_pids[0] if active_pids else None
|
||||
|
||||
def get_store_primary_platform_id(
|
||||
def get_store_fallback_platform_id(
|
||||
self,
|
||||
db: Session,
|
||||
store_id: int,
|
||||
) -> int | None:
|
||||
"""
|
||||
Get the primary platform ID for a store's menu visibility config.
|
||||
Get the fallback platform ID for a store's menu visibility config.
|
||||
|
||||
Prefers the active StorePlatform marked is_primary, falls back to
|
||||
the first active StorePlatform by ID.
|
||||
Returns the first active StorePlatform ordered by joined_at.
|
||||
Used only when platform_id is not available from JWT context.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
@@ -480,7 +480,7 @@ class MenuService:
|
||||
"""
|
||||
from app.modules.tenancy.services.platform_service import platform_service
|
||||
|
||||
return platform_service.get_primary_platform_id_for_store(db, store_id)
|
||||
return platform_service.get_first_active_platform_id_for_store(db, store_id)
|
||||
|
||||
def get_merchant_for_menu(
|
||||
self,
|
||||
|
||||
@@ -39,20 +39,6 @@ class OnboardingAggregatorService:
|
||||
a unified interface for the dashboard onboarding banner.
|
||||
"""
|
||||
|
||||
def _get_store_platform_ids(self, db: Session, store_id: int) -> set[int]:
|
||||
"""Get platform IDs the store is actively subscribed to."""
|
||||
from app.modules.tenancy.models.store_platform import StorePlatform
|
||||
|
||||
rows = (
|
||||
db.query(StorePlatform.platform_id)
|
||||
.filter(
|
||||
StorePlatform.store_id == store_id,
|
||||
StorePlatform.is_active.is_(True),
|
||||
)
|
||||
.all()
|
||||
)
|
||||
return {r.platform_id for r in rows}
|
||||
|
||||
def _get_enabled_providers(
|
||||
self, db: Session, store_id: int, platform_id: int
|
||||
) -> list[tuple["ModuleDefinition", OnboardingProviderProtocol]]:
|
||||
@@ -68,10 +54,10 @@ class OnboardingAggregatorService:
|
||||
from app.modules.registry import MODULES
|
||||
from app.modules.service import module_service
|
||||
|
||||
store_platform_ids = self._get_store_platform_ids(db, store_id)
|
||||
if not store_platform_ids:
|
||||
# Fallback to the passed platform_id if no subscriptions found
|
||||
store_platform_ids = {platform_id}
|
||||
# Only check the current platform, not all subscribed platforms.
|
||||
# This prevents cross-platform content leakage (e.g. showing OMS steps
|
||||
# when logged in on the loyalty platform).
|
||||
store_platform_ids = {platform_id}
|
||||
|
||||
providers: list[tuple[ModuleDefinition, OnboardingProviderProtocol]] = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user