""" 權限 Schemas """ from datetime import datetime from typing import Optional from pydantic import BaseModel, Field, ConfigDict, field_validator from app.schemas.base import BaseSchema, TimestampSchema # 系統名稱常數 VALID_SYSTEMS = ["gitea", "portainer", "traefik", "keycloak"] # 存取層級常數 VALID_ACCESS_LEVELS = ["admin", "user", "readonly"] class PermissionBase(BaseSchema): """權限基礎 Schema""" system_name: str = Field(..., description="系統名稱: gitea, portainer, traefik, keycloak") access_level: str = Field("user", description="存取層級: admin, user, readonly") @field_validator('system_name') @classmethod def validate_system_name(cls, v): """驗證系統名稱""" if v.lower() not in VALID_SYSTEMS: raise ValueError(f"system_name 必須是以下之一: {', '.join(VALID_SYSTEMS)}") return v.lower() @field_validator('access_level') @classmethod def validate_access_level(cls, v): """驗證存取層級""" if v.lower() not in VALID_ACCESS_LEVELS: raise ValueError(f"access_level 必須是以下之一: {', '.join(VALID_ACCESS_LEVELS)}") return v.lower() class PermissionCreate(PermissionBase): """創建權限 Schema""" employee_id: int = Field(..., description="員工 ID") granted_by: Optional[int] = Field(None, description="授予人 ID") model_config = ConfigDict( json_schema_extra={ "example": { "employee_id": 1, "system_name": "gitea", "access_level": "user", "granted_by": 2 } } ) class PermissionUpdate(BaseSchema): """更新權限 Schema""" access_level: str = Field(..., description="存取層級: admin, user, readonly") granted_by: Optional[int] = Field(None, description="授予人 ID") @field_validator('access_level') @classmethod def validate_access_level(cls, v): """驗證存取層級""" if v.lower() not in VALID_ACCESS_LEVELS: raise ValueError(f"access_level 必須是以下之一: {', '.join(VALID_ACCESS_LEVELS)}") return v.lower() class PermissionInDB(PermissionBase): """資料庫中的權限 Schema""" id: int tenant_id: int employee_id: int granted_at: datetime granted_by: Optional[int] = None model_config = ConfigDict(from_attributes=True) class PermissionResponse(PermissionInDB): """權限響應 Schema (包含關聯資料)""" employee_name: Optional[str] = Field(None, description="員工姓名") employee_number: Optional[str] = Field(None, description="員工編號") granted_by_name: Optional[str] = Field(None, description="授予人姓名") model_config = ConfigDict( json_schema_extra={ "example": { "id": 1, "tenant_id": 1, "employee_id": 1, "system_name": "gitea", "access_level": "admin", "granted_at": "2020-01-01T00:00:00", "granted_by": 2, "employee_name": "陳保時", "employee_number": "EMP001", "granted_by_name": "管理員" } } ) class PermissionListItem(BaseSchema): """權限列表項 Schema (簡化版)""" id: int employee_id: int system_name: str access_level: str granted_at: datetime employee_name: Optional[str] = None employee_number: Optional[str] = None model_config = ConfigDict(from_attributes=True) class PermissionBatchCreate(BaseSchema): """批量創建權限 Schema""" employee_id: int = Field(..., description="員工 ID") permissions: list[PermissionBase] = Field(..., description="權限列表") granted_by: Optional[int] = Field(None, description="授予人 ID") model_config = ConfigDict( json_schema_extra={ "example": { "employee_id": 1, "permissions": [ {"system_name": "gitea", "access_level": "user"}, {"system_name": "portainer", "access_level": "readonly"} ], "granted_by": 2 } } ) class PermissionFilter(BaseSchema): """權限篩選 Schema""" employee_id: Optional[int] = Field(None, description="員工 ID") system_name: Optional[str] = Field(None, description="系統名稱") access_level: Optional[str] = Field(None, description="存取層級") @field_validator('system_name') @classmethod def validate_system_name(cls, v): """驗證系統名稱""" if v and v.lower() not in VALID_SYSTEMS: raise ValueError(f"system_name 必須是以下之一: {', '.join(VALID_SYSTEMS)}") return v.lower() if v else None @field_validator('access_level') @classmethod def validate_access_level(cls, v): """驗證存取層級""" if v and v.lower() not in VALID_ACCESS_LEVELS: raise ValueError(f"access_level 必須是以下之一: {', '.join(VALID_ACCESS_LEVELS)}") return v.lower() if v else None