Some checks failed
Move all auth schemas (UserContext, UserLogin, LoginResponse, etc.) from legacy models/schema/auth.py to app/modules/tenancy/schemas/auth.py per MOD-019. Update 84 import sites across 14 modules. Legacy file now re-exports for backwards compatibility. Add missing tenancy service methods for cross-module consumers: - merchant_service.get_merchant_by_owner_id() - merchant_service.get_merchant_count_for_owner() - admin_service.get_user_by_id() (public, was private-only) - platform_service.get_active_store_count() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
119 lines
3.7 KiB
Python
119 lines
3.7 KiB
Python
# app/modules/tenancy/routes/api/merchant.py
|
|
"""
|
|
Tenancy module merchant API routes.
|
|
|
|
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/).
|
|
"""
|
|
|
|
import logging
|
|
|
|
from fastapi import APIRouter, Depends, Query, Request
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.deps import get_current_merchant_api, get_merchant_for_current_user
|
|
from app.core.database import get_db
|
|
from app.modules.tenancy.schemas import (
|
|
MerchantPortalProfileResponse,
|
|
MerchantPortalProfileUpdate,
|
|
MerchantPortalStoreListResponse,
|
|
)
|
|
from app.modules.tenancy.schemas.auth import UserContext
|
|
from app.modules.tenancy.services.merchant_service import merchant_service
|
|
|
|
from .email_verification import email_verification_api_router
|
|
from .merchant_auth import merchant_auth_router
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter()
|
|
|
|
# Include auth routes (/auth/login, /auth/logout, /auth/me, /auth/forgot-password, /auth/reset-password)
|
|
router.include_router(merchant_auth_router, tags=["merchant-auth"])
|
|
|
|
# Include email verification routes (/resend-verification)
|
|
router.include_router(email_verification_api_router, tags=["email-verification"])
|
|
|
|
# Account routes are defined below with /account prefix
|
|
_account_router = APIRouter(prefix="/account")
|
|
|
|
|
|
# ============================================================================
|
|
# ACCOUNT ENDPOINTS
|
|
# ============================================================================
|
|
|
|
|
|
@_account_router.get("/stores", response_model=MerchantPortalStoreListResponse)
|
|
async def merchant_stores(
|
|
request: Request,
|
|
skip: int = Query(0, ge=0, description="Number of records to skip"),
|
|
limit: int = Query(100, ge=1, le=200, description="Max records to return"),
|
|
merchant=Depends(get_merchant_for_current_user),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""
|
|
List all stores belonging to the merchant.
|
|
|
|
Returns a paginated list of store summaries for the authenticated merchant.
|
|
"""
|
|
stores, total = merchant_service.get_merchant_stores(
|
|
db, merchant.id, skip=skip, limit=limit
|
|
)
|
|
|
|
return MerchantPortalStoreListResponse(
|
|
stores=stores,
|
|
total=total,
|
|
skip=skip,
|
|
limit=limit,
|
|
)
|
|
|
|
|
|
@_account_router.get("/profile", response_model=MerchantPortalProfileResponse)
|
|
async def merchant_profile(
|
|
request: Request,
|
|
merchant=Depends(get_merchant_for_current_user),
|
|
):
|
|
"""
|
|
Get the authenticated merchant's profile information.
|
|
|
|
Returns merchant details including contact info, business details,
|
|
and verification status.
|
|
"""
|
|
return merchant
|
|
|
|
|
|
@_account_router.put("/profile", response_model=MerchantPortalProfileResponse)
|
|
async def update_merchant_profile(
|
|
request: Request,
|
|
profile_data: MerchantPortalProfileUpdate,
|
|
current_user: UserContext = Depends(get_current_merchant_api),
|
|
merchant=Depends(get_merchant_for_current_user),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""
|
|
Update the authenticated merchant's profile information.
|
|
|
|
Accepts partial updates - only provided fields are changed.
|
|
"""
|
|
# Apply only the fields that were explicitly provided
|
|
update_data = profile_data.model_dump(exclude_unset=True)
|
|
for field_name, value in update_data.items():
|
|
setattr(merchant, field_name, value)
|
|
|
|
db.commit()
|
|
db.refresh(merchant)
|
|
|
|
logger.info(
|
|
f"Merchant profile updated: merchant_id={merchant.id}, "
|
|
f"user={current_user.username}, fields={list(update_data.keys())}"
|
|
)
|
|
|
|
return merchant
|
|
|
|
|
|
# Include account routes in main router
|
|
router.include_router(_account_router, tags=["merchant-account"])
|