Files
Aislo/B01_Dashboard/B01_Dashboard_Schema.py
T
eomsangdonandClaude Opus 5 2adb5507a4 feat(B01,B02): 팀원 등록 방식 교체·사용자 삭제/비활성화·B02 등록 화면 정비
B01
- 팀원 등록을 계정 대리 생성에서 「소속 없는 기존 가입자 검색·선택」으로 교체, 미가입자는 안내 메일만 발송
- 사용자 계정 삭제 API 신설, 삭제 모달에서 회사 제외/계정 삭제 선택, 관리자 수정 모달에 활성·비활성 상태 지정
- 기본정보 폼과 사용자 수정 폼을 공용 입력칸 한 벌로 통일 (이름 > 직급 > 이메일 > 부서 > 전화)
- 프로젝트 담당자 선택의 신규 등록 항목 제거

B02
- 프로젝트명 자동 조합 (사업연도 + 사업지역 + 임도종류 + 직접 입력값) 및 미리보기 표시
- 예상 연장 입력칸 제거, 노선 종료 누가거리 제목에 구간 연장 표기, 표지 값은 프로젝트명·연장에서 파생
- 취소 버튼 추가 (대시보드 복귀), 담당자 기본값을 생성자로 지정

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 11:24:43 +09:00

93 lines
3.8 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):
# 팀원 등록은 「이미 가입한 사람을 고르는」 일이다 (2026-09-06 사용자 확정) —
# 계정을 대신 만들지 않는다. 소속이 없는 가입자만 고를 수 있다.
user_id: int = Field(gt=0)
class InviteMemberRequest(BaseModel):
"""아직 가입하지 않은 사람에게 보내는 가입 안내 메일."""
email: str = Field(min_length=3, max_length=255)
name: str | None = Field(default=None, max_length=100)
class UpdateCompanyLogoRequest(BaseModel):
# 회사 대표 로고 (company_assets.id, kind=LOGO). None 이면 지정을 지운다.
logo_asset_id: int | None = Field(default=None, gt=0)
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)
# 계획노선 사용 범위 (2026-09-04 사용자 지시) — 비우면 전 구간.
route_start_m: float | None = Field(default=None, ge=0)
route_end_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)