Skip to content

[FEATURE] 보안 등급별 링크 현황 카드 API 연동#69

Merged
kbh0218 merged 7 commits into
devfrom
feat/#60-security-level-link-status-card-api
May 29, 2026
Merged

[FEATURE] 보안 등급별 링크 현황 카드 API 연동#69
kbh0218 merged 7 commits into
devfrom
feat/#60-security-level-link-status-card-api

Conversation

@kbh0218

@kbh0218 kbh0218 commented May 26, 2026

Copy link
Copy Markdown
Contributor

Closes #60

개요

홈 화면의 보안 등급별 링크 현황 placeholder 영역을 실제 통계 API 기반 카드 UI로 교체했습니다.

백엔드 dev에 이미 머지된 GET /api/v1/analyses/statistics API 계약을 확인한 뒤, 프론트 공통 API 클라이언트 패턴에 맞춰 publicApiRequest로 연동했습니다. 응답은 { safe, caution, danger } 구조로 정리하고, 홈 화면 진입 시 등급별 통계를 조회해 안전/주의/위험 카드에 표시하도록 구성했습니다.

카드 UI는 기존 디자인 토큰인 Colors.brand.verdict.*, Colors.brand.surface, Colors.brand.line, Typography.*를 사용해 구현했습니다. 화면 파일에는 별도 헥스/rgb 색상 하드코딩을 추가하지 않았고, 기존 홈 화면의 섹션 구조와 SectionHeader를 재사용했습니다.

로딩, API 에러, 데이터 없음 상태도 카드 레이아웃을 유지한 채 표시되도록 처리했습니다. 작은 휴대폰에서도 카드 UI가 깨지거나 부자연스럽지 않은 것을 확인했습니다.

주요 구현 내용

  • 홈 화면의 보안 등급별 링크 현황 placeholder 제거
  • safe, caution, danger 등급별 현황 카드 UI 적용
  • GET /api/v1/analyses/statistics 통계 API 연동
  • 통계 응답 타입 VerdictStatisticsResponse 추가
  • 로딩 상태에서 카드 숫자를 -, 보조 문구를 집계 중으로 표시
  • API 에러 상태에서 카드 숫자를 -, 보조 문구를 확인 불가로 표시
  • 데이터 없음 상태에서 카드 숫자 0, 보조 문구 기록 없음 표시
  • 기존 디자인 토큰과 공통 API 클라이언트 패턴 준수

파일별 역할

  • api/analyses.ts: verdict 통계 응답 타입 및 fetchVerdictStatistics API 함수 추가
  • app/(tabs)/(home)/index.tsx: 홈 화면 보안 등급별 현황 카드 UI, API 조회, 로딩/에러/빈 상태 처리

해결한 이슈 목록

  • 홈 화면의 보안 등급별 링크 현황 placeholder 구조 확인
  • 표시 등급 기준을 safe, caution, danger로 정리
  • 등급별 현황 카드 UI 적용
  • 각 등급별 라벨, 개수, 색상, 시각 요소 정의
  • 로딩 상태 처리
  • API 에러 및 데이터 없음 상태 처리
  • 백엔드 등급별 통계 API 존재 여부 확인
  • 기존 API 응답 구조를 프론트 타입으로 정리
  • 공통 API 클라이언트 패턴에 맞춰 API 연동
  • 홈 화면 진입 시 등급별 현황 데이터 조회
  • 작은 휴대폰에서 카드 UI 깨짐 여부 확인

체크 사항

  • 커밋/코딩 컨벤션에 맞게 작성
  • API_ERD_WORKING_NOTES.md 기준에 따라 프론트 레포 안에서만 코드 수정
  • 백엔드 코드는 수정하지 않고 API 계약 확인 용도로만 사용
  • API base URL, Authorization, { data: ... } unwrap을 직접 처리하지 않음
  • npx tsc --noEmit 통과
  • npm run lint 통과
  • 화면 파일에 헥스/rgb/rgba 색상 하드코딩 없음 확인
  • 기존 저장 링크 목록/북마크/삭제/제목 수정 흐름은 유지

참고사항

  • API endpoint: GET /api/v1/analyses/statistics
  • 실제 백엔드 응답은 { data: { safe, caution, danger } } 형태이며, 프론트 공통 API 클라이언트가 data를 unwrap합니다.
  • 해당 API는 백엔드 SecurityConfig 기준 인증 불필요 API입니다.
  • Android 에뮬레이터 및 preview 빌드에서의 실제 API 연동 확인은 PR 이후 추가 확인이 필요합니다.

Screenshots or Video

  • 메인화면 캡쳐본 입니다
일반화면 캡쳐
  • 작은화면의 경우 캡쳐본 입니다
작은화면 캡쳐
  • spring 서버를 끈 상황에 뜨는 화면입니다
로딩,에러,데이터 없음 상태 처리

@kbh0218 kbh0218 requested review from minsoo0506 and sunm2n May 26, 2026 12:47
@kbh0218 kbh0218 self-assigned this May 26, 2026

@sunm2n sunm2n left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 올려주신 화면에서 기록 없음이 뜨는 경우 카드의 상태인 (ex 확인 필요, 접근 주의)등의 위치에 오는 것이 좋아보이지 않아 보입니다.
해당 위치는 카드 색상에 대한 정보를 주는 공간이기 때문에 차라리 0일때 0 그대로 보여주는 것이 -(dash) 보다 좋다고 생각이 됩니다.
또한 지금 코드 상에서

케이스 1 — safe, caution, danger 모두 0

getStatisticsViewStatus의 .every() 조건에 걸려 status = 'empty'
케이스 2 — 일부만 0 (예: safe=5, caution=0, danger=0)

.every() 조건에 안 걸려 status = 'ready'

