[URECA] 미니프로젝트 회고록 - 너로 정했다!

2025. 5. 31. 21:47·Activities/LG U+ URECA

🎮 너로 정했다! - 밸런스 게임 플랫폼 개발 회고록

안녕하세요! 오늘은 LG U+ 유레카 SW교육과정에서 진행한 미니프로젝트 '너로 정했다!' 개발 회고입니다. 유레카에서 진행한 첫 프로젝트라는 점에서 뜻깊었는데요. 곧 종합 프로젝트를 앞두고 있어 작성해보았습니다!

 

 

📝 프로젝트 소개

기본 정보

  • 프로젝트명: 너로 정했다!
  • 주제: 밸런스 게임 기반의 소셜 인터랙티브 커뮤니티 플랫폼
  • 개발 기간: 2025.03.13 ~ 03.21 / 05.07 ~ 05.20 (총 약 20일 - 피그마 디자인 제외)
  • 팀 구성: 4인
  • 배포 링크: 서비스 바로가기
 

너로 정했다!

 

oh-no-its-me.vercel.app

 

프로젝트 주제 선정 배경

저희는 미니프로젝트인만큼 규모는 작지만 실제로 이용할 수 있는 서비스를 만들고자 했습니다.

 

그래서 단순한 투표가 아닌 밸런스 게임 형식을 통해 선택의 재미와 고민을 나눌 수 있는, 실제로 활용 가능한 소셜 플랫폼을 만들고자 했습니다. 서비스 타겟은 저희 프론트엔드 대면반 사람들이었는데요. 교육과정 중 지친 일상 속에서 ‘무인도에서 누가 가장 잘 살아남을까?’ 같은 가볍고 유쾌한 질문을 통해, 구성원들이 매일 소통하고 웃을 수 있는 공간을 만들고 싶었습니다! 

 

기술 스택  및 아키텍처

Frontend

React + Vite + TypeScript + Tailwind CSS + Redux Toolkit

 

Create React App이 아닌 Vite를 선택한 이유는 빠른 빌드 속도와 개발 서버 성능 때문입니다. 특히 TypeScript와의 궁합도 좋고, 저를 제외한 3명의 팀원이 모두 Java 언어 기반의 앱 개발 경험이 있었기에 더 익숙할 것이라고 생각했습니다. 또한 Redux Toolkit을 선택한 이유는 전역 상태 관리가 필요했기 때문인데요. 특히 토스트 메시지나 인증 상태 같은 것들을 컴포넌트 간에 공유하는 데에 사용했습니다.

 

Backend

Spring Boot + MyBatis + JWT + MySQL + Swagger

 

백엔드는 Spring Boot로 구성했어요. JPA보다는 MyBatis를 선택했는데, 물론 LG U+ 측의 요구사항이기도 했지만 저희 서버 자체가 복잡한 쿼리보다는 단순한 CRUD가 많아서 러닝 커브를 고려한 선택이기도 했습니다.

  • MyBatis를 사용해 직접 SQL 쿼리를 작성함으로써, 복잡한 ORM 없이도 원하는 로직을 쉽게 컨트롤할 수 있었습니다.
  • Swagger를 통해 API 문서를 자동 생성하고 팀원들과 공유함으로써, 프론트-백 간의 협업도 원활하게 진행했습니다.
  • 로그 관리는 Slf4j 기반 로그를 전반적으로 사용하여 디버깅과 배포 후 모니터링에도 도움이 되었습니다.

인프라 & 배포

Docker + AWS RDS (MySQL) + Render + Vercel

 

인프라는 전적으로 제가 담당한 부분입니다!

  • 프론트엔드: Vercel로 배포
  • 백엔드: Docker 컨테이너화 후 Render에 배포
  • 데이터베이스: AWS RDS MySQL 인스턴스 사용

처음에는 AWS Elastic Beanstalk + EC2를 사용했지만, 미니 프로젝트 특성상 Render가 무료에다가 배포도 아주 간단해서 바꾸게 되었습니다. 물론 성능은 많이 아쉬웠지만요.. 😅 

시스템 아키텍처

주요 기능 소개

 

 

1. 회원 인증 시스템

  • JWT 기반 로그인/회원가입
  • 리프레시 토큰을 활용한 자동 토큰 갱신
  • 로그아웃 시 토큰 무효화

2. 밸런스 게임 투표

  • 매일 새로운 주제 업데이트
  • 후보자 랜덤 추출 기능
  • 타이머 기반 실시간 결과 발표
  • 투표 후 결과 카드로 시각화

3. 익명 댓글 커뮤니티

  • 투표 후 익명으로 의견 공유
  • 실시간 댓글 업데이트

