Files
sam-react-prod/claudedocs/[REF-2026-02-19] code-dedup-commonization-checklist.md
유병철 012a661a19 refactor(WEB): 회계/결재/건설 등 공통화 3차 및 검색/상태 유틸 추가
- search.ts: 범용 검색 유틸리티 추출 (텍스트/날짜/상태 필터링)
- status-config.ts: 상태 설정 공통 유틸 추가
- 회계 모듈 types 간소화 및 컬럼 설정 공통 패턴 적용
- 회계 page.tsx 통일 (bad-debt/bills/deposits/sales 등 9개)
- 결재함(승인/기안/참조) 공통 패턴 적용
- 건설 모듈 견적/인수인계/이슈/기성 등 코드 정리
- IntegratedListTemplateV2 개선
- LanguageSelect/ThemeSelect 정리
- 체크리스트 문서 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:26:27 +09:00

25 KiB
Raw Blame History

코드 중복 제거 및 공통화 체크리스트

작성일: 2026-02-19 기반: 4개 에이전트 병렬 분석 결과 (회계 page.tsx / 회계 컴포넌트 / 유틸 중복 / 비회계 페이지) 구조: 6개 작업 패키지 (WP) — 의존성 기반 병렬화 설계


작업 패키지 의존성 맵

Phase 1 (독립 — 전부 병렬 가능):
  [x] WP-1: 날짜 하드코딩 긴급 수정 (10파일) ✅
  [x] WP-2: formatAmount/formatDate import 통일 (35+파일) ✅
  [x] WP-3: 차량관리 edit 페이지 리다이렉트 전환 (6파일) ✅

Phase 2 (Phase 1 완료 후 — 서로 간 병렬 가능):
  [x] WP-4: 공통 훅 추출 (useDateRange, useAccountingListPage 등) ✅
  [x] WP-5: 회계 컴포넌트 공통 패턴 추출 (팩토리 함수, 공통 컴포넌트) ✅

Phase 3 (Phase 2 완료 후):
  [x] WP-6: .toISOString().split('T')[0] → getTodayString() 전환 (15파일 26건) ✅

병렬 실행 판단 기준

판단 조건
병렬 가능 수정 파일이 겹치지 않고, 새 유틸/훅에 의존하지 않음
순차 필요 새로 만드는 훅/유틸을 다른 WP에서 import해야 하는 경우

WP-1: 날짜 필터 하드코딩 긴급 수정 완료 (2026-02-19)

심각도: 🔴 CRITICAL (데이터 누락 버그) 난이도: 낮음 | 파일 수: 10 | 예상 변경량: 각 2줄 병렬: Phase 1 — 독립 실행 가능

현황

매출관리와 동일한 버그. 2025-xx-xx 하드코딩으로 잘못된 기간 데이터 표시.

수정 완료

WP-4에서 useDateRange('currentYear') 적용으로 이미 수정된 파일:

  • accounting/DepositManagement/index.tsx
  • accounting/WithdrawalManagement/index.tsx
  • accounting/BillManagement/index.tsx

이번 세션에서 추가 발견 및 수정한 파일 (동일 버그):

  • accounting/BillManagement/BillManagementClient.tsx — 실제 page에서 사용되는 컴포넌트 ('2025-09-01'~'2025-09-03'useDateRange('currentYear'))
  • accounting/PurchaseManagement/index.tsx — ('2025-01-01'~'2025-12-31'useDateRange('currentYear'))
  • approval/ApprovalBox/index.tsx — ('2025-09-01'~'2025-09-03'useDateRange('currentYear'))
  • approval/ReferenceBox/index.tsx — ('2025-09-01'~'2025-09-03'useDateRange('currentYear'))
  • approval/DraftBox/index.tsx — ('2025-01-01'~'2025-12-31'useDateRange('currentYear'))
  • process-management/ProcessListClient.tsx — ('2025-01-01'~'2025-12-31'useDateRange('currentYear'))
  • hr/VacationManagement/index.tsx — ('2025-12-01'~'2025-12-31'useDateRange('currentMonth'))
  • hr/SalaryManagement/index.tsx — ('2025-12-01'~'2025-12-31'useDateRange('currentMonth'))
  • pricing-table-management/PricingTableListClient.tsx — ('2025-01-01'~'2025-12-31'useDateRange('currentYear'))
  • checklist-management/ChecklistListClient.tsx — ('2025-01-01'~'2025-12-31'useDateRange('currentYear'))

