-
[정글 WEEK00_미니프로젝트] 개발 일지 - 공구장터⚡️Extracurricular Activites/정글 2025. 3. 14. 19:45
3월 11일부터 13일까지 3일동안 프로젝트에 푹 빠져있었는데 오랜만에 기분좋은 긴장감을 느꼈다.
규모가 큰 프로젝트는 아니었지만 협업하면서 배운 점이 많다.
경력이 없는 팀원들이었지만 구현을 참 잘 했고 열정도 넘쳤다. 한편 git 사용법이은 내가 알려줄 수 있는 게 많았다.
아쉬웠던 부분은 개인적으로 리팩토링을 진행했다.
1. 기획 의도
편리한 공동구매 서비스 제공
2. 서비스 소개
1. 공구를 원하는 물품이 생기면
2. 공구장터에 들어가본다.
2-1. 원하는 물품이 없으면 게시글을 작성한다.
2-2. 원하는 물품이 이미 있으면 해당 물품 게시글에 댓글과 희망 구매 개수를 작성한다.
3. 공구가 마감될 때까지 대기한다.
4. 공구장터 슬랙 계정으로 구매 확정 메세지를 받는다.
3. 서비스 프로세스
Slack OAuth
유저가 Slack 소셜 로그인을 시도하면 공구장터 서버가 OAuth로 인증을 받고, Slack 서버가 인증을 해주면 공구장터 서버의 사용자 정보 요청 엔드포인트로 리디렉션을 해준다.
리디렉션된 엔드포인트에서 Slack 서버에 사용자 정보를 요청하고 응답을 받으면 DB에 사용자 정보를 저장한다.
공구장터 JWT 인증 체계
OAuth가 성공해 사용자 신원이 확인되었으면 JWT로 공구장터 서버 자체 Access Token과 Refresh Token을 발급한다.
Access Token의 만료 기간은 12시간으로 잡았고, Refresh Token의 만료 시간은 5개월로 잡아서, 5개월의 교육기간 내에 다시 로그인을 할 필요가 없도록 만들었다.
Access Token은 유저에게 쿠키를 통해 전달하고, Refresh Token은 DB에 저장한다.
그 이후 모든 API 요청 응답은 JWT 인증 기반으로 동작한다.
DM 송신
매일 오전 9시에 APScheduler를 통해 마감된 게시글을 확인하고 게시글 작성자와 댓글 작성자에게 구매 확정 DM을 보내준다.
4. 아키텍쳐
Flask 기반 SSR 웹 애플리케이션
웹 애플리케이션의 백엔드는 Flask로 구성하고, 서버 사이드 렌더링(SSR)을 위해 Jinja2 템플릿 엔진을 활용했다.
클라이언트 사이드 렌더링(CSR) 방식과 비교했을 때, SSR은 초기 페이지 로딩 속도가 빠르고, 검색 엔진 최적화(SEO)에 유리하다는 장점이 있다. 반면, CSR은 페이지 전환 시 부드러운 사용자 경험(UX)을 제공할 수 있으나, 초기 로딩 속도가 상대적으로 느릴 수 있다. 본 프로젝트에서는 주로 SSR 방식으로 보다 빠른 초기 페이지 렌더링과 SEO 효과를 극대화했다.
메인 페이지 로그인 페이지 게시글 작성 페이지 게시글 페이지 - 댓글 작성 게시글 페이지 - 게시글 수정 게시글 페이지 - 구매 개수 입력 모달창 스타일링과 UI 구성
CSS 스타일 라이브러리로는 Bulma를 사용했다.
또다른 CSS 스타일링을 위한 라이브러리 Tailwind는 유틸리티 클래스 기반으로 세밀한 스타일 조정이 가능한 반면, Bulma는 CSS만으로 구성된 경량 프레임워크로, 별도의 JavaScript 의존성 없이도 직관적인 스타일링이 가능하다는 점이 강점이다. 이를 활용해 반응형 디자인을 손쉽게 적용하고, 유지보수가 용이한 스타일링을 구축했다.
데이터베이스 설계 및 MongoDB 활용
데이터베이스는 MongoDB를 사용했다.
MongoDB는 문서(Document) 기반의 데이터 모델을 제공하며, 스키마를 엄격하게 고정할 필요 없어 서브도큐먼트(Subdocument)를 활용한 비정규화 방식으로 데이터를 저장했다. 이를 통해 특정 문서 조회 시 연관된 데이터를 join하지 않고 한 번에 가져올 수 있었다.
Slack 연동을 통한 소셜 로그인 및 웹훅 처리
Slack과 공구장터 서버를 연동하여 소셜 로그인 기능과 웹훅 처리 기능을 구현했다.
Slack OAuth를 활용해 사용자가 간편하게 로그인할 수 있도록 하고, 공구 마감 알림 메시지와 같은 특정 이벤트를 Slack 웹훅을 통해 자동으로 전송하도록 구성했다.Slack은 HTTPS 서버만 리디렉트를 지원하므로, 개발 환경에서는 ngrok을 사용해 http://localhost:5000/oauth/callback을 https://8b29-1-238-129-195.ngrok-free.app/oauth/callback으로 리버스 프록시를 설정했다. 운영 환경에서는 AWS EC2에 Caddy를 설치하여 https://43.201.98.116.nip.io/oauth/callback로 HTTPS를 적용했다.
5. 코드 개선
도메인 설계 수정
- product → post
- 게시글당 하나의 상품이 있는 것이기 때문에 product가 아닌 post 단위로 변경했다.
아래는 도메인 관리가 안 되어있어서 분리를 위해 생성한 도메인이다.
- alarm
- 메세지 전송 대상 게시물 확인 및 Slack으로 DM 전송
- board
- 게시글 x N
- comment
- 댓글
- reply
- 대댓글
- reply
- 댓글
- order
- 모달창을 통해 상품 주문
Restful하게 api 설계 수정
설계를 기능별로 각자 하다보니 Restful하지 않은 api도 많았고, 동사가 들어간 경우, /api처럼 불필요한 접두사가 들어간 경우도 많았다.
- post
- 모든 게시글 조회
- GET /api/products → GET /posts
- 특정 게시글 조회
- GET /product-detail/<id> → GET /post/<id>
- 게시글 생성
- POST /api/product → POST /post
- 게시글 수정
- POST /update_post → PATCH /post/<id>
- 상품 구매
- POST /buy_product/post_id → POST /order
- 모든 게시글 조회
- login
- 소셜 로그인
- GET api/check-login → login
- 소셜 로그인
- comment
- 댓글 작성
- POST /new_comment → POST /comment
- 댓글 조회
- GET /read_comment → GET /comment/<id>
- 댓글 수정
- POST /update_comment → PATCH /comment<id>
- 댓글 삭제
- POST /delete_comment → PUT /comment/<id>
- body에 {”status”: “deleted”}
- POST /delete_comment → PUT /comment/<id>
- 대댓글 작성
- POST /new_reply → POST /comment/<id>/reply
- 대댓글 조회
- GET /read_replies → GET /comment/<id>/replies
- 대댓글 수정
- POST /update_reply → PATCH /comment/<comment_id>/reply/<reply_id>
- 대댓글 삭제
- POST /delete_reply → PUT /comment/<id>/reply/<reply_id>
- body에 {”status”: “deleted”}
- POST /delete_reply → PUT /comment/<id>/reply/<reply_id>
- 댓글 작성
프로젝트 구조 개선
기존에는 모든 비즈니스 로직이 app.py에 있었는데 도메인별로 파일을 분리하고 templates html 파일들도 위에서 적용한 도메인 설계를 반영했다.
- templates
- login.html (변경 없음)
- index.html → post-list.html
- create-product.html → product-new.html
- product-detail.html → product.html
- app.py → run.py (run.py가 Flask 초기화한 app._init__.py를 호출)
- app
- __init__.py (Flask 초기화, config 등록)
- controller
- alarm.py
- board.py
- comment.py
- login.py
- order.py
- post.py
- core
- auth.py (jwt 인증 관련)
- database.py (MongoDB 커넥션 생성)
- .env (client id, client secret 등 credentials 저장)
변경 후 변경 전 'Extracurricular Activites > 정글' 카테고리의 다른 글
[정글 WEEK02_알고리즘] 개발 일지 - 시험 (0) 2025.03.28 [정글 WEEK02_알고리즘] 개발 일지 - 문제 풀이 (0) 2025.03.26 [정글 WEEK02_알고리즘] 개발 일지 - 퀴즈 (0) 2025.03.26 [정글 WEEK01_알고리즘] 개발 일지 - 1주차 마무리 (0) 2025.03.23 정글의 시작점에서, 찬찬히 돌아보며 (4) 2025.03.14 - product → post