<aside>
“일상의 불편함을 코드로 해결하며, 끊임없이 발전하는 개발자 김민희입니다.”
</aside>
성명 : 김민희
지원분야 : SW 개발 (신입)
학력사항 : 신라대학교 경영학전공 (2015.03 - 2020.02)
현재주소 : 부산시 사상구 모라동 **(근무지 이상 가능)
생년월일 : 1996-10-11 (만 28세)
휴대폰 : +82) 010-5784-3378
이력서 : 김민희 이력서 url
이메일 : minhi0449@gmail.com
<aside> <img src="/icons/gradebook_gray.svg" alt="/icons/gradebook_gray.svg" width="40px" />
</aside>
프로젝트 기간 | 2024년 11월 18일 → 2024년 12월 26일 (6주) |
---|---|
기술 스택 | Java, React, Spring Boot, JPA, MySQL, Redis, MongoDB |
팀 구성(7명) | (팀장)최준혁, 강은경, 김민희, 박경림, 정지현, 하정훈, 황수빈 |
나의 구현 기능 | 게시판(Board) |
CRUD(작성/목록/상세보기/수정/삭제), 첨부파일(업로드/다운로드), | |
댓글(작성/수정/삭제/비밀댓글), 검색/페이징 | |
주요 기능 | 관리자, 프로젝트, 게시판, 채팅, 드라이브, 캘린더, 페이지 |
Github | https://github.com/minhi0449/antwork |
시연 영상 | https://youtu.be/EtwH4WvMnJo?t=764 |
결과보고서 | ‣ |
<aside> <img src="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" alt="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" width="40px" />
개발 및 기여 내용
구현 기능 | 기여도 설명 |
---|---|
**카테고리 생성 모달/ | |
입력값 검증** | • React 모달(+Zustand)로 제목·설명 입력 후 공백·중복명 검증 후 카테고리 생성 |
• 성공 시 토스트 알림 및 사이드바 즉시 갱신, 새로고침 없이 카테고리 추가 | |
**카테고리 목록 캐싱/ | |
렌더링** | |
• 앱 시작 단계에 한 번만 목록을 불러와 전역 상태로 보관 | |
• 사이드바·드롭다운 등 여러 컴포넌트가 동일 데이터를 재사용해 불필요한 재요청 방지 | |
**카테고리별 | |
게시글 접근 링크** | • 사이드바에서 동적으로 생성된 카테고리 항목을 클릭하면 해당 카테고리 ID를 포함한 URL로 이동 |
• URL 파라미터 기반 라우팅으로 검색·페이징·새로고침 이후에도 동일 카테고리 컨텍스트를 유지해 일관된 사용자 경험 제공 |
</aside>
<aside> <img src="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" alt="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" width="40px" />
개발 및 기여 내용
구현 기능 | 설명 |
---|---|
입력값 검증 | • 제목·내용 입력 시 trim()으로 공백 제거, 빈 값일 경우 alert 경고 |
• 클라이언트 측 검사로 서버 요청 감소 | |
• 사용자 입력 오류 방지 및 서버 부하 절감 | |
**인라인 수정 | |
(Inline Edit)** | • React useState로 수정 모드(isUpdate) 구현, 동일 페이지에서 즉시 수정. 새로고침 제거 → 사용자 중심으로 설계 |
• FormData로 수정 데이터 전송, 스프링 JPA Dirty Checking으로 변경 필드만 업데이트해 트래픽과 I/O 최소화 | |
• 클릭 수 감소로 사용자 경험 개선 및 코드 복잡도↓ | |
**첨부파일 관리 | |
(업로드)** | • 드래그 앤 드롭 UI로 파일 선택, FormData로 최대 10MB 파일 업로드 |
• BoardFileUpload 컴포넌트 재사용으로 코드 중복 감소 | |
• 직관적 파일 업로드와 개발 효율성 증대 | |
**권한 기반 | |
수정·삭제** | |
• React 조건부 렌더링으로 작성자만 수정/삭제 버튼 표시 | |
• Spring Security로 작성자 ID 검증 | |
• 보안 강화 및 작성자 중심 UX 제공 | |
**클라이언트-서버 | |
분리** | • React SPA로 UI, Spring Boot REST API로 데이터 처리 |
• axios 로 API 호출 통합 | |
• 시스템 안정성 및 코드 유지보수성 향상 | |
안전한 삭제 처리 | • 2단계 확인 모달로 실수 삭제 방지 및 삭제 완료 후 자동 목록 리다이렉트 구현 |
• 게시글 삭제 시 연관된 첨부파일과 댓글을 cascade 방식으로 일괄 정리하여 데이터 정합성 보장 | |
• 삭제된 게시글 URL 직접 접근 시 404 처리로 완전한 삭제 상태 관리 |
</aside>
<aside> <img src="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" alt="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" width="40px" />
개발 및 기여 내용
구현 기능 | 설명 |
---|---|
**첨부파일 목록/ | |
대용량 표시** | |
• 게시글 상세 페이지에서 첨부파일 전체를 리스트로 제공 | |
• 파일명, 용량, 100MB 이상 파일은 ‘대용량’으로 구분하여 사용자 인식 용이 | |
저장 구조 설계 | |
• UUID 기반 파일명을 사용하여 이름 충돌 없이 업로드 | |
• 다양한 확장자 대응 및 서버 디렉토리 구조 유지로 운영 안정성 확보 | |
**안정적인 | |
다운로드 처리** | |
• 서버에서 파일 존재 여부·권한을 검증한 후 응답 제공 → 오류 발생 가능성 최소화 | |
• 파일이 실제 서버에 존재하는지, 권한이 유효한지를 서버 측에서 사전 확인 | |
• 응답이 문제 없을 때만 파일을 사용자에게 제공하여 오류 가능성 제거 | |
간편한 다운로드 흐름 | • 클릭 즉시 다운로드 실행, 페이지 전환 없이 파일 접근 가능 |
**게시글 좋아요 | |
(토글 방식)** | • 한 번 클릭으로 좋아요 등록, 다시 클릭 시 취소되는 토글 구조로 설계 |
• 불필요한 중복 클릭 방지와 직관적인 UI 제공 → 사용자 경험(UX) 간소화 | |
**좋아요 상태 저장/ | |
전환 처리** | |
• 사용자와 게시글 간 1:1 관계를 유지하기 위해 BoardLike 테이블 사용 | |
• 기존 좋아요 기록 존재 시 → 삭제, 없으면 → 등록 | |
• existsByBoardIdAndUserId()로 상태 판별 → 데이터 무결성 확보 | |
**좋아요 수/ | |
상태 실시간 반영** | |
• 좋아요 버튼 클릭 시 서버 응답으로 받은 likeCount, liked를 기반으로 클라이언트에서 즉시 UI 상태 변경 | |
• 새로고침 없이도 반응형 UX 제공 → SPA 장점 활용 | |
상태값 동기화 | • 클라이언트는 좋아요 수와 상태를 useState로 관리하되, 서버에서 응답받은 최신 상태로 갱신 |
• 리스트/상세 페이지 간 좋아요 수의 데이터 일관성 유지 | |
</aside> |
<aside> <img src="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" alt="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-80fd-a3d6-007afb26ef57" width="40px" />
</aside>
<aside> <img src="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-8049-bd3d-007ab51e6f6f" alt="notion://custom_emoji/05b1ac8a-59e5-41ce-bdf8-3d2507e07b93/1b626d45-1b22-8049-bd3d-007ab51e6f6f" width="40px" />
</aside>