bmc_hub/app/timetracking/backend/timer_transaction.py

36 lines
1.7 KiB
Python
Raw Normal View History

"""Serialize opt-in remote/desktop timer writes using the same transaction helpers."""
from contextlib import nullcontext
from functools import wraps
from app.core.config import settings
from app.core.database import atomic_transaction, _transaction_connection, execute_query
def serialized_timer(function):
@wraps(function)
async def wrapped(*args, **kwargs):
# Leave legacy behavior unchanged while remote control is disabled.
if not settings.REMOTE_ENABLED:
return await function(*args, **kwargs)
import inspect
arguments = inspect.signature(function).bind_partial(*args, **kwargs).arguments
user = arguments.get('current_user')
if not isinstance(user, dict) or not user.get('id'):
return await function(*args, **kwargs)
context = nullcontext() if _transaction_connection.get() else atomic_transaction()
with context:
ids = {int(user['id'])}
payload = arguments.get('payload') or {}
if function.__name__ in {'start_live_timer_v1', 'create_manual_time_v1'}:
raw_ids = payload.get('medarbejder_ids') or [payload.get('medarbejder_id')]
if isinstance(raw_ids, list):
for uid in raw_ids:
try:
if uid is not None:
ids.add(int(uid))
except (ValueError, TypeError):
pass # The existing handler supplies the validation error.
execute_query('SELECT user_id FROM users WHERE user_id=ANY(%s) ORDER BY user_id FOR UPDATE', (sorted(ids),))
return await function(*args, **kwargs)
return wrapped