다크모드
BE/FE 참고 — 빌링 데모 시드 팩토리 (A안 단지 규모 스케일업)
정본 코드:
src/composables/demoSeed.js. 캐리오버:docs/SESSION-CARRYOVER-2026-06-21-PM.md(A안). 배경: 구 데모는 수작업 2계약(홍길동·김철수)이라 결산이 가짜 배수(HOUSEHOLD_SCALE=11000)로 단지처럼 보였다. A안 = 빌링 데모 자체를 단지 규모로 재시드 → 전 화면(리스트·연체료·수납·결산) 일관 + 배수 제거 + 결산 실적 자연발생.
단일 팩토리 buildSeed(config)
빌링 데모 전체(부과항목·차원·배분라인·이월·수납시드)를 한 곳에서 결정적으로 방출. useCharges/useAllocations/useForwarding/useReceipts가 모듈 로드 시 1회 소비(상수 바인딩 — computed 안 호출 금지).
scale 노브 DEMO_CONFIG(단일 진실원):
householdCount: 300 // 세대수
monthlyChargePerUnit: 150000 // 세대당 월 관리비(현실값)
chargeMix: { 일반관리비:.55(과세), 수도료:.25(면세), 장기수선충당금:.20 } // 합=1
overdueEvery: 5 // 코호트 N번째마다 1개월 이월(집계 연체료 스케일)
meta: { currentLabel:'2025-12', currentDue:'2026-01-31', postingDate:'2025-12-28' }- 부과항목 풀:
baseChargePrincipal = monthlyChargePerUnit × householdCount × share. 배분 공식(allocate)이 풀을 전 라인 가중치로 분배 → 세대당 현실 금액 자연 산출. (monthlyChargePerUnit=0이면 레거시 11k/5k/4k — byte-equivalent 모드.)
두 구획
- 구획 A — 명명예시(앞 K=2): 홍길동(c-hong, taxProfiles 2·101/102, 2개월 이월 고정 리터럴)·김철수(c-kim, 개시선수금·미식별입금). 교육 시나리오 보존. 이월(prior)은 scale 무관 고정(특정 입주민 과거 연체 스토리). 단, 당기(current)는 공유 풀이라 스케일됨 → 홍길동 총미수도 단지 규모로 변동(구 36,625 → 스케일값).
- 구획 B — 동질 코호트(N−K):
c-gen-####(유닛 1003~1300, 충돌 회피). 단일유닛·전월점유.overdueEvery마다 1개월 이월 → 집계 연체료가 단지 규모로 스케일.
수납 시드(영수증) — 데모 수납/연체 시연 (2026-06-28)
빈약하던 영수증 시드(명명 3건)를 코호트 전반으로 보강 → 수납/연체/마지막수납일 화면이 실데이터로 산다.
receiptSeeds형태:{ kind:'receipt'|'advance', contractCode, memberCode, method, receivedAt, identified, amount?, payFraction? }.amount명시 = 고정 입금액(명명예시·미식별).payFraction= 그 계약 미수총액(forwardingtotal) × 비율을 부트스트랩 시 해석(seedDemoReceipts). 하드코딩 금액 회피 → householdCount·요율 변경에도 완납/부분/선수금 정확(_seedExpect파생 철학과 정합).
- 코호트 아키타입(
cohortReceiptFraction(idx)=idx % 4):1.0완납 ·0.6부분수납 ·1.15선수금(초과납→잔여 선수금 적립). 연체(이월 보유=overdueEvery) 세대는 수납 시드 미부여 → 미납 유지(연체/독촉 triage가 살아있게). N=15 비연체 10세대 분포 = 완납5·부분2·선수금3, 연체 3세대(미납). - 수단·입금일 분산:
COHORT_RECEIPT_METHODS(계좌이체/가상계좌/자동이체/현금/신용카드 순환) ·COHORT_RECEIPT_DATES(2025-12~2026-06 12개 분산) → 마지막수납일 컬럼이 실감나게 퍼짐. - 미식별(가수금) 2건(
identified:false) → suspense 풀(0257) 시연. - ⚠ 회귀 안전(핵심):
seedDemoReceipts()는 앱 부트스트랩(main.js)에서만 호출·어떤 테스트도 호출 안 함(의도된 GL 격리). 따라서receiptSeeds를 늘려도_seedExpect·회계/GL·forwarding 테스트는 영향 0(빈collected에서 파생). 시드 단위·차원·이월·부과풀은 무변경 → 686 vitest 회귀 0 실증.
성능 (단지 규모 N² 방지) — 필수
소수 계약 가정으로 짠 .find/filter/매호출 재빌드가 300계약에서 O(N²) 폭주(풀스위트 분 단위·useClosing 92s). 정정:
useAllocations: 차원 룩업 = Map(unitMap/memberMap), 라인 그룹 = Map(linesByContract/Unit/Member/Charge). 청구 집계(invoicingByContract/Unit/Member)·세금계산서·allocate모두 Map 소비.- 빌더 메모이즈:
_invByContract/Unit/Member(useAllocations)·_fwdContract/Unit/Member(useForwarding)를 모듈레벨 computed로. 함수 시그니처(invoicingByContract())는 유지(return _computed.value) → 호출부 무변경.lateFeesFor/저널이 계약별로 반복 호출해도 캐시 반환. charges/lines/collected/adjusted 변경 시 Vue가 자동 무효화. - 결과: 300계약 풀스위트 92s → 4.0s(베이스라인 수준).
- ⚠ 신규 빌더/집계 추가 시 "매호출 전체 재빌드" 금지 — Map·메모이즈 패턴 준수.
결산 연환산 (HOUSEHOLD_SCALE 제거)
useBudgetActuals: 구 HOUSEHOLD_SCALE(가짜 배수) 삭제. 빌링은 대표 1개월 모델, 예산/결산은 연간 → settlementActuals = 월 집계 × MONTHS_PER_YEAR(12). 12 = 정직한 개월수(배수 아님). 검증: 관리비수익 결산 432M(=월 36M×12) vs 예산 480M = 집행률 90%.
테스트 (seed-derived)
절대 숫자 어서션은 src/composables/__tests__/_seedExpect.js 도메인 파생으로(매출·미수·부채·연체료·이월·forwardingTotal). 스케일(householdCount) 변경에 자동 적응. 명명예시 이월(고정)만 seed.priorPeriods 파생. 시각: scripts/probe-scale.mjs(리스트 행수·결산 실적).
세출 비용 GL 직접집계 (2026-06-21 추가)
demoSeed.js EXPENSE_SEEDS: 단지 월 비용 대표 6과목(예산 세출 말단budgetName↔ CORE 비용계정accountCode1:1 — 급여→0802·식대등복리후생비→0811·수선유지비→0820·위탁관리수수료→0831·경비비→0837·차량유지비→0822). 각 monthly ×12 ≈ 예산액(~100% 집행).useBillingJournal.vouchersExpense(): DR 비용계정 / CR 미지급금(0253) 단일 전표 →billingVouchers합류 → 전기 시 IS 판매/관리(sga) 섹션 자동집계. 영업이익 = 매출 − 판매/관리비.useBudgetActuals.settlementActuals.expense: 장기수선비 + EXPENSE_SEEDS 각 ×12 → 결산 세출 "실적"(동일 시드라 IS와 정합).- 정합 게이트:
__tests__/settlementIsReconciliation.spec.js— IS sga(월) =totalExpense()(EXPENSE_SEEDS 합) · 결산 세출 실적 = IS sga ×12 · 미지급금(0253) 대변 = 비용 차변 합. 매직넘버 없이 두 경로 일치(scale 무관). - BS 영향: DR 비용/CR 미지급금 → 자산 불변, 부채 +미지급금, 자본(당기순이익) −비용.
_seedExpect: expectedNetIncome = 매출−비용+연체료 / expectedLiabilities += 미지급금 / expectedOperatingIncome = 매출−비용.
잔여(후속)
- 세출 전 과목 매핑(현재 대표 6과목 — 나머지 예산 세출 과목은 demoSettlement). + 운영성과표(서식2) 정합.
- manual/collecting-cases 등 사용자 문서의 예시 숫자(구 36,625·15,825·10,400) + 스크린샷은 단지 규모로 미갱신 — 명명예시 당기값이 스케일돼 stale. 스크린샷 재생성과 함께 일괄 갱신 필요.
- 환산 정밀화: 연체료 backlog ×12는 근사(스톡을 플로우로 연환산) — 필요 시 분리.