- B01 프로젝트 수정: 과업책임자·분야별책임자·설계자를 회사 구성원 목록(select)에서 지정. 회사 로고·설계자 서명 칸은 누르면 등록 목록 모달(선택·삭제·신규 추가 업로드). - 백엔드: `company_assets`(013) CRUD 라우트 신설 — 목록·업로드(Form+File, 2MB·확장자 검사)·수정·소프트 삭제·파일 서빙. `_scope_company` 로 SYSTEM_ADMIN 만 타 회사 지정, `_check_project_refs` 로 담당자·자산이 같은 회사·같은 종류인지 검사(400). - projects 조회·수정에 pm/field_lead/designer/logo_asset/signature_asset 5칸 합류. 중복 3곳을 `_project_rows` 로 묶어 700줄 제한 유지. - B07 표제란: 로고·서명 출처를 `companies.logo_path`/`users.signature_path` 에서 프로젝트가 고른 `company_assets` 로 전환(삭제된 자산은 그림째 제외). - 검증: pytest 143 통과(신규 4), tsc·ruff·prettier 통과. 공용 브라우저 사용자 경로 (업로드→선택→저장→재열기) 및 종단도 API 표제란 글자 4건·그림 2건 수치 확인. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
76 lines
3.0 KiB
Python
76 lines
3.0 KiB
Python
"""B01_Dashboard 요청 스키마."""
|
|
|
|
from datetime import date
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class UpdateUserRequest(BaseModel):
|
|
name: str = Field(min_length=1, max_length=100)
|
|
position: str | None = Field(default=None, max_length=100)
|
|
department: str | None = Field(default=None, max_length=100)
|
|
phone: str | None = Field(default=None, max_length=50)
|
|
|
|
|
|
class CreateCompanyRequest(BaseModel):
|
|
name: str = Field(min_length=1, max_length=255)
|
|
business_registration_number: str = Field(min_length=1, max_length=20)
|
|
business_address: str | None = Field(default=None, max_length=500)
|
|
business_owner: str | None = Field(default=None, max_length=100)
|
|
|
|
|
|
class JoinCompanyRequest(BaseModel):
|
|
company_id: int = Field(gt=0)
|
|
|
|
|
|
class AddMemberRequest(BaseModel):
|
|
email: str = Field(min_length=3, max_length=255)
|
|
|
|
|
|
class ProcessJoinRequest(BaseModel):
|
|
action: str = Field(pattern="^(APPROVE|REJECT)$")
|
|
reason: str | None = Field(default=None, max_length=500)
|
|
|
|
|
|
class ChangeUserRoleRequest(BaseModel):
|
|
role: str = Field(pattern="^(SYSTEM_ADMIN|ADMIN|USER)$")
|
|
|
|
|
|
class AssignCompanyRequest(BaseModel):
|
|
company_id: int | None = Field(default=None, gt=0)
|
|
|
|
|
|
class UpdateProjectRequest(BaseModel):
|
|
name: str = Field(min_length=1, max_length=255)
|
|
region: str | None = Field(default=None, max_length=100)
|
|
road_type: str | None = Field(default=None, max_length=100)
|
|
project_year: int | None = Field(default=None, ge=1900, le=2100)
|
|
estimated_length_m: float | None = Field(default=None, ge=0)
|
|
memo: str | None = Field(default=None, max_length=5000)
|
|
status: str | None = Field(default=None, max_length=50)
|
|
# 도면 표제란·표지에 실리는 값 (2026-09-02). 프로그램이 지어낼 수 없어 사람이 넣는다.
|
|
client_org: str | None = Field(default=None, max_length=255)
|
|
project_number: str | None = Field(default=None, max_length=100)
|
|
work_amount: str | None = Field(default=None, max_length=100)
|
|
# 설계일자는 확정일 자동이 아니라 사용자 지정이다 (2026-09-02 사용자 확정).
|
|
design_date: date | None = None
|
|
# 담당자는 회사 구성원(users) 중에서, 로고·서명은 회사 공유 자산(company_assets) 중에서
|
|
# 고른다 — 같은 회사 것인지는 라우터가 확인한다.
|
|
pm_user_id: int | None = Field(default=None, gt=0)
|
|
field_lead_user_id: int | None = Field(default=None, gt=0)
|
|
designer_user_id: int | None = Field(default=None, gt=0)
|
|
logo_asset_id: int | None = Field(default=None, gt=0)
|
|
signature_asset_id: int | None = Field(default=None, gt=0)
|
|
|
|
|
|
class AdminUpdateUserRequest(UpdateUserRequest):
|
|
status: str | None = Field(
|
|
default=None, pattern="^(NO_COMPANY|PENDING|ACTIVE|INACTIVE|REJECTED)$"
|
|
)
|
|
|
|
|
|
class UpdateCompanyAssetRequest(BaseModel):
|
|
label: str = Field(min_length=1, max_length=100)
|
|
# 사용자 계정에 물릴 수도(개인 서명) 아닐 수도(회사 공용 직인) 있다.
|
|
user_id: int | None = Field(default=None, gt=0)
|