Skip to content

관리비(service-charge) IA 맵 — 메뉴·탭·페이지 구조 (as-built)

독자: FE 메인테이너/AI + BE 참고. service-charge 도메인의 메뉴·콘솔탭·드릴다운·에디션 구조를 한눈에. SSOT: src/composables/billingLines.js(디스크립터: sidebar·consoleTabs·editions) + src/router/buildLineRoutes.js(매니페스트: seg→뷰). 라우트 무결성 scripts/audit-route-integrity.mjs. 라벨은 src/i18n/locales/ko.json billing.*. 2026-06-27 기준(데모 리워크 반영: 에디션 라벨 SSOT 통일·initial-data/group 삭제·조정 데드시트 제거).

실제 제품 leyve-admin-frontend v3-style과의 순차 대조는 사람 검수 가이드에서 페이지별 상태를 관리한다. AI 에이전트는 구현·재검수 전에 AI 검수 계약을 따른다.

A. 사이드바 — 개요 + 업무 + 설정

개요                  → /service-charge/overview

관리비
├─ 정기 관리비          → /service-charge/actual          ◆ 에디션: 확정 관리비
└─ 중간정산             → /service-charge/provisional      ◆ 독립 단건 초안·확정

검침                  → /service-charge/metering/general

설정
├─ 기본 설정            → /service-charge/setting/general
├─ 부과 항목            → /service-charge/setting/item/general
├─ 개시 미수금          → /service-charge/setting/initial-data/general
├─ 수납 충당 규칙       → /service-charge/setting/collecting
├─ 연체료 정책          → /service-charge/setting/surcharge
└─ 회계 연결            → /service-charge/setting/account/general

정의: billingLines.js sidebar[]. 렌더: components/billing/_core/shell/LineAsideOrg.vue.

B. 정기 관리비 콘솔 — 11개 route unit + 5개 탐색 범위

정기 관리비 → 회차 리스트 → [콘솔] 진입. 11개 route unit은 유지하되 한 줄에 모두 노출하지 않는다. 1단에서 업무 범위를 선택하고 2단에서 해당 범위의 세부 탭을 선택한다. 중간정산은 이 콘솔을 사용하지 않는다.

상위 범위세부 탭seg게이팅
개요개요general
부과·조정부과charging/assessment
부과·조정조정pre-adjustment-viewactual, planned
청구·고지청구invoicing/contract
청구·고지공지notice/generalfeature=notice
청구·고지세금계산서tax-invoice
수납·미수수납collecting/contract
수납·미수이월forwarding/brought-forwardfeature=forwarding
수납·미수연체료late-fee/overview
수납·미수선수금·가수금advance-receiptfeature=advanceReceipt
보고서보고서report/summary-tablefeature=reports

정의: billingLines.js consoleTabs[]. 공유 콘솔(invoicing/collecting/late-fee/forwarding/tax-invoice/account/advance-receipt)은 actual과 다른 billing line이 사용한다. provisional은 공유 _core route/component를 소비하지 않는다.

C. 드릴다운 — 세대 계정 허브

수납 리스트 행 ↗  →  /service-charge/actual/console/account/:unitKey?tab=
   세대 × 기간 6탭(읽기): 부과 · 청구 · 정산 · 연체 · 이월 · 조정

views/billing/_core/console/account/. 진입=수납 유닛 리스트 행 우측 ↗.

D. 정기 관리비와 중간정산 제품 경계

정기 관리비 (actual)중간정산 (provisional)
진입/service-charge/actual 회차 → console/service-charge/provisional 단일 목록
대상월별 유닛·계약·멤버 3축platform core 프로퍼티 공간 1건
흐름부과→청구→수납→이월초안→확정 또는 취소
Fact부과 confirmation + 청구 versionprovisional settlement confirmation
다른 상품선택 deliveryopaque source 문자열 + generic event

