Skip to content

feat: 스터디 익명 제안 & 투표 기능 추가#9

Merged
songkg7 merged 6 commits intomainfrom
feat/proposal-voting
Mar 12, 2026
Merged

feat: 스터디 익명 제안 & 투표 기능 추가#9
songkg7 merged 6 commits intomainfrom
feat/proposal-voting

Conversation

@dojinyou
Copy link
Copy Markdown
Member

@dojinyou dojinyou commented Mar 11, 2026

  • DB 마이그레이션(005): proposal_periods, study_proposals, study_proposal_votes 테이블 생성
  • ProposalRepository: 기간 생성/조회, 제안 CRUD, 투표 토글(insert/delete), 확정 처리
  • /제안시작: 운영진 역할 확인 후 제안 기간 생성, 운영진-자유채팅 채널에 공지
  • /제안: Modal로 익명 제안 수집, 채널에 게시 후 🚀 리액션 추가
  • /투표: SelectMenu로 제안 선택, 토글 투표, 3표 달성 시 자동 확정 메시지

- DB 마이그레이션(005): proposal_periods, study_proposals, study_proposal_votes 테이블 생성
- ProposalRepository: 기간 생성/조회, 제안 CRUD, 투표 토글(insert/delete), 확정 처리
- /제안시작: 운영진 역할 확인 후 제안 기간 생성, 운영진-자유채팅 채널에 공지
- /제안: Modal로 익명 제안 수집, 채널에 게시 후 🚀 리액션 추가
- /투표: SelectMenu로 제안 선택, 토글 투표, 3표 달성 시 자동 확정 메시지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
/제안시작, /제안, /투표 추가로 비관리자에게 보이는 커맨드가
2개에서 5개로 증가하여 테스트 기대값 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@songkg7
Copy link
Copy Markdown
Member

songkg7 commented Mar 12, 2026

• Findings

  1. High: 동시 투표 시 vote_count가 실제 투표 수와 영구적으로 어긋날 수 있습니다. ToggleVote:134는 일반 트랜잭션 안에서 표 수를 다시 계산해 vote_count:175에 덮어쓰지만, 부모 proposal
    row를 잠그지 않습니다. 두 명이 동시에 투표하면 둘 다 같은 stale count를 기록할 수 있고, 그 값을 기준으로 하는 자동 확정 로직(handler_vote.go:124)도 3표 달성을 놓칠 수 있습니다.
  2. High: 실제 투표 처리 경로에는 마감 검증이 없습니다. /투표 최초 진입은 활성 기간을 확인하지만(handler_vote.go:17), 선택 메뉴 제출을 받는 newVoteSelectHandler:73는 곧바로
    ToggleVote:134를 호출합니다. 그래서 마감 전에 열어둔 select menu가 살아 있는 동안에는 마감 후에도 투표가 들어갈 수 있고, 다음 기간이 시작된 뒤에도 이전 기간 proposal에 표를 넣을
    수 있습니다.
  3. High: proposal 생성이 Discord 게시와 원자적으로 묶여 있지 않아, 보이지 않는 proposal이 DB에 남습니다. CreateProposal:190을 먼저 실행한 뒤 채널 조회/메시지 전송을
    handler_propose.go:197, handler_propose.go:222에서 처리하는데, 이 구간에서 실패해도 row는 롤백되지 않습니다. 그 row는 ListProposals:112로 그대로 노출되므로, 사용자에게는 실패로
    보였던 제안이 /투표 목록에는 계속 나타나는 숨은 데이터가 됩니다.
  4. Medium: 마감일 처리 자체가 잘못되어 있습니다. handler_propose.go:55와 handler_propose.go:61는 입력 날짜를 무조건 23:59:59 UTC로 저장하고, 과거 날짜도 막지 않습니다. 그래서 2026-
    03-12를 넣으면 실제 마감 시각은 2026-03-13 08:59:59 KST가 되고, 과거 날짜를 넣어도 성공 메시지(handler_propose.go:101)는 나가지만 GetActivePeriod:53에서는 즉시 비활성으로 취급됩
    니다.
  5. Medium: “활성 제안 기간은 하나만 존재” 규칙이 DB에서 보장되지 않습니다. handler_propose.go:65에서 먼저 조회하고 handler_propose.go:95에서 나중에 insert 하는 구조인데, 스키마
    (005_create_proposals.sql:1)에는 이를 막는 constraint가 없습니다. 운영진이 동시에 /제안시작을 치면 여러 활성 기간이 생길 수 있고, 이후 GetActivePeriod:53는 가장 최근 것만 보여줘
    서 이전 기간은 사실상 숨겨집니다.

@songkg7 songkg7 merged commit 4a86ddd into main Mar 12, 2026
7 checks passed
@songkg7 songkg7 deleted the feat/proposal-voting branch March 12, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants