Phase 5 전체 리팩토링 계획 및 잔여 작업 목록
1. 결론
Phase 5의 핵심 목표는 포털 운영 화면과 공통 composite를 Ant Design의 표현 계층과 상태 계층으로 통일하면서, 기존 포털의 public API, callback payload, design token, CSS class contract를 유지하는 것이다. 현재 menuManagement와 PortalExploreDialog의 주요 native control 전환은 완료되었다. 남은 작업은 새로운 대형 컴포넌트를 무분별하게 추가하는 것이 아니라, Theme policy 저장 흐름의 표준화, 관리 컴포넌트의 후속 adapter 정리, public export 분리, token·legacy CSS 정리, 통합 접근성 검증 순서로 진행하는 것이 적절하다.
모든 native element를 제거하는 것이 목표는 아니다.
button과a처럼 의미와 keyboard 동작이 명확한 semantic element는 유지할 수 있다. 전환 대상은 자체 스타일·상태·validation을 중복 구현하는 입력, 목록, modal, feedback primitive이다.
2. 현재까지 완료된 범위
| Phase | 완료된 주요 범위 | 보존한 계약 |
|---|---|---|
| Phase 0–1 | antd, @ant-design/icons, PortalConfigProvider, theme mapping | design token, theme-client contract, provider API |
| Phase 2 | AuthCard, ThemePicker, BrandMark, icon facade | 기존 props, callback, class names, accessibility semantics |
| Phase 3 | menu adapter, icon facade, PortalShell, PortalAdminShell, PortalThemePolicySettings 1차 전환, DirectoryManagement | permission policy, navigation model, directory adapter |
| Phase 4 | data shells, PortalDialog, PortalTree, field/tabs/table primitive, asset attachment | loading/empty/error/success state, query adapter, table/tree contract |
| Phase 5 진행 | menuManagement 상세 field·quick link·validation, PortalExploreDialog | controlled payload, search callback, permission-filtered result, legacy wrapper classes |
현재 로컬 기준 검증은 다음과 같다.
ui-react test files: 9 passed
ui-react tests: 38 passed
ui-react typecheck: passed
workspace build scope: design-tokens, theme-client, ui-react passedAnt Design 6의 기존 List deprecation warning과 SSR Modal portal warning은 기능 실패가 아니며, 아래 P1 작업에서 별도 처리한다.
3. Phase 5 잔여 대상 목록
P0: PortalThemePolicySettings 저장 흐름 강화
PortalThemePolicySettings.tsx는 이미 Card, Radio, Checkbox.Group, Select, Button을 사용한다. 그러나 저장 상태가 local useState에만 있고, field validation, server error, reset/cancel, dirty state가 명시적인 계약으로 정리되어 있지 않다. 따라서 이 컴포넌트는 primitive 전환 대상이 아니라 Form 상태 계약 강화 대상이다.
| 작업 | 구현 기준 | 검증 |
|---|---|---|
| Form ownership | Form과 Form.Item을 사용해 field label/help/error 연결 | field accessible name |
| 초기값 | value를 기준으로 초기 상태를 명시하고 controlled update 정책 문서화 | 초기 policy equality |
| 정책 validation | 승인·게시 상태, selectable list, default theme 관계 검증 | invalid submit 차단 |
| 저장 상태 | saving 동안 submit 중복 실행 차단 | button loading/disabled |
| server error | field key 기반 오류를 UI error list로 변환 | retry 시 입력 보존 |
| reset/cancel | 초기 snapshot과 현재 상태 비교 | dirty state callback 또는 내부 표시 |
| accessibility | aria-describedby, error association, keyboard radio/select | keyboard-only test |
권장 adapter:
mapPortalThemePolicyErrors(
errors: Record<string, string | string[]>
): Record<string, string[]>기존 onSave(policy) payload는 변경하지 않는다.
P1: PortalMenuManagement 후속 정리
메뉴 편집의 주요 control은 Ant Design으로 전환되었다. 다음 후속 작업은 기능 추가보다 입력 adapter와 edge case 검증에 초점을 둔다.
| 대상 | 계획 |
|---|---|
| access scopes | 값 목록이 제공될 때 Select mode="multiple"을 사용하고, 목록이 없을 때 comma-separated 자유 입력 유지 |
| roles/group IDs | 서버 제공 option 유무에 따라 동일한 dual-mode adapter 적용 |
| parent group | 자기참조, disabled group, DIVIDER/GROUP parent 금지 검증 |
| reorder | 순서 변경 후 sortOrder 재계산과 updatedAt 일관성 검증 |
| reserved menu | system reserved menu의 disable/delete 방지 |
| validation | Alert 표시, role, focus 이동, issue 식별자 검증 |
| list primitive | 현재 Ant Design List의 Listy 대체 가능성 확인 후 버전 전략 기록 |
권장 adapter:
portalAccessRuleToSelectValues(rule, field)
selectValuesToPortalAccessRule(rule, field, values)adapter는 원본 access rule을 직접 변경하지 않고 새 객체를 반환해야 한다.
P1: PortalExploreDialog 후속 검증
PortalExploreDialog의 Ant Design 구현은 완료되었다. 남은 작업은 사용성 및 통합 검증이다.
Modalopen/close와 ESC 동작Input.Search입력·Enter·clear callback- loading, empty, answer, citation 상태
- result selection payload와 close 동작
onAsk중복 실행 방지- focus return과 accessible dialog name
getContainer={false}의 SSR·소비 포털 동작 확인- 결과
href이동 정책과onSelect우선순위 확인
P1: index.tsx public composite 분리
현재 root entrypoint에는 BrandMark, AuthCard, ThemePicker, PortalButton, DirectorySyncAdminPanel, AdminSection, OperationalMetricGrid, AdminEmptyState, AdminFeedback 등 여러 composite가 함께 있다. 이 파일을 바로 breaking change로 나누지 않고, feature 파일을 만든 뒤 root에서 compatibility re-export하는 방식으로 분리한다.
권장 구조:
src/auth/AuthCard.tsx
src/branding/BrandMark.tsx
src/explore/PortalExploreDialog.tsx
src/admin/DirectorySyncAdminPanel.tsx
src/admin/AdminSection.tsx
src/theme/ThemePicker.tsx
src/navigation/menuManagement.tsx
src/index.tsx # public compatibility facade분리 기준은 visual size가 아니라 domain ownership이다. 순수 type과 low-level adapter는 기존 feature 파일에 남길 수 있다.
P1: DirectorySyncAdminPanel 및 admin feedback 표준화
DirectorySyncAdminPanel은 현재 StatusBadge와 PortalButton을 사용하지만, error와 sync status 표시가 native paragraph 기반이다. 다음을 표준화한다.
- 상태별
Alert또는Result사용 여부 결정 - sync error의
role="alert" - sync action의 loading/disabled/async rejection 처리
- organization/user metric을
Statistic또는 기존 token metric 중 하나로 통일 AdminSection,AdminFeedback,AdminEmptyState의 status semantics 통일
이 작업은 public props를 변경하지 않고, status rendering과 accessibility만 보강한다.
P2: Data/content primitive deprecation 처리
Phase 4에서 전환한 dataShells, contentComponents, assetAttachments에는 Ant Design List 사용이 남아 있다. Ant Design 6에서 Listy가 안정적으로 사용할 수 있는지 확인한 뒤 결정한다.
| 결과 | 조치 |
|---|---|
Listy가 동일한 key/render contract 제공 | adapter를 만들고 Listy로 교체 |
| API가 다르거나 안정성이 부족 | List 유지, 버전 pin과 migration note 추가 |
| portal CSS와 충돌 | wrapper class만 유지하고 item primitive CSS 위임 |
SSR Modal warning은 test setup에서 client-like container를 제공하거나, component의 portal strategy를 문서화하여 처리한다.
P2: Token·legacy CSS 정리
Ant Design primitive의 색상과 크기는 PortalConfigProvider의 component token을 우선한다. styles.css는 layout, wrapper spacing, responsive behavior, legacy class contract만 담당해야 한다.
정리 대상:
- native input/select/button에만 필요한 중복 스타일
- Ant Design DOM class에 직접 결합된 selector
pf-*상태 색상과 Ant Design semantic color 중복 정의- light/dark theme에서 대비가 깨지는 고정 색상
- focus-visible ring을 덮어쓰는 legacy selector
보존 대상:
pf-*public wrapper class- portal layout grid와 responsive breakpoint
- consumer가 의존할 수 있는 semantic role과 label
- design token variable 이름
4. 전체 실행 순서
| 순서 | 작업 | 산출물 | 완료 기준 |
|---|---|---|---|
| 1 | Theme policy Form·error adapter | policy source, adapter, tests | invalid submit 차단 및 정상 payload 유지 |
| 2 | menu access adapter | pure adapter, edge case tests | scope/role/group payload 손실 없음 |
| 3 | ExploreDialog 통합 접근성 | interaction tests, SSR note | dialog/search/result/answer 흐름 통과 |
| 4 | DirectorySync/admin feedback 표준화 | admin components, status tests | loading/error/status semantics 통일 |
| 5 | public composite export 분리 | feature files, root re-export | 기존 import path와 declaration 유지 |
| 6 | List/Listy 및 Modal warning 결정 | migration note 또는 adapter | warning 처리 전략 고정 |
| 7 | token/CSS audit | CSS diff, theme regression tests | primitive style duplication 감소 |
| 8 | workspace 통합 검증 | smoke test, release checklist | build/check/test와 접근성 기준 통과 |
5. 테스트 계획
단위 테스트
각 컴포넌트는 정상 상태만 검증하지 않고 loading, empty, error, disabled, submitting, permission-filtered 상태를 함께 검증한다. Callback assertion은 호출 횟수만 확인하지 않고 payload의 구조와 불변성까지 확인한다.
접근성 테스트
| 영역 | 검증 항목 |
|---|---|
| Modal | dialog role, accessible name, ESC, close button, focus return |
| Form | label association, error association, keyboard navigation, disabled explanation |
| List | list/item semantics, actionable item keyboard operation |
| Feedback | alert/status live region, error severity, readable contrast |
| Theme | light/dark focus ring, disabled contrast, selected state |
| Shell | navigation landmark, active item, responsive menu close |
통합 테스트
통합 테스트는 다음 사용자 흐름을 하나의 소비 포털 관점에서 확인한다.
PortalConfigProvider에서 light/dark theme을 설정한다.PortalShell에서 navigation과 search를 연다.PortalExploreDialog에서 query를 입력하고 결과를 선택한다.PortalMenuManagement에서 메뉴를 생성하고 access rule을 수정한다.PortalThemePolicySettings에서 정책 저장 성공·실패·재시도를 실행한다.DirectoryManagement에서 filter, pagination, mutation을 실행한다.AssetAttachmentList에서 empty와 download action을 확인한다.
최종 명령은 다음과 같다.
pnpm -r build
pnpm -r check
pnpm -r test추가로 SSR static render, keyboard-only navigation, reduced motion, light/dark theme, legacy CSS class contract를 확인한다.
6. 리스크와 대응
| 리스크 | 영향 | 대응 |
|---|---|---|
| Form으로 변경하면서 controlled callback timing 변화 | 소비 포털 상태 동기화 오류 | callback adapter를 순수 함수로 분리하고 payload snapshot 테스트 추가 |
Select multiple 전환 중 자유 문자열 손실 | 권한 정책 손상 | option이 없으면 기존 Input 유지 |
| Modal portal과 SSR 차이 | 테스트·초기 hydration 경고 | client container 전략을 명시하고 SSR 테스트 분리 |
| Ant Design 6 deprecation | 다음 major upgrade 비용 증가 | List/Listy spike와 migration note를 Phase 5 완료 조건에 포함 |
| legacy CSS 제거로 소비 포털 레이아웃 변화 | 시각적 회귀 | wrapper class와 visual contract를 먼저 snapshot |
| root export 분리 중 declaration 변화 | compile-time breaking change | dist .d.ts 비교와 compatibility re-export 유지 |
7. Phase 5 완료 기준
Phase 5는 다음 조건을 모두 충족할 때 완료한다.
menuManagement의 주요 입력·목록·validation surface가 Ant Design 기반이다.PortalExploreDialog가 Ant Design Modal/Search/List 상태 흐름을 사용한다.PortalThemePolicySettings가 명시적인 Form validation과 save error 계약을 갖는다.DirectorySyncAdminPanel과 admin feedback의 status semantics가 통일된다.- 기존 public props, exports, callback payload, permission policy가 유지된다.
- loading, empty, error, success, disabled, submitting 상태가 표준화된다.
- dialog, form, live region, focus, keyboard interaction이 테스트된다.
- provider token과 legacy wrapper CSS의 책임이 분리된다.
List/Listy와 SSR Modal warning의 처리 방침이 문서화된다.- 전체 workspace build, check, test와 대표 소비 포털 smoke test가 통과한다.
8. 권장 완료 일정
| 기간 | 범위 |
|---|---|
| 1일차 | Theme policy Form, error adapter, save/reset tests |
| 2일차 | menu access adapter, reserved/parent/reorder edge cases |
| 3일차 | ExploreDialog interaction/accessibility integration tests, DirectorySync feedback |
| 4일차 | public export split and declaration compatibility check |
| 5일차 | List/Listy decision, token/CSS audit, light/dark regression |
| 6일차 | workspace integration smoke test, migration note, release checklist |
일정은 순차 작업 기준이며, 각 작업의 테스트와 typecheck가 완료된 뒤 다음 범위로 이동한다.