
Some checks failed
Deploy to Production, build images and push to Gitea Registry / build_and_push (pull_request) Failing after 1m24s
This commit adds new guidelines for FastAPI and Vue.js development, emphasizing best practices for component structure, API performance, and data handling. It also introduces caching mechanisms using Redis for improved performance and updates the API structure to streamline authentication and user management. Additionally, new endpoints for categories and time entries are implemented, enhancing the overall functionality of the application.
136 lines
5.2 KiB
Python
136 lines
5.2 KiB
Python
from __future__ import annotations
|
|
from datetime import date, datetime
|
|
from typing import Optional, List, Any
|
|
from pydantic import BaseModel, ConfigDict, field_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
|
|
|
|
@field_validator('custom_interval_days', mode='before')
|
|
@classmethod
|
|
def check_custom_interval_days(cls, value, values):
|
|
# Pydantic v2 uses `values.data` to get all fields
|
|
# For older Pydantic, it might just be `values`
|
|
# This is a simplified check; actual access might differ slightly
|
|
# based on Pydantic version context within the validator.
|
|
# The goal is to ensure custom_interval_days is present if frequency is 'custom'.
|
|
# This validator might be more complex in a real Pydantic v2 setup.
|
|
|
|
# A more direct way if 'frequency' is already parsed into values.data:
|
|
# freq = values.data.get('frequency')
|
|
# For this example, we'll assume 'frequency' might not be in 'values.data' yet
|
|
# if 'custom_interval_days' is validated 'before' 'frequency'.
|
|
# A truly robust validator might need to be on the whole model or run 'after'.
|
|
# For now, this is a placeholder for the logic.
|
|
# Consider if this validation is better handled at the service/CRUD layer for complex cases.
|
|
return value
|
|
|
|
class ChoreCreate(ChoreBase):
|
|
group_id: Optional[int] = None
|
|
parent_chore_id: Optional[int] = None
|
|
|
|
@field_validator('group_id')
|
|
@classmethod
|
|
def validate_group_id(cls, v, values):
|
|
if values.data.get('type') == ChoreTypeEnum.group and v is None:
|
|
raise ValueError("group_id is required for group chores")
|
|
if values.data.get('type') == ChoreTypeEnum.personal and v is not None:
|
|
raise ValueError("group_id must be None for personal chores")
|
|
return v
|
|
|
|
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
|
|
# last_completed_at should generally not be updated directly by user
|
|
|
|
@field_validator('group_id')
|
|
@classmethod
|
|
def validate_group_id(cls, v, values):
|
|
if values.data.get('type') == ChoreTypeEnum.group and v is None:
|
|
raise ValueError("group_id is required for group chores")
|
|
if values.data.get('type') == ChoreTypeEnum.personal and v is not None:
|
|
raise ValueError("group_id must be None for personal chores")
|
|
return v
|
|
|
|
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()
|