1차 프로젝트 - '펀딩할래' 리뷰
프로젝트 개요
- 프로젝트 주제 : 커뮤니티 중심 크라우드 펀딩 사이트
- 기간 : 2024.08.14 ~ 2024.08.29
- 팀 내 역할 : 팀장 (프로젝트 관리 및 개발)
- 개발 페이지 : 펀딩 페이지, 커뮤니티 페이지, 마이 페이지
- 기술 스택
프로젝트 취지
1차 프로젝트는 커뮤니티 중심의 신뢰성과 소속감을 기반으로 한 크라우드 펀딩 플랫폼을 개발하기 위해 시작되었습니다.
주제 조사 과정에서 많은 크라우드 펀딩 사이트들이 커뮤니티 중심으로 운영되고 있다는 점을 확인하였고,
이를 바탕으로 신뢰성과 소속감을 강조하는 커뮤니티 중심의 크라우드 펀딩 플랫폼을 기획하고 개발하였습니다.
저는 이번 프로젝트에서
펀딩 페이지, 커뮤니티 페이지, 마이 페이지 부분을 맡았습니다.
✅펀딩 페이지
펀딩 페이지 상단에는 리액트의 slider 기능을 사용하여 이미지 슬라이더를 구현했습니다.
또한 더 나은 디자인과 사용자 경험을 위해 slick-theme를 사용했습니다.
import Slider from 'react-slick';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
슬라이더 우측에는 해당 펀딩에 대한 기본적인 정보들을 담았습니다.
정보 부분 하단에는 창작자 소개란을 담았고 팔로우, 문의 기능을 구현했습니다.
본문에서는 화면을 나눠서
좌측에는 펀딩에 대한 상세정보를,
우측에는 펀딩에 대한 리워드를 선택할 수 있게 구성했습니다.
좌측에 있는 펀딩 상세정보에서는
네비바를 둬서 커뮤니티, 후기 탭으로 쉽게 이동할 수 있게 구성했고,
소개 버튼을 클릭하면 지정된 섹션으로 부드럽게 이동할 수 있도록 구현했으며,
sticky 옵션을 적용해 항상 상단에 고정되도록 구성하여 사용자들이 상세 내용을 더욱 편리하게 확인할 수 있도록 사용자 경험을 개선했습니다.
우측에 위치한 리워드 선택 탭에서는 펀딩 리워드를 선택할 때
호버 효과를 적용해 시각적으로 확인할 수 있도록 구현했습니다.
🖥️ 화면 시연
✅커뮤니티 페이지
펀딩 페이지의 네비바를 통해 이동된 커뮤니티 페이지입니다.
커뮤니티 기능 강화를 위해 펀딩 창작자가 직접 업데이트를 작성할 수 있도록 하여,
후원자와 창작자 간의 소통과 참여를 높이고 커뮤니티의 활성화를 유도하였습니다.
창작자가 글을 남기면 최종 작성 일자를 표시해 사용자 참여를 유도하였습니다.
창작자가 쓴 글은 readonly 속성을 적용해 확인만 가능할 수 있게 하였습니다.
마찬가지로 후원자도 댓글을 작성할 수 있으며
댓글 작성 시 아이콘, 닉네임, 작성 날짜가 보이며 수정, 삭제가 가능하게 구현 하였습니다.
하단에는 댓글 페이지네이션을 통해 사용자 편의성을 제공했습니다.
Spring Boot와 MyBatis를 활용하여 백엔드를 구현하였습니다.
로직은 Controller → Service(interface) → ServiceImpl(구현체) → DAO → Mapper 순으로 진행되도록 설계하였습니다.
댓글 작성 시 특정 페이지를 구분하기 위해 gubun 값을 사용하여 각 페이지에 대한 댓글을 관리하였으며,
주요 기능으로는 작성(POST), 조회(GET), 수정(PUT), 삭제(DELETE) 가 있습니다.
먼저 댓글 데이터를 주고받을 DTO를 정의하였습니다.
DTO
@Data
public class CommentDTO {
private int id;
private String username;
private String text;
private String createdAt;
private int gubun;
}
Controller
컨트롤러에서는
@RequestBody를 사용하여 클라이언트에서 전달된 JSON 데이터를 DTO 객체로 변환하였고,
받아온 댓글 데이터를 Service interface에 전달하여 로직을 처리하도록 구현하였습니다.
@Autowired
private CommentService commentService;
@PostMapping("/{gubun}")
public CommentDTO addComment(@PathVariable("gubun") int gubun, @RequestBody CommentDTO comment) {
comment.setGubun(gubun);
commentService.insertComment(comment);
return comment;
}
하나의 클래스에는 단 하나의 책임을 가져야 한다는 SRP 원칙과
기존 코드를 수정하지 않고도 기능을 확장할 수 있도록 설계해야 한다는 OCP 원칙을 적용하여,
Service를 인터페이스와 구현체로 분리함으로써 유연성과 유지보수성을 높였습니다.
Service(interface)
insertComment에 대한 추상화된 인터페이스를 만들었고,
호출된 메서드는 실제 구현체인 Impl로 위임되게 하였습니다.
@Override
public int insertComment(CommentDTO dto) {
return commentDAO.insertComment(dto);
}
ServiceImpl (구현체)
@Service 어노테이션을 사용하여 스프링 의존성 주입을 설정하였으며,
CommentServiceImpl 클래스가 commentService로 주입되도록 구현하였습니다.
컨트롤러에서 insertComment(comment)를 호출하면, CommentServiceImpl의 insertComment 메서드가 실행되며,
DAO를 호출하여 데이터를 전달합니다.
@Service
public class CommentServiceImpl implements CommentService {
@Autowired
private CommentDAO commentDAO;
@Override
public int insertComment(CommentDTO dto) {
return commentDAO.insertComment(dto);
}
}
DAO
DAO 에서는 @Mapper 어노테이션을 사용해 MyBatis가 DAO를 Mapper로 인식하고, Mapper XML과 연결되도록 하였습니다.
@Mapper
public interface CommentDAO {
int insertComment(CommentDTO dto);
}
Mapper
최종적으로 Mapper는 namespace를 통해 DAO를 찾고,
DAO에서 호출한 메서드와 매핑된 id 값을 기준으로 쿼리문을 실행하여 데이터베이스에 데이터를 저장하도록 구현하였습니다.
<mapper namespace="com.example.demo.dao.CommentDAO">
<insert id="insertComment" parameterType="com.example.demo.dto.CommentDTO">
INSERT INTO comments (username, text, created_at, gubun)
VALUES (#{username}, #{text}, CURRENT_TIMESTAMP, #{gubun})
</insert>
CRUD에 해당하는 조회, 수정, 삭제 기능 또한 동일한 방식으로 구현하였습니다.
🖥️ 화면 시연
✅마이 페이지
마지막으로 마이페이지 입니다.
프로필 이미지와 닉네임, 가입 날짜가 표시되며 수정하기 버튼을 통해 닉네임을 수정할 수 있습니다.
리액트의 주요 기능 중 하나인 useState를 사용해서 상태를 관리하게 하였습니다.
프로필 이름과 자기소개 업데이트는 데이터베이스에 저장되지 않고 클라이언트 상태로만 관리되게 하였습니다.
🖥️ 화면 시연
프로젝트 후기
이번 프로젝트는 제가 처음 맡은 프로젝트였을 뿐만 아니라 팀장 역할까지 맡아 큰 책임감을 가지고 임했던 프로젝트였습니다.
처음에는 무엇을 어떻게 해야 할지 몰라 막막하기도 했지만, 팀원들이 함께 도와주고 협력하면서 프로젝트를 완성할 수 있었습니다.
특히, 이번 프로젝트는 팀원들과 함께 배우고 성장할 수 있었던 값진 경험이 되었습니다.
프로젝트를 진행하면서 의사소통과 협업의 중요성을 깊이 깨달았습니다.
혼자서 모든 것을 해결하려 하기보다는, 서로 소통하며 각자의 역할에 집중했을 때 효율이 훨씬 높아진다는 것을 느꼈습니다.
저는 프로젝트의 방향성을 팀원들에게 잘 전달하려 노력했고, 부족한 부분은 팀원들에게 믿고 맡겼더니 결과적으로 제가 잘할 수 있는 부분에 집중할 수 있었습니다.
또한 프로젝트를 진행하며 열심히 하는 팀원의 모습을 보면서 스스로를 돌아보게 되는 계기가 되었습니다.
그 모습에 자극을 받아, 저도 열심히 하는 팀원에게 미안한 마음이 들지 않도록 더 열심히 참여해야겠다는 동기를 가지게 되었습니다.
결과적으로, 프로젝트를 시작했을 때와 비교해 많은 것을 배우고 성장할 수 있었습니다.
처음에는 잘 몰랐던 부분들이 하나씩 익숙해지면서, 개발 과정과 협업의 중요성을 더욱 깊이 이해하게 되었습니다.
1차 프로젝트는 제게 단순한 개발 작업 이상의 배움과 성장의 기회를 제공한 값진 경험이었습니다.
물론, 첫 프로젝트였던 만큼 아쉬운 점도 많았습니다.
처음 구상했던 만큼 높은 완성도를 이루지 못한 부분이나 전체적인 디테일은 아쉽지만, 프로젝트를 진행하면서 개발 프로세스와 협업 방식에 대해 많은 것을 배울 수 있었습니다.
클라이언트에서 서버로의 흐름, 프로젝트 시작 시 페이지를 구상하고 역할을 분배하는 방법, 그리고 팀원들과의 의사소통을 통해 프로젝트를 효율적으로 진행하는 법 등
개발의 전 과정을 체험하며 값진 교훈을 얻은 프로젝트였습니다.