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

@@ -37,6 +37,56 @@ export interface ChoreSchedule {
updated_at: number
}
export interface Routine {
id: string
name: string
points: number
image_id: string | null
image_url?: string | null
}
export const ROUTINE_FIELDS = ['id', 'name', 'points', 'image_id'] as const
export interface RoutineItem {
id: string
routine_id: string
name: string
image_id: string | null
order: number
}
export interface RoutineSchedule {
id: string
child_id: string
routine_id: string
mode: 'days' | 'interval'
day_configs: DayConfig[]
default_hour?: number
default_minute?: number
default_has_deadline?: boolean
interval_days: number
anchor_date: string
interval_has_deadline: boolean
interval_hour: number
interval_minute: number
enabled?: boolean
created_at: number
updated_at: number
}
export interface ChildRoutine {
id: string
name: string
points: number
image_id: string | null
image_url?: string | null
custom_value?: number | null
schedule?: RoutineSchedule | null
extension_date?: string | null
pending_status?: 'pending' | 'approved' | null
approved_at?: string | null
items: RoutineItem[]
}
export interface ChildTask {
id: string
name: string
@@ -72,12 +122,13 @@ export interface Child {
name: string
age: number
tasks: string[]
routines?: string[]
rewards: string[]
points: number
image_id: string | null
image_url?: string | null // optional, for resolved URLs
}
export const CHILD_FIELDS = ['id', 'name', 'age', 'tasks', 'rewards', 'points', 'image_id'] as const
export const CHILD_FIELDS = ['id', 'name', 'age', 'tasks', 'routines', 'rewards', 'points', 'image_id'] as const
export interface Reward {
id: string
@@ -114,7 +165,7 @@ export interface PendingConfirmation {
child_image_id: string | null
child_image_url?: string | null
entity_id: string
entity_type: 'chore' | 'reward'
entity_type: 'chore' | 'reward' | 'routine'
entity_name: string
entity_image_id: string | null
entity_image_url?: string | null
@@ -151,6 +202,11 @@ export interface Event {
| ChoreScheduleModifiedPayload
| ChoreTimeExtendedPayload
| ChildChoreConfirmationPayload
| RoutineModifiedEventPayload
| ChildRoutinesSetEventPayload
| RoutineScheduleModifiedPayload
| RoutineTimeExtendedPayload
| ChildRoutineConfirmationPayload
}
export interface ChildModifiedEventPayload {
@@ -194,6 +250,16 @@ export interface RewardModifiedEventPayload {
operation: 'ADD' | 'DELETE' | 'EDIT'
}
export interface RoutineModifiedEventPayload {
routine_id: string
operation: 'ADD' | 'DELETE' | 'EDIT'
}
export interface ChildRoutinesSetEventPayload {
child_id: string
routine_ids: string[]
}
export interface TrackingEventCreatedPayload {
tracking_event_id: string
child_id: string
@@ -211,7 +277,7 @@ export interface ChildOverrideDeletedPayload {
entity_type: string
}
export type EntityType = 'task' | 'reward' | 'penalty' | 'chore' | 'kindness'
export type EntityType = 'task' | 'reward' | 'penalty' | 'chore' | 'kindness' | 'routine'
export type ActionType =
| 'activated'
| 'requested'
@@ -254,7 +320,7 @@ export const TRACKING_EVENT_FIELDS = [
'metadata',
] as const
export type OverrideEntityType = 'task' | 'reward' | 'chore' | 'kindness' | 'penalty'
export type OverrideEntityType = 'task' | 'reward' | 'chore' | 'kindness' | 'penalty' | 'routine'
export interface ChildOverride {
id: string
@@ -292,3 +358,20 @@ export interface ChildChoreConfirmationPayload {
task_id: string
operation: 'CONFIRMED' | 'APPROVED' | 'REJECTED' | 'CANCELLED' | 'RESET'
}
export interface RoutineScheduleModifiedPayload {
child_id: string
routine_id: string
operation: 'SET' | 'DELETED'
}
export interface RoutineTimeExtendedPayload {
child_id: string
routine_id: string
}
export interface ChildRoutineConfirmationPayload {
child_id: string
routine_id: string
operation: 'PENDING' | 'APPROVED' | 'REJECTED' | 'RESET'
}