feat: enhance task and reward management by clearing pending confirmations on unassignment
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m29s

This commit is contained in:
2026-04-21 16:52:06 -04:00
parent 60dbb8a129
commit bc481527c8
2 changed files with 47 additions and 7 deletions

View File

@@ -42,6 +42,10 @@ def approve_chore(user_id: str, child_id: str, task_id: str) -> dict | None:
raise ValueError(f'Child {child_id} not found for user {user_id}')
child = Child.from_dict(child_result)
if task_id not in child.tasks:
logger.info(f'Task {task_id} no longer assigned to child {child_id}; skipping approve')
return None
PendingQ = Query()
existing = pending_confirmations_db.get(
(PendingQ.child_id == child_id) & (PendingQ.entity_id == task_id) &
@@ -161,6 +165,10 @@ def approve_reward_request(user_id: str, child_id: str, reward_id: str) -> dict:
raise ValueError(f'Child {child_id} not found for user {user_id}')
child = Child.from_dict(child_result)
if reward_id not in child.rewards:
logger.info(f'Reward {reward_id} no longer assigned to child {child_id}; skipping approve')
return None
RewardQ = Query()
reward_result = reward_db.get(
(RewardQ.id == reward_id) & ((RewardQ.user_id == user_id) | (RewardQ.user_id == None))
@@ -176,11 +184,19 @@ def approve_reward_request(user_id: str, child_id: str, reward_id: str) -> dict:
raise ValueError(f'Child {child_id} has insufficient points for reward {reward_id}')
PendingQ = Query()
removed = pending_confirmations_db.remove(
existing = pending_confirmations_db.get(
(PendingQ.child_id == child_id) & (PendingQ.entity_id == reward_id) &
(PendingQ.entity_type == 'reward')
(PendingQ.entity_type == 'reward') & (PendingQ.status == 'pending') &
(PendingQ.user_id == user_id)
)
if not existing:
logger.info(f'No pending reward for child {child_id}, reward {reward_id} — already resolved')
return None
pending_confirmations_db.remove(
(PendingQ.child_id == child_id) & (PendingQ.entity_id == reward_id) &
(PendingQ.entity_type == 'reward') & (PendingQ.user_id == user_id)
)
if removed:
send_event_to_user(user_id, Event(EventType.CHILD_REWARD_REQUEST.value,
ChildRewardRequest(child_id, reward_id, ChildRewardRequest.REQUEST_GRANTED)))

View File

@@ -211,7 +211,7 @@ def set_child_tasks(id):
# Convert back to list if needed
new_tasks = list(new_task_ids)
# Identify unassigned tasks and delete their overrides
# Identify unassigned tasks and delete their overrides and pending confirmations
old_task_ids = set(child.tasks)
unassigned_task_ids = old_task_ids - new_task_ids
for task_id in unassigned_task_ids:
@@ -220,6 +220,12 @@ def set_child_tasks(id):
if override and override.entity_type == 'task':
delete_override(id, task_id)
logger.info(f"Deleted override for unassigned task: child={id}, task={task_id}")
# Clear any pending chore confirmation
PendingQ = Query()
pending_confirmations_db.remove(
(PendingQ.child_id == id) & (PendingQ.entity_id == task_id) &
(PendingQ.entity_type == 'chore') & (PendingQ.user_id == user_id)
)
# Replace tasks with validated IDs
child_db.update({'tasks': new_tasks}, ChildQuery.id == id)
@@ -253,6 +259,12 @@ def remove_task_from_child(id):
if task_id in child.get('tasks', []):
child['tasks'].remove(task_id)
child_db.update({'tasks': child['tasks']}, ChildQuery.id == id)
# Clear any pending chore confirmation for this task
PendingQ = Query()
pending_confirmations_db.remove(
(PendingQ.child_id == id) & (PendingQ.entity_id == task_id) &
(PendingQ.entity_type == 'chore') & (PendingQ.user_id == user_id)
)
return jsonify({'message': f'Task {task_id} removed from {child["name"]}.'}), 200
return jsonify({'error': 'Task not assigned to child'}), 400
@@ -602,7 +614,7 @@ def set_child_rewards(id):
if reward_db.get((RewardQuery.id == rid) & ((RewardQuery.user_id == user_id) | (RewardQuery.user_id == None))):
valid_reward_ids.append(rid)
# Identify unassigned rewards and delete their overrides
# Identify unassigned rewards and delete their overrides and pending confirmations
new_reward_ids_set = set(valid_reward_ids)
unassigned_reward_ids = old_reward_ids - new_reward_ids_set
for reward_id in unassigned_reward_ids:
@@ -610,6 +622,12 @@ def set_child_rewards(id):
if override and override.entity_type == 'reward':
delete_override(id, reward_id)
logger.info(f"Deleted override for unassigned reward: child={id}, reward={reward_id}")
# Clear any pending reward confirmation
PendingQ = Query()
pending_confirmations_db.remove(
(PendingQ.child_id == id) & (PendingQ.entity_id == reward_id) &
(PendingQ.entity_type == 'reward') & (PendingQ.user_id == user_id)
)
# Replace rewards with validated IDs
child_db.update({'rewards': valid_reward_ids}, ChildQuery.id == id)
@@ -640,6 +658,12 @@ def remove_reward_from_child(id):
if reward_id in child.get('rewards', []):
child['rewards'].remove(reward_id)
child_db.update({'rewards': child['rewards']}, ChildQuery.id == id)
# Clear any pending reward confirmation for this reward
PendingQ = Query()
pending_confirmations_db.remove(
(PendingQ.child_id == id) & (PendingQ.entity_id == reward_id) &
(PendingQ.entity_type == 'reward') & (PendingQ.user_id == user_id)
)
return jsonify({'message': f'Reward {reward_id} removed from {child["name"]}.'}), 200
return jsonify({'error': 'Reward not assigned to child'}), 400