doclib 기능 모듈 리팩토링 계획 및 1차 실행 결과
작성자: Manus AI 기준 브랜치: main시작 기준 커밋: f5681d887011d3110c3d8886b8d68f88d728aa7e
1. 목표
doclib의 기능이 단일 main 브랜치와 대형 관리 페이지에 누적되면서, 기능의 소유 위치를 한눈에 파악하기 어려워졌다. 이번 리팩토링은 기존 화면 경로와 데이터 동작을 유지하면서 소스코드를 관리자, 게시판, 권한 관리, 첨부파일, API 관리의 다섯 모듈로 재구성한다.
main은 검증된 기능이 누적되는 안정 브랜치로 유지한다. 복잡도는 브랜치 개수가 아니라 화면·상태·API 책임의 경계를 명확하게 나누어 관리한다.
| 원칙 | 적용 기준 | 1차 결과 |
|---|---|---|
| 기능 우선 배치 | 업무별 화면·상태·API를 동일한 기능 폴더 아래에 둔다. | 다섯 최상위 기능 모듈을 도입했다. |
| 얇은 라우트 진입점 | 라우트 파일은 화면 조합 또는 재내보내기만 담당한다. | pages/Admin.tsx는 AdminPage 재내보내기로 축소했다. |
| 공개 경계 | 다른 기능은 기능 모듈의 index.ts만 사용한다. | 게시판·권한·첨부파일·API 관리 모듈에 공개 진입점을 추가했다. |
| 행동 보존 | URL, 탭 식별자, HTTP API와 저장 데이터 형식을 유지한다. | 타입 검사와 프로덕션 빌드를 통과했다. |
| 점진적 상태 분리 | 공용 Provider를 즉시 삭제하지 않고 도메인 계약부터 이동한다. | 생성·수정 입력 타입과 첨부 보관 타입을 기능별 state로 이동했다. |
2. 적용한 구조
client/src/
features/
admin/
components/
AdminSummaryDashboard.tsx
Modal.tsx
PasswordChangeModal.tsx
pages/
AdminPage.tsx
index.ts
boards/
components/
BoardAdministration.tsx
CategoryAdministration.tsx
CategoryAuditExplorer.tsx
state/types.ts
index.ts
access/
components/
GroupsPanel.tsx
OrganizationAdministration.tsx
RoleReassignmentWidget.tsx
UsersPanel.tsx
state/types.ts
index.ts
attachments/
api/document-library-api.ts
components/FilesPanel.tsx
state/types.ts
index.ts
api-management/
components/
ApiKeyManagement.tsx
ApiMonitoringWidget.tsx
ArchiveApiGuide.tsx
SwaggerArchiveExplorer.tsx
index.ts
contexts/
PortalDataContext.tsx
pages/
Admin.tsx관리 화면의 대형 로컬 패널은 기능 소유 폴더로 추출했다. 게시판·카테고리·감사 로그는 boards, 사용자·그룹·조직도·역할 재지정은 access, 파일 목록·삭제·복구·첨부파일 HTTP 클라이언트는 attachments, API 키·문서·탐색기·상태 모니터링은 api-management가 소유한다. 관리 페이지는 탭 URL 상태, 권한 검사 및 기능 컴포넌트 조합만 담당한다.1 2
| 모듈 | 현재 소유 책임 | 외부 사용 방식 |
|---|---|---|
admin | 관리 레이아웃, 대시보드, 비밀번호 변경, 공용 모달 | AdminPage를 라우트에서 재내보낸다. |
boards | 게시판·카테고리 관리와 감사 로그 | @/features/boards의 공개 export를 사용한다. |
access | 사용자·그룹·조직도·역할 재지정 | @/features/access의 공개 export를 사용한다. |
attachments | 파일 관리, 파일 보관 상태, 다운로드·업로드 API | @/features/attachments의 화면·API export를 사용한다. |
api-management | API 키, API 가이드, API 탐색, 상태 모니터링 | @/features/api-management의 공개 export를 사용한다. |
3. 공용 상태 경계
PortalDataContext는 기존 호환성을 위해 유지하되, 게시판·권한 관리의 생성·수정 입력 타입과 첨부파일 보관 상태 타입을 각 기능의 state/types.ts에서 가져오도록 바꿨다. 이 변경으로 Provider가 모든 도메인 계약을 정의하지 않게 되었고, 다음 단계에서 검증 함수·명령 함수·영속화 코드를 도메인별 훅으로 옮길 수 있는 기반을 만들었다.3
| 다음 분리 대상 | 현재 위치 | 후속 목적 |
|---|---|---|
| 게시판 명령 | PortalDataContext의 카테고리·게시판 CRUD 함수 | boards/state로 이동해 게시판 규칙을 한곳에 둔다. |
| 권한 명령 | 사용자·그룹·조직도 변경 함수 | access/state와 Directory API 경계로 이동한다. |
| 첨부파일 명령 | 삭제·복구·파일 보관 상태 | attachments/state와 Archive API 경계로 이동한다. |
| 영속화 조합 | 여러 도메인을 동시에 저장하는 effect | 최종적으로 각 기능의 저장 훅을 조합하는 얇은 Provider로 축소한다. |
4. 검증 결과
| 검증 항목 | 결과 | 비고 |
|---|---|---|
| TypeScript 검사 | 통과 | pnpm check 성공 |
| 프로덕션 빌드 | 통과 | Vite 클라이언트 빌드 및 Node 서버 번들 성공 |
| 단위 테스트 | 37개 통과, 2개 스킵 | 외부 비밀정보가 필요 없는 테스트 전부 통과 |
| 외부 연동 테스트 | 2개 보류 | ARCHIVE_API_KEY, Cloudflare R2 환경변수가 현재 검증 환경에 없어 실패했으며 리팩토링 코드 오류는 아님 |
프로덕션 번들은 생성되었으며, JavaScript 번들 크기 경고는 기존 애플리케이션의 코드 분할 개선 과제로 남는다. 이 리팩토링은 기능 경계를 명확히 해 이후 관리자·첨부파일·API 관리 화면을 지연 로딩으로 전환하기 쉽게 만든다.
5. 후속 개발 규칙
새 기능은 우선 해당 기능 모듈 안에 화면·상태·API 파일을 둔다. 여러 기능에 걸치는 화면은 페이지 계층에서 공개 export를 조합하며, 한 기능이 다른 기능의 내부 components 또는 state 파일을 직접 import하지 않는다. 공통 UI만 components/ui에 두고, 공통 도메인 타입은 shared에 둔다.
비디오 스트리밍 개발은 이번 main 반영 후 갱신된 feature/video-streaming 브랜치에서 시작한다. 스트리밍 기능은 새 기능 모듈로 두되, 파일 선택·업로드는 attachments, 접근 판단은 access의 공개 경계를 통해 연결한다.