Skip to content

Feat: API 업데이트#111

Merged
DreamPaste merged 4 commits intodevfrom
feat/SOS-61-api-update
Jan 3, 2026
Merged

Feat: API 업데이트#111
DreamPaste merged 4 commits intodevfrom
feat/SOS-61-api-update

Conversation

@DreamPaste
Copy link
Member

주요 변경사항

  1. 날짜 필드명 변경: createdDate, lastModifiedDatecreatedAt, updatedAt
  2. 투표 정보 구조 개선: 투표 관련 6개 필드를 voteInfo 객체로 그룹화

🗓️ 1. 날짜 필드명 변경

변경된 응답 필드

모든 엔티티의 날짜 필드가 다음과 같이 변경되었습니다:

기존 필드명 새 필드명 설명
createdDate createdAt 생성일시
lastModifiedDate updatedAt 수정일시

영향받는 API

  • 사용자 API: /api/users/**
  • 투표 게시판 API: /community/votesboard/**
  • 자유 게시판 API: /community/freeboard/**
  • 댓글 API: 모든 댓글 관련 엔드포인트

마이그레이션 예시

Before (기존)

interface User {
  id: string;
  username: string;
  createdDate: string;      // ❌ 변경 필요
  lastModifiedDate: string; // ❌ 변경 필요
}

After (변경 후)

interface User {
  id: string;
  username: string;
  createdAt: string;  // ✅ 새로운 필드명
  updatedAt: string;  // ✅ 새로운 필드명
}

🗳️ 2. 투표 정보 구조 개선

변경된 응답 구조

투표 관련 필드들이 voteInfo 객체로 그룹화되었습니다.

Before (기존 구조)

interface VoteboardDetailResponse {
  postId: number;
  title: string;
  content: string;

  // ❌ 개별 필드들 (삭제됨)
  selectedOptionIds: number[];
  totalVotes: number;
  voteStatus: 'IN_PROGRESS' | 'COMPLETED';
  endTime: string;
  allowRevote: boolean;
  allowMultipleChoice: boolean;

  // 기타 필드...
  hasVoted: boolean;
  viewCount: number;
  createdDate: string;  // ❌ 변경됨
  lastModifiedDate: string;  // ❌ 변경됨
}

After (새로운 구조)

interface VoteInfo {
  selectedOptionIds: number[];
  totalVotes: number;
  voteStatus: 'IN_PROGRESS' | 'COMPLETED';
  endTime: string;
  allowRevote: boolean;
  allowMultipleChoice: boolean;
}

interface VoteboardDetailResponse {
  postId: number;
  title: string;
  content: string;

  // ✅ voteInfo 객체로 그룹화
  voteInfo: VoteInfo;

  // 기타 필드...
  hasVoted: boolean;  // ✅ 최상위 레벨 유지 (사용자별 정보)
  viewCount: number;
  createdAt: string;    // ✅ 필드명 변경
  updatedAt: string;    // ✅ 필드명 변경
}

주요 변경 포인트

voteInfo 객체에 포함된 필드

voteInfo: {
  selectedOptionIds: number[];      // 사용자가 선택한 옵션 ID 목록
  totalVotes: number;               // 총 투표 참여자 수
  voteStatus: VoteStatus;           // 투표 상태 (진행중/완료)
  endTime: string;                  // 투표 마감 시간
  allowRevote: boolean;             // 재투표 허용 여부
  allowMultipleChoice: boolean;     // 중복 선택 허용 여부
}

🔝 최상위 레벨에 유지된 필드

  • hasVoted: 사용자의 투표 참여 여부 (사용자별 정보이므로 분리)

🔧 프론트엔드 코드 수정 가이드

1️⃣ Orval 타입 재생성

# OpenAPI 스펙에서 TypeScript 타입 재생성
npm run orval
# 또는
pnpm orval

2️⃣ 코드 마이그레이션

날짜 필드 접근 변경

// ❌ Before
const createdDate = post.createdDate;
const updatedDate = post.lastModifiedDate;

// ✅ After
const createdDate = post.createdAt;
const updatedDate = post.updatedAt;

투표 정보 접근 변경

// ❌ Before
const totalVotes = post.totalVotes;
const isInProgress = post.voteStatus === 'IN_PROGRESS';
const canRevote = post.allowRevote;
const selectedOptions = post.selectedOptionIds;

// ✅ After
const totalVotes = post.voteInfo.totalVotes;
const isInProgress = post.voteInfo.voteStatus === 'IN_PROGRESS';
const canRevote = post.voteInfo.allowRevote;
const selectedOptions = post.voteInfo.selectedOptionIds;

// ✅ hasVoted는 최상위 레벨에 유지
const hasVoted = post.hasVoted;

React 컴포넌트 예시

// ❌ Before
function VotePostCard({ post }: { post: VoteboardDetailResponse }) {
  return (
    <div>
      <h3>{post.title}</h3>
      <p>총 투표수: {post.totalVotes}</p>
      <p>상태: {post.voteStatus}</p>
      <p>재투표: {post.allowRevote ? '가능' : '불가'}</p>
      <p>생성일: {formatDate(post.createdDate)}</p>
    </div>
  );
}

// ✅ After
function VotePostCard({ post }: { post: VoteboardDetailResponse }) {
  return (
    <div>
      <h3>{post.title}</h3>
      <p>총 투표수: {post.voteInfo.totalVotes}</p>
      <p>상태: {post.voteInfo.voteStatus}</p>
      <p>재투표: {post.voteInfo.allowRevote ? '가능' : '불가'}</p>
      <p>생성일: {formatDate(post.createdAt)}</p>
    </div>
  );
}

📊 응답 예시

투표 게시글 상세 조회 응답

{
  "postId": 1,
  "author": {
    "userId": "user-123",
    "nickname": "투표왕",
    "address": "서울시 강남구",
    "userType": "FOUNDER"
  },
  "category": "restaurant",
  "title": "우리 동네 맛집 투표",
  "content": "어떤 음식점을 좋아하시나요?",
  "images": [],
  "voteOptions": [
    {
      "id": 1,
      "content": "한식",
      "sequence": 0,
      "voteCount": 15,
      "percentage": 37.5
    },
    {
      "id": 2,
      "content": "중식",
      "sequence": 1,
      "voteCount": 10,
      "percentage": 25.0
    }
  ],
  "hasVoted": true,
  "voteInfo": {
    "selectedOptionIds": [1],
    "totalVotes": 40,
    "voteStatus": "IN_PROGRESS",
    "endTime": "2025-12-31T23:59:59",
    "allowRevote": true,
    "allowMultipleChoice": false
  },
  "viewCount": 120,
  "commentCount": 5,
  "likeCount": 8,
  "isLiked": false,
  "isAuthorized": true,
  "isAuthor": false,
  "canEdit": false,
  "canDelete": false,
  "createdAt": "2025-01-01T10:00:00",
  "updatedAt": "2025-01-01T10:00:00"
}

🎯 체크리스트

프론트엔드에서 다음 항목들을 확인해주세요:

필수 작업

  • npm run orval 또는 pnpm orval 실행하여 TypeScript 타입 재생성
  • createdDatecreatedAt 변경 (전체 검색 후 일괄 수정)
  • lastModifiedDateupdatedAt 변경 (전체 검색 후 일괄 수정)
  • 투표 관련 필드 접근 경로 변경 (post.totalVotespost.voteInfo.totalVotes)
  • hasVoted는 최상위 레벨 유지 확인 (post.hasVoted)

테스트

  • 투표 게시글 목록 조회 테스트
  • 투표 게시글 상세 조회 테스트
  • 투표 참여/변경/취소 플로우 테스트
  • 날짜 포맷팅 정상 동작 확인
  • 투표 상태 UI 표시 확인

🔍 영향받는 필드 전체 목록

VoteboardDetailResponse 변경사항

기존 경로 새 경로 타입 설명
totalVotes voteInfo.totalVotes number 총 투표자 수
voteStatus voteInfo.voteStatus VoteStatus 투표 상태
selectedOptionIds voteInfo.selectedOptionIds number[] 선택한 옵션 ID
endTime voteInfo.endTime string 마감 시간
allowRevote voteInfo.allowRevote boolean 재투표 허용
allowMultipleChoice voteInfo.allowMultipleChoice boolean 중복선택 허용
hasVoted hasVoted boolean ✅ 위치 변경 없음
createdDate createdAt string 생성일시
lastModifiedDate updatedAt string 수정일시

VoteboardSummary 변경사항

VoteboardDetailResponse와 동일한 구조 변경 적용


💡 팁

1. 일괄 검색 및 수정

VSCode에서 다음 정규식으로 검색하여 일괄 수정 가능:

검색: \.createdDate
교체: .createdAt

검색: \.lastModifiedDate
교체: .updatedAt

검색: \.totalVotes
교체: .voteInfo.totalVotes

검색: \.voteStatus
교체: .voteInfo.voteStatus

2. TypeScript 컴파일 에러 활용

Orval로 타입을 재생성한 후, TypeScript 컴파일 에러를 따라가면서 수정하는 것이 가장 안전합니다.

# 타입 에러 확인
npm run type-check
# 또는
tsc --noEmit

@DreamPaste DreamPaste requested a review from youdaeng2 December 29, 2025 12:57
@DreamPaste DreamPaste self-assigned this Dec 29, 2025
Copilot AI review requested due to automatic review settings December 29, 2025 12:57
@DreamPaste DreamPaste added the Fix 🔧 문제가 있는 내용을 수정합니다! label Dec 29, 2025
@linear
Copy link

linear bot commented Dec 29, 2025

@DreamPaste DreamPaste added Feat 💡 새로운 기능을 구현하고 추가합니다! 휘건 labels Dec 29, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

이 PR은 백엔드 API 응답 구조를 개선하기 위한 두 가지 주요 변경사항을 반영합니다:

  1. 날짜 필드명을 더 직관적인 이름으로 변경 (createdDatecreatedAt, lastModifiedDateupdatedAt)
  2. 투표 관련 6개 필드를 voteInfo 객체로 그룹화하여 구조를 명확히 개선

주요 변경사항:

  • 생성된 TypeScript 타입 정의 업데이트 (Orval을 통한 자동 생성)
  • 투표 게시판 컴포넌트에서 새로운 API 구조에 맞게 필드 접근 방식 수정
  • VoteInfo 인터페이스 및 관련 타입 추가

Reviewed changes

Copilot reviewed 2 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
apps/web/src/generated/api/models/voteboardSummary.ts createdDate/lastModifiedDatecreatedAt/updatedAt으로 변경하고, 6개의 투표 관련 필드를 voteInfo 객체로 그룹화
apps/web/src/generated/api/models/voteboardDetailResponse.ts 투표 게시글 상세 응답 타입에 동일한 날짜 필드명 변경 및 voteInfo 구조 적용
apps/web/src/generated/api/models/voteInfo.ts 투표 정보를 캡슐화하는 새로운 VoteInfo 인터페이스 추가
apps/web/src/generated/api/models/voteInfoVoteStatus.ts VoteInfo에서 사용되는 투표 상태 enum 타입 정의 추가 (DELETED 상태 포함)
apps/web/src/generated/api/models/userResponse.ts 사용자 응답 타입의 날짜 필드명 변경 적용
apps/web/src/generated/api/models/index.ts 새로 추가된 VoteInfoVoteInfoVoteStatus 타입 export
apps/web/src/app/main/community/votesboard/components/VoteboardForm.tsx 수정 모드에서 초기 데이터를 설정할 때 voteInfo 객체를 통해 필드 접근하도록 수정
apps/web/src/app/main/community/votesboard/components/VoteBoardCard.tsx voteInfo 객체에서 필요한 필드들을 구조 분해하여 사용하도록 리팩토링

@github-actions
Copy link

@github-actions
Copy link

github-actions bot commented Dec 29, 2025

📦 번들 분석 결과

📊 번들 크기 요약

항목
📦 전체 번들 크기 3.7M
📄 JavaScript 크기 1.6M
🗂️ JavaScript 파일 수 64개

🔍 주요 청크 파일 (크기순)

79e27356-a397cfaca953c890.js - 169K
framework-69e0f7d37422957b.js - 137K
main-a3247b30c12eafe6.js - 130K
2356-dea7484209cf7469.js - 122K
9870-dbaf3a370645f2d3.js - 121K
polyfills-42372ed130431b0a.js - 110K
5867-b97ee42a40c66b62.js - 90K
5251-dc07ab16b26ff9a9.js - 75K
page-a1946fe19c26d153.js - 30K
2845-56a40d00b08c6d2e.js - 28K

🤖 자동 생성된 번들 분석 리포트

@github-actions
Copy link

github-actions bot commented Dec 29, 2025

⚡ Lighthouse 성능 분석 결과

📊 전체 평균 점수

지표 점수
🚀 Performance 75점
♿ Accessibility 87점
✅ Best Practices 100점
🔍 SEO 100점

📈 측정 현황

  • 측정 성공: 15/16 페이지
  • 상태: success

📄 페이지별 상세 분석

🏠 커뮤니티 페이지: /main/community

지표 점수
🚀 Performance 74점
♿ Accessibility 80점
✅ Best Practices 100점
🔍 SEO 100점

📊 상세 분석 보기

👥 창업자 페이지: /main/founder

지표 점수
🚀 Performance 75점
♿ Accessibility 87점
✅ Best Practices 100점
🔍 SEO 100점

📊 상세 분석 보기

🏡 홈 페이지: /main/home

지표 점수
🚀 Performance 75점
♿ Accessibility 91점
✅ Best Practices 100점
🔍 SEO 100점

📊 상세 분석 보기

🗺️ 지도 페이지: /main/maps

지표 점수
🚀 Performance 75점
♿ Accessibility 87점
✅ Best Practices 100점
🔍 SEO 100점

📊 상세 분석 보기

👤 프로필 페이지: /main/profile

지표 점수
🚀 Performance 75점
♿ Accessibility 88점
✅ Best Practices 100점
🔍 SEO 100점

📊 상세 분석 보기

🔗 전체 상세 분석 결과

📊 전체 상세 Lighthouse 분석 결과 보기

📄 측정된 페이지

  • /main/community
  • /main/founder
  • /main/home
  • /main/maps
  • /main/profile

모든 페이지에서 성능 측정이 완료되었습니다.


🤖 자동 생성된 Lighthouse 성능 리포트

@github-actions
Copy link

github-actions bot commented Jan 3, 2026

@DreamPaste DreamPaste merged commit 41b9a73 into dev Jan 3, 2026
4 checks passed
@DreamPaste DreamPaste deleted the feat/SOS-61-api-update branch January 3, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feat 💡 새로운 기능을 구현하고 추가합니다! Fix 🔧 문제가 있는 내용을 수정합니다! 휘건

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants