Coverage for modules\planner\schemas.py: 100%
124 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-05 09:25 +0800
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-05 09:25 +0800
1from typing import Optional, List
2from pydantic import BaseModel, ConfigDict
3from uuid import UUID
4from datetime import datetime, date
5from decimal import Decimal
7class ProjectIn(BaseModel):
8 name: str
9 key: str
10 description: Optional[str] = None
11 color: Optional[str] = '#6366F1'
12 lead_id: Optional[UUID] = None
13 department_id: Optional[UUID] = None
14 goal: Optional[str] = None
15 roadmap_start: Optional[date] = None
16 roadmap_end: Optional[date] = None
18class ProjectOut(BaseModel):
19 id: UUID
20 name: str
21 key: str
22 description: Optional[str] = None
23 color: str
24 status: str
25 lead_id: Optional[UUID] = None
26 lead_name: Optional[str] = None
27 tasks_count: int = 0
28 completed_tasks_count: int = 0
29 created_at: datetime
30 updated_at: datetime
31 department_id: Optional[UUID] = None
32 department_name: Optional[str] = None
33 goal: Optional[str] = None
34 roadmap_start: Optional[date] = None
35 roadmap_end: Optional[date] = None
37 model_config = ConfigDict(from_attributes=True)
39class BoardColumnOut(BaseModel):
40 id: UUID
41 name: str
42 order: int
43 limit: int
44 status_category: str
46 model_config = ConfigDict(from_attributes=True)
48class BoardOut(BaseModel):
49 id: UUID
50 project_id: UUID
51 name: str
52 columns: List[BoardColumnOut]
54 model_config = ConfigDict(from_attributes=True)
56class TaskIn(BaseModel):
57 project_id: UUID
58 column_id: Optional[UUID] = None
59 title: str
60 description: Optional[str] = None
61 priority: Optional[str] = 'MEDIUM'
62 status: Optional[str] = 'TODO'
63 assignee_id: Optional[UUID] = None
64 due_date: Optional[date] = None
65 estimated_hours: Optional[Decimal] = Decimal('0.00')
66 tags: Optional[List[str]] = []
68class TaskMoveIn(BaseModel):
69 column_id: UUID
70 order: int
71 status: Optional[str] = None
73class TaskUpdateIn(BaseModel):
74 title: Optional[str] = None
75 description: Optional[str] = None
76 priority: Optional[str] = None
77 status: Optional[str] = None
78 column_id: Optional[UUID] = None
79 assignee_id: Optional[UUID] = None
80 due_date: Optional[date] = None
81 estimated_hours: Optional[Decimal] = None
82 tags: Optional[List[str]] = None
84class TaskCommentIn(BaseModel):
85 content: str
87class TaskCommentOut(BaseModel):
88 id: UUID
89 task_id: UUID
90 author_id: UUID
91 author_name: str
92 author_avatar: Optional[str] = None
93 content: str
94 created_at: datetime
96 model_config = ConfigDict(from_attributes=True)
98class TaskOut(BaseModel):
99 id: UUID
100 project_id: UUID
101 project_key: str
102 board_id: Optional[UUID] = None
103 column_id: Optional[UUID] = None
104 column_name: Optional[str] = None
105 title: str
106 description: Optional[str] = None
107 task_number: int
108 task_code: str
109 priority: str
110 status: str
111 order: int
112 assignee_id: Optional[UUID] = None
113 assignee_name: Optional[str] = None
114 assignee_avatar: Optional[str] = None
115 reporter_id: UUID
116 reporter_name: str
117 due_date: Optional[date] = None
118 estimated_hours: Decimal
119 logged_hours: Decimal
120 tags: List[str]
121 comments_count: int = 0
122 created_at: datetime
123 updated_at: datetime
125 model_config = ConfigDict(from_attributes=True)
127class TimeLogIn(BaseModel):
128 hours: Decimal
129 description: Optional[str] = None
130 logged_date: Optional[date] = None
132class TimeLogOut(BaseModel):
133 id: UUID
134 task_id: UUID
135 user_id: UUID
136 user_name: str
137 hours: Decimal
138 description: Optional[str] = None
139 logged_date: date
140 created_at: datetime
142 model_config = ConfigDict(from_attributes=True)