36 lines
1.7 KiB
Python
36 lines
1.7 KiB
Python
|
|
"""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
|