다크모드
계약관리 프론트엔드 핸드오프
/contract-management/contracts는 공통 Workspace AppHeaderOrg·AppAsideOrg 셸 안에서 렌더링한다. 계약관리는 별도 상품이지만 플랫폼 전환·계정·상품 메뉴 경험은 다른 Company 상품과 동일하게 유지한다.
라우트와 통합 경계
독립 route export는 src/router/contractManagementRoutes.js다.
- canonical:
/contract-management/contracts - alias:
/contract-management - view:
src/views/contract-management/IndexView.vue
이 wave는 중앙 src/router/index.js, 상품 catalog, route access, workspace navigation, i18n을 수정하지 않는다. 통합 wave에서 route array를 중앙 router에 추가하고 contract-management entitlement와 내비게이션을 연결해야 한다.
컴포넌트 트리
text
IndexView
└─ ContractManagementMainOrg
├─ 계약 목록 table
├─ Create 3xl sheet
├─ Read/Edit 3xl detail sheet
│ └─ ContractDocumentTrustMol (READ 연결 컬렉션)
├─ 상세 시트의 활성 계약 amendment/renewal form mode
├─ amendment/renewal 영향 확인 EDS dialog
└─ 상태 전이 EDS dialogContractManagementMainOrg.vue는 목록의 계약명 클릭으로 상세 시트를 연다. 별도 상세 텍스트 버튼은 없다. 상세는 관리코드를 오른쪽 위에 작게 표시하고 계약 등록번호·이름을 주요 식별 정보로 사용한다.
데이터 계층
contractManagementRepo.js: RPC args, 응답 normalization, 사용자 오류 변환useContractManagement.js: active Company/Office scope, stale response 차단, loading/error, list와 command upsertpartyDirectoryRepo.js: 현재 Office에서 선택 가능한 Party 목록
모든 mutation은 매 호출마다 request key를 만든다. caller가 같은 request key를 명시하면 서버 exact replay를 사용할 수 있다. amendment/renewal도 expectedRevision과 request key를 함께 보내며 성공 응답의 새 current version으로 선택 aggregate를 교체한다. revision conflict가 나면 최신 계약을 다시 조회하고 사용자가 변경 내용을 재확인해야 한다.
Sheet 패턴
- Create: 3xl, 단일 평면 form card, 모든 필드 펼침, footer 취소/등록
- Read: 계약 조건, 당사자, 버전 collection disclosure
- Edit: 같은 detail sheet가 전체 form mode로 전환, 모든 속성 펼침
- 저장 gate:
valid && dirty && !submitting - 편집 취소: 저장된 selected aggregate로 draft를 다시 동기화
- 관리코드: Create open 시
CT-{timestamp}제안값, 최초 등록 전 수정 가능 - 종료·취소:
window.prompt가 아닌 EDS dialog. 종료일/취소사유 validation 후 명시 확인 - 활성 계약 변경·갱신: 기존 Read/Edit 시트 안의 명시적 command에서 시작하며, 일반 초안 편집과 별도 form mode를 사용
- amendment: 적용일과 변경 사유 필수, 현재 활성 기간 밖 날짜 차단
- renewal: 기존 종료일 다음 날을 시작일로 고정하고 새 종료일·사유 필수
- 이력:
changeKind,effectiveOn,changeReason,supersedesVersionNumber를 버전 collection에 표시하고 과거 버전을 편집 대상으로 만들지 않음 - command: footer의 계약 변경/계약 갱신 → 전체 form → 변경 내용 확인 → 영향 확인 dialog → 확정. 계약 갱신은 현재 종료일이 있는 경우에만 노출
Select는 registry의 공식 Select 계열을 사용하고, 입력은 field + field-label + input input-bordered 어휘를 사용한다. 로컬 scoped CSS나 page override는 없다.
CRM query handoff
다음 query가 canonical route에 오면 Create sheet를 자동으로 열되 create RPC는 호출하지 않는다.
sourceProduct,sourceType,sourceIdsourceRegistrationNumbersourceSnapshotVersion=crm-deal-contract-draft-handoff.v1titlecounterpartyRegistrationNumber,counterpartyNamecurrency,expectedAmount,interestLine
prefill은 계약명·매출 유형·통화·예상금액·조건 요약에 적용한다. 등록번호 또는 이름이 현재 Party 목록과 일치하면 주 당사자를 선택한다. source identity와 snapshot은 Create RPC에만 전달된다. 사용자가 등록을 누르기 전에는 계약 생성 완료로 표시하면 안 된다.
활성 계약 변경·갱신 데이터 흐름
- 활성 계약 상세가 현재 revision·version과 전체 당사자 snapshot을 form draft에 복제한다.
- 사용자가 amendment/renewal을 선택하면 종류별 날짜 gate를 적용한다. renewal 시작일은 UI에서
현재 endsOn + 1일로 제안하며 서버가 정확히 다음 날인지 다시 검증한다. - repo가
amend_contract_management_contract또는renew_contract_management_contract에 전체 새 조건·당사자, 적용일, 사유,expectedRevision, request key를 전달한다. - 성공하면 composable이 목록 aggregate와 열린 상세를 응답의 새 불변 버전으로 upsert한다. 이전 버전은 collection에 남긴다.
- Office가 바뀌거나 더 최신 command/load가 끝났다면 오래된 응답을 폐기한다.
판매·매출채권 연결은 화면 내부 store 공유나 hard FK가 아니다. 변경된 계약 version snapshot을 후속 판매·청구계획 입력으로 전달하는 optional adapter 경계만 유지한다. 판매 상품이 없거나 권한이 없어도 계약 amendment/renewal 성공을 되돌리지 않는다.
확장 포인트
- 계약 version→판매·매출채권 청구계획 adapter
- CRM 결과 회신 adapter
- Party 검색/신규 등록 nested flow
- query handoff consumed 표시와 안전한 URL 정리
- 서버 pagination과 상태/유형 filter
다른 상품은 optional adapter로만 연결한다. Contract Management UI와 repo는 Billing·CRM·임대차관리 모듈이 없어도 동작해야 한다.
계약 문서·증명 연결은 docs/handoff/frontend/contract-document-trust.md를 따른다. 계약 편집 commit과 문서 생성 요청을 결합하지 않으며, 현재 불변 버전마다 별도 request를 만든다.
테스트
contractManagementRepo.spec.js: normalization, RPC payload, error mappinguseContractManagement.spec.js: scope, explicit create, amendment/renewal command, stale responsecontractManagementMigration.spec.js: ownership, RLS/RPC/outbox, hard dependency 금지ContractDocumentTrustUi.spec.js: 기존 상세 시트의 계약 변경·갱신 form, 영향 확인 dialog와 version history 표시
중앙 router 통합 후에는 route access와 query handoff component test를 추가하는 것이 권장된다.