Files
2026-01-11 08:37:21 +08:00

76 lines
2.2 KiB
Python

from pydantic import BaseModel, Field, computed_field, model_validator
from typing import Optional
from datetime import datetime, date
from decimal import Decimal
from enum import Enum
class SecurityLevel(str, Enum):
PUBLIC = "public"
DEPARTMENT = "department"
CONFIDENTIAL = "confidential"
class ProjectBase(BaseModel):
title: str = Field(..., min_length=1, max_length=500)
description: Optional[str] = Field(None, max_length=10000)
budget: Optional[Decimal] = Field(None, ge=0, le=99999999999)
start_date: Optional[date] = None
end_date: Optional[date] = None
security_level: SecurityLevel = SecurityLevel.DEPARTMENT
@model_validator(mode="before")
@classmethod
def apply_name_alias(cls, values):
if isinstance(values, dict) and not values.get("title") and values.get("name"):
values["title"] = values["name"]
return values
@computed_field
@property
def name(self) -> str:
return self.title
class ProjectCreate(ProjectBase):
department_id: Optional[str] = None
template_id: Optional[str] = None
class ProjectUpdate(BaseModel):
title: Optional[str] = Field(None, min_length=1, max_length=500)
description: Optional[str] = Field(None, max_length=10000)
budget: Optional[Decimal] = Field(None, ge=0, le=99999999999)
start_date: Optional[date] = None
end_date: Optional[date] = None
security_level: Optional[SecurityLevel] = None
status: Optional[str] = Field(None, max_length=50)
department_id: Optional[str] = None
@model_validator(mode="before")
@classmethod
def apply_name_alias(cls, values):
if isinstance(values, dict) and not values.get("title") and values.get("name"):
values["title"] = values["name"]
return values
class ProjectResponse(ProjectBase):
id: str
space_id: str
owner_id: str
status: str
department_id: Optional[str] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class ProjectWithDetails(ProjectResponse):
owner_name: Optional[str] = None
space_name: Optional[str] = None
department_name: Optional[str] = None
task_count: int = 0