fix: store menu 404, logger crash, platform detection, and sidebar UX
All checks were successful
All checks were successful
- Fix store menu API URL (/store/menu/render/store, not /store/core/...) - Fix storeLog/merchantLog fallback to console object instead of console.log - Embed platform_id/platform_code in store JWT from URL context at login - Use token_platform_id in store menu endpoint with DB fallback for old tokens - Add "Menu unavailable" warning in sidebar fallback for all three frontends - Standardize admin section default to all-open (consistent with store/merchant) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -95,8 +95,10 @@ async def get_rendered_store_menu(
|
||||
# Get the store from the JWT token's store context
|
||||
store = store_service.get_store_by_id(db, current_user.token_store_id)
|
||||
|
||||
# Resolve the store's platform via service layer
|
||||
platform_id = menu_service.get_store_primary_platform_id(db, store.id)
|
||||
# Platform from JWT (set at login from URL context), fall back to DB for old tokens
|
||||
platform_id = current_user.token_platform_id
|
||||
if platform_id is None:
|
||||
platform_id = menu_service.get_store_primary_platform_id(db, store.id)
|
||||
|
||||
# Get filtered menu with platform visibility and store_code interpolation
|
||||
menu = menu_service.get_menu_for_rendering(
|
||||
|
||||
@@ -214,7 +214,7 @@ function data() {
|
||||
// Initialize openSections for new sections (default: first section open)
|
||||
if (this.openSections[section.id] === undefined) {
|
||||
// Default: first section open, rest closed
|
||||
this.openSections[section.id] = (sections.indexOf(section) === 0);
|
||||
this.openSections[section.id] = true;
|
||||
}
|
||||
}
|
||||
console.debug('Menu config loaded:', this.visibleMenuItems.size, 'items');
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
// Use centralized logger (guarded: log-config.js loads with defer, so it may not be ready yet)
|
||||
const merchantLog = (window.LogConfig && window.LogConfig.log) || console.log;
|
||||
const merchantLog = (window.LogConfig && window.LogConfig.log) || console;
|
||||
|
||||
console.log('[MERCHANT INIT-ALPINE] Loading...');
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
// Use centralized logger (guarded: log-config.js loads with defer, so it may not be ready yet)
|
||||
const storeLog = (window.LogConfig && window.LogConfig.log) || console.log;
|
||||
const storeLog = (window.LogConfig && window.LogConfig.log) || console;
|
||||
|
||||
console.log('[STORE INIT-ALPINE] Loading...');
|
||||
|
||||
@@ -129,7 +129,7 @@ function data() {
|
||||
|
||||
this.menuLoading = true;
|
||||
try {
|
||||
this.menuData = await apiClient.get('/store/core/menu/render/store');
|
||||
this.menuData = await apiClient.get('/store/menu/render/store');
|
||||
// Initialize section open state from response
|
||||
for (const section of (this.menuData?.sections || [])) {
|
||||
if (this.openSections[section.id] === undefined) {
|
||||
|
||||
@@ -27,6 +27,7 @@ from app.modules.tenancy.models.user_password_reset_token import (
|
||||
UserPasswordResetToken, # noqa: API-007
|
||||
)
|
||||
from app.modules.tenancy.services.user_auth_service import user_auth_service
|
||||
from middleware.platform_context import get_current_platform
|
||||
from middleware.store_context import get_current_store
|
||||
from models.schema.auth import LogoutResponse, StoreUserResponse, UserContext, UserLogin
|
||||
|
||||
@@ -110,12 +111,19 @@ def store_login(
|
||||
f"for store {store.store_code} as {store_role}"
|
||||
)
|
||||
|
||||
# Get platform from URL context (middleware-detected)
|
||||
platform = get_current_platform(request)
|
||||
platform_id = platform.id if platform else None
|
||||
platform_code = platform.code if platform else None
|
||||
|
||||
# Create store-scoped access token with store information
|
||||
token_data = auth_service.auth_manager.create_access_token(
|
||||
user=user,
|
||||
store_id=store.id,
|
||||
store_code=store.store_code,
|
||||
store_role=store_role,
|
||||
platform_id=platform_id,
|
||||
platform_code=platform_code,
|
||||
)
|
||||
|
||||
# Set HTTP-only cookie for browser navigation
|
||||
|
||||
@@ -88,7 +88,11 @@
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="px-6 py-3 text-xs text-gray-400">Loading menu...</p>
|
||||
<div class="px-6 mt-4">
|
||||
<p class="text-xs text-gray-400 dark:text-gray-500">
|
||||
Menu unavailable. Showing default items only.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Fallback: static dashboard link (if menu API fails) -->
|
||||
<!-- Fallback: static dashboard link + warning (if menu API fails) -->
|
||||
<div x-show="!menuLoading && !menuData" x-cloak>
|
||||
<ul class="mt-6">
|
||||
<li class="relative px-6 py-3">
|
||||
@@ -99,6 +99,11 @@
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="px-6 mt-4">
|
||||
<p class="text-xs text-gray-400 dark:text-gray-500">
|
||||
Menu unavailable. Showing default items only.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Fallback: static dashboard link (if menu API fails) -->
|
||||
<!-- Fallback: static dashboard link + warning (if menu API fails) -->
|
||||
<div x-show="!menuLoading && !menuData" x-cloak>
|
||||
<ul class="mt-6">
|
||||
<li class="relative px-6 py-3">
|
||||
@@ -99,6 +99,11 @@
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="px-6 mt-4">
|
||||
<p class="text-xs text-gray-400 dark:text-gray-500">
|
||||
Menu unavailable. Showing default items only.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions (static, outside dynamic menu) -->
|
||||
|
||||
Reference in New Issue
Block a user