fix(tenancy): fix team CRUD bugs + add member integration tests

Store team page:
- Fix undefined user_id (API returns `id`, JS used `user_id`)
- Fix wrong URL path in updateMember (remove redundant storeCode)
- Fix update_member_role route passing wrong kwarg (new_role_id → new_role_name)
- Add update_member() service method for role_id + is_active updates
- Add :selected binding for role pre-selection in edit modal

Merchant team page:
- Add missing db.commit() on invite, update, and remove endpoints
- Fix forward-reference string type annotation on MerchantTeamInvite
- Add :selected binding for role pre-selection in edit modal

Shared fixes:
- Replace removed subscription_service.check_team_limit with usage_service
- Replace removed subscription_service.get_current_tier in email service
- Fix email config bool settings crashing on .lower() (value_type=boolean)

Tests: 15 new integration tests for store team member API endpoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-28 21:06:21 +01:00
parent 0455e63a2e
commit 332960de30
10 changed files with 541 additions and 22 deletions

View File

@@ -25,6 +25,7 @@ from app.modules.tenancy.schemas import (
MerchantStoreUpdate,
)
from app.modules.tenancy.schemas.auth import UserContext
from app.modules.tenancy.schemas.team import MerchantTeamInvite
from app.modules.tenancy.services.merchant_service import merchant_service
from app.modules.tenancy.services.merchant_store_service import merchant_store_service
@@ -192,7 +193,7 @@ async def merchant_team_store_roles(
@_account_router.post("/team/invite")
async def merchant_team_invite(
data: "MerchantTeamInvite",
data: MerchantTeamInvite,
current_user: UserContext = Depends(get_current_merchant_api),
merchant=Depends(get_merchant_for_current_user),
db: Session = Depends(get_db),
@@ -233,6 +234,7 @@ async def merchant_team_invite(
error=str(e),
))
db.commit()
success_count = sum(1 for r in results if r.success)
if success_count == len(results):
message = f"Invitation sent to {data.email} for {success_count} store(s)"
@@ -268,6 +270,7 @@ async def merchant_team_update_role(
new_role_name=role_name,
actor_user_id=current_user.id,
)
db.commit()
return {"message": "Role updated successfully"}
@@ -289,6 +292,7 @@ async def merchant_team_remove_member(
user_id=user_id,
actor_user_id=current_user.id,
)
db.commit()
@_account_router.get("/profile", response_model=MerchantPortalProfileResponse)

View File

@@ -277,12 +277,13 @@ def update_team_member(
"""
store = request.state.store
store_team_service.update_member_role(
store_team_service.update_member(
db=db,
store=store,
user_id=user_id,
new_role_id=update_data.role_id,
role_id=update_data.role_id,
is_active=update_data.is_active,
actor_user_id=current_user.id,
)
db.commit()