[FE-13] 지원 목록 화면

작업 내용 (설계 의도)

근거 설계: 20260722-공고알림앱-design-fe-web.md — “S-06 지원 목록” 근거 요구: FR-50(회사 단위 분류) · FR-42(미지원 = 기록 미존재) · NFR-5(무기한 보존)

변경 사항

“지금 어디까지 진행됐나”만 답하는 화면입니다(토스 1 thing per 1 page). 카드에 회사·공고명·현재 상태·마지막 전이일만 두고 그 이상 넣지 않습니다.

핵심 설계 의도:

  • 진행 중과 종료를 섹션으로 분리합니다. 섞이면 “지금 신경 쓸 것”을 고를 수 없습니다. NFR-5로 종료된 지원이 계속 쌓이므로 종료 섹션은 5건을 넘으면 “더 보기”로 접습니다 — 시간이 지날수록 진행 중 항목이 종료 항목에 묻히는 것을 막는 장치입니다.
  • REJECTED는 탈락 시점 단계를 병기합니다(“불합격 · 서류전형”). 이 정보가 목록에 없으면 어느 단계에서 떨어졌는지 확인하려고 매번 상세에 들어가야 합니다.
  • 회사 필터는 URL search params가 SSOT입니다(?companyId=) — 뒤로가기·링크 공유가 동작해야 합니다.
  • 삭제 UI를 만들지 않습니다 — 지원 이력은 무기한 보존합니다(NFR-5, BE에 삭제 엔드포인트 없음).
  • 지원 기록 생성 진입점을 이 화면에 두지 않습니다 — 생성은 공고 상세(FE-11)에서만 가능합니다. 공고 없이 지원이 존재할 수 없기 때문이며(FR-42), 여기에 생성 버튼을 두면 공고 선택이라는 단계가 중복됩니다.

계약 리스크 (blocking): 목록 카드가 companyName·jobPostingTitle·currentStatus·rejectedAtStage·lastTransitedAt에 의존하는데 TDD 계약이 “목록”으로만 명시돼 있습니다 → 계약 요청 #8. 회사명·공고명 없이는 무엇에 지원했는지 식별할 수 없어 화면이 성립하지 않습니다.

범위: src/pages/application/ApplicationListPage.tsx(스텁 대체), ApplicationCard(이 화면 전용), src/api/application/list.ts, src/hooks/application/useApplications.ts.

Single Writer 주의: api/application/ 아래 create.ts(FE-11)·transition.ts(FE-14)·interview.ts(FE-15)·detail.ts(FE-16)를 건드리지 않습니다.

의존

  • FE-05 (ApplicationStatusChip)
  • BE 의존: BE-14 (지원 목록 조회 API)

다이어그램

처리 흐름

sequenceDiagram
    participant U as 사용자
    participant P as ApplicationListPage
    participant R as useSearchParams
    participant H as useApplications
    participant S as 서버
    U->>P: /applications 진입
    P->>H: companyId (선택)
    H->>S: GET /api/applications
    S-->>P: 지원 목록
    P->>P: 진행 중 · 종료 섹션 분리
    alt 종료 5건 초과
        P-->>U: 5건 + "더 보기"
    else
        P-->>U: 전건
    end
    U->>P: 회사 필터 선택
    P->>R: companyId URL 갱신 후 재조회

클래스 의존

flowchart LR
    subgraph Page["pages/application"]
        List[ApplicationListPage]
        Card[ApplicationCard]
    end
    subgraph Domain["components/domain"]
        SC[ApplicationStatusChip]
    end
    subgraph Hooks["hooks/application"]
        H[useApplications]
    end
    subgraph Api["api/application"]
        A[list.ts]
    end
    subgraph Utils["utils · constants"]
        T[isTerminalStatus]
        D[formatDate]
    end
    List --> H
    List --> Card
    List --> T
    Card --> SC
    Card --> D
    H --> A

테스트 케이스

  • 지원 목록이 회사명·공고명·상태 칩·마지막 전이일과 함께 렌더된다
  • 진행 중 지원과 종료된 지원이 별도 섹션으로 분리 렌더된다
  • 종료 섹션이 진행 중 섹션보다 아래에 렌더된다
  • 종료된 지원이 6건이면 5건만 보이고 “더 보기”가 렌더된다
  • “더 보기” 클릭 시 나머지 종료 지원이 렌더된다
  • REJECTED 지원 카드에 탈락 단계가 병기된다 (“불합격 · 서류전형”)
  • 상태별로 칩 톤이 다르게 렌더된다 (진행 중·합격·불합격·사퇴)
  • 카드 클릭 시 /applications/{id}로 이동한다
  • 회사 필터 선택 시 URL의 companyId가 갱신되고 재조회된다
  • 회사 필터 결과가 0건이면 필터 해제 안내가 포함된 empty가 렌더된다
  • 지원 기록이 전혀 없으면 “공고 상세에서 지원 기록을 남길 수 있어요” empty와 회사 목록 이동 수단이 렌더된다
  • 조회 실패 시 에러 대체와 [다시 시도]가 렌더된다
  • 로딩 중 카드 스켈레톤이 렌더된다
  • 지원 삭제 버튼과 생성 버튼이 존재하지 않는다
  • URL에 companyId를 직접 넣고 진입하면 해당 필터가 적용된 상태로 렌더된다