4주간의 이슈 트레커 프로젝트에 이어서 두번째 프로젝트가 시작되었다.
이번 프로젝트에서는 FE 2명, BE 2명에 추가로 iOS 2명이 함께 하게되어 총 6명이 팀을 이루어서 진행하게 되었다.
프로젝트 주제는 유명한 당근 중고거래 앱을 구현해보는 프로젝트로, 새로운 기능이 많이 보였고 무엇보다 이제는 처음이 아니라는 생각에 역시나 부담감을 가지고 시작하게 되었다.
첫번째 프로젝트에서는 동료의 주도하에 수동적으로 프로젝트의 방향성을 따라 갔지만, 두번째 프로젝트 부터는 적극적으로 참여하고 의견을 표현하기로 마음 먹었다.
그라운드룰을 먼저 정하는 단계에서 첫번째 프로젝트에서 서로가 아쉬웠던 점을 공유하고 이 부분을 채울 수 있는 공동 목표를 정해보자는 의견을 공유했다.
내가 첫번째 프로젝트에서 가장 아쉬웠던 점은 학습보다 구현에 치우친 점이었다. 프로젝트도 리액트도 처음이라 팀원들을 따라가기 급급하여 기능이 구현되면 바로 다음 파트로 넘어 갔기에 이번 프로젝트에서는 내가 구현한 내용은 확실히 알고 넘어가고 싶었다.
다행히도 모든 팀원이 나와 비슷한 경험과 생각을 가지고 있었기에 우리팀의 가장 중요한 가치는 하나를 하더라고 확실히 하자는 목표가 정해졌다.
💡 우리팀의 가장 중요한 가치는?
하나를 하더라도 확실히! ⇒ 근거있는 맛있는 코드
#2_프로젝트_second-hand_team-03_GitHub 주소
첫번째 프로젝트에서도 협업도구 GitHub을 통해 프로젝트를 진행했으나 Issues관리는 Linear라는 도구의 도움을 받았는데, 이번에는 GitHub의 프로젝트와 이슈, 마일스톤 등을 적극 활용하기로 했다.
Linear | GitHub | |
---|---|---|
장점 | - 직관적이고 작업 항목 생성, 수정, 삭제가 간편하다. | - GitHub 레포와 통합되어 있어서 이슈의 추적이나 수정에 편리하다. |
- 어플리케이션이 가벼워서 퀘적한 사용감을 느낄 수 있다. | - GitHub이 개방적인 플렛폼이기에 이슈를 공유하고 커뮤니케이션 하기에 좋다. | |
단점 | - branch 이름을 사용자가 정하기 어렵다. | - 직관성과 자동화 세팅이 Linear보다 불편해서 손이 더 많이 간다. |
두 도구 모두 이번이 첫 사용이고 많은 기능을 사용해 보지 못한 개인적인 생각으로
동료들과 함께 선호도를 확인하고 프로젝트에 적용함이 좋다.
프로젝트를 성공하기 위해서는 기술, 도구를 잘 사용하여 개발을 잘하는 것도 중요하지만 코드스쿼드에서 가장 강조하는 것이 협업
이다.
협업을 잘 하기 위해서는 동료들과의 소통이 원활해야하며 이를 실천하는 방법으로 데일리 스크럼
과 회고
하는 시간을 정해서 동료들과의 소통 시간을 만들었다.
특히 회고를 '잘' 하기 위해서 KPT라는 회고 템플릿을 사용하기로 했다.
이전 프로젝트에서도 매주 회고를 진행하긴 했지만, KPT 템플릿으로 무엇을 이야기 할지 정하니 모든 동료의 생각과 원하는 프로젝트 방향을 공유 할 수 있어서 더욱 큰 효과를 줄 수 있었다.
이전 프로젝트에서 FE의 브렌치를 따로 가져오고 FE팀원과 각자의 작업을 PR과 리뷰를 통해 서로의 코드를 이해하는 방식이 마음에 들었기에 이번에도 같은 방식을 채용하기로 했다.
다만, 각 클래스별로 매주 리뷰어에게 코드를 공유해야 하기에 보다 깔끔한 커밋 히스토리로 정리하기 위해서 리뷰어에게 PR을 보내는 팀 저장소의 각 클래스 브렌치에는 merge가 아닌 rebase로 코드를 통합하기로 했다.
리뷰어를 위한 코드스쿼드 저장소, team 저장소, 클래스 저장소가 존재하기에 PR 컨벤션에 대한 정리가 필요함을 느꼈고, 이를 그림으로 만들어서 팀원들과 공유했다.
2주차에서는 본격적으로 프로젝트 구현 작업에 들어갔는데, 이전 프로젝트의 경험으로 우선적으로
모든 팀원과 함께 작업해야하는 부분이 있었다.
이전 프로젝트에서도 FE와 BE가 함께 기획서를 분석하면서 스토리를 구성했지만, 구성된 스토리의 순서가 맞지 않았다.
예를들어 FE에서는 이슈 리스트가 제일 먼저 필요한 페이지이지만, BE에서는 모든 API가 준비된 이후에 완성되는 페이지였다.
이에 전체적인 스토리를 6명 모두가 함께 백로그를 작성하며 하나의 스토리로 통일하고
매주 공통의 스프런트를 통일해서 작업 순서와 속도를 맞추기 위해 노력했다.
매주 스프런트를 정하고 작업 순서와 속도를 맞추자는 취지는 좋았지만,
각 클래스별로 필요한 선행작업과 작업 난이도가 다르기에 달성율의 차이가 발생했고, 마지막 4주차에서의 달성율은 더욱 커지게 되었다.
매주 진행되는 스프런트를 클래스별로 더욱 세분화하여 달성 가능한 목표로 선정함이 필요함을 알았기에 프로젝트 방향에 개선이 필요하다.
이전 프로젝트에서의 경험으로 BE도 배포와 API 연동작업을 먼저 해두고 프로젝트 구현을 진행하기로 했다. 물론 아직 아무 페이지도 존재하지 않기에 아주 간단한 GET, POST, DELETE 정도를 확인할 수 있는 간단한 웹을 만들었다.
import { useEffect, useState } from 'react';
import { ThemeProvider } from 'styled-components';
import axios from 'axios';
import theme from '../../styles/theme';
import GlobalStyles from '../../styles/GlobalStyles';
interface IData {
id: number;
name: string;
}
const App = () => {
const [data, setData] = useState<IData[]>([]);
const [value, setValue] = useState<string>('');
const fetchData = async () => {
try {
const response = await axios.get('http://3.39.207.31:8080/api/test');
console.log(response);
setData(response.data);
} catch (error) {
console.log(error);
}
};
const addUser = async (name: string) => {
try {
await axios.post('http://3.39.207.31:80/api/test', {
name,
});
setValue('');
fetchData();
} catch (error) {
console.error(error);
}
};
const deleteUser = async (id: number) => {
try {
await axios.delete(`http://3.39.207.31:80/api/test/${id}`);
fetchData();
} catch (error) {
console.error(error);
}
};
useEffect(() => {
fetchData();
}, []);
return (
<ThemeProvider theme={theme}>
<GlobalStyles />
<ul>
{data.map((user) => (
<div key={user.id}>
<li>{user.name}</li>
<button onClick={() => deleteUser(user.id)}>삭제</button>
</div>
))}
</ul>
<input value={value} onChange={(e) => setValue(e.target.value)} />
<button onClick={() => addUser(value)}>추가</button>
</ThemeProvider>
);
};
export default App;
코드 구현에 앞서 설계의 필요성은 이전 프로젝트에서 크게 느꼈기에 이번 프로젝트는 모든 컴포넌트 구현 전에 설계를 해보고 작업을 진행하기 위해 노력했다.
바로 설계가 안되는 부분 또한 당연히 존재했지만, 처음부터 완벽한 설계는 많은 경험을 토대로 만들어지는 능력이라고 생각한다.
설계 조금, 코드 조금, 다시 설계 수정, 코드 수정을 반복하며 설계를 하려는 습관
을 가지기 위한 한 걸음을 나아가보자.
3주차에 들어오면서 구현해야하는 기능은 너무나 많았고 시간은 부족했다.
4주 동안 모든 기능을 구현하기란 불가능하다고 판단해서 제일 구현해보고 싶었던 기능을 선택하고 그것을 3주차와 4주차에 진행을 하기 위한 스프런트로 구성했다.
3주차에 내가 선택한 기능은 물품등록(POST) 이다.
내 물건 팔기 페이지에서 사진, 제목, 가격, 내용 등 모든 데이터를 취합하고 완료 버튼으로 한번에 POST를 요청하는 것이 기획서의 요구사항이었다.
처음 설계는 내 물건 팔기 페이지에서 POST 보낼 데이터를 postObject로 상태를 관리하고 하위 각 컴포넌트에서 값이 입력되면 postObject에 값을 업데이트 해주도록 구성했다.
API명세서에서 요구하는 형식에 맞추어 기능을 다 구현한 상황에서 BE로부터 이미지(사진)은 formData 형식으로 보내주어야 한다고 한다는 요청이 들어왔다.
아니... 이제와서..... 갑자기.......?
기존 API명세서에는 이미지가 URL(string)형식으로 되어 있었기에 input된 파일을 createObjectURL로 만들어주기만 했었다. 잘 생각해보니 URL은 로컬 환경에서의 URL로 DB에는 파일 자체가 저장이 되어야 한다는 생각으로 이해가 되었지만 formData에 대한 학습과 설계의 변경이 필요하게 되었다.
API명세서에 너무 의존하지 말고 새로운 작업이 들어가거나 처음 API를 사용하게 된다면 BE와의 대화를 통해 싱크를 지속적으로 맞춰야 함을 또 한 번 배울 수 있었다.
마지막 주차에서는 채팅 기능을 도전하기로 했다.
이번 프로젝트에서 가장 어려운 기능이고 만들어본 사람이 없었던 기능이기에 사실 4주라는 기간동안 구현을 할 수 있을까...? 라는 걱정이 앞선 부분이지만, BE에서 꼭 한번 해보고 싶다고 했으며 나도 BE와 함께 협업을 하는 입장에서 좋은 기회라고 생각하고 한 번 도전하기로 했다.
우선 프런트 입장에서 채팅방에 대한 로직과 컴포넌트를 고민해 보았다.
판매자와 구매자만의 채빙방이 존재한다.
구매자는 물품상세에서 판매자에게 채팅을 건다.
2-1. 해당 물품에 대한 방이 생성된다.
2-2. 방의 참여자는 해당 물품의 판매자와 나 자신 뿐이다.
판매자는 채팅방 목록에서 생성된 방으로 들어간다.
3-1. 판매자는 자신이 참여된 채팅방 리스트를 볼 수 있다.
서로의 대화창은 로그인된 사람 중심으로 표현된다.
4-1. 내가 보낸 메시지와 받은 메시지의 UI가 다르다.
채팅방을 나가도 대화 목록은 남아 있는다.
채팅방에 대한 설계와 view를 구현하는데까지만 3일이 걸렸고,
마지막 프로젝트 데모까지 남은 시간은 단 하루.. 뿐이었다.
더욱이 BE에서는 채팅 기능 구현에 성공했다고 한다.
지금은 내가 학습과 설계 후 구현에 들어간다면 선택과 집중으로 채팅 구현만 목표로 잡아둔 4주차 데모에서 보여줄 기능이 없어지게 된다.
여기서 나의 채팅 구현 설계가 변경되었다.
그렇게 BE 동료와 리액트로 채팅 구현 페어 프로그래밍을 진행하게 되었다.
마지막 하루, BE 동료와 리액트로 페어 프로그래밍을 진행하게 되었다.
BE에서 먼저 채팅 구현을 완성했기에, 동료의 머리 속에는 어떤 요청이 필요하고 어떤 반응이 나가는지 머리속에 존재하고 있었기에 옆에서 실시간으로 지금이 view적으로 어디 부분인데, 여기서 이제 방을 만들거다 어떤 요청이 필요한가?
또, 나는 여기서 이런 이런 데이터가 필요한데 이 데이터를 주는 API는 존재하는가? 와 같은 방식으로 바로바로 피드백을 받을 수 있었다.
소켓통신에 대한 학습과 이해에 대한 시간이 부족하고 코드도 고민하고 설계한 코드가 아닌 다른 사람들의 글과 BE 동료의 도움으로 구현된 채팅 기능이지만, 데모 날 아침에 딱 기능 구현이 완성되었다.
하나를 알더라도 확실하게라는 팀의 가치를 지키는 방식은 아니였지만,
리액트 코드를 모르는 BE 동료에게 코드를 보여주며 이해시키고, BE에서 설계한 로직을 듣고 이해하면서 리액트 코드에 적용하며 보낸 이 시간이 기능 구현에 있어서는 굉장히 효율적이다고 생각했다. 더욱이 서로의 입장과 생각을 실시간으로 듣고 이해하고 적용할 수 있으니 굉장히 유익하고 무엇보다 성공했을떄의 짜릿함은 더욱 크게 돌아왔다.
다행히 BE 동료도 리액트라는 라이브러리에 흥미에 가지게 되었고, view 적인 부분을 고민해가며 코드를 작성하는 프런트의 입장도 경험하게 되어 굉장히 만족한 시간을 가질 수 있었다고 한다.
코드스쿼드 마스터즈에서 진행하는 마지막 수업이자 2번째 그룹 프로젝트가 마무리 되었다. 팀 활동에 적극적으로 참여하고 코드 작성도 주도적으로 할 수 있었기에 만족도가 높은 프로젝트였다.
아쉬움이라면 프로젝트를 끝까지 완성하지 못한 부분인데,
기획서 단계에서부터 4주만에 완성하기는 어려운 분량이라고 한다.
그래서..!!
우리 팀은 이 프로젝트를 계속 진행해서 완성 시키기로 했다!
짧은 시간안에 끝내지 않고 시간을 더 투자해서 우리 팀이 가지고 있는 가치
하나를 하더라도 확실히! 를 실천하려고 한다.