[FE-29] 1단계 배선 · 통합
작업 내용 (설계 의도)
근거: 지원 관리 확장 FE 웹 설계 화면 목록 > 기존 화면 확장(S-04 관리 상태 섹션) · S-16·S-17 진입 경로 · 1단계 라우팅 흐름 · Query 규약 > 무효화 매핑 · BE 역제안 4건 — 전부 수용의 C-1(공고 상세 dedupGroupId·watchState 확정) · Single Writer per File 검증 > 단계 1 wave 3, 지원 관리 확장 TDD 1단계 — 관리 상태 (FR-73~77) · 상태 전이 표의 FR-75 항목.
변경 사항
- 단계 1의 마지막 wave 단독 통합 티켓입니다. wave 2의 6개 티켓이 각자 컴포넌트를 만들되 공통 파일 배선은 전부 여기로 미뤘습니다 — 같은 wave에서
WatchlistCard.tsx·JobPostingDetailPage.tsx를 여러 티켓이 건드리면 머지 충돌이 나기 때문입니다. pages/posting/WatchStateSection.tsx를 신규로 만들고JobPostingDetailPage.tsx에 배선합니다. 이 섹션은 현재 관리 상태(칩·우선순위·목표일·태그)를 요약해 보여 주고, 분류 시트(S-16)와 상세 편집 시트(S-17) 진입점을 제공합니다.pages/watchlist/WatchlistCard.tsx의[분류]버튼에 S-16 시트를 실제로 연결합니다. FE-24는 버튼과disabled조건까지만 만들었고, FE-25는 시트만 만들었습니다.- 역제안 계약 1이 확정돼 초안의 블로커가 해제됐습니다(C-1). 공고 상세 응답에
dedupGroupId·watchState2필드가 추가되므로, 라우터 state 폴백·임시 분기·“직접 URL 진입 시 섹션 미렌더” 제약은 전부 삭제합니다.- 진입 경로와 무관하게 응답의
dedupGroupId를 단일 경로로 소비합니다 — 보관함 카드 탭·디스코드 알림 딥링크·직접 URL·새로고침 어느 쪽이든 관리 상태 섹션이 완전히 동작합니다. watchState가 상세 응답에 함께 오므로 상세 화면은 관리 상태 조회를 위한 추가 왕복을 하지 않습니다. 섹션은 응답 값으로 곧바로 렌더합니다.watchState === null은 미분류(정상)입니다(C 확정) — 기본 폼으로 열고 관리 상태 선택 UI를 활성한 채 “아직 분류하지 않은 공고예요”를 안내합니다. 오류로 표시하지 않고 404 분기를 만들지 않습니다(미분류는 404가 아닙니다).409 FEATURE_DISABLED면 관리 상태 섹션을 숨깁니다(또는 “준비 중”).watchlist.management플래그 OFF 구간이며 사용자 조작 실패가 아니므로 롤백 토스트를 띄우지 않습니다. 공고 상세의 나머지 섹션은 그대로 렌더됩니다.dedupGroupId === null(08:30 배치 전)이어도 분류는 가능합니다 — 저장 경로 분기는useSaveWatchState(FE-25)가 흡수하므로 이 티켓의 배선은 그대로입니다.
- 진입 경로와 무관하게 응답의
- 지원 생성 시의 FR-75 ① 자동 복구를 화면에서 확인합니다 —
EXCLUDED였던 공고에 지원을 만들면 서버가 관리 상태를INTERESTED로 되돌립니다. FE는 이 전이를 스스로 계산하지 않고, 지원 생성 성공 후['job-postings','cross-company']와['dedup-groups', id]접두사를 무효화해 서버가 내려준 값으로 갱신합니다. - 마찬가지로
hasApplication은 서버 파생 값입니다. FE가 지원 목록과 대조해 계산하지 않고 응답 값을 그대로AppliedBadge표시에 씁니다(FR-73). - 지원 생성 기존 무효화 매핑에
['job-postings','cross-company']와['dashboard']를 추가하고, 상태 전이·면접 생성 기존 무효화에['dashboard']를 추가합니다 — 보관함과 대시보드가 지원 도메인의 변화를 즉시 반영해야 합니다. - 1단계 라우팅 흐름 전체를 통합 검증합니다: 부팅 → 세션 → 게이트 → 보관함 → 분류 시트 → 공고 상세 → 상세 편집 시트, 대시보드 → 지원 상세 → 담당자 시트.
롤백: WatchStateSection 배선과 카드의 시트 연결을 제거하면 wave 2 산출물이 각자 고립된 상태로 되돌아가며, 기존 공고 상세·보관함은 그대로 동작합니다.
의존
- FE-24 —
WatchlistCard(분류 버튼·disabled조건). - FE-25 —
WatchStateSheet·WatchStateDetailSheet·WatchStatusChip·WatchPriorityMark와 mutation. - FE-23 — 인증 게이트 구현(통합 흐름 검증의 시작점).
- BE-48 — dedup 그룹·MANUAL·platform. BE-55 — 1단계 E2E.
- BE-52 — 공고 상세 확장 응답(
dedupGroupId·watchState). C-1 확정 계약이며, 이 값이 있어야 딥링크·직접 URL 진입에서 관리 상태 섹션이 동작합니다.
다이어그램
처리 흐름
sequenceDiagram participant User as 사용자 participant List as WatchlistCard participant Detail as JobPostingDetailPage participant Section as WatchStateSection participant Sheet as WatchState 시트 User->>List: 카드 탭 List->>Detail: /job-postings/:id 이동 Detail->>Section: 상세 응답의 dedupGroupId · watchState 전달 Section->>Sheet: 관리 정보 편집 열기 Sheet-->>Section: 저장 후 목록·상세 무효화
컴포넌트 의존
flowchart LR Card[WatchlistCard FE-24] --> Sheet[WatchStateSheet FE-25] Detail[JobPostingDetailPage] --> Section[WatchStateSection] Section --> Sheet Section --> DetailSheet[WatchStateDetailSheet FE-25] Section --> Chip[WatchStatusChip FE-25] Detail --> Contract["상세 응답 dedupGroupId · watchState"] Contract --> Section Create[지원 생성] --> Invalidate[cross-company · dashboard 무효화]
테스트 케이스
- 보관함 카드의
[분류]를 누르면 S-16 시트가 열리고 상태를 고르면 카드 칩이 갱신된다. dedupGroupId === null인 카드의[분류]도 활성이고 시트가 열려 분류가 저장된다.- 보관함에서 카드를 탭해 공고 상세로 진입하면 관리 상태 섹션이 렌더되고 현재 상태·우선순위·태그가 보인다.
- 공고 상세에 직접 URL로 진입해도(보관함 경유 없음) 관리 상태 섹션이 렌더되고 현재 상태·우선순위·태그가 보인다.
- 상세 응답의
watchState === null이면 관리 상태 섹션이 미분류 기본 폼으로 열리고 선택 UI가 활성이며 에러 표시가 보이지 않는다. - 관리 상태가
409 FEATURE_DISABLED면 관리 상태 섹션이 숨겨지고 롤백 토스트가 뜨지 않으며 공고 상세의 다른 섹션은 정상 렌더된다. - 배선 코드에 미분류를 404로 처리하는 분기가 0건이다.
- 공고 상세 진입 시 관리 상태를 위한 추가 조회 요청이 발생하지 않고 상세 응답의
watchState만 소비한다. - 디스코드 딥링크로 공고 상세에 진입해도 관리 상태 섹션이 완전히 동작한다(분류·상세 편집 모두 가능).
- 공고 상세의 다른 섹션은 관리 상태 섹션 유무와 무관하게 정상 렌더된다.
- 관리 상태 섹션에서 상세 편집 시트를 열어 저장하면 시트가 닫히고 섹션 값이 갱신된다.
- 관리 상태 저장 성공 시 보관함 목록과 공고 상세 쿼리가 함께 무효화된다.
EXCLUDED공고에 지원을 생성하면 무효화 후 재조회 결과의 관리 상태가INTERESTED로 표시되고, FE가 전이를 자체 계산하지 않는다.- 지원 생성 성공 시
['job-postings','cross-company']와['dashboard']가 무효화된다. - 상태 전이·면접 생성 성공 시
['dashboard']가 무효화된다. hasApplication=true인 공고에AppliedBadge가 보이고, FE가 지원 목록과 대조해 계산하지 않는다.- 미인증 상태에서 보관함·대시보드·공고 상세 어느 경로로 진입해도 로그인 화면으로 이동한다.
- 관리 상태 섹션을 다크 모드로 렌더하면 시맨틱 토큰 class만 사용하고 하드코딩 색이 0건이다.