[FE-49] 3단계 회귀 · 다크 모드 · 접근성 전수 점검
작업 내용 (설계 의도)
근거: 지원 관리 확장 FE 웹 설계 Testing Plan(레벨별 필수 케이스) · Testing Plan > 반드시 커버할 실패·엣지 경로 #48 · 테마 토큰(검증) · 접근성 · Release Scenario — 점진 공개 · Single Writer per File 검증 > 단계 3 wave 3 · Open Questions #8.
변경 사항
- 3단계를 닫는 검증 전용 티켓입니다. 테스트 파일만 수정합니다 — 프로덕션 파일을 이 티켓에서 고치면 wave 2·3 티켓의 소유 경계가 무너지고 리뷰 대상이 뒤섞입니다. 수정이 필요한 결함을 발견하면 해당 담당 티켓에 되돌려 보고하고, 이 티켓은 재검증만 수행합니다.
- [소유권 확정 2026-08-09] 색 가드 헬퍼는 만들지 않고 소비만 합니다. 렌더 단위 색 가드
web/src/test/hardcodedColor.ts(expectNoHardcodedColor)는 1단계 FE-20 소유이므로main에서 import해 씁니다. 이 헬퍼는 팔레트 이름을 검사하지 않습니다(정당한 시맨틱 토큰bg-neutral-chip-bg를 오탐하므로) — 원색 리터럴(#hex·rgb())만 봅니다. 파일 단위 소스 스캔인theme/no-hardcoded-color.test.ts와는 다른 층이며, 이 티켓은 둘 다 소비하고 어느 쪽도 새로 만들지 않습니다. - 3단계 신규 화면 4종(연락 검토 목록·연락 검토 상세·추천도 가중치·운영 소스 상태)의 다크 모드 렌더를 전수 확인합니다. 기존
components/**/darkMode.test.tsx선례를 따르고,theme/no-hardcoded-color스캔이 신규 디렉토리를 실제로 훑어 하드코딩 색 0건임을 재확인합니다(스캔은 디렉토리 재귀이므로 신규 파일이 자동 포함되는지까지 확인합니다). - 접근성을 항목별로 점검합니다 — 대시보드 칸반 컬럼의
aria-label(건수 포함)과 가로 스크롤 컨테이너의 키보드 접근, 추천도 게이지의role="meter"+aria-valuenow/min/max+ 숫자 텍스트 병기, 반영 불가 후보의disabled+aria-disabled+ 사유aria-describedby연결, 시트의 포커스 트랩·Esc닫기·role="dialog", 파일 입력의<label htmlFor>연결. - 색·길이만으로 정보를 전달하지 않는지 확인합니다 — 신뢰도 칩·소스 상태 칩·축 충족 표시에 텍스트 라벨이 항상 병기되는지 점검합니다. 다크 모드에서 톤이 바뀌어도 의미 전달이 유지돼야 합니다.
- 1·2단계 화면 회귀를 확인합니다 — 인증 게이트를 통과한 뒤 기존 11개 화면이 3단계 배선(대시보드 배너·공고 상세 섹션·운영 세그먼트) 추가 후에도 정상 동작하는지, 탭 5개 구조와 라우팅이 유지되는지 봅니다.
- 점진 공개 하위 호환을 회귀 케이스로 고정합니다 —
contact.inbound-webhookOFF(연락 0건 긍정 빈 상태),source.registry-statusOFF(registryStatus: null→ 상태 미확인),matching.field-weighted-scopeOFF·재평가 전(matchScore: null→ 기존matched폴백). 플래그를 조회하지 않고 응답 형태만으로 하위 호환되는지 확인합니다. - 완료 기준은
tsc --noEmit·eslint·vitest run이 전부 exit code 0입니다. 파이프로 tail을 걸어 실패를 가리지 않고 exit code로 판정합니다. - Open Question 8을 이 티켓에서 판단합니다 — 기존
web/scripts/capture-usecases.mjs(Playwright) 하네스에 3단계 신규 화면을 등록할지 결정합니다. 단위 테스트는.dark클래스 렌더만 확인하고 실제 대비를 보지 않으므로, 등록하면 스크린샷으로 대비를 눈으로 확인할 수 있습니다. 등록 여부와 사유를 결정해 문서(Open Questions)에 반영합니다.
의존
- FE-42 · FE-43 · FE-44 · FE-45 · FE-46 — 3단계 wave 2 화면·컴포넌트 전부가 병합돼 있어야 전수 점검이 성립합니다.
- FE-47 — 착수된 경우에만 매칭 근거 박스를 점검 대상에 포함합니다(계약 미확정으로 미착수면 제외하고
matchScore: null폴백만 확인). - FE-48 — 대시보드 배너·공고 상세 배선이 회귀 점검 대상입니다.
- BE-79 — 3단계 E2E·통합 검증과 짝을 이룹니다.
다이어그램
처리 흐름
sequenceDiagram participant Runner as 검증 실행 participant Dark as 다크 모드 렌더 테스트 participant Scan as no-hardcoded-color 스캔 participant A11y as 접근성 속성 점검 participant Gate as 완료 판정 Runner->>Dark: 3단계 화면 4종 .dark 렌더 Runner->>Scan: 신규 디렉토리 재귀 스캔 Runner->>A11y: meter·aria-disabled·포커스 트랩 확인 Dark-->>Gate: 통과 여부 Scan-->>Gate: 하드코딩 색 0건 여부 A11y-->>Gate: 속성 누락 여부 Gate-->>Runner: tsc·eslint·vitest exit code 0
컴포넌트 의존
flowchart LR Suite[3단계 검증 스위트] --> ContactList[연락 목록 화면] Suite --> ContactDetail[연락 상세 화면] Suite --> Weight[가중치 화면] Suite --> Registry[소스 상태 세그먼트] Suite --> Wiring[대시보드 배너 · 공고 상세 배선] Suite --> Legacy[1·2단계 기존 화면] Suite --> ColorScan[no-hardcoded-color 스캔] Suite --> Capture[capture-usecases 하네스 판단]
테스트 케이스
- 3단계 신규 화면 4종을
.dark로 렌더하면 전부 정상 렌더되고 라이트 모드와 동일한 정보가 보인다. no-hardcoded-color스캔이 3단계 신규 디렉토리를 포함해 실행되고 하드코딩 색 0건을 보고한다.- 대시보드 칸반 컬럼에 건수를 포함한
aria-label이 붙고 가로 스크롤 컨테이너를 키보드로 조작할 수 있다. - 추천도 게이지에
role="meter"와aria-valuenow·aria-valuemin·aria-valuemax가 있고 숫자 텍스트가 함께 보인다. - 반영 불가(
terminal) 후보가aria-disabled와aria-describedby로 사유에 연결된다. - 3단계 시트·다이얼로그가 포커스 트랩과
Esc닫기를 유지하고role="dialog"계약을 승계한다. - 신뢰도 칩·소스 상태 칩·축 충족 표시가 색뿐 아니라 텍스트 라벨을 항상 병기한다.
- 인증 게이트를 통과한 뒤 기존 11개 화면이 3단계 배선 추가 후에도 정상 렌더되고 탭 5개 구조가 유지된다.
- 연락 0건·
registryStatus: null·matchScore: null응답에서 각각 긍정 빈 상태·상태 미확인 칩·기존 매칭 표시 폴백이 나오고 오류로 표현되지 않는다. tsc --noEmit·eslint·vitest run이 전부 exit code 0으로 종료한다.- 프로덕션 파일 수정이 필요한 결함을 발견하면 이 티켓에서 고치지 않고 담당 티켓으로 되돌려 보고한 기록이 남는다.
capture-usecases하네스에 3단계 신규 화면을 등록할지 결정하고 그 사유가 기록된다.