검증

  • npx tsc --noEmit 통과
  • useState('2025 잔존 0건 확인

WP-2: formatAmount / formatDate import 통일 완료 (2026-02-19)

심각도: 🟡 HIGH (코드 품질) 난이도: 낮음 | 파일 수: 24파일 수정 / 10파일 스킵 | 예상 변경량: 각 파일 2-5줄 (로컬 함수 삭제 + import 추가) 병렬: Phase 1 — 독립 실행 가능

2-A: formatAmount/formatNumber/formatCurrency 통일 — 21파일 완료

canonical: src/lib/utils/amount.tsformatNumber(), formatAmountWon()

  • VehicleDispatch 3파일 → import { formatNumber as formatAmount } from '@/lib/utils/amount'
  • 결재 문서 5파일 → import { formatNumber as formatCurrency } from '@/lib/utils/amount'
  • SalesDetail, PurchaseDetail → import { formatNumber as formatAmount } from '@/lib/utils/amount'
  • GiftCertificateManagement, DailyReport → import { formatNumber as formatAmount } from '@/lib/utils/amount'
  • StageCard, ProjectCard → import { formatNumber as formatAmount } from '@/lib/utils/amount'
  • ProjectListClient → import { formatAmountWon as formatAmount } from '@/lib/utils/amount'
  • PricingTableForm, PricingTableListClient → import { formatNumber } from '@/lib/utils/amount'
  • DirectConstructionContent, IndirectConstructionContent → import { formatNumber } from '@/lib/utils/amount'
  • SubscriptionClient, SubscriptionManagement → import { formatAmountWon as formatCurrency } from '@/lib/utils/amount'

스킵 (다른 동작):

  • ReceivablesStatus (0일 때 '' 반환), VendorLedger (0일 때 '' 반환), VendorLedgerDetail (괄호 옵션)
  • CEODashboard/components.tsx (showUnit 옵션)

2-B: formatDate 통일 — 3파일 완료

canonical: src/lib/utils/date.tsformatDate()

  • OrderManagementListClient, OrderManagementUnified, ConstructionManagementListClient → import { formatDate } from '@/lib/utils/date'

스킵 (다른 출력 형식 — canonical formatDate와 비호환):

  • BoardDetail, BoardForm (formatDateTime: YYYY-MM-DD HH:MM)
  • SubscriptionClient, SubscriptionManagement (한국어: YYYY년 M월 D일)
  • PermissionManagement (date-fns format 사용)
  • ProductionDashboard (M/D 형식)
  • HandoverReportDocumentModal (한국어 long date)

검증

  • TypeScript 빌드 에러 없음 확인
  • 각 수정 파일에서 포맷 결과가 기존과 동일한지 확인 (동일 로직 import)

WP-3: 차량관리 edit 페이지 리다이렉트 전환 이전 세션에서 완료

심각도: 🟡 HIGH (코드 중복) 난이도: 낮음 | 파일 수: 6 (3쌍) 병렬: Phase 1 — 독립 실행 가능

현황

이전 세션에서 이미 완료됨. 3개 edit 페이지 모두 리다이렉트 스텁으로 교체되어 있고, 3개 [id]/page.tsx 모두 useSearchParams로 mode를 읽고 있음.

수정 완료

  • vehicle-management/vehicle/[id]/edit/page.tsxrouter.replace(...?mode=edit) 리다이렉트 스텁
  • vehicle-management/vehicle/[id]/page.tsxuseSearchParams + mode 처리
  • vehicle-management/forklift/[id]/edit/page.tsx → 리다이렉트 스텁
  • vehicle-management/forklift/[id]/page.tsxuseSearchParams + mode 처리
  • vehicle-management/vehicle-log/[id]/edit/page.tsx → 리다이렉트 스텁
  • vehicle-management/vehicle-log/[id]/page.tsxuseSearchParams + mode 처리

WP-4: 공통 훅 추출 완료 (2026-02-19)

심각도: 🟡 HIGH (아키텍처 개선) 난이도: 중간 | 신규 파일: 2개 | 적용 파일: 18개 병렬: Phase 2 — WP-4와 WP-5는 서로 병렬 가능.

4-A: useDateRange 훅 — 15파일 적용 완료

위치: src/hooks/useDateRange.ts 프리셋: 'currentYear' | 'currentMonth' | 'today' | 'none'

  • src/hooks/useDateRange.ts 생성
  • 회계 5개 컴포넌트 적용:
    • SalesManagement → useDateRange('currentYear')
    • DepositManagement → useDateRange('currentYear')
    • WithdrawalManagement → useDateRange('currentYear')
    • BillManagement → useDateRange('currentYear')
    • GiftCertificateManagement → useDateRange('currentMonth') (date-fns import 제거)
  • 건설 10개 ListClient 적용 (모두 useDateRange('today') — UTC 버그도 동시 수정):
    • ProgressBillingManagementListClient, OrderManagementListClient
    • ConstructionManagementListClient, IssueManagementListClient
    • WorkerStatusListClient, PricingListClient
    • UtilityManagementListClient, SiteManagementListClient
    • StructureReviewListClient, HandoverReportListClient

스킵 (비호환):

  • ExpectedExpenseManagement (현재월 ~ 3개월 후 커스텀 범위)
  • TaxInvoiceIssuance (filters 객체 패턴, 별도 날짜 관리)

4-B: useAccountingListPage 훅 — 3개 page.tsx 적용 완료

위치: src/hooks/useAccountingListPage.ts 효과: 50줄 → 20줄 (DEFAULT_PAGINATION + useSearchParams + useEffect + state 통합)

  • src/hooks/useAccountingListPage.ts 생성 (DEFAULT_PAGINATION 포함)
  • src/hooks/index.ts에 양쪽 훅 export 추가
  • 회계 3개 page.tsx 적용:
    • accounting/sales/page.tsx (56줄 → 22줄)
    • accounting/deposits/page.tsx (53줄 → 20줄)
    • accounting/withdrawals/page.tsx (53줄 → 20줄)

미적용 (패턴 비호환):

  • bills: 추가 searchParams (billType, page, vendorId)
  • expected-expenses: mode 없음, 커스텀 fetch params
  • gift-certificates: 리스트 자체 로딩, edit 모드 별도
  • bad-debt-collection: Promise.all + summary
  • vendors: total 사용 (pagination 미사용)
  • tax-invoice-issuance: 복합 mode (edit+id), Promise.all

검증

  • TypeScript 빌드 에러 없음 확인
  • 15파일 useDateRange 적용 + 3파일 useAccountingListPage 적용

WP-5: 회계 컴포넌트 공통 패턴 추출 완료

심각도: 🟢 MEDIUM (코드 품질) 난이도: 중간 | 신규 파일: 1개 | 영향 파일: 5개 컴포넌트 병렬: Phase 2 — WP-4와 서로 병렬 가능 (겹치는 파일 없음)

5-A: 팩토리 함수 추출

위치: src/components/accounting/shared/index.ts (신규 생성)

4개 유틸리티 함수 생성 및 적용:

  • createDeleteItemHandler(deleteFn, setData, msg) — 4개 컴포넌트 적용 (Sales, Deposit, Withdrawal, Bill)
    • 7줄 inline handler → 1줄 팩토리 호출 (컴포넌트당 -6줄)
  • extractUniqueOptions(data, fieldKey, opts?) — 5개 컴포넌트 적용 (Sales, Deposit, Withdrawal, Bill, ExpectedExpense)
    • 4-6줄 useMemo body → 1줄 호출 (컴포넌트당 -3~5줄)
  • createDateAmountSortFn(dateField, amountField, direction) — 3개 컴포넌트 적용 (Sales, Deposit, Withdrawal)
    • 15줄 switch문 → 1줄 팩토리 호출 (컴포넌트당 -14줄)
    • Bill은 'maturityDate' 추가 정렬이 있어 제외, ExpectedExpense는 createdAt 정렬이라 제외
  • computeMonthlyTotal(data, dateField, amountField) — 3개 컴포넌트 적용 (Sales, Deposit, Withdrawal)
    • 6줄 (currentMonth/currentYear + filter + reduce) → 1줄 (컴포넌트당 -5줄)

5-B: 스코프 조정 (계획 대비)

적용하지 않은 항목과 사유:

  • createFilterFn — 각 컴포넌트의 customFilterFn이 너무 상이 (필드명, 조건문 구조 다름). 추상화 비용 > 이점
  • AccountSubjectSavePanel — UI+로직이 각 컴포넌트마다 미묘하게 다름 (Withdrawal은 배열, Deposit은 Set). 현재 수준으로 충분
  • useRefreshableData — Deposit/Withdrawal 2곳만 사용. 훅 생성 오버헤드가 이점을 초과

검증

  • TypeScript 빌드 에러 없음 (npx tsc --noEmit 통과)
  • 삭제/정렬/필터 로직이 기존과 동일한 동작 보장 (동일한 switch/filter 구현을 shared로 이동)

정량 결과

  • 삭제된 중복 코드: ~120줄 (5파일 × 평균 24줄/파일)
  • 신규 공통 코드: ~130줄 (shared/index.ts)
  • 순 효과: 중복 제거 + 단일 소스 오브 트루스 확보

WP-6: toISOString UTC 버그 전환 완료 (2026-02-19)

심각도: 🟢 MEDIUM (잠재적 타임존 버그) 난이도: 중간 | 파일 수: 15파일 26건 | 예상 변경량: 각 1-2줄 병렬: Phase 3 — WP-4의 useDateRange가 먼저 필요 (일부 파일 중복)

현황

new Date().toISOString().split('T')[0]은 UTC 기준이라 KST 00:00~08:59에 전날 날짜 반환. src/lib/utils/date.tsgetTodayString()/getLocalDateString() 이미 존재.

수정 완료

건설관리 10파일 — WP-4에서 useDateRange('today')로 이미 수정됨 (Phase 2에서 완료)

getTodayString() 적용 (7파일, 11건):

  • quotes/QuoteTransactionModal.tsx — const today 초기화 (1건)
  • vehicle-management/VehicleLogList/actions.ts — writeDate + createdAt 기본값 (2건)
  • pricing-table-management/actions.ts — create/update changedDate (2건)
  • pricing-table-management/PricingTableForm.tsx — 변경일 Input value (1건)
  • material/ReceivingManagement/actions.ts — reportDate ×2 + today 변수 (3건)
  • material/ReceivingManagement/ReceivingDetail.tsx — adjustmentDate (1건)
  • accounting/TaxInvoiceManagement/ManualEntryModal.tsx — writeDate 기본값 (1건)

getLocalDateString() 적용 (7파일, 13건):

  • pricing-distribution/PriceDistributionList.tsx — startDate + endDate (2건)
  • pricing-distribution/actions.ts — createdAt + effectiveDate (2건)
  • material/StockStatus/StockStatusList.tsx — startDate + endDate (2건)
  • quality/InspectionManagement/InspectionList.tsx — startDate + endDate (2건)
  • material/ReceivingManagement/ReceivingList.tsx — startDate + endDate (2건)
  • outbound/ShipmentManagement/ShipmentList.tsx — startDate + endDate (2건)
  • outbound/VehicleDispatchManagement/VehicleDispatchList.tsx — startDate + endDate (2건)

both 적용 (1파일, 2건):

  • accounting/TaxInvoiceManagement/CardHistoryModal.tsx — today (getTodayString) + monthAgo (getLocalDateString)

검증

  • npx tsc --noEmit 통과 — TypeScript 에러 0건
  • src/ 내 잔여 .toISOString().split('T')[0] = 0건 (date.ts 주석 1건 제외)

병렬 실행 계획 요약

┌─────────────────────────────────────────────────────────────┐
│ Phase 1 (독립 — 동시 3개 병렬)                                │
│                                                             │
│  WP-1 날짜 하드코딩    WP-2 format 통일    WP-3 edit 리다이렉트  │
│  (3파일, ~10분)       (35파일, ~40분)     (6파일, ~20분)       │
│  ↓                   ↓                  ↓                   │
├─────────────────────────────────────────────────────────────┤
│ Phase 2 (Phase 1 완료 후 — 동시 2개 병렬)                      │
│                                                             │
│  WP-4 공통 훅 추출              WP-5 컴포넌트 공통화            │
│  (신규 2-3파일 + 70파일 적용)    (신규 3-5파일 + 7파일 적용)     │
│  ↓                              ↓                           │
├─────────────────────────────────────────────────────────────┤
│ Phase 3 (Phase 2 완료 후)                                     │
│                                                             │
│  WP-6 toISOString UTC 버그 전환                               │
│  (60+파일, 가장 큰 작업)                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Phase별 병렬 가능 근거

Phase WP 조합 병렬 가능 이유
1 WP-1 + WP-2 + WP-3 수정 파일이 완전히 겹치지 않음. 기존 유틸만 사용, 신규 생성 없음
2 WP-4 + WP-5 WP-4는 hooks/ + page.tsx, WP-5는 components/accounting/shared/ + 컴포넌트 내부. 파일 겹침 없음
3 WP-6 단독 WP-4의 useDateRange 훅을 일부 파일에서 활용해야 하므로 Phase 2 이후

WP-7: .toLocaleString() → formatNumber() 마이그레이션 완료 (2026-02-19)

심각도: 🟢 MEDIUM (코드 일관성) 난이도: 낮음 | 파일 수: 52파일, 183건 | 방법: Node.js 자동 마이그레이션 스크립트

수정 완료

  • 52개 파일에서 183건 .toLocaleString()formatNumber() 자동 치환
  • formatNumber import 자동 추가
  • 5개 파일 수동 import 수정 (double-quote import 패턴)

검증

  • npx tsc --noEmit 통과
  • src/ 내 잔여 .toLocaleString() = 0건 (amount.ts 내부 제외)

WP-8: 인라인 formatDate → date.ts import 마이그레이션 완료 (2026-02-19)

심각도: 🟢 MEDIUM (코드 일관성) 난이도: 낮음 | 파일 수: 21파일, 32건 | 방법: Node.js 자동 마이그레이션 스크립트

수정 완료

  • .split('T')[0]formatDate() 변환 (21파일)
  • new Date().toISOString().slice(0, 10)getTodayString() 변환
  • dateVar.toISOString().slice(0, 10)getLocalDateString(dateVar) 변환
  • 6개 파일 수동 import 수정 (JSDoc 삽입 버그)

스킵 항목

  • ?.split('T')[0] || '' — formatDate는 null일 때 '-' 반환 (falsy 의미 다름)
  • .toLocaleDateString() — 42건, 로케일 표시 형식으로 canonical과 비호환
  • .toISOString().slice(0,10).replace(/-/g,'') — YYYYMMDD 형식 (파일명용)

검증

  • npx tsc --noEmit 통과

WP-9: useDeleteDialog 훅 채택 확대 완료 (2026-02-20)

심각도: 🟢 MEDIUM (코드 일관성) 난이도: 중간 | 전체 후보: ~56파일 | 기존 채택자: 7파일

완료된 작업 (9파일)

  • src/hooks/index.ts에 useDeleteDialog export 추가
  • settings/RankManagement/index.tsx 마이그레이션 (단건 삭제, number ID)
  • settings/TitleManagement/index.tsx 마이그레이션 (단건 삭제, number ID)
  • settings/AccountManagement/AccountDetail.tsx 마이그레이션 (상세→삭제→목록, number ID)
  • settings/PermissionManagement/PermissionDetailClient.tsx 마이그레이션 (상세→삭제→목록, number ID)
  • accounting/DepositManagement/DepositDetail.tsx 마이그레이션 (상세→삭제→목록)
  • accounting/WithdrawalManagement/WithdrawalDetail.tsx 마이그레이션 (상세→삭제→목록)
  • hr/CardManagement/CardDetail.tsx 마이그레이션 (상세→삭제→목록)
  • board/BoardDetail/index.tsx 마이그레이션 (deletePost 클로저 캡처, 2-arg delete)
  • board/BoardManagement/BoardDetailClientV2.tsx 마이그레이션 (deleteBoard + forceRefreshMenus)

의도적 스킵 (마이그레이션 비적합)

  • settings/AccountManagement/AccountDetailForm.tsx — prop 기반 삭제 + isSaving 공유
  • settings/PermissionManagement/PermissionDetail.tsx — prop 기반 + IntegratedDetailTemplate 연동
  • settings/PermissionManagement/index.tsx — bulk+single 혼합 다이얼로그
  • board/CommentSection/CommentItem.tsx — void onDelete prop, 행동 변경됨
  • hr/EmployeeManagement/index.tsx — 780줄, 복잡한 useMemo, 위험도 높음
  • hr/DepartmentManagement/index.tsx — bulk+single 혼합 다이얼로그
  • settings/PopupManagement/PopupDetailClientV2.tsx — IntegratedDetailTemplate 내부 처리

최종 채택 현황: 7(기존) + 9(신규) = 16파일

검증

  • npx tsc --noEmit 통과 (모든 수정 파일 tsc 에러 0건)

Phase 간 의존성 상세

의존 관계 이유
WP-4 → WP-1 WP-1에서 수정한 날짜 초기값 패턴을 useDateRange 훅 설계에 반영
WP-5 → WP-2 WP-2에서 통일된 formatAmount를 공통 컴포넌트에서 import
WP-6 → WP-4 useDateRange가 getTodayString()을 내부 사용하므로 훅 완성 후 적용

WP-10: 검색 필터 유틸 search.ts 완료 (2026-02-20)

심각도: 🟢 MEDIUM (코드 일관성) 난이도: 중간 | 신규 파일: 1개 | 적용 파일: 9개

10-A: search.ts 유틸 생성

위치: src/lib/utils/search.ts (~70줄)

  • filterByText<T>(data, query, fields, options?) — 텍스트 검색 (case-insensitive 기본)
  • filterByEnum<T>(data, field, value, allValue?) — enum 필터 ('all' short-circuit)
  • filterByDateRange<T>(data, field, startDate?, endDate?) — 날짜 범위 필터
  • applyFilters<T>(data, filters) — 필터 체이닝 파이프라인
  • textFilter, enumFilter, dateRangeFilter — 팩토리 함수 (applyFilters용)

10-B: 회계 모듈 적용 (9파일)

# 파일 변경 내용 상태
1 VendorManagement/VendorManagementClient.tsx useMemo 체인 → applyFilters (text 3필드 + enum 4개)
2 BadDebtCollection/index.tsx customFilterFn → applyFilters (enum 2개)
3 ExpectedExpenseManagement/index.tsx useMemo 체인 → applyFilters (text 3필드 + enum 1개)
4 SalesManagement/index.tsx customFilterFn → applyFilters (enum 2개 + issuance 인라인 유지)
5 DepositManagement/index.tsx customFilterFn → applyFilters (text 4필드 + enum 2개)
6 WithdrawalManagement/index.tsx customFilterFn → applyFilters (text 4필드 + enum 2개)
7 CardTransactionInquiry/index.tsx filteredData useMemo → filterByEnum (1개)
8 ReceivablesStatus/index.tsx filteredData useMemo → filterByText (1필드)
9 GiftCertificateManagement/index.tsx customFilterFn → applyFilters (enum 2개)

스킵: BillManagement — 서버 사이드 필터링 (API params), 클라이언트 사이드 필터 없음

검증

  • npx tsc --noEmit 통과 (기존 orders/actions.ts 1건 외 에러 0건)

WP-11: 상태 설정 채택 확대 완료 (2026-02-20)

심각도: 🟢 MEDIUM (코드 일관성) 난이도: 중간 | 수정 파일: status-config.ts + types.ts 4개

11-A: 도메인별 상태 설정 추가 (status-config.ts)

7개 회계 도메인 설정 추가:

  • BAD_DEBT_COLLECTION_STATUS_CONFIG (collecting, legalAction, recovered, badDebt)
  • TAX_INVOICE_STATUS_CONFIG (pending, journalized, error)
  • BILL_STATUS_CONFIG (stored~dishonored 8개)
  • SALES_STATUS_CONFIG (monthlyClose, lastMonth, agreed, outstanding)
  • DEPOSIT_STATUS_CONFIG (inputWaiting~confirmed 7개)
  • PAYMENT_STATUS_CONFIG (pending, partial, paid, overdue)
  • MATCH_STATUS_CONFIG (matched, unmatched)

11-B: types.ts 인라인 상수 마이그레이션 (4파일)

# 파일 제거한 인라인 상수 대체
1 BadDebtCollection/types.ts COLLECTION_STATUS_LABELS, STATUS_BADGE_STYLES, STATUS_FILTER_OPTIONS, STATUS_SELECT_OPTIONS BAD_DEBT_COLLECTION_STATUS_CONFIG re-export
2 ExpectedExpenseManagement/types.ts PAYMENT_STATUS_LABELS, PAYMENT_STATUS_FILTER_OPTIONS PAYMENT_STATUS_CONFIG re-export
3 DailyReport/types.ts MATCH_STATUS_LABELS, MATCH_STATUS_COLORS MATCH_STATUS_CONFIG re-export
4 DepositManagement/types.ts DEPOSIT_STATUS_LABELS, DEPOSIT_STATUS_COLORS DEPOSIT_STATUS_CONFIG re-export

스킵 (shape 비호환):

  • SalesManagement — SALES_STATUS_LABELS에 'all' 키 포함, STATUS_LABELS와 shape 불일치
  • TaxInvoiceManagement — INVOICE_STATUS_MAP{label, color} 결합 형태, 분리하면 더 복잡
  • WithdrawalManagement — WITHDRAWAL_TYPE 설정 미추가 (status가 아닌 type 분류)
  • BillManagement — 수취/발행 분기 헬퍼 함수 복잡

검증

  • npx tsc --noEmit 통과 (기존 orders/actions.ts 1건 외 에러 0건)
  • types.ts re-export로 소비 컴포넌트 import 경로 변경 불필요

WP-12: Loading Skeleton 전환 (GenericPageSkeleton → ListPageSkeleton) 완료 (2026-02-20)

심각도: 🟢 MEDIUM (UX 개선) 난이도: 낮음 | 파일 수: 9 | 예상 변경량: 각 2줄 (import + JSX)

현황

회계 모듈 9개 page.tsx가 GenericPageSkeleton(form 레이아웃 고정)을 사용하여 실제 리스트 페이지 구조(필터+통계카드+테이블)와 불일치. 이미 ListPageSkeleton이 존재하지만 회계 모듈에서 미사용.

수정 완료 (9파일)

# 파일 props 상태
1 accounting/deposits/page.tsx showStats statsCount={4} tableColumns={7}
2 accounting/sales/page.tsx showStats statsCount={4} tableColumns={10}
3 accounting/withdrawals/page.tsx showStats statsCount={4} tableColumns={7}
4 accounting/bad-debt-collection/page.tsx showDateRange={false} showCreateButton={false} showStats statsCount={4} tableColumns={8}
5 accounting/bills/page.tsx tableColumns={9}
6 accounting/expected-expenses/page.tsx showStats statsCount={2} tableColumns={7}
7 accounting/vendors/page.tsx showDateRange={false} showStats statsCount={3} tableColumns={10}
8 accounting/tax-invoice-issuance/page.tsx showStats statsCount={4} tableColumns={10}
9 accounting/gift-certificates/page.tsx showStats statsCount={4} tableColumns={8}

검증

  • npx tsc --noEmit 통과 (기존 orders/actions.ts 1건 외 에러 0건)
  • GenericPageSkeleton 회계 모듈 내 잔존 0건
  • 브라우저 화면 검수: Slow 3G + CPU 20x 쓰로틀링으로 스켈레톤 캡처 확인
  • vendors 페이지 showCreateButton 수정 (화면 검수에서 발견)