Skip to content

Contest community#740

Open
taekoong wants to merge 8 commits into
developfrom
contest-community
Open

Contest community#740
taekoong wants to merge 8 commits into
developfrom
contest-community

Conversation

@taekoong

@taekoong taekoong commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Changelog

  • 대회 내 질문 사항을 나눌 수 있는 대회 내 커뮤니티 기능을 생성하였습니다.

  • 대회 글 작성 시 열람 범위를 선택할 수 있도록 추가했습니다.

  • 제한글은 목록에서 숨기지 않고 회색 톤 카드와 자물쇠 아이콘으로 표시되도록 변경했습니다.

    • 제한글 상세 열람 권한을 작성자, 대회 주최자, super admin만 상세 열람 가능
    • 권한 없는 사용자는 목록에서는 볼 수 있지만 상세 진입은 차단됨
  • 주최자가 답변할 시 주최자임을 사용자 아이디 옆에 표시해두었습니다.

Testing

스크린샷 2026-07-03 오후 4 07 23 대회 중 질문 작성이 가능한 게시판 화면입니다. 작성자가 대회 주최자만 열람이 가능하게 설정한 질문은 배경이 회색으로 뜹니다. 스크린샷 2026-07-03 오후 4 07 36

위와 같이 접근 불가 게시글을 상세히 보려고 시도 시 우측 상단 메세지가 뜹니다.

스크린샷 2026-07-03 오후 4 09 59 글 작성은 모달창의 형식으로 설정되며, 대회 참여자 전체/주최자만 열람을 선택한 후 글을 작성할 수 있습니다. 스크린샷 2026-07-03 오후 4 08 01 전체 글 보기/내 질문 보기 의 칸으로 나누어 본인이 작성한 질문글을 빠르게 열람할 수 있습니다. 스크린샷 2026-07-03 오후 4 08 41 대회 주최자가 작성한 답변은 댓글 우측 대회 주최자임을 밝혀 답변 해결이 원활하게 되도록 하였습니다.

Ops Impact

DB migration 필요

Version Compatibility

N/A

@taekoong taekoong requested review from Neibce and wlsgur11 July 3, 2026 07:18
@taekoong taekoong self-assigned this Jul 3, 2026
@Neibce Neibce requested a review from Copilot July 3, 2026 07:20
@Neibce

Neibce commented Jul 3, 2026

Copy link
Copy Markdown
Member

@codex review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

대회 진행 중 질문을 나눌 수 있는 대회 전용 커뮤니티(게시글/질문) 기능을 추가하고, 게시글 열람 범위(대회 참여자 전체 / 주최자만)주최자 댓글 배지 표시를 지원하도록 프론트/백엔드를 확장한 PR입니다.

Changes:

  • Contest 영역에 커뮤니티 페이지/라우트를 추가하고 목록 UI(잠금 표시, 내 질문 필터, 작성 모달)를 구현
  • 게시글 visibility 필드 추가 및 목록/상세에서 열람 가능 여부(can_view)와 접근 제한 로직 반영 (DB migration 포함)
  • 게시글 상세에서 대회 운영자(주최자) 댓글/대댓글에 “운영자” 배지 표시

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frontend/src/pages/oj/views/contest/SideNavBar.vue 대회 사이드바에 커뮤니티 진입 메뉴 추가
frontend/src/pages/oj/views/contest/index.js ContestCommunity lazy import/export 추가
frontend/src/pages/oj/views/contest/children/ContestCommunity.vue 대회 커뮤니티 목록/작성 모달 UI 및 잠금/필터 로직 추가
frontend/src/pages/oj/views/community/PostDetail.vue 댓글/대댓글에 운영자 배지 UI 추가
frontend/src/pages/oj/views/community/CreatePostPage.vue 대회 컨텍스트(contestID) 처리 및 작성 후 라우팅 분기 추가
frontend/src/pages/oj/router/routes.js contest-community / contest-community-create 라우트 추가
frontend/src/pages/admin/views/contest/Contest.vue (현재) 머지 충돌 마커가 남아 있어 빌드 불가 상태
frontend/src/i18n/oj/en-US.js Contest 커뮤니티 관련 i18n 키 추가
backend/community/views/oj.py visibility 저장/기본값 처리, 목록 can_view/is_mine 주석, 상세 열람 제한 추가
backend/community/tests.py visibility 목록/상세 제한 및 운영자 배지 응답 테스트 추가
backend/community/serializers.py visibility/is_mine/can_view 및 is_contest_host 필드 직렬화 추가
backend/community/models.py Post.visibility 필드 및 enum 추가
backend/community/migrations/0004_post_visibility.py visibility 필드 추가 마이그레이션
backend/account/decorators.py contest_id 추론(기존 self.contest 재사용) 개선

Comment thread frontend/src/pages/admin/views/contest/Contest.vue Outdated
Comment thread frontend/src/pages/oj/views/contest/children/ContestCommunity.vue

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1264fe8cbe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread frontend/src/pages/admin/views/contest/Contest.vue Outdated
Comment on lines +116 to +119
if not getattr(self, "contest", None):
try:
# use self.contest to avoid query contest again in view.
self.contest = Contest.objects.select_related("created_by").get(id=contest_id, visible=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Re-check visibility for preloaded contests

When a view preloads self.contest, this branch skips the only lookup that enforces visible=True. PostDetailAPIView now sets self.contest = post.contest, so posts belonging to a contest later hidden/deleted in admin can still be read by any user who otherwise passes the public/password/status checks; please either validate self.contest.visible here or reload by id with visible=True.

Useful? React with 👍 / 👎.

Comment on lines +163 to +165
if (post.visibility == Post.Visibility.CONTEST_HOSTS and
post.author != request.user and
not request.user.is_contest_admin(post.contest)):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce host-only access on comment endpoints

This only blocks the post detail response for CONTEST_HOSTS; the /community/posts/<id>/comments endpoints still fetch by post_id without the same visibility check, and the list response exposes locked post ids. A non-host contest participant can therefore call the comments API directly to read or add comments on a host-only question, so the same author/host/super-admin guard should be applied to comment list/create/update/delete.

Useful? React with 👍 / 👎.

"contest",
"comment_count",
"is_mine",
"can_view",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Suppress previews for locked posts

Adding can_view does not prevent the list serializer from still returning content_preview for rows where can_view is false. The UI hides that preview, but any contest participant can inspect the API response and read the first 100 characters of a host-only question despite being denied detail access; the server should blank or omit preview/content fields for non-viewable posts.

Useful? React with 👍 / 👎.

Comment on lines +60 to +64
visiblePosts() {
if (this.activeTab === "my") {
return this.posts.filter(
(post) => post.is_mine && post.post_type === "QUESTION",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Filter my questions before paginating

The “내 질문 보기” tab filters only the current already-paginated page of all contest posts, while fetchPosts and total still come from the unfiltered server query. Once a contest has more than one page, a user's own question on a later page can make this tab show empty on page 1 and pagination counts all posts instead of their questions; request a server-side “mine/question” filter or otherwise paginate the filtered dataset.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants