사용자-태그 관계 플러그인 만들기

안녕하세요, 현재 특정 플러그인을 개발 중인데 아직 어디서부터 시작해야 할지 감이 오지 않습니다(여기에 있는 소개 자료를 읽고 몇 가지 간단한 플러그인을 설치해서 소스를 조금씩 만져봤습니다).

설정: 시스템의 여러 사용자 이름과 해당 사용자가 관련 있는 태그가 포함된 CSV 파일이 있습니다. 예를 들어, "user1, tag#1"이라는 항목은 "user1은 tag#1에 대해 알고 있다"는 의미입니다. 여러 사용자가 하나의 태그와 관련될 수 있고, 한 사용자는 여러 태그와 관련될 수 있습니다. 또한, 이 CSV 파일은 주기적으로 업데이트됩니다(거의 매일 한 번씩). 이 파일은 Discourse 인스턴스를 호스팅하는 서버와 동일한 서버에 있습니다.

플러그인이 이상적으로 작동해야 하는 방식: 예시 CSV와 이미지를 통해 설명하겠습니다.

CSV:

userOP, tag#1
userOP, tag#2
user2, tag#1

위 CSV를 기준으로, CSV에 포함된 태그 중 하나가 포함된 토픽이 생성될 때마다(토픽 작성자가 목록에 없을 수도 있음), 이상적인 출력은 다음과 같아야 합니다:

또한, 사용자는 사용자 패널에서 클릭 가능한 링크로 자신의 알려진 태그를 볼 수 있으며, "알려진 태그"라는 이름의 추가 탭이 있습니다:

이상적으로는, 이 탭이 왼쪽 상단 메뉴를 통해 빠르게 접근할 수 있어야 합니다:

즉, CSV에 정의된 관계를 기반으로, 자신이 관련 있는 태그가 포함된 토픽에 게시물을 작성하는 모든 사용자(OP 또는 기타 사용자)에게 작은 텍스트나 배지가 표시되어야 합니다.

이를 어떻게 구현할 수 있을지에 대한 제안에 열려 있습니다.

Rails 쪽에서 해야 할 일 중 하나는 사용자/태그 관계를 직렬화기(serializer)에 추가하여 프론트엔드에서 해당 데이터를 사용할 수 있도록 하는 것입니다. add_to_serializer를 호출하는 다른 플러그인을 찾아보거나 Discourse 소스에서 검색해 보세요. 해당 메서드는 소스 코드에 잘 문서화되어 있습니다.

이후 Ember에서 플러그인 아웃렛(plugin outlet)을 사용하여 해당 데이터를 페이지에 추가할 수 있습니다. 테마 컴포넌트 문서에 이에 대한 예제가 나와 있습니다.

저라면 CSV 파일 대신 사용자 정의 필드를 관리하기 위한 라우트를 추가할 것 같습니다. 하지만 CSV 방식을 고집한다면, 매시간 파일을 읽어들이는 작업(job)이 필요할 수 있으므로 jobs/scheduled에 관련 코드가 있는 플러그인을 찾아보세요.

all_the_plugins라는 Discourse 저장소가 있습니다. 가끔 예제를 찾기 위해 grep으로 검색하곤 합니다. github.com/discourse를 둘러보면 이 저장소를 찾을 수 있을 것입니다.

정보 주셔서 감사합니다. 현재 제가 가지고 있는 멘탈 모델은 태그에 사용자_연결(attached_users)이라는 이름의 커스텀 필드(예: tag_description)를 추가하는 것입니다. 위의 예시에서는 tag#1에 attached_users: [“userOP”, “user1”]가 포함되어야 합니다.

그 다음, 이를 직렬화기(serializer)에 어떻게 추가하고 게시글에서 어떻게 표시할지 알아봐야 합니다.

이렇게 생각하면서 또 다른 아이디어가 떠올랐습니다. 태그를 기반으로 사용자를 토픽에 할당하는 discourse assign(Discourse Assign)을 사용하면, 이 정보를 이미 토픽에서 가져올 수 있고 표시하는 것도 더 쉬울 것 같습니다. 다만 discourse assign은 사용자를 프로그래매틱하게 추가할 수 있는 방법을 제공하지 않습니다.

assign을 사용하는 것이 좋은 방법인 것 같습니다. API를 통해 사용자를 추가할 수 있을 것으로 확신합니다. Discourse API 역공학하기를 참고해 보세요.

서버에 너무 큰 부하를 줄까 봐 걱정됩니다. 과제가 많을 텐데, 이전 아이디어에서는 기본적으로 태그에 과제를 할당하는 방식이었기 때문에 각 주제별로 별도로 할당할 필요가 없었거든요.

자체 개발 및 유지보수보다 유지 관리 중인 기존 플러그인을 사용하는 것이 훨씬 쉽습니다.

이 작업은 간단한 플러그인으로 수행할 수 있습니다.

수행해야 할 작업

플러그인은 다음을 수행해야 합니다:

  1. known_tags라는 사용자 사용자 정의 필드를 추가합니다. 이는 문자열 목록입니다.

  2. 사용자가 known_tags를 편집할 수 있는 사용자 프로필 인터페이스를 추가합니다. 이를 위해 완전히 새로운 프로필 탭을 추가할 필요는 없다고 생각하지만, 원한다면 추가할 수도 있습니다. 사용자가 직접 편집하는 것을 원하지 않는다면, 관리자만 편집할 수 있도록 설정하고 CSV 파일에 기반하여 사용자 프로필에 직접 들어가서 업데이트하면 됩니다.

  3. PostCreator의 before_create_post 또는 post_created 이벤트를 사용하여 토픽의 태그에 기반하여 원하는 내용을 게시물에 추가하는 이벤트 후크를 추가합니다.

수행 방법

1번과 2번 부분은 아래에 링크된 토픽의 다른 모델에 대한 예시 플러그인과 매우 유사합니다. 유추하여 스스로 해결해 볼 수 있는지 확인해 보세요. 정말 막막하다면 그 부분에 대한 힌트를 요청해 주세요.

3번 부분도 플러그인의 plugin.rb 파일에 들어가게 됩니다. 다음과 같은 형태가 될 것입니다.

on(:post_created) |post, opts, user|
  if post.is_first_post? && post.topic.tags.present?
     user_ids = UserCustomField.where(name: 'known_tags', value: post.topic.tags).pluck(:user_id)
     usernames = User.where(id: user_ids).pluck(:username)
     new_raw = post.raw + "something something #{usernames}"
     PostRevisor.new(post).revise!(
      user,
      {
        raw: new_raw,
        edit_reason: "some reason"
      },
      skip_validations: true,
      bypass_bump: true
    )
  end 
end

스스로 한번 도전해 보세요. 정말 막막해지면 도와드리겠습니다. 스스로 해결하려는 강한 의지가 보이면 더 적극적으로 도와드리고 싶어 하거든요 :slight_smile:

정말 좋은 로드맵을 제공해 주셔서 감사합니다. 바로 진행하겠습니다. 작은 질문이 하나 있습니다:

이 부분은 해당 접근 방식에서 수동으로 수행해야 하는 것인가요(여기서 수동이란 인터페이스를 통해 항목을 하나씩 추가하는 것을 의미합니다)? 이상적으로는 CSV 파일의 데이터 양이 적지 않고 시간이 지날수록 증가할 것이므로, 관리자 API 키를 사용하여 이 작업을 수행하고 싶습니다.

아니요, 수동으로 처리할 필요는 없습니다. CSV를 기반으로 사용자 정의 필드를 채우는 방법은 꽤 다양합니다. 실제로는 업데이트를 어떻게 처리하고 싶느냐에 따라 달라집니다. 먼저 다른 부분들을 처리한 뒤, 소규모 데이터셋으로 이 부분을 테스트해 보시는 것을 권장합니다. 그 후 동작 방식에 만족스러우시면 CSV를 자동으로 가져오도록 설정하세요. 그 부분을 효율적으로 만드는 것은 이차적인 단계입니다.