feat: Implement routines feature with CRUD operations and child assignment
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m0s

- Add backend routines management with add, get, update, delete, and list functionalities.
- Create models for Routine, RoutineItem, RoutineSchedule, and RoutineExtension.
- Develop event types for routine confirmation and modification.
- Implement frontend components for routine assignment, confirmation dialog, and routine management views.
- Add unit tests for routine API and integration tests for routine CRUD flow.
- Create end-to-end test plan for routines feature covering parent and child interactions.
This commit is contained in:
2026-05-05 09:08:19 -04:00
parent 082097b4f9
commit eb775ba7d8
41 changed files with 2847 additions and 29 deletions

View File

@@ -10,7 +10,7 @@ from api.pending_confirmation import PendingConfirmationResponse
from api.reward_status import RewardStatus
from api.utils import send_event_for_current_user, get_validated_user_id
import api.child_action_helpers as chore_actions
from db.db import child_db, task_db, reward_db, pending_reward_db, pending_confirmations_db, users_db
from db.db import child_db, task_db, reward_db, routine_db, pending_reward_db, pending_confirmations_db, users_db
from db.tracking import insert_tracking_event
from db.child_overrides import get_override, delete_override, delete_overrides_for_child
from events.types.child_chore_confirmation import ChildChoreConfirmation
@@ -35,6 +35,8 @@ from utils.digest_token import create_action_token
from collections import defaultdict
from db.chore_schedules import get_schedule
from db.task_extensions import get_extension_for_child_task
from db.routine_schedules import delete_schedules_for_child as delete_routine_schedules_for_child
from db.routine_extensions import delete_extensions_for_child as delete_routine_extensions_for_child
import logging
child_api = Blueprint('child_api', __name__)
@@ -163,6 +165,14 @@ def delete_child(id):
deleted_count = delete_overrides_for_child(id)
if deleted_count > 0:
logger.info(f"Cascade deleted {deleted_count} overrides for child {id}")
# Cascade delete routine schedule/extension rows for this child.
delete_routine_schedules_for_child(id)
delete_routine_extensions_for_child(id)
# Remove pending routine confirmations for this child.
PendingQuery = Query()
pending_confirmations_db.remove((PendingQuery.child_id == id) & (PendingQuery.entity_type == 'routine'))
if child_db.remove((ChildQuery.id == id) & (ChildQuery.user_id == user_id)):
resp = send_event_for_current_user(Event(EventType.CHILD_MODIFIED.value, ChildModified(id, ChildModified.OPERATION_DELETE)))
@@ -1104,6 +1114,7 @@ def list_pending_confirmations():
RewardQuery = Query()
TaskQuery = Query()
RoutineQuery = Query()
ChildQuery = Query()
for pr in pending_items:
@@ -1122,8 +1133,12 @@ def list_pending_confirmations():
# Look up entity details based on type
if pending.entity_type == 'reward':
entity_result = reward_db.get((RewardQuery.id == pending.entity_id) & ((RewardQuery.user_id == user_id) | (RewardQuery.user_id == None)))
else:
elif pending.entity_type == 'chore':
entity_result = task_db.get((TaskQuery.id == pending.entity_id) & ((TaskQuery.user_id == user_id) | (TaskQuery.user_id == None)))
elif pending.entity_type == 'routine':
entity_result = routine_db.get((RoutineQuery.id == pending.entity_id) & ((RoutineQuery.user_id == user_id) | (RoutineQuery.user_id == None)))
else:
entity_result = None
if not entity_result:
continue