Skip to content

refactor: 프론트엔드 미사용 코드 정리 (869줄) + knip 게이트 승격 - #249

Merged
k002bill2 merged 5 commits into
mainfrom
refactor/dead-code-cleanup
Aug 9, 2026
Merged

refactor: 프론트엔드 미사용 코드 정리 (869줄) + knip 게이트 승격#249
k002bill2 merged 5 commits into
mainfrom
refactor/dead-code-cleanup

Conversation

@k002bill2

Copy link
Copy Markdown
Owner

요약

대시보드의 미사용 코드를 5배치로 정리하고, 재발을 막도록 CI knip 게이트를 승격했습니다.
51파일 869줄 삭제, 기능 변경 없음.

knip Unused exports 88 → 8, Unused files 8 → 0, Duplicate exports 19 → 0.

배치 구성

커밋 내용 지표
93469f3 미사용 파일 8건 삭제 files 8 → 0
f64d3bc knip 게이트 승격 + 중복 default export 19건 duplicate 19 → 0
abb35a1 스켈레톤 7종 (barrel 줄 + 파일 동시) exports 69 → 55
b45ffb8 barrel 7종 미사용 재노출 29줄 exports 55 → 27
95cbbe5 dead code 함수·컴포넌트 12건 + export 축소 4건 exports 27 → 8

게이트 승격 (재발 방지)

- "knip": "knip --dependencies"
+ "knip": "knip --dependencies --include files"
+ "knip:all": "knip"

CI frontend-knip(required)이 이제 미사용 파일도 차단합니다.
exports/types까지 켜지 않은 이유는 잔여 86건이 즉시 CI를 빨간불로 만들기 때문이며,
백엔드 mypy의 래칫 전략(pyproject.toml disable_error_code)과 같은 방식으로
현재 수준에서 고정하고 악화만 막습니다. 조사는 게이트 밖 knip:all로 합니다.

검증

배치마다 아래 5종을 전부 통과(exit 0)했고, 각 배치에 Codex 외부 리뷰를 돌려 지적 0건입니다.

게이트 최종 결과
tsc --noEmit exit 0
eslint 에러 0
knip (CI 게이트) exit 0
vitest run 205 파일 / 4365 테스트 통과 (5배치 내내 불변)
vite build 성공
test:coverage threshold 에러 없음 — Statements 71.67% → 71.96%, Lines 72.86% → 73.13%

판정 근거에 대한 메모

정적 "unused" 판정을 그대로 신뢰하지 않고 모듈 그래프로 확인했습니다. 실제로 세 번 갈렸습니다.

  1. 상대경로 grep은 판정 불가'../audit'이 출발 디렉토리에 따라 stores/audit
    components/audit 중 무엇을 가리키는지 달라집니다
  2. 형제 파일 참조 — barrel 29줄 제거 시 고아 파일이 0건이었습니다. 소비자가 같은
    디렉토리의 형제 파일이라 경로 기반 grep에는 보이지 않습니다
  3. unused export ≠ 미사용 — knip의 unused export는 "외부에서 안 쓰인다"입니다.
    같은 파일 안에서 쓰이는 것은 본체를 두고 export만 제거했습니다
    (splitArgs/applySandboxPreset, formatTrendLabel/normalizeProvider)

남긴 것

  • unused exports 8건 — 테스트 동반 삭제 필요(feedback 셀렉터 3종),
    이름 단위 편집(MergeRequestCard), 스토어 구현체 멀티라인 블록(orchestration 4종).
    각각 별도 판단이 필요해 이번 범위에서 제외했습니다
  • exported types 78건 — 정리 권고하지 않습니다. TS 타입은 컴파일 시 소거되어 출력
    변화가 0이고 게이트 대상도 아닌 반면, FastAPI↔React 계약 타입이라 integration-qa
    대조 근거로 쓰입니다
  • AuditLogFilter 중복 정의 (stores/audit.ts:31, components/audit/AuditLogTable.tsx:45)
    — 삭제가 아니라 통합 리팩터 후보라 손대지 않았습니다
  • 백엔드 ERA001 21건 / ARG 81건 — 별건. 크로스모듈 dead code는 vulture 설치 선행 필요

테스트 계획

  • npm run type-check / npm run lint / npm run knip
  • npm run test:coverage (4365건 통과, 임계치 충족)
  • npm run build
  • Codex 외부 리뷰 5회 (배치별) — 지적 0건
  • CI 7개 job 통과 확인

