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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions