Skip to content

회계 홈 FE 메인테이너 핸드오프

라우트·진입

  • /accounting/accounting/overview redirect
  • /accounting/overview는 기존 /accounting/app-view 셸의 자식
  • productCatalog.accounting.entry, 데스크톱/모바일 회계 사이드 메뉴가 모두 overview로 진입

컴포넌트

  • View: src/views/accounting/overview/IndexView.vue
  • Main: src/components/accounting/overview/OverviewMainOrg.vue
  • Test: src/components/accounting/overview/__tests__/OverviewMainOrg.spec.js
  • 홈 운영 읽기 모델: src/composables/accountingPeriodReadModel.js
  • 운영 후보 Repo: src/composables/accountingJournalRepo.js
  • 원천 참고(read-only): .../journal-entry-general/general/blocks/BillingIntakeOrg.vue
  • 운영 검토 큐: .../general/blocks/OperatingCandidateQueueOrg.vue
  • 수기 후보 생성: .../general/overlays/SheetCreateManualJournalCandidateArt.vue
  • 후보 상세: .../general/overlays/SheetReadJournalCandidateArt.vue
  • 승인·반려 확인: .../general/overlays/DialogReviewJournalCandidateArt.vue
  • 운영 전표 큐: .../general/blocks/OperatingEntryQueueOrg.vue
  • 전표 상세: .../general/overlays/SheetReadJournalEntryArt.vue
  • 승인·전기 확인: .../general/overlays/DialogProcessJournalEntryArt.vue
  • 전기완료 정정: .../general/overlays/DialogCorrectJournalEntryArt.vue
  • 운영 장부 공통 화면: src/components/accounting/operating-read-model/OperatingBooksOrg.vue
  • 운영 장부 읽기 모델: src/composables/accountingOperatingReadModel.js
  • 인쇄 payload: src/composables/accountingPrintPayload.js
  • 인쇄 미리보기: src/views/accounting/print/AccountingPrintView.vue
  • 일반전표 빠른 입력: .../journal-entry-general/general/blocks/DynamicTableOrg.vue
  • 빠른 입력 순수 로직: src/composables/accountingVoucherGrid.js
  • 매입매출 빠른 입력: .../journal-entry-purchases-sales/general/blocks/DynamicTableOrg.vue
  • 매입매출 순수 로직: src/composables/accountingTradeVoucherGrid.js
  • 거래처원장: src/components/accounting/operating-read-model/OperatingPartnerLedgerOrg.vue (view: 'balance' | 'description' × scope: 'account' | 'overall')
  • 거래처원장 순수 로직: src/composables/accountingPartnerLedger.js
  • 개시잔액 입력: .../basic-setting/opening-balance/general/blocks/DynamicTableOrg.vue
  • 개시잔액 순수 로직: src/composables/accountingOpeningBalanceGrid.js
  • 현금출납장: src/components/accounting/operating-read-model/OperatingCashBookOrg.vue
  • 일계표/월계표: src/components/accounting/operating-read-model/OperatingPeriodicReportOrg.vue (kind: 'daily' | 'monthly')
  • 매입매출장·부가세 기초자료: src/components/accounting/operating-read-model/OperatingVatReportOrg.vue
  • 부가세 기초 순수 로직: src/composables/accountingVatReport.js
  • 거래처 코드도움: src/composables/usePartnerCodeAssist.js (파티 디렉터리 관리코드 정본)
  • 결산 작업대: .../financial-statement/closing-adjustment-entry/general/MainOrg.vue + blocks/Closing{Checklist,TrialBalance,DepreciationDraft,AdjustmentEntries}Org.vue
  • 고정자산 등록: .../basic-setting/fixed-asset/general/blocks/DynamicTableOrg.vue
  • 고정자산 순수 로직: src/composables/accountingFixedAssets.js
  • 자금일보: src/components/accounting/operating-read-model/OperatingFundsDailyOrg.vue
  • 예적금 현황: src/components/accounting/operating-read-model/OperatingDepositStatusOrg.vue
  • 계좌 마스터: .../ledger/funds-report/general/blocks/DynamicTableOrg.vue
  • 자금 순수 로직·read model: src/composables/accountingFunds.js
  • 증빙 어휘·정합 SSOT: src/composables/accountingTradeDocuments.js
  • 전자세금계산서 현황: src/components/accounting/operating-read-model/OperatingETaxStatusOrg.vue
  • 결산 작업대 읽기 모델: src/composables/accountingClosingWorkbench.js
  • 운영 재무제표: src/components/accounting/operating-read-model/OperatingStatementsOrg.vue (statement: 'income-statement' | 'balance-sheet')
  • 운영 재무제표 읽기 모델: src/composables/accountingOperatingStatements.js
  • 재무제표 순수 빌더: src/composables/financialStatementBuilders.js (useFinancialStatements에서 추출 — 시나리오·운영 공용)

데이터 흐름

  • 운영 홈 집계 (저장된 UUID Office): useAccountingPeriodReadModelaccountingJournalRepo.listCandidates/listEntries만 읽는다
  • Prototype 시나리오 (데모 Office): useGeneralLedger + useClosing + useFinancialStatements
  • 연결 원천 상품 상태: useModuleSubscription

홈은 읽기 전용이다. 전기·마감 같은 상태변경은 기존 상세 기능으로 이동해 수행한다. 저장된 Office에서는 헤더에 운영 장부를, 데모 Office에서는 Prototype 시나리오 데이터를 표시하며 두 소스를 한 화면에서 합산하지 않는다.

Wave 13 운영 홈 seam

  • accountingPeriodWorkQueue: 후보(pending_review | accepted | rejected)·전표(draft | approved | posted | reversed) 상태별 건수를 집계한다.
  • accountingPeriodImbalances: 반려 후보를 제외한 차대 불일치 항목을 미결 오류로 수집한다.
  • accountingPeriodStatus: 후보·전표에 embed된 accounting_periods.status를 파생하고 자료 없는 기간은 empty로 구분한다.
  • accountingClosingReadiness: open 기간에서 검토 대기·승인 대기·전기 대기·차대 불일치가 0일 때만 ready를 반환하고, 남은 업무는 blocker 문장 목록으로 노출한다. 실제 마감 실행은 홈이 아니라 기존 결산 기능이 소유한다.
  • 당월 차변·대변 합계·차대 일치는 Wave 12 operatingJournalLines projection(posted | reversed)을 재사용한다.
  • 홈 카운트 클릭은 일반전표입력으로 이동하며 query로 초기 필터를 전달한다: 후보는 ?candidateStatus=pending_review&period=YYYY-MM, 전표는 ?entryStatus=draft|approved|posted&period=YYYY-MM.
  • OperatingCandidateQueueOrg/OperatingEntryQueueOrg는 마운트 시 위 query를 검증 후 초기 탭·기간에 적용하고, 허용 목록 밖 값은 기본값(pending_review/action_required, 현재 월)으로 되돌린다.

운영 후보 seam

  • submitManualCandidateV1: 회계 담당자가 작성한 full payload를 submit_manual_accounting_journal_candidate_v1에 전달한다. mock과 Supabase adapter가 같은 메서드 계약을 사용한다.
  • SheetCreateManualJournalCandidateArt: 3xl 집중 폭의 전체 CREATE 폼이다. 증빙일·적요와 2개 이상의 분개 라인을 모두 펼쳐 표시하고, 각 라인의 계정코드와 차변/대변 한쪽 입력 및 전체 차대 일치를 검증한다.
  • Create sheet-footer의 저장은 valid && dirty && !saving일 때만 활성화된다. 작성 중 취소는 확인을 거치며 성공하면 같은 기간 pending_review 후보 큐를 refresh한다.
  • BillingIntakeOrg: 기존 관리비 원천은 읽기 전용 참고 목록이다. 브라우저에서 원천 store를 읽어 후보를 push하는 action과 checkbox는 없다. 서버 delivery가 회계 inbox에 전달하고 FE는 운영 후보 큐만 읽는다.
  • makeSupabaseAccountingJournalRepo: 후보·전표의 테이블 직접 쓰기 없이 명시적 RPC만 호출한다.
  • mockAccountingJournalRepo: 테스트·환경 미설정 시 같은 상태 순서와 full-payload idempotency를 재현한다.
  • OperatingCandidateQueueOrg: 장부·기간별 후보 최대 200건을 조회하고 상태·검색 필터를 적용
  • SheetReadJournalCandidateArt: 후보 라인을 정규화해 차대 균형과 원천·전표 상태를 표시
  • DialogReviewJournalCandidateArt: 후보 승인 확인 또는 사유 필수 반려를 수행

KcLep형 일반전표 빠른 입력 seam

  • 레거시 정적 15행과 동작 없는 단축키 툴바를 DynamicTableOrg 단일 회계형 작업대로 교체했다.
  • accountingVoucherGrid: 금액 정규화, 행 검증, 선택 전표 차대 검증, TSV 행·열 배치, 수기 후보 draft 변환을 순수 함수로 제공한다.
  • 표는 table-editable·table-divide-x/y·sticky-thead/tfoot SSOT 어휘를 유지하고 모바일에서도 카드로 바꾸지 않는다.
  • type=date|month.input 정본이 제공하는 캘린더 indicator를 사용한다. 전표 구분 native Select는 <div class="select select-sm"><select>…</select></div> anatomy를 지키며 <select class="select">로 합치지 않는다.
  • Enter | Shift+Enter | ArrowUp | ArrowDown은 같은 열을 이동하고 마지막 행 아래로 이동하면 새 행을 만든다. Tab은 브라우저의 표 셀 순서를 그대로 사용한다.
  • 다중행 paste는 사용자 paste 이벤트의 text/plain만 읽고 시작 셀부터 TSV를 채운다. Clipboard 권한을 요청하거나 백그라운드에서 읽지 않는다.
  • 선택 행은 동일 전표번호·동일 전표일·2개 이상·각 행 유효·차대 일치일 때만 candidate-draft를 emit한다.
  • MainOrg는 draft를 OperatingCandidateQueueOrg.openManualCandidateSheet로 전달하고, SheetCreateManualJournalCandidateArt.prepare가 전체 폼에 미리 채운다.
  • 빠른 표는 저장을 직접 수행하지 않는다. 기존 수기 후보 시트의 valid && dirty 게이트와 submitManualCandidateV1만 운영 쓰기를 소유한다.

후보 검토 UI는 reviewCandidate RPC에 연결됐다. 승인 결과는 운영 DB의 전표 초안이며, 기존 useGeneralLedger.post는 시나리오 엔진이므로 운영 DB 전기와 혼용하지 않는다.

Wave 11 as-built 경계

  • 수기 후보 Create는 submit_manual_accounting_journal_candidate_v1만 호출한다.
  • 다른 상품 후보는 브라우저가 원천 store를 읽어 generic submit을 호출하지 않는다. server delivery worker가 receive_accounting_source_event_v1을 호출한다.
  • FE는 inbox가 만든 pending_review 후보를 기존 큐에서 읽을 뿐 producer payload를 재구성하지 않는다.
  • billingVoucherToJournalCandidatesyncBillingVouchersToJournalRepo는 소비처가 없어 제거됐다. BillingIntakeOrg읽기 전용 · 자동 수신 안내만 제공한다.
  • 회계 컴포넌트에서 전자문서 컴포넌트·composable 직접 import를 제거했다. 전자문서 상품이 없어도 수기 후보→검토→승인→전기를 완주할 수 있다.

운영 전표 seam

  • listEntries(bookId, periodKey): RLS SELECT로 전표·기간·원천 요약·차대 합계를 최대 200건 조회
  • loadEntry(entryId): 전표 헤더와 라인을 명시적 ID 필터로 결합
  • accountingEntryLines / accountingEntryTotals: DB numeric 문자열을 화면 숫자로 정규화하고 차대 합계를 계산
  • filterAccountingEntries: 기본 action_required에서 draft·approved만 묶고 상태·검색 필터를 적용
  • OperatingEntryQueueOrg: Office·기간별 승인 대기 → 전기 대기 → 전기 완료
  • SheetReadJournalEntryArt: 3xl 집중 폭에서 차대·계정·원천·승인/전기 시각을 표시
  • DialogProcessJournalEntryArt: 승인과 전기의 영향을 분리해 명시 확인
  • 상태 변경은 repo의 approveEntry / postEntry만 호출하며 컴포넌트에서 Supabase를 직접 호출하지 않는다.

전기완료 정정 seam

  • accountingEntryKindMeta: 원전표·역분개 전표·대체전표 표시를 관계 필드로 구분한다.
  • loadEntry: 엔트리·라인과 accounting_journal_corrections 관계를 RLS SELECT로 결합한다.
  • correctEntry(entryId, correction): correct_accounting_journal_entry RPC만 호출한다.
  • OperatingEntryQueueOrg: 정정 대상기간을 ensureBook으로 보장한 뒤 정정 RPC를 호출하고 원전표 상세·목록을 다시 읽는다.
  • SheetReadJournalEntryArt: posted 원전표에만 정정을 제공하고, 이미 corrected인 원전표와 reversal_of_entry_id가 있는 역분개 전표에는 제공하지 않는다. 정정 연결에서 원전표·역분개·대체전표 상태를 함께 보여준다.
  • DialogCorrectJournalEntryArt: 열린 대상기간·정정일·필수 사유와 역분개만 | 역분개+대체 draft 조건부 폼을 소유한다. 대체 라인은 원전표 스냅샷으로 시작하며 차대 일치 전에는 확인할 수 없다.
  • 다이얼로그가 생성한 requestKey는 같은 제출 재시도 동안 유지한다. 성공 시 역분개 전표번호와 대체 초안 생성 여부를 상세 메시지로 표시한다.

정정으로 생성된 대체 draft는 기존 승인 대기 → 전기 대기 → 전기 완료 큐를 그대로 사용한다. 역분개 전표는 즉시 posted이며 다시 정정할 수 없다. 전기된 대체전표는 이후 별도 원전표로 정정할 수 있다.

✅ corrections migration은 운영 Supabase에 적용돼 있다(2026-07-21 확인·rollback smoke PASS).

Wave 12 운영 장부 seam

  • accountingOperatingReadModel: 저장된 UUID Office에서는 accountingJournalRepo로 기간별 운영 전표를 읽고, 데모 Office에서는 useGeneralLedger의 Prototype 시나리오를 별도 모드로 읽는다.
  • 운영 장부에는 posted | reversed 원전표와 posted 역분개 전표를 포함하고 draft | approved는 제외한다.
  • OperatingBooksOrg: journal | ledger | trial-balance prop에 따라 동일 projection을 분개장·총계정원장·합계잔액시산표로 표현한다.
  • 분개장 전표번호는 기존 SheetReadJournalEntryArtreadOnly로 열어 원전표를 추적한다. 전표 처리 큐의 승인·전기·정정 동작은 그대로 유지한다.
  • 분개장·시산표의 계정과목은 accountCode query를 가진 총계정원장으로 이동하며 해당 계정을 즉시 선택한다.
  • 총계정원장은 계정목록과 거래 명세를 한 화면에 두고 거래별 누계잔액을 표시한다.
  • 시산표는 같은 계정 집계의 차변잔액·차변합계·대변합계·대변잔액을 표시한다.
  • 기간·검색·새로고침과 차변합계=대변합계 스트립은 세 화면에서 같은 위치와 의미를 유지한다.
  • 모바일에서도 회계 표를 카드로 변환하지 않는다. 표 컨테이너 내부만 가로 스크롤해 복사 가능한 행·열 구조를 보존한다.

인쇄 미리보기 seam

  • /accounting/print-preview는 회계 셸 바깥의 인증 라우트이며 AccountingPrintView를 lazy load한다.
  • @leysys/print-ds는 exact dependency(현재 1.0.11designSystemPackageContract.spec이 버전 계약 가드)이고 인쇄 View에서만 CSS를 lazy import한다. 화면 캡션의 하드코딩 버전 문자열은 Wave 28에서 제거(스테일 1.0.9 정정).
  • accountingPrintPayloadslip | general-ledger | trial-balance payload를 현재 모듈과 sessionStorage에 보존한다. 새로고침은 견디지만 다른 기기의 영속 원본은 아니다 — 영속 원본은 아래 서버 보관.
  • 화면의 인쇄는 payload 저장 후 미리보기로 이동하고, 미리보기의 인쇄window.print()를 호출한다.
  • 서버 원본 보관(Wave 28): printPayloadBasebookId(운영 read model book id)·operating 플래그를 payload에 싣고, 미리보기의 [서버 원본 보관](운영 payload에서만 노출 — canArchive)이 repo.createPrintDocument(bookId, {requestKey, documentKind, periodKey, payload, entryId})create_accounting_print_document_v1을 호출한다. requestKey는 print-${type}-${generatedAt} 고정(더블클릭·재시도 멱등). 성공 시 원본 #N 보관됨 배지+해시 8자리, 실패(print_payload_ledger_mismatch 등)는 accountingJournalErrorMessage 한국어 안내. 서버가 payload 합계를 원장과 재검증하므로 stale 화면은 보관이 거부된다.
  • 인쇄 원본 보관함(Wave 30): 라우트 ledger/print-archive/general(사이드내비 accounting.nav.printArchive) → OperatingPrintArchiveOrg + useAccountingPrintArchive(read model — listPrintDocuments limit 100, 운영 Office 한정, 쓰기 RPC 0). 표시 행은 printArchiveRows(문서번호·종류 라벨·검증 차대합계·해시 8자리 축약 — 고유코드 UUID 비노출, PrintArchiveWorkbench.spec.js 정적 가드).
  • 보관 원본 재출력(Wave 31): 보관함 행의 문서번호 클릭(주 식별자 클릭 IA — font-medium+hover:underline) → archive.loadDocumentrepo.loadPrintDocument(payload 포함 단건) → setAccountingPrintPayload({...payload, returnPath: 보관함, archived: {documentNo, contentHash}}) → 미리보기 재렌더. AccountingPrintViewpayload.archived 마커에서 [서버 원본 보관] 대신 원본 #N 보관됨 배지를 띄운다(재보관·새 문서 발급 없음). 뒤로가기는 보관함으로 복귀.
  • 전표 상세는 showPrint prop과 print emit으로 기존 시트 구조를 재사용한다.
  • 인쇄 화면에 제품 로컬 CSS override를 추가하지 않았다. 문서 표면·A4·표 어휘는 print-ds를 사용하고 화면 도구막대는 기존 디자인 SSOT 컴포넌트를 사용한다.
  • 감사 이력(Wave 36 — KcLep 앵커 T2-3): 라우트 ledger/audit-trail/general(사이드내비 accounting.nav.auditTrail, 장부 그룹 말미 — KcLep에 없는 화면이라 P2 별도 메뉴로 append, 코어 트리 재배치 없음) → OperatingAuditTrailOrg + useAccountingAuditTrail(read model — listAuditEvents limit 200, 운영 Office 한정, 쓰기 RPC 0·신규 서버 객체 0). 표시 행은 auditTrailRows(action 라벨·badge — AUDIT_ACTION_META 13종 전수, 요약은 auditEventSummary가 payload의 고객측 식별만 추출: 전표번호·문서번호·기간·원천 — entity/actor UUID 비노출). 필터는 AUDIT_ENTITY_FILTERS(전체/전표/분개 후보/회계기간/인쇄 원본) + 키워드(filterAuditTrailRows). mock repo는 서버 RPC의 감사 기록을 미러한다(recordAuditEvent — 상태전이 시점만·멱등 재호출 무기록·내부 전기는 postEntry({silent})entry.posted 이중 기록 방지). 스펙 accountingAuditTrail.spec.js(어휘 전수·UUID 비노출·필터·기록 흐름 11건). 확장 포인트: 작업자 표시(프로필 join view 선행 필요 — BE 핸드오프 참조)·서버 페이지네이션(offset seam은 이미 관통).

Wave 13 결산 작업대 seam

  • useClosingWorkbench: 기간 read model(useAccountingPeriodReadModel)의 같은 SELECT projection 위에 결산 판정만 얹는다. 저장된 Office는 운영 후보·전표를, 데모 Office는 useGeneralLedger/useClosing 시나리오 엔진을 읽으며 두 소스를 합산하지 않는다.
  • operatingClosingChecks/scenarioClosingChecks: 검토 대기 후보·승인·전기 대기 전표·차대 일치를 pass/fail 행으로 만들고, 미결 항목은 일반전표입력 딥링크 query를 함께 반환한다.
  • closingWorkbenchState: not-started → inspecting → ready → closed 상태머신. 점검 실행을 거치기 전에는 ready로 건너뛰지 않고, 자료 없는 기간(empty)은 미착수로 유지한다.
  • closingNominalSummary: 계정과목 유형으로 수익·비용 잔액과 예상 당기손익을 요약한다 (마감분개 대상 규모).
  • closingAdjustmentEntries: 결산 조정 전표 = source_type 'manual' 전표. 별도 조정 장부 없이 기존 수기 후보 → 검토 → 승인 → 전기 흐름을 재사용하며, 수기 조정 입력 버튼은 일반전표입력으로 이동만 한다.
  • 운영 마감 실행(Wave 15 → Wave 26 서버 재계산 승격): 마감분개는 이제 서버(close_accounting_period_v1)가 계정과목 마스터(accounting_account_master)로 직접 재계산해 전기한다. FE 프리뷰는 operatingClosingEntryLines(= accountingClosingEntryLines.jsclosingEntryLinesOf — 서버 수식과 동형인 parity SSOT, mock repo도 같은 함수로 재계산)가 산출하고, 서버 잔액 view가 로드된 경우에만 closingLines를 교차검증 입력으로 보낸다(폴백 200cap 상태에서는 null — 서버 단독 재계산). 서버가 closing_lines_mismatch/closing_account_master_missing을 던지면 accountingJournalErrorMessage가 한국어로 안내한다. 커밋 직전 window.confirm으로 라인 수·당기순이익·잠금을 명시한다.
  • 운영 마감 취소(역분개): 사유 필수(window.prompt) → repo.reopenPeriodreopen_accounting_period_v1. 마감분개는 물리 삭제 없이 역분개로 상쇄되고 corrections 계약을 재사용한다. 재오픈 후 재마감은 Wave 26 인덱스 정정으로 서버에서도 동작한다(기간당 활성 마감분개 1건). 시나리오 모드는 기존 useClosing.closePeriod/reopenPeriod 유지.
  • useAccountingPeriodReadModel 잔액 승격(Wave 26): accountBalances가 서버 잔액 view(listAccountPeriodBalancesoperatingAccountBalancesFromPeriodRows) 원천으로 바뀌었다(serverBalancesReady 폴백 명시 — 실패 시 기존 라인 projection 200cap). 결산 작업대 시산표·마감 프리뷰·회계 홈 차대 판정이 함께 cap을 벗어난다.
  • ✅ migration 20260720210000_accounting_period_atomic_close.sql은 2026-07-21 운영 Supabase에 적용됐고 스모크 2종 PASS. 재오픈 close-fields 결함은 20260721083000 정정 migration으로 함께 해소. Wave 26 migration 20260721210000(마스터 시드 355행+서버 재계산+재마감 인덱스 정정)도 2026-07-21 운영 적용·스모크 PASS(BE 핸드오프 참조).
  • 회계 홈의 결산 단계와 결산 배지는 결산 작업대 라우트로 이동한다.

Wave 13 운영 재무제표 seam

  • financialStatementBuilders: KcLep 구조 트리 롤업(IS/BS/포괄손익)을 {accountCode, debitTotal, creditTotal} 잔액 주입형 순수 빌더로 추출했다. useFinancialStatements는 시나리오 어댑터로 남고 return 형태는 무변경(회귀 0)이다.
  • useAccountingOperatingStatements: listEntries(bookId, null)로 전 기간 운영 전표를 읽고 posted | reversed 라인을 기초(<선택 월)·당월(=선택 월)·기말(≤선택 월) 잔액으로 분리한다. 기간 변경은 재조회 없이 computed 분할로 반응한다.
  • BS는 기말 잔액 본문에 계정별 기초 · 당기 증감 · 기말 컬럼을 join하고, 마감분개 부재 상태에서는 누계 당기순이익을 이익잉여금에 합성 주입(net-income 라인)해 대차평형을 유지한다. 결산 조정은 마감 실행 전 0으로 명시한다.
  • IS는 누계(기수 개시~선택 월)를 본문으로 하고 당월 증감을 보조 컬럼으로 join한다.
  • 계정 행 클릭은 accountCode query로 총계정원장(ledger-general/monthly)에 역추적 진입한다. 합성 net-income 라인은 드릴다운 제외.
  • 알려진 한계(프로토타입): 기초만 있고 기말 0인 계정은 행 생략(화면 각주로 고지), 전 기간 200전표 cap, 재무제표 인쇄 미지원(print-ds 연결 후속). 확정 보고서는 서버 read API 승격 대상.
  • external 화면 2종(balance-sheet/external, income-statement/external)은 trial-balance와 같은 패러다임으로 MainOrg가 Org 하나만 소비하며, 레거시 정적 블록·오버레이는 삭제했다. internal/standard/comprehensive 변형은 아직 레거시다.

Wave 14 매입매출전표 seam

  • accountingTradeVoucherGrid: 한 행 = 한 전표. 유형(과세|영세|면세|불공제)별 부가세 자동 계산(tradeVatAmount), 매출/매입·외상/현금별 분개 자동 파생(tradeVoucherLines — 파생 결과는 구조적으로 차대 균형), 단일 행 선택 → 후보 draft 변환.
  • 정규화 계약: 과세구분은 후보 라인의 실필드 taxCategory로 저장한다(수기 후보 시트의 taxCategory: null 하드코딩 제거 — 서버 RPC는 원래 수용). 거래처코드·증빙·결제·품목은 dimensions.{partnerCode,documentType,settlementType,itemName}로 전달한다.
  • 파생 상대 계정: 매출 외상 0108 외상매출금 / 현금 0103 보통예금 / 부가세 0255, 매입 부가세 0135, 매입 채무 기본 0253 미지급금(재화 0251 구분·거래처 마스터 안정 ID는 후속). 불공제 매입은 부가세를 비용에 합산하고 0135를 만들지 않는다.
  • 매입매출전표입력 화면은 일반전표와 같은 OperatingCandidateQueueOrg(후보 큐+수기 후보 시트)를 재사용한다. 저장은 시트의 submitManualCandidateV1만 소유한다.

Wave 14 거래처원장 seam

  • accountingPartnerLedger: operatingJournalLines projection에서 거래처 라인만 그룹핑한다. 거래처 키 = 정규화 dimensions.partnerCode(구 prototypePartnerCode 겸용) 우선, 없으면 거래처명 — 거래처 마스터 안정 ID(partner_id) 연결 전의 명시적 임시 관례다.
  • partnerLedgerAccounts(거래처 라인 보유 계정 후보) → partnerLedgerBalances(계정 한정 또는 총괄 잔액, 순차변 부호) → partnerLedgerRows(거래처 시계열 누계) 순으로 파생한다.
  • OperatingPartnerLedgerOrguseAccountingOperatingReadModel을 재사용해 운영/Prototype 시나리오 모드를 함께 지원하고, ledger-business-partner의 잔액·내용·총괄잔액·총괄내용 4개 라우트가 view·scope prop으로 소비한다.
  • 잔액 탭 거래처 클릭 → 같은 범위 내용 탭으로 ?partner=&accountCode= 딥링크. 순차변 잔액 관례(채권 양수·채무 (대변) 표기)는 화면·InfoHint에 명시한다.

Wave 16 개시잔액·마감분개 정합 seam

  • accountingOpeningBalanceGrid: BS 계정(자산·부채·자본) 한정 검증(statementAccountType), 차대 차액 → 미처분이익잉여금(0377) 자동 밸런싱(이월이익/이월결손 양방향), dimensions.kind='opening-balance' 개시분개 draft → 기존 수기 후보 흐름 재사용. 별도 개시잔액 저장소·RPC 없음 (정본: ACCOUNTING-OPENING-BALANCE-CARRYFORWARD-2026-07-20). Wave 29부터 같은 BS 한정 검증이 서버 게이트로도 실행된다(수기 후보 v1 진입 래퍼 — opening_balance_bs_account_required/opening_balance_account_master_missing, accountingJournalErrorMessage 한국어 안내). 그리드 검증은 UX 프리체크, 서버가 최종 권위. mock repo도 동형(accountingOpeningBalanceServerGuard.spec.js).
  • 기수 이관은 파생적 — 월 마감분개 + 누적 파생 구조에서 별도 이월 기계를 만들지 않는다 (같은 정본).
  • 마감분개 재무제표 정합(Wave 15 결함 수정): operatingJournalLinesisClosing(마감분개 + 그 역분개)을 표시하고, 운영 IS는 isClosing 제외 집계, BS 자본 주입은 잔여 명목 순이익(마감분개 포함 잔액의 nominal net — 마감된 몫은 이미 0377에 있음)으로 바뀌었다. 시나리오 엔진의 isClosing 제외와 동형이며 부분 마감 상태에서도 대차평형이 유지된다.

Wave 17 잔여 장부 seam

  • 계정별원장(ledger-account/account)은 OperatingBooksOrg view="ledger":show-views="false"로 재사용한다 — 신규 read model 0. KcLep 정합의 총계정원장(월계)/계정별원장(명세) 차별화는 다월 조회 계약과 함께 후속.
  • OperatingCashBookOrg: 현금및현금성자산(0101·0102·0103) 한정 readModel.accountLedger — 입금=차변·출금=대변·누계잔액.
  • OperatingPeriodicReportOrg: operatingAccountBalances를 일자(일계표) 또는 선택 월(월계표)로 집계 — 차대 일치 스트립 포함. 현금/대체 분해 컬럼은 상대라인 현금성 판정 계약 후속.
  • 관리항목별 변형(부서·사원·프로젝트·현장·전체계정)은 dimensions 관리항목 축 정착 후 연결 — 레거시 화면 유지 상태를 명시한다.

Wave 18 부가세 기초자료 seam

  • vatTradeRows: dimensions.tradeType가 있는 전표만 부가세 행으로 파생한다 — 공급가액 = taxCategory 보유 subject 라인 순액, 세액 = 0255(매출)/0135(매입) 순액. 역분개 전표는 dimensions 복제 덕에 음수 행으로 파생되어 합계에서 자동 상쇄된다. 일반 수기 전표는 집계 제외(부가세 거래는 매입매출전표로 입력하는 계약).
  • vatPartnerSummary/vatTypeTotals/vatEstimatedPayable: 거래처별 합계(매수·공급가액·세액), 유형별 소계, 납부(환급)예상세액 = 매출세액−매입세액(불공제는 0135 부재로 자연 제외).
  • 신고기간은 KcLep 정합 4구간(1기 예정/확정·2기 예정/확정, VAT_QUARTERS). 전 기간 fetch는 useAccountingOperatingStatements를 재사용한다 — Wave 27부터 명세 원천은 서버 매입매출 명세 view(아래 Wave 27 seam).
  • 후속: 국세청 양식 서식 자동 작성·전자신고 파일, 거래처 사업자번호(안정 ID) 연결.

Wave 37 부가가치 서식 정합 seam (T0-3 — KcLep 부가가치 탭)

  • OperatingVatReportOrgKcLep 부가가치 서식 4종 세그먼트로 재구성했다(activeForm 탭: return·taxInvoice·cardCash·detail). 상단 납부(환급)예상세액 스트립은 서식과 무관하게 상시 노출. 신규 서버 객체·migration·라우트 없음 — 기존 vatTradeRows 파생 순수 read model 확장 + 화면 재구성뿐.
  • 신규 순수 함수(accountingVatReport.js):
    • vatTaxInvoiceAggregate(rows, tradeType): 세금계산서합계표(매출처별/매입처별). TAX_INVOICE_DOCUMENTS(전자세금계산서·전자계산서) 증빙만 필터 → vatPartnerSummary + 총계(매수·공급가액·세액). 신용카드·현금영수증 제외가 KcLep 정합의 핵심.
    • vatCardCashSummary(rows): 신용카드매출전표등수령명세서. CARD_CASH_DOCUMENTS(신용카드·현금영수증)만 매출/매입 × 증빙별 소계.
    • vatReturnSummary(rows): 부가가치세 신고서 요약(KcLep 일반과세). 매출 = 세금계산서 발급분/카드·현금/기타/영세율/면세, 매입 = 세금계산서 수취분/그 밖의 공제/불공제. payable = salesVat − deductibleVat. 면세 매입은 매입세액 없어 제외(정직 고지 InfoHint).
  • 크로스체크 불변식(spec): vatReturnSummarysales.vat/purchase.deductibleVat/payable가 기존 vatEstimatedPayable와 합계 일치(서식 분해가 총량을 바꾸지 않음).
  • 증빙 필터(documentTypeFilter)는 전표 명세 세그먼트에만 적용한다(detailRows) — 합계표·신고서는 전 증빙 집계. 기존 vatDocumentTotals는 신고서 요약으로 대체돼 화면 미사용(순수 함수는 유지).
  • ⚠ 아직 KcLep 상단 모듈 레일의 부가가치 탭 자체는 준비중(AppSideNavTabOrg disabled) — 서식 콘텐츠는 재무회계 → 장부 → 매입매출장 안에 정착시켰다. 부가가치 모듈 레일 활성화(전용 사이드내비 + 조건부 렌더)는 후속 구조 Wave.

Wave 38 부동산임대공급가액명세서 seam (T3-1 — KcLep 부가가치 첨부서류)

  • 라우트 ledger/lease-supply-statement/general(사이드내비 accounting.nav.leaseSupplyStatement, 장부 그룹의 세금계산서현황 다음) → OperatingLeaseSupplyStatementOrg + 순수 read model accountingLeaseSupplyStatement.js. 신규 서버 객체·migration 없음 — 임대차 계약 캐논(useLeaseContracts)을 읽기 전용 소비(도메인 간 read-only 참조·쓰기 0).
  • leaseSupplyStatementRows(contracts, {year, quarter}): 과세(taxation === '과세') + 재무조건 확정(financialTermsPersisted) + 조회 분기와 겹치는 계약만 명세 행. 반환 {rows, totals, period, rateBasisPoints}.
    • quarterPeriodBounds(year, quarter): 분기 경계·일수(분기 끝 월 3·6·9·12는 2월 말일 계산 불요 — endDay 하드코딩, 겹침 일수만 Date.parse 일수 계산으로 윤년 자동 처리).
    • deemedRentRateBasisPoints(year): 국세청 고시 정기예금이자율(연도별 basis points, DEEMED_RENT_RATE_BASIS_POINTS_BY_YEAR 2021~2025, 미지정 연도 최신 폴백 350). 연도 고시 갱신 시 이 맵만 추가.
    • deemedRentAmount(deposit, rateBps, days): 간주임대료 = 보증금 × 이자율/10000 × 일수 ÷ 365(원단위 반올림).
    • 임대료 과세표준 = round(월세 × 3개월 × 과세일수 ÷ 분기일수) — 분기 중 개시·종료는 일할.
  • 데이터 소스 필드(normalizeLeaseContract): taxation(과세/면세)·financialTermsPersisted·deposit.agreed(보증금)·baseRent(월세)·startsOn/endsOn(임대기간)·tenant·unit·registrationNumber. 전용면적은 계약 캐논에 미승격 → 화면 컬럼 없음(후속).
  • 스펙 accountingLeaseSupplyStatement.spec.js(기간·이자율·간주임대료 계산 + 과세필터·일할·합계·미확정 안전 8건) + 화면 정적 가드 4건.
  • 장부 그룹 잠정 배치Wave 39에서 부가가치 모듈로 이관 완료(아래 seam). 후속: 전용면적 컬럼(계약 캐논 승격 선행), 신고서 서식/전자신고.