4. 반응형 UI/UX

  • 모바일/데스크톱 대응 반응형 디자인
  • 토스트 메시지 시스템

나의 역할

🎨 프론트엔드 개발

이번 프로젝트에서 프론트엔드를 맡으면서 단순한 화면 구현을 넘어 상태 관리, 보안, UX 향상까지 고려한 다양한 기능들을 직접 구현해볼 수 있었습니다.

1. Redux Toolkit 기반 전역 상태 관리

  • 전체적인 슬라이스 구조, 타입 명세, reducer 통합 등을 모두 직접 구현
  • 이외에도 로그인 상태, 페이징 상태 등 다양한 전역 상태를 분리하여 관리

리덕스는 처음이었지만, 실제로 써보니 그 강력함을 체감할 수 있었습니다. 특히 토스트 메시지 시스템을 구현하며 전역 상태 관리의 필요성을 어떤 컴포넌트에서든 dispatch(showToast())만 호출하면 전역에서 알림이 뜨도록 구성했는데 이 부분이 매우 유용했습니다!

// 사용 예시
dispatch(show({ message: '투표가 완료되었습니다!', type: 'success' }));

 

이 구조 덕분에 각 컴포넌트는 더 깔끔하게 유지됐고, 기능 간 의존성도 최소화할 수 있었습니다.

 

2. Axios 인터셉터 + JWT 자동 인증 처리

웹 시큐리티 과목을 수강한 후, 기존 로그인 방식을 전면 개편해 JWT 기반 인증 구조를 도입했습니다.

다음은 설계한 클라이언트 JWT 인증 과정입니다!

  • 모든 요청에 Access Token을 자동으로 헤더에 삽입
  • 401 오류 발생 시, 저장된 Refresh Token을 활용해 자동으로 Access Token을 갱신
  • 갱신 실패 시 사용자 정보를 초기화하고 로그아웃 처리
// 401 응답 시 자동 토큰 재발급 및 재요청
if (error.response?.status === 401 && !originalRequest._retry) {
  const res = await axios.post('/token/refresh', { ... });
  const newAccessToken = res.data.accessToken;
  originalRequest.headers['Authorization'] = `Bearer ${newAccessToken}`;
  return axiosInstance(originalRequest);
}

 

이 부분을 구현하면서 가장 힘들었던 점은 중복 갱신 요청을 방지하고, 실패 시 일관된 예외 처리를 하는 것이었습니다. 덕분에 실제 서비스에서 인증 시스템이 어떻게 작동해야 하는지 깊이 이해할 수 있었습니다.

 

3. 캐릭터 랜덤 애니메이션 구현 (UX 강화)

메인 페이지가 너무 정적이라, 페이지에 생동감을 더하고 싶어서 framer-motion을 활용한 캐릭터 플로팅 애니메이션을 구현했습니다.

  • getRandomPosition() 함수로 랜덤한 위치 좌표 생성
  • useAnimation()과 setInterval()을 활용해 캐릭터가 주기적으로 새로운 위치로 이동
  • 초기 위치는 중앙에서 시작, 이동은 부드러운 ease-in-out 트랜지션 적용
controls.start({
  x: `${x}vw`,
  y: `${y}vh`,
  transition: {
    duration,
    ease: 'easeInOut',
  },
});

 

덕분에 사용자가 메인 페이지에 접속했을때 심심하지 않고, 시각적으로 눈에 띄는 화면을 구성할 수 있었습니다.

 

🧑‍💻 백엔드 개발

이번 프로젝트에서 백엔드를 Spring Boot 기반으로 처음 개발해보았습니다.

1. JWT 인증 로직 구현

가장 중점을 둔 부분 중 하나는 JWT 기반 인증 시스템 구축이었습니다. 로그인 시 발급된 Access Token과 Refresh Token을 활용해 요청을 인증하고, 토큰이 만료된 경우에는 자동으로 재발급하는 구조를 구현했습니다.

  • Interceptor 기반의 인증 흐름을 설계하여 모든 API 요청 전에 토큰 유효성을 검사하고, 사용자 정보를 추출해 request에 주입
  • Access Token 만료 시 Refresh Token을 활용한 재발급 로직도 포함
  • 재발급된 토큰은 응답 헤더를 통해 클라이언트에 다시 전달되며, 프론트에서는 인터셉터를 통해 이를 자동 반영하도록 구현했습니다.

이 과정에서 가장 어려웠던 점은 Spring Security 필터 체인과 HandlerInterceptor의 적용 순서, 그리고 예외 발생 시의 처리 흐름이었습니다.

직접 로그를 찍으며 흐름을 따라가고, 예외 상황에 따른 대응 방식들을 테스트하면서 흐름을 공부했습니다.


2. 🌐 WebMvcConfig 설정 및 CORS 정책 정리

전역 Config 설정과 CORS(Cross-Origin Resource Sharing) 문제를 해결하는데 시간을 다소 썼습니다.

  • 프론트엔드가 Vercel에 배포되어 있는 만큼, 도메인 간 요청에 대한 허용 설정이 필수였는데요! 특히 Authorization, Refresh-Token 헤더가 브라우저에서 접근 불가한 문제가 있었는데, allowedHeaders, exposedHeaders를 명시적으로 설정해 해결했습니다.
  • 또한 Swagger 문서 접근, 정적 리소스(/img/**) 처리 등 예외 URL에 대한 세밀한 설정도 함께 진행했습니다. 이 과정에서 OPTIONS 사전 요청과 HEAD 방식까지 허용해야 하는 상황 등, 실제 현업과 유사한 상황을 경험할 수 있어 큰 도움이 되었습니다.

트러블슈팅

 

1. 이미지 경로 하드코딩 문제

문제 상황

여러 컴포넌트에서 이미지 경로가 /assets/images/...처럼 하드코딩되어 있어 유지보수에 큰 어려움이 있었습니다.

 

해결 과정

  • 이미지 경로를 상수로 정의 (IMAGES.로고, ICONS.이름)
  • 모든 컴포넌트에서 해당 상수를 사용하도록 리팩토링
  • 남아있는 하드코딩 경로 전수 조사 및 정리

결과

유지보수가 훨씬 쉬워졌고, 디자인 리소스 변경이 생겨도 일괄 적용이 가능해졌습니다.

 

2. Pagination 컴포넌트 리팩토링

문제 상황

기존에 Process라는 이름으로 구현된 페이지 인디케이터 컴포넌트는 역할이 모호하고 재사용이 어려운 구조였습니다.

 

해결 과정

  • 컴포넌트 이름을 Pagination으로 변경하여 기능 명확화
  • 원형 버튼은 PaginationDot 하위 컴포넌트로 분리
  • Tailwind CSS 변수(var(--color-primary-base))를 활용해 스타일 분리
  • useSelector로 상태를 연결하고, useDispatch로 페이지 상태를 동기화
<Pagination totalPages={4} currentPage={page} onPageChange={setPage} />

 

결과

구조가 명확해지고 다른 페이지에서도 재사용 가능한 컴포넌트로 발전했습니다.

프로젝트를 통해 이런 것을 배웠어요!

1. 리더십과 협업

저는 팀장으로서 최선을 다해 팀을 서포트하기 위해 노력했는데요. 팀장으로서 가장 크게 배운 점은 혼자 잘하는 것보다, 함께 성장하는 것이 중요하다는 사실이었습니다. 처음에는 빠르게 구현하는 데 집중했지만, 팀원들이 점차 React를 이해하고 함께 개발할 수 있게 되면서 팀 전체의 만족도가 훨씬 높아졌습니다. 또한 팀원들도 팀이 너무 좋았다고 자주 얘기해주었습니다.

 

 

또한 코드리뷰도 적극적으로 하기 위해 노력했습니다! 후반부에는 급해서 거의 구두로 진행했지만요..ㅎ

2. 풀스택 개발 경험

기존에는 프론트엔드에 집중했지만, 이번 프로젝트에서는 Spring 기반 백엔드도 함께 구축했습니다. 이 과정에서 교육과정에서 배운 REST API 설계, JWT 인증 흐름, DB 연동 등을 경험하며 시스템의 전반적인 흐름을 이해할 수 있게 되었습니다.

프론트만 할 때는 ‘이게 왜 안 되지?’라는 생각이 많았다면,

이제는 ‘백엔드에서 어떤 응답이 와야 할까?’를 먼저 고민하게 되었습니다.

 

3. DevOps 및 인프라 구축 경험

Docker를 이용한 백엔드 컨테이너화, AWS RDS 세팅, Render/Vercel 배포 자동화까지 처음부터 끝까지 직접 구축해보았는데 상당히 힘들었습니다. 

  • 환경별 .env 설정 분리
  • CI/CD를 활용한 자동 배포 구성
  • HikariCP 커넥션 풀 설정 누락으로 인한 DB 연결 이슈 -> 이 부분은 며칠동안 끙끙 앓다가 백엔드 강사님이 도와주셔서 해결되었습니다..ㅎㅎ
spring.datasource.hikari.maximum-pool-size=100
spring.datasource.hikari.minimum-idle=10

실수 하나로 100번은 재배포한 것 같지만..? 덕분에 인프라 설정 하나하나의 중요성을 뼈저리게 느끼게 된 계기였습니다!!

프로젝트 결과

  • 총 20일이라는 짧은 개발 기간 동안 완성도 높은 웹 애플리케이션 완성
  • HTTPS 배포 성공 및 자동 CI/CD 환경 구축
  • React가 처음이었던 팀원들의 개발 역량 향상에 도움
  • JWT 인증, 상태 관리, API 설계 등 실무 기술 습득
  • 협업 문화 정착 (코드 리뷰, 브랜치 전략, 문서화 등)

회고

이번 프로젝트에서 가장 힘들었던 부분은 JWT 토큰 갱신 로직이었습니다. 단순히 백엔드에서 토큰을 발급하는 것을 넘어서, 프론트엔드에서는 Axios 인터셉터로 자동 처리하고, 중복 갱신을 막는 로직까지 구현해야 했기 때문에 예상보다 훨씬 복잡했습니다. 게다가 도중에 프론트만 아니라 백엔드 API 코드까지 대폭 수정해야 했던 상황도 있었습니다. 하지만 팀원 모두가 자발적으로 함께 문제를 분석하고 토론하며 해결했습니다.

 

무엇보다 느낀 건, 기술적인 문제보다 중요한 건 소통이라는 점이었는데요!

 

프로젝트 마지막 날, 모든 기능이 정상적으로 작동하는 것을 확인했을 때의 짜릿함은 아직도 생생합니다.특히 다들 처음엔 React가 너무 어려웠는데, 덕분에 실력이 많이 늘은 것 같다고 말해주어서 팀 리더로서 뿌듯함과 보람을 느꼈습니다. 매일 슬랙과 구두를 통한 적극적인 질문과 코드 리뷰, 서로를 배려하는 태도 덕분에 팀 전체가 함께 성장할 수 있었습니다. 좋은 사람들과 함께해서 재밌는 경험이었고 덕분에 오빠 언니들과 더욱 친해질 수 있었습니다. 진짜 미니 플젝 4조 안녕..🥹

 

따수운 우리 팀.. 그리울거야

프로젝트 관련 링크 정리

  • 깃허브
  • 피그마
  • 스웨거
저작자표시 비영리 동일조건 (새창열림)

'Activities > LG U+ URECA' 카테고리의 다른 글

[URECA] 종합프로젝트 회고록 - MoonoZ  (2) 2025.06.29
[URECA] 자기소개 페이지 만들기 과제 회고  (0) 2025.01.26
[URECA] 정적 사이트를 Github Pages로 1분만에 배포해보자  (4) 2025.01.22
[URECA] LG유플러스 SW교육과정 유레카 2기 합격 후기 (프론트엔드)  (2) 2025.01.11
'Activities/LG U+ URECA' 카테고리의 다른 글
  • [URECA] 종합프로젝트 회고록 - MoonoZ
  • [URECA] 자기소개 페이지 만들기 과제 회고
  • [URECA] 정적 사이트를 Github Pages로 1분만에 배포해보자
  • [URECA] LG유플러스 SW교육과정 유레카 2기 합격 후기 (프론트엔드)
abyss-s
abyss-s
프론트엔드 개발합니다!
  • abyss-s
    abyss-s의 블로그입니다.
    abyss-s
  • 전체
    오늘
    어제
    • 분류 전체보기 (190) N
      • Web (16)
        • JavaScript (6)
        • TypeScript (1)
        • React (5)
        • Vue (0)
        • Storybook (1)
        • Next.js (1)
      • Backend & Infra (8)
        • Database (3)
        • Node.js (2)
        • SpringBoot (1)
      • PS (71)
      • CS (30)
        • OS (13)
        • Structure & Algorithm (5)
        • Network (10)
        • 정보처리기사 (2)
      • Language (18)
        • OOP (1)
        • JAVA (13)
        • C++ (4)
      • Activities (14) N
        • 멋쟁이 사자처럼 (2)
        • OSSCA (3)
        • LG U+ URECA (5) N
        • Project (2)
      • AI (0)
      • Git & Github (5)
      • Notion (1)
      • IT (4)
      • Statistics (11)
      • Book (4)
      • Diary (1)
      • Game (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
    • 백준
    • 트위터
  • 공지사항

    • abyss-s의 티스토리에 오신 것을 환영합니다.
  • 인기 글

  • 태그

    BFS
    github
    파이썬
    그리디
    BAEKJOON
    운영체제
    React
    Java
    OS
    자바기반응용프로그래밍
    생활코딩
    백준
    JavaScript
    DP
    네트워크
    Python
    자바스크립트
    C++
    통계학
    코드트리
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
abyss-s
[URECA] 미니프로젝트 회고록 - 너로 정했다!
상단으로

티스토리툴바