다음 2가지 상황에서 화면에 기록 없음 혹은 확인 필요와 같은 카드에 대한 정보를 보여주는 것이 일관되지 않는 것으로 확인됩니다 이 부분도 체크 부탁드립니다

Comment thread app/(tabs)/(home)/index.tsx Outdated
return 'loading';
}

if (errorMessage) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

statisticsErrorMessage가 boolean처럼 사용됨 문제

코드:

  const [statisticsErrorMessage, setStatisticsErrorMessage] = useState('');
  // ...
  if (errorMessage) { return 'error'; }  // 실제 문자열 내용은 안 씀

표시되는 에러 문구는 항상 STATISTICS_STATUS_LABELS['error']에서 옵니다.
statisticsErrorMessage의 실제 문자열 값은 전혀 사용되지 않습니다.
나중에 에러 코드별 다른 메시지를 추가하려 할 때 혼동을 줄 수 있는 코드입니다.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다. 해당 상태는 실제 에러 메시지를 화면에 노출하는 용도가 아니라, 통계 조회 실패 여부를 판단하는 플래그로만 사용되고 있었습니다.

기존 statisticsErrorMessage는 문자열 상태였지만 실제 문자열 값은 사용하지 않고 truthy 여부만 확인하고 있었기 때문에, 역할이 더 명확하도록 hasStatisticsError boolean 상태로 변경했습니다.

에러 상태에서 화면에 표시되는 문구는 기존과 동일하게 STATISTICS_STATUS_LABELS.error를 통해 관리하도록 유지했습니다.

@kbh0218

kbh0218 commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

현재 올려주신 화면에서 기록 없음이 뜨는 경우 카드의 상태인 (ex 확인 필요, 접근 주의)등의 위치에 오는 것이 좋아보이지 않아 보입니다. 해당 위치는 카드 색상에 대한 정보를 주는 공간이기 때문에 차라리 0일때 0 그대로 보여주는 것이 -(dash) 보다 좋다고 생각이 됩니다. 또한 지금 코드 상에서

케이스 1 — safe, caution, danger 모두 0

getStatisticsViewStatus의 .every() 조건에 걸려 status = 'empty'
케이스 2 — 일부만 0 (예: safe=5, caution=0, danger=0)

.every() 조건에 안 걸려 status = 'ready'

다음 2가지 상황에서 화면에 기록 없음 혹은 확인 필요와 같은 카드에 대한 정보를 보여주는 것이 일관되지 않는 것으로 확인됩니다 이 부분도 체크 부탁드립니다

피드백 주신 부분 반영했습니다!

기존에는 safe/caution/danger가 모두 0일 때 getStatisticsViewStatus에서 empty 상태로 분기되면서, 각 카드 하단의 상태 설명 영역이 모두 기록 없음으로 변경되고 있었습니다.

해당 영역은 말씀해주신 것처럼 카드 색상 및 등급의 의미를 설명하는 자리라고 판단하여, empty 상태가 카드 내부 문구에 영향을 주지 않도록 수정했습니다.

수정 후에는 통계 값이 모두 0인 경우에도 각 카드는 아래처럼 표시됩니다.

  • 안전: 0 / 문제 없음
  • 주의: 0 / 확인 필요
  • 위험: 0 / 접근 주의

대신 기록 없음은 카드 내부가 아니라 섹션 우측 상태 라벨에서만 표시되도록 분리했습니다.
즉, “전체 통계가 없다”는 정보와 “각 카드가 어떤 등급을 의미하는지”에 대한 정보를 분리했습니다.

또한 기존에는 아래 두 케이스에서 같은 0 값임에도 카드 하단 문구가 다르게 표시되는 문제가 있었습니다.

  • safe=0, caution=0, danger=0 → 기록 없음
  • safe=5, caution=0, danger=0 → 확인 필요, 접근 주의

이를 해결하기 위해 StatisticsViewStatus에서 empty 상태를 제거하고, 모두 0인지 여부는 hasNoStatistics 값으로 별도 판단하도록 변경했습니다.
이제 일부만 0이든 전체가 0이든 카드 하단 문구는 항상 동일하게 카드 등급 설명을 보여줍니다.

0일 때 dash(-) 대신 0을 보여주는 부분은 정상 조회 완료 상태에서는 이미 0이 표시되는 구조였고, dash는 loading/error 상태에서만 표시되고 있었습니다.
따라서 이 부분은 별도로 변경하지 않았고, 로딩 중이거나 조회 실패한 경우에는 실제 값이 확정되지 않은 상태이므로 기존처럼 -를 유지했습니다.

@kbh0218

kbh0218 commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

추가로 홈 화면 통계 카드가 최신 데이터를 더 잘 반영하도록 수정했습니다.

기존에는 보안 등급별 링크 현황 통계를 홈 화면 최초 mount 시점에만 조회하고 있었습니다. 이 경우 링크 검사/저장 후 홈으로 돌아왔을 때 홈 화면이 이미 살아 있는 상태라면 통계 카드가 새 분석 결과를 바로 반영하지 못할 수 있었습니다.

그래서 통계 조회 로직을 useEffect에서 useFocusEffect로 변경했습니다. 홈 화면이 다시 포커스될 때마다 fetchVerdictStatistics를 재호출하도록 해서, 검사 결과 저장 후 홈으로 돌아오거나 탭 이동으로 홈에 재진입할 때 통계 카드가 최신 값을 다시 가져오도록 했습니다!

@kbh0218 kbh0218 merged commit c03bc33 into dev May 29, 2026
@kbh0218 kbh0218 deleted the feat/#60-security-level-link-status-card-api branch May 29, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] 보안 등급별 링크 현황 카드 API 연동

2 participants