legacy /service-charge/provisional/console/**는 root로 redirect한다. actual route와 Fact는 변경하지 않는다.

E. 라인레벨(에디션 무관) 라우트

setting/{general,surcharge,collecting,account/general,item/{general,group},initial-data/general}, metering/general. buildLineRoutes.js lineLevel{}. actual/provisional 공유. account/general은 관리비 소유 연결 안내 페이지이며 재무회계 신청 시에만 회계 계정과목 라우트로 이동한다.

F. 구현 상태 (데모 관점)

  • 실배선: 수납·연체료·이월표시·예산/결산·정책설정(충당순서·연체료할증)·계정 허브·회계(GL/재무제표)·단계 진행·부과 시작/확정 게이트.
  • 첫 부과 0원 UX: useFirstChargeReadiness.chargeAmountsReady가 0원이면 DialogChargeAmountRequiredArt를 modal로 열어 본문 레이아웃을 차지하지 않는다. 직접 입력은 Dialog를 닫고 DynamicTableOrg.focusFirstChargeInput()으로 현재 breakpoint의 첫 부과원금 입력에 포커스하며, 회계 비용 가져오기는 기존 DialogImportChargeExpensesArt로 전환한다. useChargingCommit은 부과원금 0원과 미배분 잔액을 각각 hard-stop한다.
  • actual 불변 부과 확정: actual 배분 3축의 [확정]buildChargingConfirmationSnapshot()으로 service-charge-calculation.v1 snapshot을 만들고 serviceChargeConfirmationRepo.confirmCharging()을 호출한다. 브라우저에서 회계·전자문서 store를 직접 호출하지 않는다.
  • provisional 독립 workflow: root에서 실제 목록→create sheet→선택 row read/edit sheet→명시 confirm dialog→immutable Fact가 동작한다. operator-owned 계산 항목과 실제 단가만 사용하며 mock 월행·단가·공간을 자동 생성하지 않는다.
  • actual 불변 청구 확정: actual 청구 3축 ActionBar는 useInvoicingCommit으로 최신 부과 확정본을 읽고 serviceChargeInvoiceSnapshot의 계약별 공급가액·부가세·합계를 service_charge_invoice_versions에 append한다. supplyAmountinvoicingByContract.currentPeriod이며 전체 합은 부과 확정 totals.allocated와 같아야 한다. 확정본 버전을 표시하고 재오픈 후 재확정하면 다음 버전을 생성한다.
  • 단일 RPC·상태 동기화: Supabase 경로는 부과·청구 각각 confirm_service_charge_facts 한 번만 호출한다. 성공 응답의 workflow statuses/versionuseConsoleStage에 반영하고, 응답이 불명확하면 scope를 다시 읽어 이미 확정된 상태와 조정한다.
  • 회계 비용 가져오기: DialogImportChargeExpensesArt가 전기 완료 비용계정만 표시하고 사용자가 부과항목을 연결한다. 가져온 값은 발생·부과 기본 원금에 함께 반영하며 분개는 만들지 않는다.
  • 서버 편집 스냅샷: authSession이 로그인 세션 확인 시 hydrateChargeSnapshots()를 기다린다. useCharges는 실 Office·정산회차·edition별 service_charge_snapshots를 서버 우선으로 복구하고, 350ms scope별 debounce upsert한다. leyve.billing.charges.v1도 3축 키를 쓰며 기존 2축 값은 actual로 승격한다. actual 확정 직전에는 이 debounce를 즉시 flush·await한다.
  • actual 중간저장 상태·재시도: 배분 unit/contract/member ActionBar가 공통 ChargeDraftSaveMol을 소비한다. useChargesidle|pending|saving|saved|error 상태를 변경 없음·중간저장 대기·중간저장 중…·서버에 중간저장됨·중간저장 실패로 표시하고, pending/error에서 명시 저장 또는 재시도를 제공한다. 실패 snapshot은 재시도까지 유지하며 로컬 fallback은 이 기기에 임시 저장됨으로 정직하게 구분한다. 무동작 more_vert는 세 ActionBar에서 제거했다.
  • 확정 후 잠금: useConsoleStage().statusOf('charging')confirmed이면 부과산정의 모바일·데스크톱 금액 입력을 readonly로 만들고 회계 비용 가져오기·직접 입력을 disabled 처리한다. 이미 열린 가져오기 dialog도 submit 함수와 버튼에서 다시 hard-stop한다. 화면은 상단 부과 단계의 이전 재오픈 경로를 안내하며, 서버 trigger도 exact Office·정산회차·edition snapshot mutation을 거부한다.
  • ⚠️ 부분 구현: 관리비 화면의 delivery 건별 상태 표시는 후속이다. actual 중간저장과 부과·청구 및 provisional 확정 Fact는 서버에 배선됐다.
  • 🚧 미노출 WIP: pre/post-adjustment(조정) — 라우트만, 메뉴 미링크.

Wave 11 확정 경계

관리비 부과 확정의 서버 정본은 service_charge_charging_confirmations다. useChargingCommit은 화면 computed를 다른 상품에 보내지 않고 versioned snapshot을 구성해 confirm_service_charge_facts 하나만 호출한다. 성공 응답 뒤 stage를 갱신하며 연결 상품 delivery 실패를 확정 실패로 번역하지 않는다.

동일 화면 payload의 재시도 동안 pendingEnvelope가 request key를 유지한다. payload가 바뀌면 새 envelope를 만들고, 서버는 expected revision과 full payload를 다시 검증한다. 회계·전자문서 delivery 상태는 관리비 확정 결과와 분리된 read seam으로 표시해야 하나 현재 UI에는 아직 없다.

Wave 16 청구 확정 경계

useInvoicingCommit은 actual service-charge에서만 동작한다. serviceChargeConfirmationRepo.loadLatestCharging()으로 부과 원본을 읽고, useAllocations().invoicingByContract()의 계약별 currentPeriod를 공급가액으로 고정한다. buildServiceChargeInvoiceSnapshot()은 부과 totals.allocated와 공급가액 합을 비교하고 불일치 시 RPC 전에 중단한다. VAT는 과세원금에서 별도 계산하므로 totalAmount = supplyAmount + taxAmount다.

FE 검사는 빠른 피드백일 뿐 권위 불변식이 아니다. 20260718161000_enforce_service_charge_invoice_charging_total.sqlBEFORE INSERT trigger가 linked charging Fact의 totals.allocated와 invoice totals.supplyAmount를 다시 exact 비교한다. 우회 호출도 service_charge_invoice_charging_total_mismatch로 거부되며, useInvoicingCommit은 이를 부과 확정본과 청구 공급가액 불일치 오류로 안내한다.

ActionBar 3축은 같은 commit composable을 소비하고, 다른 billing line/edition에서는 기존 useConsoleStage.confirm('invoicing')를 유지한다. 확정 후 latestInvoiceVersion을 badge로 표시한다. 하류 수납이 시작되지 않았으면 공유 StageWidget의 이전이 서버 reopen을 수행하고, 다시 확정할 때 기존 Fact를 수정하지 않고 새 버전을 만든다. 버전 목록 read 실패는 확정 RPC 성공을 실패로 번역하지 않는다.

Wave 12~13 상품 UI 경계

관리비는 재무회계·전자세금계산서·CRM UI 없이 독립 렌더링한다.

  • src/components/service-chargesrc/views/service-charge에서 @/components/{accounting,tax-invoice,crm} 직접 import는 0이다.
  • config/product-boundaries.json에서 service-charge→accounting|tax-invoice|crm baseline 예외를 제거했다. 새 직접 경계는 감사 실패다.
  • setting/account/general/MainOrg.vueuseModuleSubscription().accountingEnabled만 읽는다. 신청 상태면 회계 계정과목 라우트로 이동하고, 미신청이면 재무회계 미신청 버튼을 disabled 처리한다. 회계 UI 컴포넌트를 embed하지 않는다.
  • 전자문서와 CRM 미신청은 관리비 화면의 기초자료·부과·청구·수납·이월을 막지 않는다. 선택 delivery는 서버 경계에서만 처리한다.

Wave 13에서 기존 유닛 업로드 연결을 실제 렌더 기준으로 재감사했다. 공용 raw-file 시트에는 upload 소비자가 없었고, 정기 관리비 일반 화면의 mount는 트리거가 렌더되지 않았으며 중간정산의 지난공지가 유닛 시트를 잘못 열고 있었다. 이 세 루트 계약은 폐기했다.

  • service-charge/_shared/SheetCreateUploadUnitArt.vue와 모든 관리비 mount를 제거했다.
  • 부과산정의 기존 업로드유닛 관리로 바뀌어 /administration/organization/workspace/property/console/unit으로 이동한다.
  • 공지의 지난공지·삭제·다운로드·추가는 구현 전까지 disabled 처리하고 죽은 commandfor를 제거했다.
  • scripts/service-charge-product-boundary.spec.js는 관리비 상품 안의 유닛 업로드 wrapper/mount/trigger가 0인지 고정한다.
  • 실제 CSV parser·preview·persist는 플랫폼 코어의 프로퍼티 유닛 페이지가 소유하고 관리비 import composable만 호출한다. 세부 계약은 프로퍼티 유닛 CSV 가져오기를 따른다.

G. 알려진 구조 부채

  • 콘솔 헤더·탭바 통일(P-STRUCT-1, 완료): 관리비 콘솔의 모든 라우트 어댑터는 BillingConsolePageHeaderOrg를 사용한다. 공용 헤더가 ConsoleTabBarOrgStageWidgetOrg를 소유하며, 선택적 뒤로가기·제목/Workspace 컨텍스트·선택적 액션/펼침 제어를 leading / headline / action 3영역으로 분리한다. leadingaction은 존재할 때만 고정되고, 없는 화면은 빈 영역을 만들지 않는다. 라우트별 탭 하드코딩과 자리 채움용 more_horiz 액션은 금지한다.
  • 정본 감사: docs/AUDIT-SERVICE-CHARGE-DEMO-READINESS-2026-06-27.md.