1
안녕하세요 비딩 시스템을 통한 중고거래서비스 비드마켓을 주제로 프로젝트를 진행한 8팀, 사이코 팀 입니다.
2
프로젝트 개요 기술 스택 및 개발 문화, 개발 이야기, 최종 결과물 순으로 발표를 진행하도록 하겠습니다.
3
프로젝트 개요입니다.
4
먼저 저희 팀소개를 하자면 다음과 같이 프론트 인원 4명 백엔드 인원 5명으로 구성이 되어 개발을 진행하였고 각팀에서 팀장이 일정 관리, 업무 할당을하며 프로젝트를 진행했습니다.
5
저희 프로젝트 주제는 온라인 비딩 시스템을 이용한 중고 물품거래 서비스 입니다.
기존 중고 물품 판매시장에서는 판매자가 중고물품의 수요대비 가격을 정확히 예상할 수 없어 고가의 제품들을 싼값에 판매하는 경우가 종종 존재했습니다.
저희 비드마켓은 비딩 시스템을 도입하여 판매자는 최대한 높은 기대수익을 얻도록 하고,구매자(낙찰자)는 2호가에 일정 금액을 더한 금액을 제외한 나머지 금액을 거슬러 받게 되어 합리적인 가격에 중고 물품을 구매할수 있습니다.
6
기술 스택과 개발문화입니다.
7
프론트엔드의 경우 다음의 프레임 워크와 라이브러리, 개발환경을 통해 개발을 진행하였습니다.
8
백엔드의 경우 다음과 같은 기술스택을 사용하였습니다.
9
저희가 협업한 방식을
저희는 애자일 스크럼 방식을 도입하여 개발을 진행하였는데요, 지라의 스크럼 보드를 도입하여 팀원들과 프로젝트의 진행상황공유를 보다 용이하게 할 수 있었습니다.
프론트 엔드, 백엔드 모두가 참여하여 스크럼을 진행한 덕분에 각자 어떤 기능을 구현하고 있는지 한눈에 확인할 수 있었고, API를 위해 프론트, 백엔드간 소통이 필요하다면 바로바로 담당자를 확인하여 소통할 수 있었습니다.
또한 Github와 연동하여 진행사항 관리를 자동화 하였습니다.
10
그리고 노션을 활용하여 회의록과, 컨벤션, 이슈들을 기록하여 팀원들과 공유하였으며, API 명세를 작성하여 프론트와 백엔드간 소통을 진행하였습니다.
11
저희는 총 4번의 스프린트를 거쳐 프로젝트를 진행하였는데요,
스프린트 플래닝단계에서는 유저스토리, 백로그를 작성하고 플래닝 포커를 진행하여 각 백로그 진행에 필요한 시간을 어림잡았습니다.
스프린트 시작단계에서는 우선순위에 따라 이번 스프린트에 진행해야할 백로그를 추가했고, 각 백로그에 담당자를 지정하여 지라티켓을 발급, 개발을 진행하였습니다.
스프린트 중간점검때에는 남은 백로그를 확인하고 스프린트 종료시까지 구현이 가능한지 점검을 하고 일정을 조정하였으며 중간 피드백을 진행하였습니다
스프린트가 종료되면 스프린트에 대한 회고를 진행하고 다음 스프린트에 대한 플래닝을 진행하였습니다.
12
Git 브렌치 전략으로는 release 브렌치를 배포브렌치로 main에서만 병합이 가능하도록 하였습니다.
해당 브렌치로 push가 되면 gitaction을 통해 자동 배포가 진행됩니다.
main 브렌치는 개발 브렌치로 일정 인원 이상의 어프로브를 받아야만 머지가 되도록 하였습니다.
main 브렌치로 지라 티켓번호에 해당하는 브렌치 명을 갖고있는 feature 브랜치를 통해 진행한 개발의 PR을 진행했습니다.
13
커밋 메세지는 앞에 Jira 티켓 번호를 붙여 관리했고 직관적으로 커밋을 파악할 수 있도록 깃모지 컨벤션을 정해서 작성했습니다.
14
코드 커브로 매 PR마다 테스트 커버리지 결과를 확인했고 소나 큐브의 정적 코드분석을 활용하여 코드 품질을 관리했습니다.
15
백엔드팀은 Rebase 통해 main브랜치에 병합하는 전략을 채용했습니다. 커밋 이력을 직관적으로 확인할 수 있고 문제가 생기는 커밋 발생시 쉽게 찾을 수 있는 장점이 있습니다.
프론트팀은 Merging 방식으로 main 브랜치에 병합하는 전략을 선택했는데요 이 방식의 장점은 커밋들의 동일성이 유지되고 충돌 발생시 해결이 용이하다는 장점이 있습니다.
16
그다음으로 저희 팀의 개발 방법에 대한 이야기를 드리도록 하겠습니다
17
먼저 백엔드팀은 가비아에서 bidmarket-api.shop 도메인을 구매하여 certbot(써봇)을 통해 ssl 인증서를 발급받아 연동하였습니다. 그리고 엔진엑스에 발급받은 인증서를 적용하고, http요청도 https 요청으로 리다이렉트 되도록 설정하였습니다. 그리고 내부 스프링 서버의 포트인 8080포트를 바라보도록 설정하였습니다.
또한 저희는 웹소켓을 사용하고 있기에 Nginx가 웹소켓 커넥션을 다룰 수 있도록, Upgrade와 Connection 헤더를 명시하였습니다.
18
리액트 클라이언트를 통해 bidmarket-api.shop 도메인의 api 서버로 요청이 들어오게되면 백엔드 서버의 내부 로직을 거쳐 응답을 내려주게 됩니다.
백엔드 서버에서는 유저 로그인 기능 구현을 위해 오어스2를, 경매 종료로직 구현을 위해 스프링 배치를 활용하였으며, 채팅 기능 구현을 위해 웹소켓을 주로 사용하였습니다.
테스트에서는 격리된 테스트 환경을 구현하기위해 테스트 컨테이너를 활용하였고, 자코코를 활용해 테스트 커버리지를 체크하며 개발을 진행하였습니다.
또한 배포를 위해 gitaction과 코드 디플로이활용하여 배포자동화를 구현하였습니다
데이터 베이스 서버로는 아마존의 RDS를 활용하였습니다.
19
CI/CD는 다음 그림과 같은 형태로 진행 됩니다.
main 브렌치 pr이 진행 되면, 코드커브와 소나큐브를 통해 테스트 결과, 정적 분석 결과 보고서를 받고 해당 보고서를 토대로 해당 pr의 부족한 부분들을 팀원들과 공유하고 피드백하였습니다.
이후 main브렌치에서 release 브렌치로 머지가 되면, gitaction을 통해 배포가 진행이 되는데요, 레포지토리의 소스코드를 s3에 업로드하고 코드 디플로이를 통해 지정한 이씨투인스턴스로 배포가 진행됩니다.
20 SEO
SEO, 즉 검색 엔진 최적화를 위해 다음과 같이 적용하였습니다.
카카오톡, Slack 등에서 메타태그 오픈그래프를 통해 저희 서비스의 소개, 상품의 소개를 다음 사진과 같이 미리보기로 볼 수 있습니다.
update bidding set won=0 where id=1; update bidding set won=0 where id=2; update bidding set won=0 where id=3; update bidding set won=0 where id=4; update bidding set won=0 where id=5; update bidding set won=0 where id=6; update bidding set won=0 where id=7; update bidding set won=0 where id=8; update bidding set won=0 where id=9; update bidding set won=0 where id=10; update bidding set won=0 where id=11; update bidding set won=0 where id=12; update bidding set won=0 where id=13; update bidding set won=0 where id=14; update product set progressed=1 where id=1; update product set progressed=1 where id=2; update product set progressed=1 where id=3; update product set progressed=1 where id=4; update product set progressed=1 where id=5; update product set progressed=1 where id=6; update product set progressed=1 where id=7; update product set progressed=1 where id=8; update product set progressed=1 where id=9; update product set progressed=1 where id=10; update product set progressed=1 where id=11; update product set progressed=1 where id=12; update product set progressed=1 where id=13; update product set progressed=1 where id=14; update product set progressed=1 where id=15; update product set progressed=1 where id=16; update product set progressed=1 where id=17; update product set progressed=1 where id=18; update product set progressed=1 where id=19; update product set progressed=1 where id=20; update product set expire_at='2022-08-16T12:45:00' where id=1; update product set expire_at='2022-08-16T14:45:00' where id=2; update product set expire_at='2022-08-16T14:40:00' where id=3; update product set expire_at='2022-08-16T13:08:00' where id=4; update product set expire_at='2022-08-16T14:25:00' where id=5; update product set expire_at='2022-08-16T14:30:00' where id=6; update product set expire_at='2022-08-16T14:45:00' where id=7; update product set expire_at='2022-08-16T14:50:00' where id=8; update product set expire_at='2022-08-16T14:55:00' where id=9; update product set expire_at='2022-08-16T15:00:00' where id=10; update product set expire_at='2022-08-16T15:05:00' where id=11; update product set expire_at='2022-08-16T15:10:00' where id=12; update product set expire_at='2022-08-16T15:15:00' where id=13; update product set expire_at='2022-08-16T15:20:00' where id=14; update product set expire_at='2022-08-16T15:25:00' where id=16; update product set expire_at='2022-08-16T15:30:00' where id=17; update product set expire_at='2022-08-16T15:35:00' where id=18; update product set expire_at='2022-08-16T15:40:00' where id=19; update product set expire_at='2022-08-16T15:45:00' where id=20; INSERT INTO `product`(title, `description`, minimum_price, category, location, thumbnail_image, progressed, expire_at, created_at, user_id) VALUES ('M1 맥북프로 13', 'M1 MacBook Pro 13인치 판매합니다. 회사에서 사용하던 제품이라 상태 좋고, 초기화 되어 있습니다. [사양] - Apple M1 CPU - 16GB 메모리 - 256GB SSD - 배터리 (57 Cycle, 100%) [구성] - 맥북 - 전원선 회사에서 판매하는 제품이라 삼성중앙역에서만 거래가 가능합니다. 전자제품 특성상 교환 및 취소가 어렵습니다.', 600000, 'DIGITAL_DEVICE', '제주 서귀포시 동홍동', 'https://dnvefa72aowie.cloudfront.net/origin/article/202207/adf7131956708b6221ff430f840e75f0065fd0fc1edbaa9219f9eac4bd50da5b.webp?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 1); update image set url = 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/E9CD41986EC23E8E7DD6451502CC596787F59A0CC41CF5CD7EAD01BC25A3DC87.jpg?q=95&s=1440x1440&t=inside' where id=51; update image set url = 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/076CF2B8987D36C61C1480856DE886E5F51B6AEF1C4C57C5F42CE69E8F3F9966.jpg?q=95&s=1440x1440&t=inside' where id=52; delete from product where id=30; delete from image where product_id=30; delete from notification where product_id=30; INSERT INTO `image`(product_id,url,`order`,created_at) VALUES (50, 'https://dnvefa72aowie.cloudfront.net/origin/article/202206/4CB30B6DA5F5388D591B9A05FF752EE648BAFAB765F1A40E7AA8DBC01F9922CF.jpg?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (51, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/9d0d88038818aa4ae16532e9e01ba7f1069f3dd537c7e65db6d6eff77fd6aa91.webp?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (52, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/479f19089a29db8f4b07cc07b485b794bc10ff884355dadbfee173dfaa712bfb.webp?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (52, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/0561e9e9555c49ebadcfdd29e918b566caada163b209828a820bddca6cb8b719.webp?q=95&s=1440x1440&t=inside', 2, '2022-07-21T14:47:00'), (52, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/99c654fd4496de3f1863072b5364cc764ba6f222cdd4674a700cf621460e7d0a.webp?q=95&s=1440x1440&t=inside', 3, '2022-07-21T14:47:00'), (53, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/F04E734834A284763D1D740E9DD26E513D6B50D69FB357A72DA572EB06CA0E69.jpg?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (53, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/A43AA0B4110013AB6834B86090EC62EE4D03DBAFDED976E2723428126B3D6953.jpg?q=95&s=1440x1440&t=inside', 2, '2022-07-21T14:47:00'), (53, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/09F0E5F9B07D9B18A7513FC5F2B4686DAA9A093D9E754227D0260ED02B9A6AF4.jpg?q=95&s=1440x1440&t=inside', 3, '2022-07-21T14:47:00'), (54, 'https://dnvefa72aowie.cloudfront.net/origin/article/202206/295C3D0C49B044FA087B2123237537453D7E9827E6E5A23F6EF1061C33416CF1.jpg?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (54, 'https://dnvefa72aowie.cloudfront.net/origin/article/202206/F5D3D30AC8242BD2D5714E09E26E864B0727457B9B826984FAE6D56F9102EB3D.jpg?q=95&s=1440x1440&t=inside', 2, '2022-07-21T14:47:00'), (54, 'https://dnvefa72aowie.cloudfront.net/origin/article/202206/555E23BAE3AC46827BA200BB929BC69CCFE38FFA62D64A7226BD5D08E014A996.jpg?q=95&s=1440x1440&t=inside', 3, '2022-07-21T14:47:00'), (55, 'https://dnvefa72aowie.cloudfront.net/origin/article/202207/D1C5535E090FAAF7C6C6632DB39443922A7F751E1D516AF2D3839C49EBBE170A.jpg?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (56, 'https://dnvefa72aowie.cloudfront.net/origin/article/202207/26aef1be795eeeef50b8636c721f1c5c379bd6d17aaf2c4bd244340e5487d87b.webp?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (56, 'https://dnvefa72aowie.cloudfront.net/origin/article/202207/9dd3202e0f6eb1dbc9bdbd9ea39ed9b6da56cef0c9a0f0f7b453144b27fe78ee.webp?q=95&s=1440x1440&t=inside', 2, '2022-07-21T14:47:00'), (57, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/CA8A1BF0388F5C7E24B97CC66E5BF4A3DFA72ECF4D397610E2557AE8763C7CCD.jpg?q=95&s=1440x1440&t=inside', 1, '2022-07-21T14:47:00'), (57, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/FBEA9CEF72CEA507AF331409BE80BDEB4465128954D7D8E12E3B5AAC37AC6C93.jpg?q=95&s=1440x1440&t=inside', 2, '2022-07-21T14:47:00'), (57, 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/1B83C5DF48D4D9F46029FC09B49DE351EC99CE76A0D5736A32D76C4836C4A2C0.jpg?q=95&s=1440x1440&t=inside', 3, '2022-07-21T14:47:00'); INSERT INTO `product`(title, `description`, minimum_price, category, location, thumbnail_image, progressed, expire_at, created_at, user_id) VALUES ('에어포스 나이키 포스 신발', '나이키 공홈 구매 정품입니다 직거래시 나이키 쇼핑백에 넣어드려요 제가 계신곳으로 이동하고요 직거래시 거파 방지 예약금(홀드금) 1만원 받고 진행합니다 현장에서 차액 주시면되요 당일 거래파기시 홀드금 환불 없습니다 (직거래 잡고 연락두절인 사람이 많습니다) 택배거래는 택포 가격 16.5 직거래시 17 제 위치로 오시면 16 우체국으로 당일 운송장 드려요 (배송비만 4000원 택포로 드려요) ', 170000, 'MAN_FASHION_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202206/4CB30B6DA5F5388D591B9A05FF752EE648BAFAB765F1A40E7AA8DBC01F9922CF.jpg?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7), ('나이키덩크하이범고래 신발', '광복 나이키 구매 상품 나코텝 덩크로우 범고래265랑 교신가능', 180000, 'MAN_FASHION_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/9d0d88038818aa4ae16532e9e01ba7f1069f3dd537c7e65db6d6eff77fd6aa91.webp?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7), ('에어조던1미드브레드밴드 신발', '새상품입니다 에어조던1미드브레드밴드 260 슬램덩크 강백호신발', 150000, 'MAN_FASHION_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/479f19089a29db8f4b07cc07b485b794bc10ff884355dadbfee173dfaa712bfb.webp?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7), ('호피탭 골구 골든구스 신발', '******마지막 가격 입니다****** 골든구스 수퍼스타 호피탭 사이즈: 35사이즈 225-230신으면 잘 맞아요 (전 보통 구두, 운동화 모두 230신어요) 구입가격 : 50만원대 / 구입은 3년 정도 된것 같은데 원래 빈티지 하게 나왔고 굽닳음 별로 없어요 안쪽 살짝 속굽 있는 모델이라 신음 키도 커보이고 편하고 이뻐요^^ 직거래,택배거래 가능 택배 선불시 +2900/ 반값 택배시 ***-****-**** 원 교환 반품 환불 안되니 신중거래 부탁드려요', 100000, 'WOMAN_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/F04E734834A284763D1D740E9DD26E513D6B50D69FB357A72DA572EB06CA0E69.jpg?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7), ('레오파드탭 슈퍼스타 신발', '선물받은건데 별로 신지않았구요 가산디지털단지 또는 현대아울렛 앞에서 직거래원해요 사이즈는 37이구요 제가 235인데 딱맞았어요 230-235 생각하시면될꺼같아요', 120000, 'WOMAN_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202206/295C3D0C49B044FA087B2123237537453D7E9827E6E5A23F6EF1061C33416CF1.jpg?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7), ('반스 레드 반스245 신발', 'abc마트 매장에서 3일 전에 구매한 거의 새상품입니다. 집 근처에 잠깐 신었는데 저한테는 너무 크네요. 택, 박스, 쇼핑백 모두 있습니다. 교환은 하지않습니다. 직거래 가능합니다. 배송비는 포함되지 않은 가격입니다. 반값택배, 일반택배 모두 가능합니다.', 59000, 'WOMAN_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202207/D1C5535E090FAAF7C6C6632DB39443922A7F751E1D516AF2D3839C49EBBE170A.jpg?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7), ('토리버치 플랫 신발', '토리버치 슬립온 8 사이즈 입니다(250) 토리버치 슬립온입니다 해외에서 사와서 한국에 없는 디자인이예요 몇번 안신었구요 가죽이라 부드럽고 신으면 더 고급져 보여요 녹양역,가능역부근 입니다 집앞 거래 합니다', 50000, 'WOMAN_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202207/26aef1be795eeeef50b8636c721f1c5c379bd6d17aaf2c4bd244340e5487d87b.webp?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7), ('구찌 신발 쇼핑백, 발렌시아가 수트케이스', '각 만원이며 수트케이스만 2만원입니다! 직거래시 저희 집앞입니다~ 사진순서대로 크기 측정해놨습니다~ 2번은 두개이상 구매시에 그냥 드리겠습니다 보니깐 상태가 별로네요ㅜ 1번- 가로32 세로45 폭13 2번- 가로45 세로36 폭16(모서리 살짝 까짐) 3번- 가로45 세로36 폭16 수트케이스- 가로63 세로120 (어지간한거 다들어갑니다)', 10000, 'WOMAN_GOODS', '서울역', 'https://dnvefa72aowie.cloudfront.net/origin/article/202208/CA8A1BF0388F5C7E24B97CC66E5BF4A3DFA72ECF4D397610E2557AE8763C7CCD.jpg?q=95&s=1440x1440&t=inside', 1, '2022-08-16T15:00:00', '2022-07-21T14:47:00', 7);