-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
✨ 기능 개요
날짜 투표(Vote) 확정 이후, 구체적인 만남 시간을 정하는 시간 투표(TimePoll) API를 구현합니다.
PRD 3.1~3.5 흐름에 대응하는 백엔드 CRUD API + 스케줄러 기반 알림 시스템입니다.
🧩 주요 작업 내용
Entity & Enum
-
TimePoll— 시간 투표 본체 (Vote FK, 상태, 확정시간, 독촉 단계 등) -
TimePollEntry— 유저별 투표 응답 (Participant FK, 선택 시간LocalTime) -
TimePollStatus— 투표 상태 enum (ONGOING,ULTIMATUM,FINALIZED)
Repository
-
TimePollRepository— 상태별/시간별 조회, 스케줄러용 쿼리 -
TimePollEntryRepository— 투표 응답 CRUD, 중복 체크, 과반 체크
DTO
-
TimePollCreateRequest— 투표 생성 (voteId, confirmedDate) -
TimePollSubmitRequest— 투표 제출 (participantId, selectedTime) -
TimePollResponse— 투표 페이지 조회 응답 (내 투표 여부 포함) -
TimePollStatusResponse— 투표 현황 응답 (status, finalizedTime, 늦은시간순 정렬, 미투표자 목록)
Service
-
TimePollService— 핵심 비즈니스 로직create()— 시간 투표 생성getTimePoll()— 투표 페이지 조회 (유저별 투표 여부 포함)submit()— 투표 제출 (중복 시 수정, 전원 완료 시 자동 확정, 현황 응답 반환)getStatus()— 현황 조회 (늦은시간순 정렬, 미투표자, status/finalizedTime 포함)accept()— "저도 그때 좋아요" 수락 (최다 득표 시간 배정, 전원 완료 시에만 확정, 현황 응답 반환)finalize()— 투표 확정 (최다 득표 시간 계산, 동률 시 늦은 시간 우선)
Controller
-
TimePollController— REST API 엔드포인트
Scheduler
-
TimePollScheduler— 1분 주기 DB 폴링 기반 스케줄러- 3분 경과: 집계 메시지 (투표자 0명 분기 처리, 3분 전 과반 시 조기 집계)
- 30분 / 2시간 / 6시간 / 12시간: 미투표자 독촉 (단계별 톤 변경)
- 24시간: 최후통첩 발송 → ULTIMATUM 상태 전환
- 최후통첩 +60분: 무응답 시 자동 확정 → FINALIZED
-
WorkingdeadApplication에@EnableScheduling추가
| Method | Endpoint | 설명 |
|---|---|---|
| POST | /api/time-polls | 투표 생성 |
| GET | /api/time-polls/{pollId}?participantId= | 투표 페이지 조회 |
| POST | /api/time-polls/{pollId}/submit | 투표 제출 |
| GET | /api/time-polls/{pollId}/status | 현황 조회 |
| POST | /api/time-polls/{pollId}/accept?participantId= | 수락 |
| POST | /api/time-polls/{pollId}/finalize | 확정 |
💬 추가 설명
submit,accept,statusAPI 모두 동일한TimePollStatusResponse형식으로 응답 반환- 시간은
LocalTime(24시간 형식, 예:18:00,16:30)으로 저장하고, 프론트에서 한국어 변환 (6시,4시반) - 기존
Vote→TimePollFK 연결, 기존Participant재활용 accept는 미투표자가 여러 명일 수 있으므로 개별 수락만 처리하고, 전원 완료 시에만finalize호출- 최다 득표 시간 동률 시 더 늦은 시간으로 확정
UniqueConstraint로 한 사람이 같은 투표에 중복 제출 방지
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels