feat: complete task management workflow
This commit is contained in:
+57
-4
@@ -1,7 +1,7 @@
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
|
||||
|
||||
class InitializeRequest(BaseModel):
|
||||
@@ -20,10 +20,14 @@ class UserOut(BaseModel):
|
||||
username: str
|
||||
|
||||
|
||||
class FolderCreate(BaseModel):
|
||||
class NameUpdate(BaseModel):
|
||||
name: str = Field(min_length=1, max_length=120)
|
||||
|
||||
|
||||
class FolderCreate(NameUpdate):
|
||||
pass
|
||||
|
||||
|
||||
class FolderOut(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: UUID
|
||||
@@ -43,6 +47,18 @@ class ListOut(BaseModel):
|
||||
is_inbox: bool
|
||||
|
||||
|
||||
class TagCreate(BaseModel):
|
||||
name: str = Field(min_length=1, max_length=80)
|
||||
color: str = Field(default="#f15a29", min_length=1, max_length=32)
|
||||
|
||||
|
||||
class TagOut(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: UUID
|
||||
name: str
|
||||
color: str
|
||||
|
||||
|
||||
class TaskCreate(BaseModel):
|
||||
title: str = Field(min_length=1, max_length=500)
|
||||
list_id: UUID
|
||||
@@ -50,16 +66,26 @@ class TaskCreate(BaseModel):
|
||||
priority: int = Field(default=0, ge=0, le=3)
|
||||
due_at: datetime | None = None
|
||||
parent_id: UUID | None = None
|
||||
tag_ids: list[UUID] = Field(default_factory=list)
|
||||
|
||||
|
||||
class TaskUpdate(BaseModel):
|
||||
title: str = Field(default=None, min_length=1, max_length=500)
|
||||
description: str = Field(default=None)
|
||||
title: str | None = Field(default=None, min_length=1, max_length=500)
|
||||
description: str | None = None
|
||||
priority: int | None = Field(default=None, ge=0, le=3)
|
||||
due_at: datetime | None = None
|
||||
completed: bool | None = None
|
||||
list_id: UUID | None = None
|
||||
tag_ids: list[UUID] | None = None
|
||||
version: int = Field(ge=1)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def reject_null_non_nullable_fields(self):
|
||||
for field in ("title", "description", "priority", "completed", "list_id"):
|
||||
if field in self.model_fields_set and getattr(self, field) is None:
|
||||
raise ValueError(f"{field} cannot be null")
|
||||
return self
|
||||
|
||||
|
||||
class TaskOut(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -74,6 +100,33 @@ class TaskOut(BaseModel):
|
||||
version: int
|
||||
|
||||
|
||||
class TaskDetailOut(TaskOut):
|
||||
tags: list[TagOut] = Field(default_factory=list)
|
||||
subtasks: list[TaskOut] = Field(default_factory=list)
|
||||
|
||||
|
||||
class TaskPage(BaseModel):
|
||||
items: list[TaskOut]
|
||||
next_cursor: str | None = None
|
||||
|
||||
|
||||
class BatchTaskUpdate(BaseModel):
|
||||
task_ids: list[UUID] = Field(min_length=1)
|
||||
completed: bool | None = None
|
||||
list_id: UUID | None = None
|
||||
due_at: datetime | None = None
|
||||
tag_ids: list[UUID] | None = None
|
||||
soft_delete: bool | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def require_operation(self):
|
||||
operations = {"completed", "list_id", "due_at", "tag_ids", "soft_delete"}
|
||||
if not self.model_fields_set.intersection(operations):
|
||||
raise ValueError("at least one batch operation is required")
|
||||
if self.soft_delete is False:
|
||||
raise ValueError("soft_delete can only be true")
|
||||
return self
|
||||
|
||||
|
||||
class BatchResult(BaseModel):
|
||||
updated: int
|
||||
|
||||
Reference in New Issue
Block a user