- API-004: Add noqa for factory-pattern auth in user_account routes and payments admin - MDL-003: Add from_attributes to MerchantStoreDetailResponse schema - EXC-003: Suppress broad except in merchant_store_service and admin_subscription_service (intentional fallbacks for optional billing module) - NAM-002: Rename onboarding files to *_service.py suffix and update all imports - JS-001: Add file-level noqa for dev-toolbar.js (console interceptor by design) - JS-005: Add init guards to dashboard.js and customer-detail.js - IMPORT-004: Break circular deps by removing orders from inventory requires and marketplace from orders requires; add IMPORT-002 suppression for lazy cross-imports - MOD-025: Remove unused OnboardingAlreadyCompletedException Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
79 lines
2.5 KiB
Python
79 lines
2.5 KiB
Python
# app/modules/tenancy/routes/api/user_account.py
|
|
"""
|
|
Self-service account API routes.
|
|
|
|
Provides GET/PUT /account/me and PUT /account/me/password
|
|
for admin, store, and merchant frontends.
|
|
"""
|
|
|
|
import logging
|
|
from collections.abc import Callable
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.database import get_db
|
|
from app.modules.tenancy.schemas.auth import UserContext
|
|
from app.modules.tenancy.schemas.user_account import (
|
|
PasswordChangeResponse,
|
|
UserAccountResponse,
|
|
UserAccountUpdate,
|
|
UserPasswordChange,
|
|
)
|
|
from app.modules.tenancy.services.user_account_service import user_account_service
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def create_account_router(auth_dependency: Callable) -> APIRouter:
|
|
"""Create an account/me router bound to the given auth dependency."""
|
|
router = APIRouter(prefix="/account/me")
|
|
|
|
@router.get("", response_model=UserAccountResponse)
|
|
async def get_my_account(
|
|
current_user: UserContext = Depends(auth_dependency),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""Get the logged-in user's account info."""
|
|
return user_account_service.get_account(db, current_user.id)
|
|
|
|
@router.put("", response_model=UserAccountResponse) # noqa: API-004
|
|
async def update_my_account(
|
|
update_data: UserAccountUpdate,
|
|
current_user: UserContext = Depends(auth_dependency),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""Update the logged-in user's account info."""
|
|
result = user_account_service.update_account(
|
|
db, current_user.id, update_data.model_dump(exclude_unset=True)
|
|
)
|
|
db.commit()
|
|
return result
|
|
|
|
@router.put("/password", response_model=PasswordChangeResponse) # noqa: API-004
|
|
async def change_my_password(
|
|
password_data: UserPasswordChange,
|
|
current_user: UserContext = Depends(auth_dependency),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""Change the logged-in user's password."""
|
|
user_account_service.change_password(
|
|
db, current_user.id, password_data.model_dump()
|
|
)
|
|
db.commit()
|
|
return PasswordChangeResponse(message="Password changed successfully")
|
|
|
|
return router
|
|
|
|
|
|
# Create routers for each frontend
|
|
from app.api.deps import (
|
|
get_current_admin_api,
|
|
get_current_merchant_api,
|
|
get_current_store_api,
|
|
)
|
|
|
|
admin_account_router = create_account_router(get_current_admin_api)
|
|
store_account_router = create_account_router(get_current_store_api)
|
|
merchant_account_router = create_account_router(get_current_merchant_api)
|