
All checks were successful
Deploy to Production, build images and push to Gitea Registry / build_and_push (pull_request) Successful in 1m37s
This commit introduces significant updates to the chore management system, including: - Refactoring the `create_chore` function to streamline the creation process and enforce assignment rules based on chore type. - Adding support for assigning chores to users, ensuring that group chores can only be assigned to group members and personal chores can only be assigned to the creator. - Updating the API endpoints and frontend components to accommodate the new assignment features, including loading group members for assignment selection. - Enhancing the user interface to display assignment options and manage chore assignments effectively. These changes aim to improve the functionality and user experience of the chore management system.
126 lines
4.7 KiB
Python
126 lines
4.7 KiB
Python
from __future__ import annotations
|
|
from datetime import date, datetime
|
|
from typing import Optional, List, Any
|
|
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
|
|
from ..models import ChoreFrequencyEnum, ChoreTypeEnum, ChoreHistoryEventTypeEnum
|
|
from .user import UserPublic
|
|
|
|
class ChoreAssignmentPublic(BaseModel):
|
|
pass
|
|
|
|
class ChoreHistoryPublic(BaseModel):
|
|
id: int
|
|
event_type: ChoreHistoryEventTypeEnum
|
|
event_data: Optional[dict[str, Any]] = None
|
|
changed_by_user: Optional[UserPublic] = None
|
|
timestamp: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
class ChoreAssignmentHistoryPublic(BaseModel):
|
|
id: int
|
|
event_type: ChoreHistoryEventTypeEnum
|
|
event_data: Optional[dict[str, Any]] = None
|
|
changed_by_user: Optional[UserPublic] = None
|
|
timestamp: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ChoreBase(BaseModel):
|
|
name: str
|
|
description: Optional[str] = None
|
|
frequency: ChoreFrequencyEnum
|
|
custom_interval_days: Optional[int] = None
|
|
next_due_date: date # For creation, this will be the initial due date
|
|
type: ChoreTypeEnum
|
|
|
|
@model_validator(mode='after')
|
|
def validate_custom_frequency(self):
|
|
if self.frequency == ChoreFrequencyEnum.custom:
|
|
if self.custom_interval_days is None or self.custom_interval_days <= 0:
|
|
raise ValueError("custom_interval_days must be a positive integer when frequency is 'custom'")
|
|
return self
|
|
|
|
class ChoreCreate(ChoreBase):
|
|
group_id: Optional[int] = None
|
|
parent_chore_id: Optional[int] = None
|
|
assigned_to_user_id: Optional[int] = None
|
|
|
|
@model_validator(mode='after')
|
|
def validate_group_id_with_type(self):
|
|
if self.type == ChoreTypeEnum.group and self.group_id is None:
|
|
raise ValueError("group_id is required for group chores")
|
|
if self.type == ChoreTypeEnum.personal and self.group_id is not None:
|
|
# Automatically clear group_id for personal chores instead of raising an error
|
|
self.group_id = None
|
|
return self
|
|
|
|
class ChoreUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
description: Optional[str] = None
|
|
frequency: Optional[ChoreFrequencyEnum] = None
|
|
custom_interval_days: Optional[int] = None
|
|
next_due_date: Optional[date] = None # Allow updating next_due_date directly if needed
|
|
type: Optional[ChoreTypeEnum] = None
|
|
group_id: Optional[int] = None
|
|
parent_chore_id: Optional[int] = None # Allow moving a chore under a parent or removing association
|
|
# last_completed_at should generally not be updated directly by user
|
|
|
|
@model_validator(mode='after')
|
|
def validate_group_id_with_type(self):
|
|
if self.type == ChoreTypeEnum.group and self.group_id is None:
|
|
raise ValueError("group_id is required for group chores")
|
|
if self.type == ChoreTypeEnum.personal and self.group_id is not None:
|
|
# Automatically clear group_id for personal chores instead of raising an error
|
|
self.group_id = None
|
|
return self
|
|
|
|
class ChorePublic(ChoreBase):
|
|
id: int
|
|
group_id: Optional[int] = None
|
|
created_by_id: int
|
|
last_completed_at: Optional[datetime] = None
|
|
parent_chore_id: Optional[int] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
creator: Optional[UserPublic] = None # Embed creator UserPublic schema
|
|
assignments: List[ChoreAssignmentPublic] = []
|
|
history: List[ChoreHistoryPublic] = []
|
|
child_chores: List[ChorePublic] = []
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
# Chore Assignment Schemas
|
|
class ChoreAssignmentBase(BaseModel):
|
|
chore_id: int
|
|
assigned_to_user_id: int
|
|
due_date: date
|
|
|
|
class ChoreAssignmentCreate(ChoreAssignmentBase):
|
|
pass
|
|
|
|
class ChoreAssignmentUpdate(BaseModel):
|
|
# Only completion status and perhaps due_date can be updated for an assignment
|
|
is_complete: Optional[bool] = None
|
|
due_date: Optional[date] = None # If rescheduling an existing assignment is allowed
|
|
assigned_to_user_id: Optional[int] = None # For reassigning the chore
|
|
|
|
class ChoreAssignmentPublic(ChoreAssignmentBase):
|
|
id: int
|
|
is_complete: bool
|
|
completed_at: Optional[datetime] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
# Embed ChorePublic and UserPublic for richer responses
|
|
chore: Optional[ChorePublic] = None
|
|
assigned_user: Optional[UserPublic] = None
|
|
history: List[ChoreAssignmentHistoryPublic] = []
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
# To handle potential circular imports if ChorePublic needs GroupPublic and GroupPublic needs ChorePublic
|
|
# We can update forward refs after all models are defined.
|
|
ChorePublic.model_rebuild()
|
|
ChoreAssignmentPublic.model_rebuild()
|