Wave 39 부가가치 모듈 레일 활성화 seam (T0-3 잔여 구조)

  • KcLep 상단 모듈 레일의 부가가치 탭을 활성화(AppSideNavTabOrg — 부가가치 버튼 disabled 해제·toPath('/accounting/vat/return/general')·isVatModule route-prefix로 active 상태). 원천징수·법인조정·개인조정은 준비중 유지.
  • 조건부 사이드내비: AppSideNavMenuOrgisVatModule = route.path.startsWith('/accounting/vat/') 추가 → v-if="isVatModule"(부가가치 메뉴: 부가가치세 신고·부동산임대공급가액명세서) / v-else(기존 재무회계 메뉴 전체). 데스크톱(LayoutView)·모바일(SheetAsideOrg)이 같은 두 컴포넌트를 공유하므로 조건부를 컴포넌트 안에 넣어 양쪽 자동 반영 — 모바일 close 계약(toPath await+close) 불변.
  • 라우트: /accounting/vat/return/general(OperatingVatReportOrg 재사용 — 매입매출장 ledger 라우트와 같은 화면의 부가가치 진입점) · /accounting/vat/lease-supply-statement/general(OperatingLeaseSupplyStatementOrg). 둘 다 /accounting/app-view children이라 회계 셸(레일+사이드내비) 안에서 렌더.
  • 이관: 부동산임대공급가액명세서 뷰/컴포넌트를 ledger/lease-supply-statementvat/lease-supply-statement로 이동(장부 nav 항목 제거). 매입매출장(OperatingVatReportOrg)은 장부에 유지(정당한 장부) + 부가가치 모듈에 "부가가치세 신고" 진입점 추가 = 한 화면 두 진입(KcLep 매입매출장=장부·부가가치세신고=부가가치 정합).
  • ⚠ 앵커: KcLep에 이미 있는 부가가치 탭을 채운 것(P3) — 새 탭 발명 아님. 후속 부가가치 서식(공제받지못할매입세액명세서·발행금액집계표 등)이 들어갈 자리 확보.

Wave 40 원천징수 모듈 활성화 + 이행상황신고서 seam (KcLep 원천징수 탭)

  • Wave 39 부가가치 모듈 패턴 재사용. AppSideNavTabOrgisWithholdingModule(route /accounting/withholding/) + 원천징수 버튼 활성화(원천징수·부가가치 활성, 법인조정·개인조정만 준비중=coming-soon 2). AppSideNavMenuOrg는 3분기 조건부(v-if isVatModule / v-else-if isWithholdingModule / v-else 재무회계). 라우트 /accounting/withholding/return/general(회계 셸 children).
  • 도메인 간 read-only 소비 = accounting→human-capital 경계 엣지(승인 baseline 1). HR 급여 스토어 usePayrollRun(human-capital 소유)의 withholdingSummary(period)/statusOf/configurePayrollRunScopeaccounting-owned 화면 OperatingWithholdingReturnOrg.vue가 직접 소비(⚠ 엣지가 화면에서 성립하도록 — src/composables는 platform-core 소유라 read model에 두면 엣지가 platform-core→human-capital가 됨. Wave 38 임대명세와 동일하게 .vue가 크로스도메인 훅 소유). 가드 스펙 scripts/accounting-human-capital-boundary.spec.js(상한 1·직접 import 금지·소비처 1곳).
  • 순수 read model accountingWithholdingReturn.js: withholdingReturnStatement(summary)(A01 근로소득 행+합계+지방소득세+납부기한, null 안전)·recentPeriods·withholdingRunStatusMeta. Vue·스토어 import 금지(순수) — 크로스도메인 훅은 .vue.
  • HR = 급여 계산·원천징수·이체 system-of-record. 회계 원천징수 탭 = 신고 서식만 read-only. 화면은 configurePayrollRunScope로 활성 Office 스코프 바인딩(공개 seam·쓰기 아님) 후 withholdingSummary 파생. hydratedKey 트리거로 async 하이드레이션 후 재계산.
  • 후속: A02(중도퇴사)·기타 소득구분·지급명세서(직원별 상세 — HR seam 확장 선행), 서식 자동 작성·전자신고, 법인조정·개인조정 모듈.

Wave 41 공제받지못할매입세액명세서 seam (후속 부가가치 첨부서식)

  • Wave 39가 확보한 부가가치 모듈 자리에 후속 첨부서식을 채운다(P3 — KcLep에 있는 서식·새 위치 발명 없음). 라우트 /accounting/vat/non-deductible/general(사이드내비 accounting.nav.nonDeductibleStatement — 부가가치 메뉴 부동산임대공급가액명세서 다음) → OperatingVatNonDeductibleStatementOrg + 매입매출장 read model(accountingVatReport.js) 순수 확장. 신규 서버 객체·migration·경계 엣지 없음(기존 tradeJournalLines 파생만).
  • 뷰/헤더/메인 3파일은 lease-supply-statement 템플릿 그대로(views/accounting/vat/non-deductible/general/IndexView.vue + components/accounting/vat/non-deductible/general/{HeaderOrg,MainOrg}.vue, MainOrg는 단일 Org 소비).
  • read model 신규 함수(accountingVatReport.js):
    • vatNonDeductibleRows(rows): tradeType === '매입' && taxType === '불공제' 행만. 불공제 매입은 부가세를 비용에 합산 기표(0135 미사용·KcLep '불공' 정합)라 vatTradeRows에서 공급대가(공급가액+세액)가 row.supply에 적립되고 vat=0. 따라서 공급가액·세액을 공급대가 역산으로 파생: netSupply = round(gross / 1.1), taxAmount = gross − netSupply(불공제=과세분 10% 전제·tradeVatAmount 정합). 역분개는 음수 공급대가로 자동 상쇄(round 부호 대칭).
    • vatNonDeductibleByPartner(rows)(거래처코드 우선 키·ko-KR 정렬)·vatNonDeductibleByDocument(rows)(증빙별·공급대가 desc)·vatNonDeductibleStatement(rows)({rows, byPartner, byDocument, totals:{count,netSupply,taxAmount,gross}}).
  • 크로스체크 불변식: statement.totals.gross === vatReturnSummary(rows).purchase.nonDeductible.supply(신고서 요약의 불공제 공급가액과 일치) — 화면 하단에 명시 노출·spec 가드.
  • 스펙: accountingVatReport.spec.js 확장 4건(역산·거래처/증빙 집계·불공제 필터·크로스체크·역분개 상쇄) + OperatingVatNonDeductibleStatementOrg.spec.js 5건(단일 Org·read model 소비·컬럼·크로스체크·읽기전용) + VatModuleActivation.spec.js 확장(nav·router).
  • 후속: 8구분 불공제 사유별 내역(필요적 기재사항 누락·비영업용 소형승용차·접대비·면세사업 관련 등)은 매입매출전표 dimensions에 불공제 사유 코드 항목 도입 선행(현재 사유 미기록 — 화면 InfoHint 정직 고지) · 공통매입세액 안분·정산(면세 겸영 비율) · 발행금액집계표 등 나머지 서식.

