- 판 = resources/master_template/calc_sites.json(기본값 = 등록부 자리 그대로 · 전부 both) - common_util_calc_sites — 묶음 8 줄(등록부 45 #) · 읽기 · 검사(잠금 · 모르는 줄 · 값 = 400) · 통째 쓰기 - GET /api/dashboard/calc-sites(로그인) · PUT /api/dashboard/admin/calc-sites(시스템 관리자) · 바뀐 줄마다 CALC_SITE_CHANGE 시스템 로그 - 대시보드 시스템 설정 「계산 자리」 카드(시스템 관리자만 · ☰ 엔 없음) · 체크 창(칸 둘 · 잠긴 줄 까닭 · 지금 서버 N 줄 · 다음 열기부터) - design_calc_sites — B05 · B06 열 때 한 번 받음 · G1 server = ground 단계 안에서만 서버 표본(cross 격자 그대로) · D3 server = 워커 안 띄움 - 시험 test_309_2_calc_sites 새 · test_b01_settings_cards · test_225_drawer_shortcuts 덧 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
112 lines
4.7 KiB
Python
112 lines
4.7 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 UiPrefsRequest(BaseModel):
|
|
"""화면 취향 묶음 — 배치·표시 값만. 키는 브라우저 등록표(`b_page_state.ts`)가 정본이다.
|
|
|
|
값은 문자열 하나(높이는 `"438"`, 접힘은 `"true"`)라 저장소에 넣던 모양 그대로다.
|
|
설계값이 섞여 들어오지 않게 **문자열만** 받는다.
|
|
"""
|
|
|
|
prefs: dict[str, str] = Field(default_factory=dict)
|
|
|
|
|
|
class CalcSitesRequest(BaseModel):
|
|
"""계산 자리 판 고침(504-2) — 바꿀 줄만 · 줄 · 값 검사는 `common_util_calc_sites`."""
|
|
|
|
sites: dict[str, str] = Field(default_factory=dict)
|
|
|
|
|
|
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)
|
|
# 참여자 (2026-09-06 사용자 확정) — 도면 표제란 3역할과 별개로, 설계에 손대는 사람들.
|
|
# 참여자면 일반 사용자도 그 프로젝트를 수정할 수 있다. 비우면 지금 값을 그대로 둔다.
|
|
member_user_ids: list[int] | None = Field(default=None)
|
|
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)
|