4조 프로젝트 : 팁퍼 (Tipper)
금융관리 초보자를 위한 팁을 드려요!
자금 마련의 기본인 예금, 적금 상품들을 비교해주고 꿀팁들을 공유하는 사이트입니다.
기능 소개
- 예적금 상품 비교 기능 설명
- 상품검색
상품 명, 은행 명을 입력하여 해당 상품을 찾아볼 수 있음
- 2-3개의 상품 비교
상품들 중 2-3개를 골라서 상품들의 조건과 만기 수령액을 미리 예상해 볼 수 있음
예금, 적금 상품들 끼리만 비교가 가능
각 상품이 단리, 복리인지 판단하여 적용
최고금리를 적용한 최대 만기 수령액을 제시
- 상품 찜하기 기능 (로그인 필요)
아 본 상품들이 마음에 든다면 찜하기 버튼을 눌러서 저장 가능함
찜한 상품은 언제든 상품 비교할 때 다시 선택하여 다른 상품과 비교 가능
마이페이지에서도 모아볼 수 있음
- 커뮤니티 기능 설명
- 금융상품 후기, 금융관리 노하우 총 2개의 탭으로 구성
- 게시글 CRUD 기능 구현 - 이미지 업로드 가능
- 게시글에 좋아요 기능 구현
- 마이페이지에서 내가 쓴 글과 좋아요를 누른 게시글 확인 가능
🏗 아키텍쳐

🍀 주요 기술
- firebase
- axios
- vercel
- lodash
🛠 트러블슈팅
CORS에러로 인한 문제
- Cross-Origin Resource Sharing(교차 출처 리소스 공유 정책)

cors에러로 openAPI의 data를 가져오지 못함
✅ 해결
→ CORS 를 해결하기 위해서는 (서버 측)Origin Allow 속성에 클라이언트에서 보내는 출처를 추가해주어야 하고 또한 배포하는 AWS 같은 곳에서도 따로 설정을 해주어야 한다고한다.
→ 서버를 수정할 수도 없어 heroku-anywhere이라는 프록시서버 설정을 사용
https://cors-anywhere.herokuapp.com/https://finlife.fss.or.kr/finlifeapi/savingProductsSearch.json?auth=`${개인인증키}`&topFinGrpNo=020000&pageNo=1
아쉬웠던 점
- 리액트쿼리와 같이 실시간으로 데이터를 받아오는 경우 한번씩 연결 끊기거나 데이터를 받아오지 못하는 에러 발생
- 서버 연결 해주기 heroku에서 남용으로 인해서 버튼을 눌렀을때만 서버를 연결할 수 있도록 변경해두어서 서버가 끊기게 되면 데이터를 가져오지 못하는 상황 발생

→위와 같은 사이트에 들어가서 서버 연결을 해줘야함
API 데이터 구조로 인한 문제


- 한 상품에 대한 기본정보(BASE_LIST)와 금리에 대한 정보가 담긴 옵션 정보(OPTION_LIST)가 같이 저장되어 있지 않고 분리되어있음
✅ 해결
기본 정보를 기준으로 중복되는 속성값인 fin_prdt_cd가 같은 데이터를 옵션정보에서 찾아서 읽어옴


코드 최적화 ( 상품 3개 선택후 비교 )
- 예금, 적금의 정보를 가져오는 함수를 각 2개씩 총 4개 생성(적금base, option / 예금base, option)
✅ 해결
→ Promiss.all() 메서드로 함수를 병렬실행
→ 전체 실행이 완료되면 한번에 모든 결과를 처리하도록 하여 최적화
- 2. 종류가 다른 3개의 배열로 선택된 금융상품의 상태 값을 각각 관리
✅ 해결
선택된 상품들의 정보를 하나의 배열에 순서대로 push함
//* 금융상품 리스트 가져오기
const handleButtonClick = async () => {
const baseListPromises = [
getDocs(collection(db, "DEPOSIT_BASE_LIST")),
getDocs(collection(db, "SAVING_BASE_LIST")),
];
const optionListPromises = [
getDocs(collection(db, "DEPOSIT_OPTION_LIST")),
getDocs(collection(db, "SAVING_OPTION_LIST")),
];
const [baseListSnapshots, optionListSnapshots] = await Promise.all([
Promise.all(baseListPromises),
Promise.all(optionListPromises),
]);
const products = [];
const depositOptionalList = [];
const savingbaseList = [];
const savingoptionalList = [];
baseListSnapshots.forEach((snapshot, index) => {
snapshot.forEach((doc) => {
const newProduct = {
id: doc.id,
...doc.data(),
};
if (index === 0) {
products.push(newProduct);
} else {
savingbaseList.push(newProduct);
}
});
});
optionListSnapshots.forEach((snapshot, index) => {
snapshot.forEach((doc) => {
const newProduct = {
id: doc.id,
...doc.data(),
};
if (index === 0) {
depositOptionalList.push(newProduct);
} else {
savingoptionalList.push(newProduct);
}
});
});
setProducts(products);
setdepositOptionalList(depositOptionalList);
setSavingbaseList(savingbaseList);
setSavingoptionalList(savingoptionalList);
};
useEffect(() => {
handleButtonClick();
}, []);
debounce처리 (lodash)
- 새 비밀번호 변경을 위해선 사용하고 있는 비밀번호를 입력하고 실시간으로 맞는지 유효성검사가 실행됨 (signInWithEmailAndPassword 메소드를 사용)
- 사용 이유 password input에서 onchange로 계속 값을 받고 있어서 signInWithEmailAndPassword메소드를 사용하는 것은 비효율적
✅ 해결
lodash에 debounce처리를 통해서 비밀번호 입력이 끝난 후 0.3초 후에 그때까지 입력된 값을 한번에 들고 한번만 함수가 실행
3번씩 호출하던 것에서 한번씩만 호출하는 것으로 효율성 높임


**렌더링 되는 모습

debounce처리 전 ⇒ 입력할 때 마다 렌더링

debounce 처리 후 ⇒ 한번만 렌더링
🧑🏻💻👩🏻💻 팀원
이름(역할) | 맡은 업무와 기능수행 | Github |
남마리나(팀장) | 프로젝트 진행, 문서 제작, 기능 구현
상품비교 결과창, 커뮤니티 게시글 작성,수정 기능 구현 | |
박상우(부팀장) | 프로젝트 진행, 기능 구현
상품비교 조건 검색 기능, 랜딩 페이지 기능 구현 | |
김원준(팀원) | 기능 구현
상품비교 조건 검색 기능, 랜딩 페이지 기능 구현 | |
남동현(팀원) | 발표, 기능 구현
홈 UI 제작, 커뮤니티 게시글 불러오기, 삭제 기능 구현 | |
조성아(팀원) | 프로젝트 기능 구현 서포트, 기능 구현
상품명 검색하기 기능, 마이페이지 기능 구현 | |
안시은(팀원) | UX/UI 디자인 | ㅤ |
Share article
Subscribe to our newsletter