티스토리 뷰
1. 프로젝트 개요 (Project Overview)
핏메이트(Fitmate)는 '핏'과 '메이트'를 결합한 이름으로, 헬스와 관련된 맞춤형 트레이닝을 돕는 친구 같은 존재를 의미합니다. 이 서비스는 운동 전문가와 건강 운동을 배우고자 하는 유저를 매칭하여 1:1 맞춤형 운동 프로그램을 제공하는 것을 목표로 합니다. 또한, AI 챗봇 기능을 제공하여 사용자 입력을 분석하여 맞춤형 운동 추천 및 운동 관련 질문에 대한 응답을 제공합니다.
2. 담당한 작업 (Task & Contribution)
백엔드 개발
- 데이터베이스 설계
- 레슨 관련 API 개발
- 레슨 요청 및 취소 기능
- 레슨 목록 및 레슨 상세 조회
- 내가 신청한 레슨 목록 조회
- 나의 요청 레슨에 대한 지정 견적 요청 생성
- 지정 견적 요청에 대한 반려 기능 (트레이너)
- 견적 관련 API 개발
- 견적 작성 기능
- 견적 목록 및 견적 상세 조회
- 견적 확정 및 반려 기능
- 리뷰 작성 가능한 견적 목록 조회
- 알림 시스템 구현
- 유저 알림 목록 조회
- 특정 알림 읽음 처리 (토글)
- 특정 유저에게 알림 전송 (SSE 방식)
- 트리거와 저장 프로시저를 이용한 알림 생성 기능 개발
- Fitmate AI 챗봇 구현
- OpenAI API를 이용하여 맞춤형 운동 추천 챗봇 개발
3. 기술적 성과 (Technical Achievements)
- AI 챗봇 구현
- OpenAI ChatGPT-4-mini를 활용한 맞춤형 운동 추천 및 질의응답 기능 구현
- 사용자 입력 분석을 최적화하여 자연스러운 한국어 문장으로 응답 제공
- 프롬프트 엔지니어링을 통해 챗봇의 답변 품질 향상
- SSE 기반 실시간 알림 시스템 구현
- PostgreSQL LISTEN/NOTIFY와 RxJS를 활용하여 SSE(Server-Sent Events) 방식의 실시간 알림 처리
- RxJS Subject를 활용한 사용자별 알림 스트림 관리 및 최적화
- 레슨 요청, 견적 확정, 레슨 완료 등의 주요 이벤트 발생 시 실시간 알림 제공
- 트리거 및 저장 프로시저 기반 알림 자동화
- PostgreSQL 트리거 및 저장 프로시저를 활용하여 레슨 상태 변경, 견적 요청 등의 이벤트 발생 시 자동으로 알림 생성
- LISTEN/NOTIFY 기능을 활용하여 서버와의 연동 없이 데이터베이스 레벨에서 실시간 알림 전송
- NestJS 기반 백엔드 아키텍처 최적화
- Dto(Data Transfer Object)를 활용하여 데이터 유효성 검증 및 타입 안전성 확보
- 서비스(Service) 로직, 컨트롤러(Controller) 로직, 레포지토리(Repository) 로직을 분리하여 각각의 책임을 명확히 구분
- 의존성 주입(Dependency Injection)과 모듈화 구조를 도입하여 유지보수성을 향상
4. 문제점 및 해결 과정 (Challenges & Solutions)
1) 발생 문제: 알림 생성 시간 오차 문제
- API 응답에서 createdAt, updatedAt 값이 현재시간보다 9시간 늦게 표시됨
- 프론트엔드에서 알림 시간이 현재시간보다 9시간 더해지는 문제 발생
2) 원인 분석
- 저장 프로시저에서 now() 사용 시 OS 타임존(KST)이 적용되어 KST 기준으로 저장됨
- 하지만 프론트엔드는 이를 UTC로 가정하고 KST 변환을 추가 수행, 결과적으로 9시간 차이 발생
3)해결 방법
- 저장 프로시저에서 now()를 UTC로 변환하여 저장하도록 수정
BEGIN
INSERT INTO "Notification" (
"userId", "type", "message", "createdAt", "updatedAt"
) VALUES (
user_id, type::"NotificationType", message,
now() AT TIME ZONE 'UTC', -- UTC 변환하여 저장
now() AT TIME ZONE 'UTC'
);
END;
- now()를 UTC 기준으로 변환하여 저장해 일관성 유지
4) 배운 점 및 개선 사항
- 데이터베이스 레벨에서의 now()는 OS 타임존 영향을 받으므로, DB에서 직접 UTC 변환이 필요함
- 애플리케이션 레이어에서 시간을 생성하면 UTC로 저장되지만, 트리거·저장 프로시저에서는 명확한 변환 적용 필요
- API 응답에서 추가 변환 없이 UTC → KST 처리가 가능하도록 시간 동기화 전략을 명확히 설정해야 함
5. 협업 및 피드백 (Collaboration & Feedback)
- 효율적인 협업
- 코드 리뷰를 통해 서로의 코드를 검토하고 개선 사항을 공유하며 전체적인 코드 품질을 향상시켰습니다.
- 지식 공유
- 알림 시스템 구현 과정에서 PostgreSQL과 SSE 기반의 실시간 알림 처리 방식뿐만 아니라, 타임존 개념에 대한 이해도를 높였습니다.
- 특히, UTC 기반 시간 저장 및 변환 방식에 대한 논의를 통해, API 응답에서의 일관된 시간 처리를 보장하는 방법을 공유하고 적용했습니다.
- 문제 발생 시 신속한 대응
- Zoom, Notion, Discord를 적극 활용하여 팀원 간 실시간 피드백을 주고받으며, 발생한 이슈를 빠르게 해결하였습니다.
- 타임존 변환 오류 및 알림 데이터 전송 관련 문제 해결을 위해 지속적인 테스트와 코드 최적화를 진행했습니다.
6. 코드 품질 및 최적화 (Code Quality & Optimization)
- NestJS 기반 아키텍처 최적화
- Dto(Data Transfer Object)를 활용하여 데이터 유효성 검증 및 타입 안전성 확보
- 인터페이스와 클래스를 적극 활용하여 의존성을 낮추고 재사용성을 높임
- 서비스(Service) 로직, 컨트롤러(Controller) 로직, 레포지토리(Repository) 로직을 분리하여 각각의 책임을 명확히 구분
- 서비스 계층 분리 및 유지보수성 향상
- 컨트롤러에서는 요청을 받아 DTO를 검증하고, 비즈니스 로직은 서비스 계층에서 처리하도록 설계
- 데이터베이스 접근 로직은 레포지토리 계층에서 관리하여 서비스 계층과 분리
- 의존성 주입 및 모듈화
- NestJS의 의존성 주입(Dependency Injection) 시스템을 활용하여 효율적인 모듈 관리를 구현
- 기능별 모듈을 분리하여 코드의 유지보수성을 향상
7. 향후 개선 사항 및 제안 (Improvements & Recommendations)
- 프롬프트 엔지니어링을 통한 챗봇 품질 개선
- 사용자 입력 의도를 보다 정확하게 분석할 수 있도록 프롬프트 최적화
- 운동 추천 응답의 정확도를 높이기 위해 다양한 예제 학습 데이터 반영
- 대화 흐름을 더욱 자연스럽게 개선하여 사용자 경험 향상
- 지속적인 피드백과 테스트를 통해 챗봇 응답 모델 최적화
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 독스루
- 리액트
- React
- d.ts
- virtual dom
- 풀스택
- typscript
- 렉시컬
- 배열 키 설정
- docthru
- 무결성
- 프로젝트
- 타입스크립트 동작원리
- usecalback
- 코드잇스프린트프리코스
- 스프린트풀스텍2기
- semantic tag
- 렌더링
- 스프린트풀스택2기
- 데이터베이스 정규화
- 코드잇스프린트
- seo
- 타입 정의 파일
- 모드잇
- lexical
- fitmate
- useMemo
- 취업까지달린다
- 데이터 이상
- 개발리포트
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
글 보관함
