백엔드: GET /v1/dashboard/summary — 회사 전체(company)+내 견적(mine) 스코프로 진행중·이번달생성·마감임박(72h)·메일미발송·동가·결렬 집계(users.company_id 조인, 읽기 전용). 프론트: /dashboard 페이지(KPI 카드 + 액션 위젯, 행 클릭→/quotation?detail= 딥링크), 사이드바·라우트 배선, 루트·로그인 리다이렉트를 /dashboard 로. orval 재생성(useGetDashboardSummary + Dashboard* 타입, QuotationData.creator_name 동기화 포함). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
48 lines
1.9 KiB
Python
48 lines
1.9 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from pydantic import Field
|
|
|
|
from common.models.gmodel import Res_WebPacketProtocol, WebPacketProtocol
|
|
|
|
|
|
class DashboardProtocol(WebPacketProtocol):
|
|
pass
|
|
|
|
|
|
class DashboardQuotationRef(WebPacketProtocol):
|
|
qt_id: uuid.UUID
|
|
name: str = ""
|
|
end_time: Optional[datetime] = None # 마감 임박 위젯에서만 채움(나머지는 None)
|
|
|
|
|
|
class DashboardActionList(WebPacketProtocol):
|
|
total: int = 0 # 전수 COUNT(최신 N개 아님)
|
|
items: list[DashboardQuotationRef] = [] # 정렬해서 상위 N개만(클릭 → /quotation?detail=qt_id)
|
|
|
|
|
|
class DashboardEmailUnsentItem(WebPacketProtocol):
|
|
qt_id: uuid.UUID
|
|
name: str = ""
|
|
unsent_count: int = 0 # 해당 견적의 미발송 세션(협력사) 수
|
|
|
|
|
|
class DashboardEmailUnsent(WebPacketProtocol):
|
|
total: int = 0 # 미발송 '협상(세션)' 전수 — 헤드라인 숫자
|
|
quotations: list[DashboardEmailUnsentItem] = [] # 견적 단위로 묶은 상위 N개
|
|
|
|
|
|
class DashboardScope(WebPacketProtocol):
|
|
in_progress: int = 0 # 진행중(마감 전) 견적 수 = status != 마감
|
|
this_month: int = 0 # 이번 달 생성 견적 수(created_at 기준)
|
|
deadline_soon: DashboardActionList = Field(default_factory=DashboardActionList)
|
|
email_unsent: DashboardEmailUnsent = Field(default_factory=DashboardEmailUnsent)
|
|
equal_bid: DashboardActionList = Field(default_factory=DashboardActionList) # 동가(수동 결정 필요)
|
|
ruptured: DashboardActionList = Field(default_factory=DashboardActionList) # 결렬(낙찰자 없이 마감)
|
|
|
|
|
|
class Res_DashboardSummary(Res_WebPacketProtocol):
|
|
company: DashboardScope = Field(default_factory=DashboardScope) # 회사 전체(company_id 스코프)
|
|
mine: DashboardScope = Field(default_factory=DashboardScope) # 내가 만든 견적(user_id 추가 스코프)
|