Wave 42 신용카드매출전표등발행금액집계표 seam (후속 부가가치 첨부서식)

  • Wave 41과 완전 평행. 라우트 /accounting/vat/card-sales/general(사이드내비 accounting.nav.cardSalesStatement — 공제받지못할매입세액명세서 다음) → OperatingVatCardSalesStatementOrg + 매입매출장 read model 순수 확장. 신규 서버 객체·migration·경계 엣지 없음. 뷰/헤더/메인은 vat/card-sales/general 하위(lease/non-deductible 템플릿 정합).
  • read model 신규 함수(accountingVatReport.js):
    • vatCardSalesRows(rows): tradeType === '매출' && CARD_CASH_DOCUMENTS.includes(documentType)(신용카드/현금영수증)만. Wave 37 신용카드수령명세서(vatCardCashSummary 매입분)와 대칭 — 이쪽은 매출 발행분.
    • vatCardSalesStatement(rows): {byDocument:[{documentType,count,supply,vat}](공급가액 desc), totals:{count,supply,vat}, taxable:{count,supply,vat}}. taxable은 과세분(taxType ∉ {영세,면세})만 — 영세/면세 카드매출은 totals엔 포함되나 taxable에서 제외(신고서 영세/면세로 별도 집계됨). 발행금액(공급대가)=supply+vat는 화면 파생.
  • 크로스체크 불변식: statement.taxable.{supply,vat} === vatReturnSummary(rows).sales.cardCash.{supply,vat}(신고서 요약의 신용카드·현금영수증 과세매출과 일치) — 화면 하단 명시 노출·spec 가드.
  • 스펙: accountingVatReport.spec.js 확장 3건(증빙별 집계·크로스체크·매입/세금계산서 제외+영세면세 분리) + OperatingVatCardSalesStatementOrg.spec.js 5건 + VatModuleActivation.spec.js 확장(nav·router).
  • 후속: 세금계산서 중복 발급분 차감(전표에 발급중복 플래그 선행 — 카드+세금계산서 동시 발급 거래를 신고서에서 이중계상하지 않기 위함) · 직불·기명식선불카드 세분류(카드종류 dimension 선행) · 서식 자동 작성·전자신고.

거래수집(T2-2) seam — 증빙 → 전표 후보 (회계 하위 창구)

  • 라우트/진입: /accounting/collection/inbox/general(회계 셸 children) → 뷰 트리오 views/accounting/collection/inbox/general/IndexViewcomponents/accounting/collection/inbox/general/{HeaderOrg,MainOrg} → 바디 operating-read-model/OperatingTransactionCollectionInboxOrg.vue. 사이드내비 = 재무회계 v-else 브랜치, 전표입력 그룹 인접 서브메뉴(accounting.nav.transactionCollection) — 별도 상단탭·isXModule 분기 없음(부가가치/원천징수와 달리 서브메뉴). i18n accounting.nav.transactionCollection + accounting.ledger.transactionCollection.{title,tabs.general}(ko·en).
  • 매퍼(operating-read-model/accountingSourceDocumentCandidate.js — accounting-owned·순수): evidenceToCandidate(evidence, {partnerPartyId}){ok,status,lines,memo}, evidenceCandidateStatus(ready/unclassified/unmapped/invalid_amount), resolveAccountCode(CoA nameKo + 별칭), resolveEvidencePartyId(evidence, parties)(순수·bizNo→UUID·UUID 가드). usePurchaseJournal P1 라인 형태 재사용. CoA(chartOfAccounts.CORE_ACCOUNTS)만 import — 증빙 seam·거래처 마스터 비참조(fetch는 Org가 소유).
    • 결제수단별 상대 계정(②): salesCounterAccount/purchaseCounterAccount(source) — 세금계산서·카드=외상(0108/0253)·현금영수증=보통예금(0103)·PG 매출=미수금(0120). 균형 불변.
    • 거래처 안정 키(①): partnerPartyId는 Org가 resolveEvidencePartyId로 해석해 opts로 주입 → 전 라인에 실림(순수 매퍼는 fetch 안 함).
  • 화면 로직: accountingSourceDocumentRepo.list(direction)로 수집 증빙 로드(매입/매출 탭·월 필터=useAccountingSourceDocuments.filterRows), 운영 장부면 useCounterparties.loadCounterparties(officeId)로 거래처 마스터 하이드레이션(platform-core·읽기 전용·경계 엣지 아님) → 행별 후보 상태 배지. ready한 행 체크 → 전표 후보 생성: 행마다 resolveEvidencePartyId(row, counterparties.value)로 UUID 해석 후 evidenceToCandidate(row, {partnerPartyId})submitManualCandidateV1(companyId, officeId, {requestKey:accounting-source-documents-{id}, …lines, payload}). 멱등(같은 증빙=같은 후보·submitted Set으로 생성 완료 배지). 운영 장부(isPersistedOffice)에서만 생성 — Prototype은 조회·자격 확인만. 생성 후 [운영 분개 후보로 이동] 딥링크(검토 큐).
  • 경계 엣지 accounting→accounting-source-documents=1: ⚠ accounting-owned .vue가 accounting-source-documents 소유 repo seam(@/composables/accountingSourceDocumentRepo)을 직접 import해야 엣지 성립(src/composables는 platform-core). accountingSourceDocumentRepo.js를 accounting-source-documents sourceRoots로 승격 + 가드 스펙 scripts/accounting-accounting-source-documents-boundary.spec.js(단일 importer=inbox Org 고정). useAccountingSourceDocuments·accountingSourceDocumentMock(sourceLabel)은 platform-core 유지(엣지 아님). config 수정 후 전체 boundary audit 재실행(excess/stale 0).
  • 스펙: accountingSourceDocumentCandidate.spec.js(명칭 해석·자격·매입/매출 라인·균형·면세·제외) · TransactionCollectionActivation.spec.js(nav·router·i18n) · accounting-accounting-source-documents-boundary.spec.js(경계 가드) · useAccountingSourceDocuments.test.js 수집 멱등 확장.
  • 후속: 실 바로빌/홈택스 수집 어댑터(자격증명·Edge) · 채무/채권 계정 거래처·증빙유형별 세분(현재 0253/0108 고정) · accounting_source_document_classification_rules 서버화 시 수집 시점 자동 계정 제안 · 매퍼 서버 확정 계약 승격.

기초정보관리 허브 인덱스(T4-1) seam

  • 라우트/진입: /accounting/basic-info/general(회계 셸 children) → 뷰 트리오 views/accounting/basic-info/general/IndexViewcomponents/accounting/basic-info/general/{HeaderOrg,MainOrg}. MainOrg가 허브 그리드 본체(별도 read-model Org 없음 — 서버 read 없는 순수 내비 인덱스). 사이드내비 = 기초정보관리(masterData) 그룹 맨 위 첫 child(accounting.nav.basicInfoHub). i18n accounting.nav.basicInfoHub + accounting.ledger.basicInfo.{title,tabs.general}(ko·en).
  • 동작: masters[] 카탈로그(거래처·계정과목·고정자산·빌링설정·개시잔액) 카드 그리드 → 클릭 시 useRouter().push(BASE + segment)로 기존 basic-setting 화면 이동. 신규 마스터·서버 객체·경계 엣지 없음 — 기존 화면 진입점만 집약(KcLep 기초정보관리 대응·비파괴 보완). 확장 포인트: 회사·환경 설정·업무용승용차 등록 카드 추가(신규 마스터 구현 시).
  • 스펙: BasicInfoHubActivation.spec.js(nav·router·5종 링크·i18n).

KcLep 기초정보 5항목 완성 seam (회사·환경·업무용승용차)

  • 3 신규 마스터(basic-setting 하위, 뷰 트리오 + platform-core localStorage 컴포저블·경계 엣지 0):
    • 회사등록 basic-setting/company/generaluseAccountingCompanyProfile(accountingCompanyProfile.js·leyve.accounting.companyProfile.v1): 사업자번호·대표자·업태·종목·과세유형(TAXATION_TYPES)·개업일·기수. 회사명·주소는 useAccountContext(읽기). read↔edit 폼(draft/save).
    • 환경등록 basic-setting/environment/generaluseAccountingEnvironment(accountingEnvironmentSettings.js): 대차차액(BALANCE_DIFF_MODES)·절사(ROUNDING_MODES)·적요/부가세/코드도움/원가구분 토글. read↔edit. ⚠ 표시·입력 보조 옵션 — 전기 규칙은 서버 권위.
    • 업무용승용차등록 basic-setting/vehicle/generaluseBusinessVehicleRegister(accountingBusinessVehicles.js): 편집 그리드(차량번호·취득·전용보험·운행기록부·업무사용비율). 순수 vehicleAnnualDepreciation(정액5년)·vehicleAnnualDeductible(업무분×비율·DEPRECIATION_ANNUAL_CAP 800만 상한)·vehicleValid. 0208 차량운반구 연결(VEHICLE_ASSET_ACCOUNT). ⚠ 주차/입주민 차량 마스터(master-data/resource)와 무관한 세무 개념.
  • 패턴: localStorage 영속은 useBarobillIntegration 미러(versioned KEY·hydrate/persist·singleton). 컴포저블은 src/composables/ flat·accounting* 네이밍 → platform-core(엣지 아님). 화면은 IndexView+HeaderOrg+MainOrg(폼/그리드 인라인·blocks/overlays 없음).
  • 허브 카드 8종(회사·거래처·계정과목·환경·업무용승용차 + 고정자산·빌링설정·개시잔액). 스펙: accountingBasicMasters.spec.js(차량 감가상각·손금 한도·프로필/환경 기본값·영속) + BasicMastersActivation.spec.js(route·nav·hub·i18n).
  • 후속: 회사 마스터·차량 대장 서버 저장(현재 Prototype localStorage) · 운행기록부 연동 · 환경 옵션의 서버 전기 규칙 반영.

