Files
HarborForge.Backend/app/schemas/schemas.py

241 lines
5.2 KiB
Python

from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
from enum import Enum
class IssueTypeEnum(str, Enum):
MEETING = "meeting"
SUPPORT = "support"
ISSUE = "issue"
MAINTENANCE = "maintenance"
RESEARCH = "research"
REVIEW = "review"
STORY = "story"
TEST = "test"
RESOLUTION = "resolution"
TASK = "task" # legacy
class IssueStatusEnum(str, Enum):
OPEN = "open"
IN_PROGRESS = "in_progress"
RESOLVED = "resolved"
CLOSED = "closed"
BLOCKED = "blocked"
class IssuePriorityEnum(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
# Issue schemas
class IssueBase(BaseModel):
title: str
description: Optional[str] = None
issue_type: IssueTypeEnum = IssueTypeEnum.ISSUE
issue_subtype: Optional[str] = None
priority: IssuePriorityEnum = IssuePriorityEnum.MEDIUM
tags: Optional[str] = None
depends_on_id: Optional[int] = None
due_date: Optional[datetime] = None
milestone_id: Optional[int] = None
class IssueCreate(IssueBase):
project_id: int
reporter_id: int
assignee_id: Optional[int] = None
# Resolution specific
resolution_summary: Optional[str] = None
positions: Optional[str] = None
pending_matters: Optional[str] = None
class IssueUpdate(BaseModel):
title: Optional[str] = None
description: Optional[str] = None
issue_type: Optional[IssueTypeEnum] = None
issue_subtype: Optional[str] = None
status: Optional[IssueStatusEnum] = None
priority: Optional[IssuePriorityEnum] = None
assignee_id: Optional[int] = None
tags: Optional[str] = None
depends_on_id: Optional[int] = None
due_date: Optional[datetime] = None
milestone_id: Optional[int] = None
# Resolution specific
resolution_summary: Optional[str] = None
positions: Optional[str] = None
pending_matters: Optional[str] = None
class IssueResponse(IssueBase):
id: int
status: IssueStatusEnum
project_id: int
reporter_id: int
assignee_id: Optional[int]
resolution_summary: Optional[str]
positions: Optional[str]
pending_matters: Optional[str]
due_date: Optional[datetime] = None
milestone_id: Optional[int] = None
created_at: datetime
updated_at: Optional[datetime]
class Config:
from_attributes = True
# Comment schemas
class CommentBase(BaseModel):
content: str
class CommentCreate(CommentBase):
issue_id: int
author_id: int
class CommentUpdate(BaseModel):
content: Optional[str] = None
class CommentResponse(CommentBase):
id: int
issue_id: int
author_id: int
created_at: datetime
updated_at: Optional[datetime]
class Config:
from_attributes = True
# Project schemas
class ProjectBase(BaseModel):
name: str
owner_name: Optional[str] = None
description: Optional[str] = None
sub_projects: Optional[list[str]] = None
related_projects: Optional[list[str]] = None
class ProjectCreate(ProjectBase):
owner_id: int
class ProjectUpdate(BaseModel):
description: Optional[str] = None
owner_name: Optional[str] = None
sub_projects: Optional[list[str]] = None
related_projects: Optional[list[str]] = None
class ProjectResponse(BaseModel):
id: int
name: str
owner_name: Optional[str] = None
project_code: Optional[str] = None
description: Optional[str] = None
sub_projects: Optional[list[str]] = None
related_projects: Optional[list[str]] = None
owner_id: int
created_at: datetime
class _ProjectResponse_Inactive(ProjectBase):
id: int
owner_id: int
project_code: str | None = None
created_at: datetime
class Config:
from_attributes = True
# User schemas
class UserBase(BaseModel):
username: str
email: str
full_name: Optional[str] = None
class UserCreate(UserBase):
password: Optional[str] = None
is_admin: bool = False
class UserResponse(UserBase):
id: int
is_active: bool
is_admin: bool
created_at: datetime
class Config:
from_attributes = True
# Project Member schemas
class ProjectMemberBase(BaseModel):
user_id: int
role: str = "dev"
class ProjectMemberCreate(ProjectMemberBase):
pass
class ProjectMemberResponse(BaseModel):
id: int
user_id: int
project_id: int
role: str = "dev"
class Config:
from_attributes = True
# Milestone schemas
class MilestoneBase(BaseModel):
title: str
description: Optional[str] = None
due_date: Optional[datetime] = None
class MilestoneCreate(MilestoneBase):
pass
class MilestoneUpdate(BaseModel):
title: Optional[str] = None
description: Optional[str] = None
status: Optional[str] = None
due_date: Optional[datetime] = None
class MilestoneResponse(MilestoneBase):
id: int
status: str
project_id: int
created_at: datetime
updated_at: Optional[datetime] = None
class Config:
from_attributes = True
# Paginated response
from typing import Generic, TypeVar
T = TypeVar("T")
class PaginatedResponse(BaseModel, Generic[T]):
items: List[T]
total: int
page: int
page_size: int
total_pages: int