다크모드
FE 핸드오프 — 연체료 현황 페이지 + 인식기준 설정
독자: FE 메인테이너/AI. 2026-06-20 신설. 연체료 현황 콘솔 탭 + 인식기준(발생/현금) 설정 UI의 라우트·컴포넌트·데이터 흐름·확장 포인트.
1. 연체료 현황 페이지 (콘솔 탭)
- 진입: 관리비 앱 → 실제/잠정 콘솔 상단 탭 "연체료" (
ConsoleTabBarOrg, active-grouplate-fee). - 라우트 seg:
late-fee/overview—buildLineRoutes.jsCORE_VIEWS+SERVICE_CHARGE_CORE등록. 동적 도달(billingPath('late-fee/overview')), audit-route-integrity [D]=0 통과. - 탭 정의:
billingLines.jsservice-chargeconsoleTabs({ group:'late-fee', labelKey:'billing.tabs.lateFee', seg:'late-fee/overview' }). - 컴포넌트:
views/billing/_core/console/late-fee/overview/IndexView.vue(Header + Main)components/billing/_core/console/late-fee/overview/HeaderOrg.vue(page-header +ConsoleTabBarOrg active-group="late-fee")components/billing/_core/console/late-fee/overview/MainOrg.vue(요약 스트립 + 계약별 테이블)
- 데이터 흐름(읽기 전용):
useForwarding.forwardingByContract()→ 이월 연체 원금(r.forwarding)·차수(r.overdueCount)useLateFee.lateFeesFor('contract', key, ASOF)→ 발생 연체료(interestEngine).ASOF='2025-12-28'= E3 전기일(useBillingJournalPOSTING_DATE)과 동일 → GL 발생액과 정합(홍길동 72).lateFeePolicy.recognitionBasis→ 인식기준 배지.
- 차수별 드릴다운(2026-06-21 신설): 행의 계약/세대 이름 클릭(§0-10 IA —
<button>+font-medium cursor-pointer hover:underline, 테이블table-hover) →selectedref 세팅 +overlays/SheetLateFeeDetailArt.vue오픈(command="show-modal" commandfor="sheet-late-fee-detail").- 시트 props:
contract-key·name·as-of.forwardingByContract().find(key).periods(미수>0) ×lateFeesFor('contract', key, asOf).perId[${key}-${label}].fee로 차수×구성요소 미수·발생 연체료 분해(읽기전용). 구성요소는DEFAULT_COMPONENT_ORDER순 정렬, 라벨billingNature.componentLabel. 합계는 리스트 행과 동일 소스·asOf → 정합.
- 시트 props:
- 테스트:
…/late-fee/overview/__tests__/MainOrg.spec.js(발생액 72·인식기준 토글·이름클릭 드릴다운 차수/구성요소 노출). - 확장 포인트: 축 토글(계약/세대/멤버 — 현재 계약), 전표 상태 컬럼(E3 전기 여부), 페이지네이션(현재 데모 소량), 드릴다운 차수별 연체료
breakdown(구간 이율) 노출.
1-B. 충당 순서 설정 페이지 (G4, 2026-06-21)
- 위치: 관리비설정 → "충당 순서"(
/service-charge/setting/collecting). 기존 mock 페이지를 실제lateFeePolicy.collectionPolicy에 배선. - 컴포넌트:
components/service-charge/setting/collecting/MainOrg.vue— 카드1(축1 연체료우선/원금우선·법정/규약 배지) · 카드2(차수순서 periodOrder) · 카드3(적용 순서 미리보기 + 워크드 예시, 읽기전용). 편집 시트overlays/SheetUpdateCollectingPriority.vue(Select+미리보기→setCollectionPolicy({componentOrder}))·SheetUpdateOutstandingPriority.vue(→setCollectionPolicy({periodOrder})). - 소비 컴포저블:
useLateFeePolicy()(policy·setCollectionPolicy),allocationOrder(compileOrder·COMPONENT_ORDER_OPTIONS·PERIOD_ORDER_OPTIONS·periodOrderLabel·componentOrderOption·previewLines·PREVIEW_SAMPLE/PREVIEW_AMOUNT),billingNature.componentLabel. - 반영 경로:
setCollectionPolicy→policy.value.collectionPolicy교체 →CollectingActionOrg가 시트 오픈 시 reactive 정책으로periodOrder/componentOrderprefill(건별 override 유지). ⚠ 인식기준과 동일 패턴(과거 상수 읽기 무반영 → reactive 정정). - 삭제/정정:
SheetUpdateBillingAmountPriority.vue(부과액 reorder, 거짓 어포던스) 제거. 구 MainOrg의 v-for 안<DialogDeleteArt>/<SheetCreateUploadUnitArt>오삽입 버그 제거. - 테스트:
composables/__tests__/{lateFeePolicy,allocationOrder}.spec.js.
1-B-2. 단계화 + 원금 내부 순서 드래그 (2026-06-22)
오너 요청: 설정을 단계별(stepped) 로 쪼개고 순서를 드래그로. 구 "고정" 부과액 내부 순서를 정책 재량으로 전환(거짓 어포던스 → 실효 컨트롤).
- 단계 구성(MainOrg): 단계1 기본 수납 순서(축1) · 단계2 차수 순서 · 단계3 원금 내부 충당 순서(드래그·규약) · 단계4 적용순서 미리보기+워크드 예시. 각 disclosure 제목에
단계 N배지. - 드래그 컴포넌트:
components/common/SortableList.vue(v-model=[{id,label}], 네이티브 HTML5 DnD). SSOT 카피 — leysys-designpattern-app/sortable-list(ADRPATTERN-SORTABLE-LIST-REORDER-2026-06-22, kanban DnD의 "컬럼 내 정밀 재정렬" 확장). 신규 token·class 0. - 단계3 구성: 법정 고정 구간(연체료→부과액) 잠금 안내(자물쇠) +
SortableList(버킷 draft) + 푸터([기본값으로]/[저장], 저장은 dirty일 때만). 저장 →setCollectionPolicy({principalOrder: draftIds}). draft는 정책 외부 변경 시watch로 재동기화. - 소비 컴포저블:
useLateFeePolicy(policy·setCollectionPolicy({principalOrder})),billingNature(PRINCIPAL_BUCKETS·bucketLabel·componentLabel),allocationOrder(compileOrder(preset, principalBuckets)·previewLines(..., principalBuckets)). - 실효 경로: 저장 →
policy.collectionPolicy.principalOrder→ ① 단계4 미리보기·워크드 예시(즉시) ②useForwarding→deriveByComponent세구분 귀속(수납 상세) ③CollectingActionOrg실제 현금 충당. 검증: 비매출·부채를 맨 위로 드래그→저장 시 단계4가연체료 → 장기수선충당금 → 과세원금 …로 갱신(probe-settings.mjs). - 단계1 편집 시트(
SheetUpdateCollectingPriority) 미리보기도principalOrder반영(일관성). - 확장 포인트: 키보드 재정렬(접근성)·터치(MDS Pointer Events)는 ADR 후속. 단지별 정책 분기.
1-B-3. 설정 스코프 토글 — 프리셋/글로벌/로컬 (2026-06-22)
ADR decisions/SETTINGS-SCOPE-GLOBAL-LOCAL-PRESET-2026-06-22. 충당순서에 시범 적용(frozen 클래스).
- MainOrg 상단 세그먼트 토글
[이 콘솔] [글로벌 기본값](scoperef).active = scope==='global' ? globalCollectionPolicy.value : policy.collectionPolicy. 단계1~4 모든 computed가active를 읽음. - provenance 배지:
active를 부모(로컬→글로벌 / 글로벌→프리셋)와 비교 →{부모}과 같음/변경됨. - 스코프 배너: 글로벌="신규 콘솔에 적용 · 기존 콘솔(이 콘솔 포함) 불변" / 로컬="이 콘솔에만 적용". + 전체 되돌리기 버튼(
resetCollectionPolicy(scope), sameAsParent면 disabled). - 시트 스코프 인지:
SheetUpdateCollectingPriority/SheetUpdateOutstandingPriority에scopeprop —activeCP(로컬/글로벌) 기준 draft·미리보기, 저장setCollectionPolicy(partial, scope). 페이지가:scope="scope"전달. - 단계3 되돌리기: [부모로](draft만 부모 principalOrder로) + [저장](dirty 게이트,
setCollectionPolicy({principalOrder}, scope)). - 소비 컴포저블:
useLateFeePolicy(policy·globalCollectionPolicy·setCollectionPolicy(p,scope)·resetCollectionPolicy(scope)) +PRESET_COLLECTION_POLICY. - 엔진 무영향: 빌링은 로컬만 읽음. 글로벌은 신규 콘솔 시드 표면. 검증 probe(글로벌 탭→배너·provenance).
- 테스트:
lateFeePolicy.spec(규칙3·되돌리기·프리셋 동결). 기존MainOrg.spec텍스트 단언 유지.
1-C. 연체요율 설정 — 엔진 배선(목업 제거, 2026-06-22)
기존 연체료 할증 페이지(setting/surcharge)의 연체요율 표는 하드코딩 목업(13개월 12/24/36/48%) + 저장 무동작이었음. 엔진(interestEngine)은 tier 기반 rateSchedule(0/3/6개월 = 3/4/5%)이라 표시·편집이 엔진과 불일치. → 표시·편집을 policy.rateSchedule에 직접 배선.
- 표시(MainOrg):
rateScheduleRows(policy.rateSchedule)→ 구간(03개월/36개월/6개월 이상)·연%·월% tier 표. 13개월 목업 표 제거. 또 "연체료 구분(일할 단리 ÷dayCount.base)"·"계산 방식(한편/양편넣기 —dayCount.inclusion)"도 정책에서 파생(과거 "월할/양편넣기" 거짓 표기 정정). - 편집(SheetUpdateSurchargeRate): 목업 13행 →
rateScheduletier 편집기(구간 개월·연이율% 입력, 구간 추가/삭제, 첫 구간 0개월 고정). 저장setRateSchedule(rows→{fromMonths, annualRate:%/100})→ 엔진 즉시 반영. close/취소 wiring 추가(과거 no-op close). - 컴포저블:
useLateFeePolicy(setRateSchedule) +rateScheduleRows(pure, 표시·편집 공유). - 스코프: 현재 단일 정책값(로컬). rateSchedule은 effective-dated 클래스 후보(법정 요율·거래일 기준) — ADR SETTINGS-SCOPE §후속에서 시점 버전화.
- 테스트:
lateFeePolicy.spec(rateScheduleRows·setRateSchedule 검증·엔진 lateFeeOf 즉시 반영·0개월 필수·정렬중복). 검증 probe(편집→저장→메인표 반영).
2. 인식기준(발생/현금) 설정 토글
- 위치: 관리비설정 → 연체료 정책(
/service-charge/setting/surcharge) → 연체료 기본 카드 행 + 편집 시트. - 컴포넌트:
components/service-charge/setting/surcharge/MainOrg.vue(인식기준 행 표시) +overlays/SheetUpdateAccountInfoArt.vue(Select + 확인 시 커밋). - 상태:
lateFeePolicy.js싱글톤policyref +setRecognitionBasis(basis)(clone 교체 — 기본 객체 불변).useLateFeePolicy()로 소비. - 반영 경로: 토글 변경 →
policy.value교체 → (a)CollectingActionOrg의recognitionBasis = computed(() => policy.value.recognitionBasis)→JournalPreviewMol분기, (b)useBillingJournal(E3 방출 여부·E4 split) 재계산, (c) 연체료 현황 배지·문서.- ⚠️ 과거
CollectingActionOrg가DEFAULT_LATE_FEE_POLICY.recognitionBasis(상수)를 읽어 토글이 무반영이었음 → reactive로 정정(2026-06-20).
- ⚠️ 과거
- 정본 분개 규칙: BE handoff
collecting-detail.md §4.
3. 메뉴 위생 (동반 수정)
- 연체료 할증 메뉴 라벨
billing.setting.discount("할인", 의미 오류) →billing.setting.surcharge("연체료 할증")로 정정. - 충당 순서(
/service-charge/setting/collecting) — 라우트만 있고 메뉴 진입점 부재였음 → 관리비설정 그룹에billing.setting.collecting("충당 순서") 노출.