Skip to content

[Feature] 시간 투표 API #31

@hayeon7898

Description

@hayeon7898

✨ 기능 개요

날짜 투표(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, status API 모두 동일한 TimePollStatusResponse 형식으로 응답 반환
  • 시간은 LocalTime (24시간 형식, 예: 18:00, 16:30)으로 저장하고, 프론트에서 한국어 변환 (6시, 4시반)
  • 기존 VoteTimePoll FK 연결, 기존 Participant 재활용
  • accept는 미투표자가 여러 명일 수 있으므로 개별 수락만 처리하고, 전원 완료 시에만 finalize 호출
  • 최다 득표 시간 동률 시 더 늦은 시간으로 확정
  • UniqueConstraint로 한 사람이 같은 투표에 중복 제출 방지

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions