Fix role_id sentinel bug: use _UNSET sentinel so None explicitly clears FK, missing param leaves unchanged
This commit is contained in:
@@ -11,6 +11,11 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
from app.core.auth import hash_password
|
from app.core.auth import hash_password
|
||||||
from app.models.user import User, UserTenant
|
from app.models.user import User, UserTenant
|
||||||
|
|
||||||
|
# Sentinel used to distinguish "not provided" from "explicitly set to None".
|
||||||
|
# When ``role_id`` is _UNSET the service leaves the existing value untouched.
|
||||||
|
# When ``role_id`` is None the service clears the FK (falls back to role string).
|
||||||
|
_UNSET: Any = object()
|
||||||
|
|
||||||
|
|
||||||
class UserService:
|
class UserService:
|
||||||
"""Handles user CRUD operations."""
|
"""Handles user CRUD operations."""
|
||||||
@@ -108,14 +113,15 @@ class UserService:
|
|||||||
user_id: uuid.UUID,
|
user_id: uuid.UUID,
|
||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
role: str | None = None,
|
role: str | None = None,
|
||||||
role_id: uuid.UUID | None = None,
|
role_id: uuid.UUID | None | Any = _UNSET,
|
||||||
is_active: bool | None = None,
|
is_active: bool | None = None,
|
||||||
) -> User | None:
|
) -> User | None:
|
||||||
"""Update a user.
|
"""Update a user.
|
||||||
|
|
||||||
``role_id`` accepts a UUID to link a custom Role, or None to leave
|
``role_id`` uses a sentinel to distinguish three states:
|
||||||
the existing value unchanged. Pass ``role_id`` explicitly as None
|
- ``_UNSET`` (default): leave the existing role_id unchanged
|
||||||
combined with the sentinel logic below to clear it.
|
- ``None``: clear the FK (fall back to the legacy ``role`` string)
|
||||||
|
- ``uuid.UUID``: link to a custom Role record
|
||||||
"""
|
"""
|
||||||
q = select(User).where(User.id == user_id, User.tenant_id == tenant_id)
|
q = select(User).where(User.id == user_id, User.tenant_id == tenant_id)
|
||||||
result = await db.execute(q)
|
result = await db.execute(q)
|
||||||
@@ -127,7 +133,7 @@ class UserService:
|
|||||||
user.name = name
|
user.name = name
|
||||||
if role is not None:
|
if role is not None:
|
||||||
user.role = role
|
user.role = role
|
||||||
if role_id is not None:
|
if role_id is not _UNSET:
|
||||||
user.role_id = role_id
|
user.role_id = role_id
|
||||||
if is_active is not None:
|
if is_active is not None:
|
||||||
user.is_active = is_active
|
user.is_active = is_active
|
||||||
|
|||||||
Reference in New Issue
Block a user