Files
orion/app/modules/analytics/routes/pages/store.py
Samir Boulahtit cb3bc3c118
Some checks failed
CI / pytest (push) Failing after 45m29s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 28s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
CI / ruff (push) Successful in 9s
feat: implement complete RBAC access control with tests
Add 4-layer access control stack (subscription → module → menu → permissions):
- P1: Wire requires_permission into menu sidebar filtering
- P2: Expose window.USER_PERMISSIONS for Alpine.js client-side gating
- P3: Add page-level permission guards on store routes
- P4: Role CRUD API endpoints and role editor UI
- P5: Audit trail for all role/permission changes

Includes unit tests (menu permission filtering, role CRUD service) and
integration tests (role API endpoints). All 404 core+tenancy tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:26:59 +01:00

96 lines
2.6 KiB
Python

# app/modules/analytics/routes/pages/store.py
"""
Analytics Store Page Routes (HTML rendering).
Store pages for analytics dashboard.
"""
import logging
from fastapi import APIRouter, Depends, Request
from fastapi.responses import HTMLResponse
from sqlalchemy.orm import Session
from app.api.deps import (
get_db,
get_resolved_store_code,
require_store_page_permission,
)
from app.modules.core.services.platform_settings_service import (
platform_settings_service, # MOD-004 - shared platform service
)
from app.modules.tenancy.models import Store, User
from app.templates_config import templates
logger = logging.getLogger(__name__)
router = APIRouter()
# ============================================================================
# HELPER: Build Store Dashboard Context
# ============================================================================
def get_store_context(
request: Request,
db: Session,
current_user: User,
store_code: str,
**extra_context,
) -> dict:
"""
Build template context for store dashboard pages.
Resolves locale/currency using the platform settings service with
store override support.
"""
# Load store from database
store = db.query(Store).filter(Store.subdomain == store_code).first()
# Get platform defaults
platform_config = platform_settings_service.get_storefront_config(db)
# Resolve with store override
storefront_locale = platform_config["locale"]
storefront_currency = platform_config["currency"]
if store and store.storefront_locale:
storefront_locale = store.storefront_locale
context = {
"request": request,
"user": current_user,
"store": store,
"store_code": store_code,
"storefront_locale": storefront_locale,
"storefront_currency": storefront_currency,
**extra_context,
}
return context
# ============================================================================
# ANALYTICS PAGE
# ============================================================================
@router.get(
"/analytics", response_class=HTMLResponse, include_in_schema=False
)
async def store_analytics_page(
request: Request,
store_code: str = Depends(get_resolved_store_code),
current_user: User = Depends(require_store_page_permission("analytics.view")),
db: Session = Depends(get_db),
):
"""
Render analytics and reports page.
JavaScript loads analytics data via API.
"""
return templates.TemplateResponse(
"analytics/store/analytics.html",
get_store_context(request, db, current_user, store_code),
)