🤖 Generated with Claude Code

https://claude.ai/code/session_017UEJENahpFQRnU6aYKkH7V

k002bill2 and others added 5 commits August 9, 2026 20:11
knip이 unused file로 판정한 8건을 제거한다. 삭제 후 tsc/eslint/vitest/build
4개 게이트로 실제 미참조를 확인했다 — 상대경로 import는 출발 디렉토리에 따라
해석이 달라져 grep만으로는 판정할 수 없다.

- barrel 4종: components/{analytics,audit,permissions,version-control}/index.ts
- stores/index.ts (각 스토어를 직접 import하는 구조라 미사용)
- ProjectAgentCard.tsx, TerminalSelector.tsx
- types/branded.ts (도입만 되고 사용처 없음)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017UEJENahpFQRnU6aYKkH7V
CI frontend-knip 게이트가 `--dependencies` 로만 돌아 미사용 파일 재발을 잡지
못했다. `--include files` 를 더해 파일 리포터를 켠다. 전체 리포터(exports/types)
로 올리지 않은 이유는 잔여 149건이 즉시 CI를 빨간불로 만들기 때문이다 —
백엔드 mypy 와 동일한 래칫 전략으로 현재 수준에서 고정하고 악화만 막는다.
조사용으로는 `knip:all` 스크립트를 별도 추가했다.

memo() 컴포넌트가 named + default 를 이중 export 하던 19건에서 default 를
제거한다. routes.tsx 는 lazy import 시 named 를 default 로 감싸는 형태라
영향이 없고, default import 사용처는 0건으로 확인했다.
knip Duplicate exports 19건 → 0, Unused exports 88 → 69.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017UEJENahpFQRnU6aYKkH7V
skeletons barrel에서 재노출만 되고 소비처가 없던 7종을 barrel 줄과 컴포넌트
파일을 함께 제거한다. barrel 줄만 지우면 파일이 고아가 되어 직전 커밋에서
승격한 knip files 게이트가 CI에서 이를 잡는다 — 두 변경은 같은 배치여야 한다.

유지: SidebarSkeleton, DashboardSkeleton, ProjectsGridSkeleton (사용 중)
knip Unused exports 69 → 55.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017UEJENahpFQRnU6aYKkH7V
barrel에서 재노출되지만 소비처가 없던 export를 제거한다. 소비자들은 해당
컴포넌트를 직접 import하고 있어 파일은 고아가 되지 않는다 — 고아 판정은
grep이 아니라 knip 모듈 그래프에 맡겼다. 같은 디렉토리 형제 파일의 import는
경로 기반 grep으로는 보이지 않아 오판을 낳는다.

대상: claude-sessions, feedback, git, monitor, organizations,
      project-configs, usage
knip Unused exports 55 → 27, exported types 80 → 78.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017UEJENahpFQRnU6aYKkH7V
knip이 unused export로 지목한 27건 중 소비자가 전혀 없는 것은 본체까지 제거하고,
같은 파일 안에서 쓰이는 것은 export 키워드만 뗐다. 두 경우가 knip 리포트에서는
동일하게 보이므로 파일 내부 호출 여부를 개별 확인했다 — 이 구분을 놓쳤을 때
verificationGuard 훅이 TS2304로 차단했다(splitArgs/applySandboxPreset).

본체 제거:
- ErrorBoundary.tsx Lazy* 5종 (주석이 "Code-split page examples"인 예제 코드,
  실제 lazy 라우팅은 routes.tsx가 담당)
- ui/Skeleton.tsx 변형 7종 (사용 중인 Skeleton·SkeletonStatCard 유지)
- admin/api.ts fetchMenuVisibility
- routes.tsx viewToPath/pathToView (동작하는 구현은 stores/navigation.ts에 별도 존재)

export 축소(내부 사용은 유지):
- analytics/utils.tsx formatTrendLabel, normalizeProvider
- llm-access/utils.ts splitArgs, applySandboxPreset

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017UEJENahpFQRnU6aYKkH7V
@k002bill2
k002bill2 merged commit da3daa1 into main Aug 9, 2026
9 checks passed
@k002bill2
k002bill2 deleted the refactor/dead-code-cleanup branch August 9, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant