feat(merchant): extract merchant portal as first-class frontend with auth, Tailwind fixes, and Gitea CI
Some checks failed
Some checks failed
- Extract login/dashboard from billing module into core (matching admin pattern) - Add merchant auth API with path-isolated cookies (path=/merchants) - Add merchant base layout with sidebar/header partials and Alpine.js init - Add frontend detection and login redirect for MERCHANT type - Wire merchant token in shared api-client.js (get/clear) - Migrate billing templates to merchant base with dark mode support - Fix Tailwind: rename shop→storefront in sources and config - DRY Makefile tailwind targets with TAILWIND_FRONTENDS loop - Rebuild all Tailwind outputs (production minified) - Add Gitea Actions CI workflow (ruff, pytest, architecture, docs) - Add Gitea deployment documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
"""
|
||||
Tenancy module merchant API routes.
|
||||
|
||||
Provides merchant-facing API endpoints for the merchant portal:
|
||||
- /account/stores - List merchant's stores
|
||||
- /account/profile - Get/update merchant profile
|
||||
Aggregates all merchant tenancy routes:
|
||||
- /auth/* - Merchant authentication (login, logout, /me)
|
||||
- /account/* - Merchant account management (stores, profile)
|
||||
|
||||
Auto-discovered by the route system (merchant.py in routes/api/).
|
||||
"""
|
||||
@@ -21,13 +21,17 @@ from app.core.database import get_db
|
||||
from app.modules.tenancy.models import Merchant
|
||||
from models.schema.auth import UserContext
|
||||
|
||||
from .merchant_auth import merchant_auth_router
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
ROUTE_CONFIG = {
|
||||
"prefix": "/account",
|
||||
}
|
||||
# Include auth routes (/auth/login, /auth/logout, /auth/me)
|
||||
router.include_router(merchant_auth_router, tags=["merchant-auth"])
|
||||
|
||||
# Account routes are defined below with /account prefix
|
||||
_account_router = APIRouter(prefix="/account")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -81,11 +85,11 @@ def _get_user_merchant(db: Session, user_context: UserContext) -> Merchant:
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# ENDPOINTS
|
||||
# ACCOUNT ENDPOINTS
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/stores")
|
||||
@_account_router.get("/stores")
|
||||
async def merchant_stores(
|
||||
request: Request,
|
||||
current_user: UserContext = Depends(get_current_merchant_from_cookie_or_header),
|
||||
@@ -114,7 +118,7 @@ async def merchant_stores(
|
||||
return {"stores": stores}
|
||||
|
||||
|
||||
@router.get("/profile")
|
||||
@_account_router.get("/profile")
|
||||
async def merchant_profile(
|
||||
request: Request,
|
||||
current_user: UserContext = Depends(get_current_merchant_from_cookie_or_header),
|
||||
@@ -140,7 +144,7 @@ async def merchant_profile(
|
||||
}
|
||||
|
||||
|
||||
@router.put("/profile")
|
||||
@_account_router.put("/profile")
|
||||
async def update_merchant_profile(
|
||||
request: Request,
|
||||
profile_data: MerchantProfileUpdate,
|
||||
@@ -177,3 +181,7 @@ async def update_merchant_profile(
|
||||
"tax_number": merchant.tax_number,
|
||||
"is_verified": merchant.is_verified,
|
||||
}
|
||||
|
||||
|
||||
# Include account routes in main router
|
||||
router.include_router(_account_router, tags=["merchant-account"])
|
||||
|
||||
Reference in New Issue
Block a user