"""B03 파일 입력 요청·응답 검증 모델.""" from pathlib import PurePath from typing import Any from pydantic import BaseModel, ConfigDict, Field, model_validator from config.config_system import UPLOAD_ALLOWED_EXT, UPLOAD_MAX_MB class FileUploadDescriptor(BaseModel): """업로드 전에 검증할 단일 파일의 이름과 크기.""" model_config = ConfigDict(extra="forbid", str_strip_whitespace=True) original_filename: str = Field(min_length=1, max_length=255) size_bytes: int = Field(gt=0) @model_validator(mode="after") def validate_file(self) -> "FileUploadDescriptor": filename = self.original_filename if PurePath(filename).name != filename or "/" in filename or "\\" in filename: raise ValueError("파일명에는 경로가 포함될 수 없습니다.") extension = PurePath(filename).suffix.lower() if extension not in UPLOAD_ALLOWED_EXT: allowed = ", ".join(UPLOAD_ALLOWED_EXT) raise ValueError(f"허용되지 않은 파일 확장자입니다. 허용 형식: {allowed}") maximum_bytes = UPLOAD_MAX_MB * 1024 * 1024 if self.size_bytes > maximum_bytes: raise ValueError(f"파일 크기는 {UPLOAD_MAX_MB}MB를 초과할 수 없습니다.") return self class UploadedFileResult(BaseModel): """저장 완료된 단일 입력 파일 정보.""" input_file_id: int original_filename: str file_type: str relative_path: str size_bytes: int metadata: dict[str, Any] class FileUploadResponse(BaseModel): """B03 다중 파일 업로드 성공 응답.""" status: str = "success" project_id: str files: list[UploadedFileResult]