Wave 34 회계 홈 재무 현황 seam

  • OverviewMainOrg재무 현황 카드 3장 + 오늘의 할 일(alfred·upharos 홈 벤치 P2 흡수 — KcLep 코어 무이탈, 기존 업무 큐·처리 순서·바로가기 유지). 순수 모듈 accountingHomeSummary: fundBalanceSummary(자금 = 0101+예금 nature 누적), periodIncomeSummary(당월 수익·비용·순이익 — 마감분개 제외), vatEstimateSummary(분기 0255−0135 발생액 + vatDueDateOf 납부 기한·D-day).
  • 원천 = 기간 read model의 서버 잔액 view 행(balanceRows) — serverBalancesReady일 때만 카드 렌더(폴백 0원 오표시 방지, 정직 숨김). 할 일 = 검토 대기·마감 가능/점검·부가세 D-day(7일 이내 error 배지), 클릭 = 해당 화면 딥링크.
  • 경계 가드 개정: scripts/accounting-tax-invoice-boundary.spec.js의 baseline 전면 금지를 승인 상한(edge=정확히 1)으로 개정(Wave 33 오너 결정 — 추가 증가 여전히 차단).

Wave 33 회계 발행 창구 seam

  • journal-entry/e-tax-invoice/general 레거시(정적 목업 블록·오버레이) 삭제 → OperatingETaxIssueOrg 단일 소비(ETaxIssueWorkbench.spec.js 가드).
  • 발행 대상 = tradeJournalLines(Wave 27 서버 명세 view) → vatTradeRows 중 매출+계산서형(ELECTRONIC_DOCUMENT_TYPES). 발행 = useTaxInvoiceIssuance.issue()(발행 원장 단일 계약 — sourceRecordKey accounting:trade:{entryId}·sourceProductKey accounting), 상태 어휘 DISPLAY_STATUS(전송대기/전송중/전송완료/오류) 재사용, 오류 시 재시도.
  • 게이팅: isModuleEnabled('tax-invoice') — 미구독은 정직 안내(메뉴는 KcLep 전표입력 그룹 자리 유지). 서버 entitlement가 최종 권위.
  • 고객 표면 공급사명 비노출 가드 준수(기능명·중립 상태 어휘만).

Wave 32 관리항목별 손익 seam

  • 관리항목 입력: 수기 후보 시트(SheetCreateManualJournalCandidateArt) 라인에 부서 (관리항목)/프로젝트 (관리항목) 선택 필드 — lineDimensions()가 빈 값은 키를 남기지 않고 dimensions에 병합(departmentName/projectName). draft 재진입 시 dimensions에서 역추출.
  • 보고서: 라우트 financial-statement/management-item-income/general(사이드내비 결산/재무제표 그룹 — 손익계산서 다음, KcLep 코어 무이탈 신규 메뉴) → OperatingManagementItemIncomeOrg + useManagementItemReport(fetch 소유 — view 정본·journalLines 200cap 폴백 serverBalancesReady 정직 고지).
  • 순수 모듈 accountingManagementItemReport: MANAGEMENT_ITEM_AXES(부서·프로젝트)·managementItemIncomeRows(축·당월/누계·미지정 마지막·마감분개 제외·계정 상세)·managementItemIncomeTotals·폴백 변환 managementItemRowsFromLines(view 행 동형 — 등가 spec 가드).
  • 화면: 축 탭 + 당월/누계 + MonthPicker + 관리항목 행 클릭 → 계정별 내역. 미지정 행은 숨기지 않는다.

Wave 27 매입매출 명세 축 서버 승격 seam

  • 명세 정본 = 서버 view accounting_trade_voucher_lines(migration 20260721230000·운영 적용): dimensions.tradeType 마커가 있는 posted|reversed 전표의 전체 라인만 노출(security_invoker — 새 권한 표면 없음). repo.listTradeVoucherLines(bookId, {limit=1000, offset}) + mock 동형.
  • useAccountingOperatingStatements가 1000라인 페이지 루프(상한 30페이지)로 view를 읽어 tradeJournalLines(journalLines와 같은 라인 형태 — tradeJournalLinesFromViewRows 매핑)를 노출한다. 매입매출장·부가세 기초자료·전자세금계산서 현황에서 200전표 cap 제거. view 미가용 시 serverTradeLinesReady=false로 journalLines(200cap) 폴백, 페이지 상한 도달은 tradeLinesTruncated로 정직 고지(조용한 절단 금지).
  • 산식(vatTradeRows 등)은 FE 단일 유지 — 읽기 전용 보고 축이라 서버 재계산 중복(parity 부담)을 만들지 않는다(마감분개 Wave 26과 대비되는 의도적 선택). 등가는 accountingTradeLinesServerPromotion.spec.js가 view 행 매핑↔라인 경로 결과 일치로 가드한다.
  • OperatingVatReportOrg/OperatingETaxStatusOrgoperating.tradeJournalLines 소비로 전환됐다(연도 필터 포함).

Wave 25 서버 승격 3차 seam

  • 재무제표 잔액 정본 = 서버 view: useAccountingOperatingStatements의 기말/기초/누계/당월 잔액과 계정 삼분해가 listAccountPeriodBalances(view) 행 기반(statementBalancesFromPeriodRows/statementTriplesFromPeriodRows)으로 교체됐다 — 재무제표·시산표에서 200전표 cap 제거. view fetch 실패(구스키마) 시 기존 라인 projection 폴백을 serverBalancesReady로 명시한다. 동형성은 등가 스펙(accountingStatementsViewSource.spec)이 라인/행 계산 결과 일치로 가드한다.
  • 라인 상세(journalLines)는 부가세·전자세금계산서 소비용으로 병행 유지(200전표 cap)했으나 — Wave 27에서 서버 명세 view로 승격 완료(위 Wave 27 seam).
  • partner_party_id backfill: migration 20260721190000 — 구라인의 관리코드(dimensions.partnerCode)를 office_party_assignments로 소급 매핑(Office별 유일 보장). 전기완료 라인 불변 트리거를 마이그레이션 트랜잭션 안에서만 일시 해제하는 1회 append-only 예외(금액·계정 불변·거래처 메타데이터만). 운영 적용 — 현 시점 매칭 0건(운영 구라인에 partnerCode 없음)·트리거 재활성 확인.

Wave 24 서버 승격 2차 seam

  • 서버 잔액 projection: view accounting_account_period_balances(계정×기간×마감구분 집계·security_invoker = on으로 기존 RLS 통과·authenticated SELECT) + repo.listAccountPeriodBalances(bookId)(mock 동일 계약 — posted|reversed·isClosing 분리). 재무제표·시산표의 기초/당월/기말은 이 행의 기간 비교로 파생 가능하며 200전표 cap이 없다. 소비 교체(useAccountingOperatingStatements → view 원천)는 후속 — 현재 화면들은 기존 라인 projection을 유지한다.
  • 전표 큐 '더 보기': OperatingEntryQueueOrgcountEntries 총건수를 표시하고(불러옴 n건 / 전체 n건), loadMoreEntries()listEntries {offset: entries.length}로 다음 페이지를 이어 붙인다. 총건수 이내면 버튼 숨김·시퀀스 가드로 기간 전환 경합을 차단한다.
  • 거래처원장 키 승격: partnerKeyOf 우선순위 = ① 라인 실필드 partnerPartyId(UUID·불변) ② dimensions.partnerCode(관리코드) ③ 거래처명. FK 이전 구라인은 ②③로 계속 묶인다 — 같은 거래처의 신구 라인 키 분열 해소는 서버 backfill(구라인 partner_party_id 채움) 후속.

Wave 23 서버 승격 1차 seam

  • partner_party_id 관통(FE 측): usePartnerCodeAssist.partnerPartyIdOf(관리코드) — 파티 디렉터리 해석 결과가 UUID일 때만 반환한다(시나리오 seed cp-# id는 서버 FK로 보내지 않음). 매입매출 그리드 applyPartnerCode가 행에 싣고 tradeVoucherLines가 모든 파생 라인의 실필드 partnerPartyId로 전달한다. 수기 후보 시트 라인 매핑·repo 정규화(accountingCandidateLines/accountingEntryLinespartnerPartyId)·SELECT 계약(partner_party_id)까지 관통. 값이 없으면 null — 저장 차단 없음.
  • 장부 페이지네이션 seam: repo.listEntries(bookId, periodKey, {limit=200, offset=0})(PostgREST range) + repo.countEntries(bookId, periodKey)(exact head count). mock repo 동일 계약. 기존 소비처는 기본값으로 무변경 — '더 보기' UI 연결은 후속.
  • 거래처원장·부가세 그룹 키는 여전히 dimensions.partnerCode(관리코드)다 — read model의 키를 partner_party_id로 교체하는 작업은 서버 projection 승격과 함께 진행한다.

Wave 19 거래처 키 안정화 seam

  • 거래처코드 정본 = 파티 디렉터리 관리코드(office_party_assignments.management_code, Office별 유일·불변). 거래처원장·부가세 합계의 partnerCode 그룹 키가 이 코드로 수렴하고, 이름이 바뀌어도 원장 키가 유지된다.
  • usePartnerCodeAssist: useCounterparties(시나리오 seed CP-#### + 운영 listByOffice) 위 thin 코드도움 — 매입매출·일반전표 그리드의 거래처코드 입력이 datalist로 후보를 제시하고, 코드 일치 시 거래처명을 자동 채운다. 조회 실패는 코드도움 미표시로 수용(입력 차단 없음).
  • partner_party_id UUID FK 서버 관통은 BE 핸드오프 참고 설계(5개 라인 쓰기 경로 일괄 수정 + 멱등 해시 호환) — 실 Postgres 검증 환경 후속.

Wave 20 고정자산·감가상각 seam

  • accountingFixedAssets: KcLep 고정자산등록의 leyve 정합 재해석 — 상각 대상 = CoA nature '상각' + controlOf 감가상각누계액 짝 보유 계정(DEPRECIABLE_ASSET_ACCOUNTS/accumulatedDepreciationAccount). 정액 = 취득가액÷내용연수, 정률 = (취득가액−전기말누계액)×상각률(1 − 0.05^(1/n) 소수 3자리 — KcLep 상각률표 동형: 5년 0.451·10년 0.259). 월할 = 연÷12, 취득월 이전 0, 비망가액 1,000원 하한 클램프.
  • depreciationDraft(assets, periodKey): 자산별 (차) 0818 감가상각비 / (대) 누계액 계정 라인 쌍(구조적 차대 균형), 증빙일 = 대상 월 말일, dimensions.{kind:'depreciation', assetId, assetCode, assetAccountCode}. 별도 상각 장부·RPC 없음 — 기존 수기 후보 gate(submitManualCandidateV1)만 운영 쓰기를 소유한다.
  • 자산 대장은 useFixedAssetRegister 모듈 스코프 스토어(Prototype 스탠드인·메모리) — 고정자산 등록 화면과 결산 작업대가 공유한다. 서버 영속·기중 전기 이력 추적(전기말누계액 자동 갱신)은 BE 참고 설계 후속.
  • 고정자산 등록 화면(basic-setting/fixed-asset/general)은 개시잔액 화면 동형: OperatingCandidateQueueOrg 재사용 + 그리드 candidate-draft emit → openManualCandidateSheet.
  • 결산 작업대 연결: ClosingDepreciationDraftOrgworkbench.activePeriod 기준 자산별 월할 초안·합계를 표시하고, candidate-draft → 작업대 MainOrg가 직접 mount한 SheetCreateManualJournalCandidateArt.prepare + showModal. 후보 생성 성공 시 운영 모드는 workbench.refresh().

Wave 21 자금 축 seam

  • accountingFunds: 자금 계정 = 0101 현금 + CoA nature '예금' 계정(0102~0106·0176·0177). fundsDailyReport(lines, dateKey)가 일자 기준 전일시재(대상일 이전 누계)·당일수입(차변)·당일지출(대변)·현재시재를 분해한다 — 행마다 opening + inflow − outflow = closing 불변식.
  • useFundsReadModel: 전 기간 fetch(listEntries(bookId, null) — 운영 재무제표 seam과 동형·200전표 cap) 또는 시나리오 prototypeEntries(export 승격). 페이지(MainOrg)가 1회 소유하고 자금일보·예적금 대조가 같은 projection을 read-model prop으로 읽는다.
  • 계좌 마스터 = useFundAccountRegister 모듈 스코프 Prototype 대장(메모리) — 계좌코드·은행·계좌번호·계좌명·예금 계정 연결·개설/만기일·이자율·원금. fundAccountRowValid가 예금 계정 한정·만기≥개설·이자율 0~100을 검증한다.
  • 예적금 현황 = 대장의 DEPOSIT_STATUS_CODES(0105/0106/0176) 행 만기 오름차순 + maturityDaysFrom D-day(30일 이내 warning·경과 error 배지).
  • fundRegisterCrosscheck: 대장 원금 합계 vs CoA 장부잔액 계정별 대조 — 개별 계좌 잔액은 대장이, 장부는 계정 합계만 아는 경계를 화면에 명시한다(계좌 차원 dimensions 서버 정착 전).
  • 전부 읽기 전용 — 쓰기 RPC 없음. 계좌 서버 마스터·입출금 자동 대사·계좌 단위 자금일보는 후속.

Wave 22 매입매출 증빙 축 seam

  • 증빙 어휘 정본 = accountingTradeDocuments.TRADE_DOCUMENT_TYPES(전자세금계산서·전자계산서·신용카드·현금영수증·기타 5종). accountingTradeVoucherGrid는 재노출(export { TRADE_DOCUMENT_TYPES })로 기존 소비처 호환을 유지한다 — 그리드·부가세 기초자료·전자세금계산서 현황이 같은 상수 객체를 공유한다(스펙이 참조 동일성까지 가드).
  • 과세구분↔증빙 정합 = documentTaxAlignmentWarning(taxType, documentType) 소프트 가드: 면세=(전자)계산서 / 과세·영세·불공제=(전자)세금계산서, 카드·현금영수증·기타는 제한 없음. 위반이어도 저장은 막지 않고 매입매출 그리드 검증 셀에 증빙 확인 경고 배지(:title=사유)로 표시한다(tradeDocumentWarning(row)).
  • vatDocumentTotals(rows): 증빙별 매수·공급가액·세액 소계 — 부가세 기초자료 화면의 증빙별 소계 표(신용카드매출전표등수령명세서·현금영수증 기초).
  • 전자세금계산서 현황(ledger/e-tax-invoice-status) = 레거시 정적 블록·오버레이 삭제 → OperatingETaxStatusOrg 단일 소비(Wave 17·18 패러다임). eTaxStatusRows(vatTradeRows)가 계산서형 증빙(ELECTRONIC_DOCUMENT_TYPES)만 발행(매출)/수취(매입)로 분류하고, 전송 상태는 연동 대기 고정 + 국세청 전송 미연동 배지로 정직 표기한다. 행별 정합 경고 포함. 읽기 전용(쓰기 RPC 0 — 스펙 가드).
  • 발행 화면(journal-entry/e-tax-invoice)은 레거시 유지 — 실발행은 바로빌 연동(BE 참고 설계) 후속이며 현황 read model이 선행 계약이다.

UI 계약

  • 실제 순서를 표현하는 5단계 rail: 전표 검토 → 전기 → 원장·시산표 → 결산 → 재무제표
  • 긴 상주 안내 대신 InfoHint로 후보/확정 경계를 설명
  • 상태 필터는 SSOT tabs-list·tabs-trigger를 사용하고, 목록 제목 클릭으로 3xl 집중 폭 상세 시트를 연다.
  • 후보 상세는 차변·대변 합계와 일치 여부를 가장 먼저 표시하고, 승인·반려는 확인 다이얼로그를 거친다.
  • 전표 상세도 같은 차대 요약과 라인 표를 재사용하되 현재 상태에 맞는 단일 다음 액션만 푸터에 표시한다.
  • 전기 확인은 전표번호 부여·원장 반영·역분개 정정 원칙을 다이얼로그에서 명시한다.
  • 모바일은 필터·검색·기간을 세로 배치하고 표만 내부 가로 스크롤한다. 페이지 전체 가로 overflow는 만들지 않는다.
  • 업무 모듈은 카드로 독립 표시하며 회계에 종속된 메뉴처럼 표현하지 않음
  • CSS·registry 추가 없음. SSOT card, badge, button, sidebar-menu만 사용
  • 모바일은 1열, sm 2열, xl 5열로 흐름을 재배치하며 문서 가로 overflow를 만들지 않음

확장

회계 홈·결산·재무제표(Wave 13~16)에 이어 계정별원장·현금출납장·일계표/월계표 대표 변형까지 운영 장부 projection에 연결됐다. 다음 단계는 운영 원자적 마감 계약, 재무제표 인쇄·서버 확정 보고서, 서버 페이지네이션·기초잔액 read API 승격이다. 매입매출전표는 거래처 안정 ID, 증빙, 공급가액·부가세·과세구분 계약을 먼저 정규화한 뒤 같은 후보→승인→전기 흐름에 연결한다. 페이지에서 Supabase를 직접 호출하지 않는다.