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

1from typing import Optional, List 

2from pydantic import BaseModel, ConfigDict 

3from uuid import UUID 

4from datetime import datetime, date 

5from decimal import Decimal 

6 

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 

17 

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 

36 

37 model_config = ConfigDict(from_attributes=True) 

38 

39class BoardColumnOut(BaseModel): 

40 id: UUID 

41 name: str 

42 order: int 

43 limit: int 

44 status_category: str 

45 

46 model_config = ConfigDict(from_attributes=True) 

47 

48class BoardOut(BaseModel): 

49 id: UUID 

50 project_id: UUID 

51 name: str 

52 columns: List[BoardColumnOut] 

53 

54 model_config = ConfigDict(from_attributes=True) 

55 

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]] = [] 

67 

68class TaskMoveIn(BaseModel): 

69 column_id: UUID 

70 order: int 

71 status: Optional[str] = None 

72 

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 

83 

84class TaskCommentIn(BaseModel): 

85 content: str 

86 

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 

95 

96 model_config = ConfigDict(from_attributes=True) 

97 

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 

124 

125 model_config = ConfigDict(from_attributes=True) 

126 

127class TimeLogIn(BaseModel): 

128 hours: Decimal 

129 description: Optional[str] = None 

130 logged_date: Optional[date] = None 

131 

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 

141 

142 model_config = ConfigDict(from_attributes=True)