다크모드
FE 핸드오프 — 세입세출 예산 페이지 (Phase 1)
독자: FE 메인테이너/AI. 2026-06-21 신설. 공동주택 회계처리기준 서식 4(세입예산서)·6(세출예산서) 비교 페이지. 라우트·컴포넌트·데이터 흐름·확장 포인트.
1. 진입 / 라우트
- 진입: 회계 앱 → 사이드바 결산 재무제표 그룹 → "예산/결산"(
AppSideNavMenuOrg.vue, 이익잉여금처분 다음). 메뉴 라벨accounting.nav.budget("예산/결산"). - 라우트:
/accounting/accounting-mgmt/financial-accounting/financial-statement/budget/general—src/router/index.js정적 child(/accounting/app-view하위, balance-sheet/standard 다음). audit-route-integrity [A]=0·[D]=0 통과(메뉴에서 참조).
2. 컴포넌트 트리
views/accounting/.../financial-statement/budget/general/IndexView.vue(HeaderOrg + MainOrg) — balance-sheet 패턴 복제.components/accounting/.../financial-statement/budget/general/HeaderOrg.vue— page-header + 제목("세입세출 예산서") + 서식 배지.components/accounting/.../financial-statement/budget/general/MainOrg.vue— 세입/세출 토글(tabs-list) + 요약 스트립 + 계층 비교 테이블.
3. 데이터 흐름 (읽기 전용)
- SSOT 컴포저블:
src/composables/budgetStructure.js(순수).REVENUE_TREE(서식 4) ·EXPENSE_TREE(서식 6) —{ label, name, children?, budget?, prior? }중첩 트리. 말단(leaf) budget/prior = Phase 1 데모값.buildBudgetRows(tree)→ 평탄 행{ label, name, depth, budget, prior, change, changeRate, isSection }. 부모는 자식 합 rollup,change=budget−prior,changeRate=prior?(change/prior*100):null.budgetSummary(tree)→ 세입/세출 총계 행.BUDGET_SHEETS.{revenue,expense}={ tree, totalLabel, title, form }.
- MainOrg:
sheetref('revenue'|'expense') →meta=BUDGET_SHEETS[sheet]→rows=buildBudgetRows(meta.tree)/summary=budgetSummary(meta.tree). 들여쓰기padClass(depth)(pl-0/4/8/12), 증감 색changeClass(+초록/−빨강).
4. 테스트
composables/__tests__/budgetStructure.spec.js— rollup(관리수익 504M·일반관리비 4단 263.3M)·증감·세입합계 530.6M·증감율 null.components/accounting/.../budget/general/__tests__/MainOrg.spec.js— 세입(관리수익·연체료수입·세입합계·530,600,000)·세출 토글(관리비용·일반관리비·이익잉여금·263,300,000).
5. 결산서 모드 (Phase 2a, 2026-06-21)
- 토글 2축: MainOrg
sheet(revenue/expense) ×mode(budget/settlement). 결산서 컬럼 = 예산액·결산액·집행률·증감(결산−예산). 요약 카드·tfoot·badge(서식 5/7) 모두 mode 분기. - 결산액 데이터:
budgetStructure.buildBudgetRows(tree, opts)가 말단에settlement(기본demoSettlement88~102% 결정적,opts.settlementActuals[과목]이 있으면 그 값으로 대체) +execRate·settlementChange제공. - 실적 어댑터(A안, 단지 규모 재시드):
src/composables/useBudgetActuals.js—sample(월 집계: 관리비수익=과세+면세원금 부과합 / 연체료수입=lateFeesFor발생합 ASOF 2025-12-28·E3 정합 / 장기수선비=장충 부과분) →settlementActuals = sample × MONTHS_PER_YEAR(12)(연환산). MainOrgbuildOpts가settlementActuals[sheet]를 buildBudgetRows에 주입 → 결산 메인 컬럼이 단지 실집계×12.isLive(name)로 "실적" 배지. 그 외 말단은 demoSettlement. - A안(구 B안
HOUSEHOLD_SCALE배수 대체): 빌링 데모를 단지 규모(300세대·현실 요율,demoSeed.js)로 재시드 → 집계가 그 자체로 단지 규모, 가짜 배수 제거. 남는 변환은 시간축(월→연 ×12). 검증: 관리비수익 결산 432M(월 36M×12) vs 예산 480M = 90%. 정본:docs/handoff/backend/demo-seed-factory.md. - 스케일 조정:
demoSeed.jsDEMO_CONFIG(householdCount·monthlyChargePerUnit·chargeMix) 한 곳. 연환산 개월수 =useBudgetActuals.MONTHS_PER_YEAR.
6. 예산 직접 입력·승인 (Phase 2b, 2026-06-21)
- 컴포저블:
src/composables/useBudget.js(싱글톤) — 연도×시트 키:draft[year][sheet]+status[year][sheet](초안/승인) +approvedAt.setAmount(year,sheet,name,value)(음수 클램프·승인 후 수정 시 초안 복귀),approve(year,sheet,date),resetDraft(year,sheet), 순수 getteroverridesFor/statusOf/approvedAtOf/isDirty(year,sheet)(미생성 연도=기본값, getter 내 reactive 변이 금지). - 주입: MainOrg
buildBudgetRows(tree, { budgetOverrides: overridesFor(year,sheet) })— 말단 예산액 대체 + 섹션/총계 즉시 rollup. 결산서 집행률(demoSettlement는 budget 파생)에도 반영. - 회계연도:
YEARS=[2024..2028]+yearref, 헤더 스테퍼(◀ 제Y(당)기 ▶, 경계 disabled). 연도별 예산·승인 독립.watch([mode,sheet,year])로 전환 시 편집 종료. - 편집 UX: 예산서(
mode==='budget')에서만editing토글. 말단 행(row.isLeaf) 예산액 셀 →<input>(:value/@input=setAmount, 컨트롤드). 카드 헤더 상태 배지(sheetStatus/sheetApprovedAtcomputed) + [예산 편집]/[승인] ↔ [초기화]/[편집 완료]. - 승인일:
new Date().toISOString().slice(0,10)(app 컴포넌트, 테스트는approve(...,date)주입으로 결정적).
7. 확장 포인트 (Phase 2c+)
- 실적 전면 자동집계:
settlementActuals에 부과/수납/GL(useFinancialStatements) 전 과목 매핑 + 결산 합계 = IS 정합 검증. (스케일 정합 선결 — 데모 빌링 시드 상향 or 실데이터.) - 전년도예산 자동 연동: 현재 전년도예산액=tree.prior(데모 고정). 이전 연도 승인예산(
overridesFor(year-1,sheet))을 전년도 컬럼에 연동. - 영구 저장: 현재
useBudget는 세션 싱글톤(in-memory) → 서버 저장소. - 회계연도 선택:
FISCAL_YEAR=2026상수 → 연도 셀렉터. - i18n: 제목/컬럼 한국어 리터럴(빌링 페이지 관행) + 메뉴만
accounting.nav.budget. 다국어화 시accounting.financialStatement.budget.*블록 추가. - 테스트:
composables/__tests__/{budgetStructure(결산·오버라이드),useBudgetActuals(연체료 72·부과>0)}.spec.js·budget/general/__tests__/MainOrg.spec.js(결산 모드·실적 연계 배지).