feat(tenancy): add profile editing in merchant team edit modal
Some checks failed
Some checks failed
Edit modal now has editable first_name, last_name, email fields with
a "Save Profile" button, alongside the existing per-store role management.
New:
- PUT /merchants/account/team/members/{user_id}/profile endpoint
- MerchantTeamProfileUpdate schema
- update_team_member_profile() service method with ownership validation
- 2 new i18n keys across 4 locales (personal_info, save_profile)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ from app.modules.tenancy.models.merchant import Merchant
|
||||
from app.modules.tenancy.models.platform import Platform
|
||||
from app.modules.tenancy.models.store import Role, Store
|
||||
from app.modules.tenancy.models.store_platform import StorePlatform
|
||||
from app.modules.tenancy.models.user import User
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -456,6 +457,58 @@ class MerchantStoreService:
|
||||
raise StoreNotFoundException(store_id, identifier_type="id")
|
||||
return store
|
||||
|
||||
def update_team_member_profile(
|
||||
self,
|
||||
db: Session,
|
||||
merchant_id: int,
|
||||
user_id: int,
|
||||
update_data: dict,
|
||||
) -> None:
|
||||
"""
|
||||
Update a team member's profile (first_name, last_name, email).
|
||||
|
||||
Validates that the user is a team member of one of the merchant's stores.
|
||||
"""
|
||||
from app.modules.tenancy.models.store import StoreUser
|
||||
|
||||
# Verify user is a team member in at least one of the merchant's stores
|
||||
stores = (
|
||||
db.query(Store)
|
||||
.filter(Store.merchant_id == merchant_id)
|
||||
.all()
|
||||
)
|
||||
store_ids = [s.id for s in stores]
|
||||
|
||||
membership = (
|
||||
db.query(StoreUser)
|
||||
.filter(
|
||||
StoreUser.store_id.in_(store_ids),
|
||||
StoreUser.user_id == user_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
if not membership:
|
||||
# Also allow updating the owner
|
||||
merchant = db.query(Merchant).filter(Merchant.id == merchant_id).first()
|
||||
if not merchant or merchant.owner_user_id != user_id:
|
||||
from app.modules.tenancy.exceptions import UserNotFoundException
|
||||
raise UserNotFoundException(str(user_id))
|
||||
|
||||
user = db.query(User).filter(User.id == user_id).first()
|
||||
if not user:
|
||||
from app.modules.tenancy.exceptions import UserNotFoundException
|
||||
raise UserNotFoundException(str(user_id))
|
||||
|
||||
if "first_name" in update_data:
|
||||
user.first_name = update_data["first_name"]
|
||||
if "last_name" in update_data:
|
||||
user.last_name = update_data["last_name"]
|
||||
if "email" in update_data and update_data["email"]:
|
||||
user.email = update_data["email"]
|
||||
|
||||
db.flush()
|
||||
|
||||
def get_merchant_team_members(self, db: Session, merchant_id: int) -> dict:
|
||||
"""
|
||||
Get team members across all merchant stores in a member-centric view.
|
||||
|
||||
Reference in New Issue
Block a user