/admin/users/list/all.json API 응답 구조 변경 사항이 있나요?

현재 Discourse 3.5.0.beta5-dev (eff31e0d42)를 실행 중입니다.

지난 1주일 정도 사이에 /admin/users/list/all.json 엔드포인트의 API 응답이 변경되었는지 아는 분이 있을까요? :thinking:

구체적으로:

GET /admin/users/list/all.json?email=email@example.com

:thinking:

이 엔드포인트는 정확한 이메일 주소로 조회했을 때, 단일 사용자를 직접 나타내는 평탄한(flat) JSON 객체를 반환했던 것으로 기억합니다.

그러나 현재 응답 구조는 사용자 객체를 새로운 users 배열 안에 감싸서 반환하는 것으로 보이며, 이로 인해 우리 측의 기존 SSO 통합 중 일부가 깨졌습니다.

참고로, 변경된 것으로 추정되는 "이전"과 “이후” 응답의 익명화된 의사 예시(pseudo example)를 아래에 첨부합니다.

이전:

{
  "id": 1,
  "username": "sampleuser",
  "name": "",
  "avatar_template": "/user_avatar/example.com/sampleuser/{size}/avatar.png",
  "active": true,
  "admin": false,
  "moderator": false,
  "last_seen_at": "2025-05-11T08:27:28.578Z",
  "created_at": "2020-01-01T12:00:00.000Z",
  "suspended": false,
  "trust_level": 1
}

이후:

{
  "users": [
    {
      "id": 1,
      "username": "sampleuser",
      "name": "",
      "avatar_template": "/user_avatar/example.com/sampleuser/{size}/avatar.png",
      "email": "someone@example.com",
      "active": true,
      "admin": false,
      "moderator": false,
      "last_seen_at": "2025-05-11T09:34:35.900Z",
      "created_at": "2020-01-01T12:00:00.000Z",
      "suspended": false,
      "trust_level": 1
    }
  ],
  "meta": {
    "message_bus_last_ids": {
      "bulk_delete": 0
    }
  }
}

이 변경을 일으킨 최근 커밋이 무엇인지 아는 분이 있을까요? :thinking:

실제로 변경되었으며 커밋은 이것입니다

diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 92d906f161..70406efce5 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -32,7 +32,16 @@ class Admin::UsersController < Admin::StaffController
   def index
     users = ::AdminUserIndexQuery.new(params).find_users
 
-    opts = { include_can_be_deleted: true, include_silence_reason: true }
+    opts = {
+      include_can_be_deleted: true,
+      include_silence_reason: true,
+      root: :users,
+      meta: {
+        message_bus_last_ids: {
+          bulk_delete: MessageBus.last_id("/bulk-user-delete"),
+        },
+      },
+    }
     if params[:show_emails] == "true"
       StaffActionLogger.new(current_user).log_show_emails(users, context: request.path)
       opts[:emails_desired] = true

어제 업데이트한 73개의 커밋을 아무리 찾아봐도 이 DEV: replace selenium driver with playwright breaking change를 발견하지 못했습니다.

링크를 공유해 주셔서 감사합니다, @RGJ

제 접근 방식:

  • /admin/users/list/all.json?email=email@example.com 로드
  • x-discourse-route 헤더 확인
  • 해당 파일(app/controllers/admin/users_controller.rb) 조회
  • 해당 메서드(index) 조회
  • “Blame” 클릭
  • 커밋 찾기

아니, 그럴 리가… :scream:

오늘 이걸 배웠네요!

@RGJ 감사합니다 :clap:t2::star_struck:

어떻게든 그 커밋을 찾아냈지만, 데이터 구조를 어디에서 변경했는지 이해할 수 없었습니다(아직도 이해가 가지 않습니다). 당시에는 스마트폰으로 보고 있어서 상황이 좀 더 어려웠습니다.

이것이 API 응답의 breaking change였던 것 같습니다 :confused:

/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js

추가된 root: :users 라인입니다.

이제 이 변경 사항의 영향을 완전히 극복했습니다.

조금 주제에서 벗어난 이야기일 수 있지만, API 응답이 수년간 “Y”였다가 “X”로 바뀌는 경우를 추적할 수 있는 방법이 있을까요? 그런 일이 발생하면 알림을 받을 수 있으면 좋겠습니다. :thinking:

매일 실행할 수 있는 스크립트 기반의 로컬 단위 테스트 같은 것이 있을까요?

하지만 이렇게 말하고 보니, 제 Discourse를 업데이트한 이후에야 통합 기능이 깨진 것을 알게 될 테니 알림이 늦게 올 것 같습니다.

아마 스테이징 환경이 필요하겠네요…

스테이징 환경을 사용할 수도 있습니다. 또한 코드를 대상으로 Discourse를 시작하고 매일 최신 Discourse에 대해 테스트를 실행하는 GitHub Action을 만들 수도 있습니다.

아하! 완벽하네요, 그 방법이 작동할 것 같으니 감사합니다 :grin:

엔드포인트를 호출하여 렌더링하는 플러그인을 만들어 테스트하는 것이 쉬운 방법이라고 생각합니다. 그리고 기본 GitHub Action을 푸시 시에만 실행하는 것이 아니라 매일 실행하도록 변경하면 좋겠습니다.

문서도 업데이트가 필요한 것 같습니다 https://docs.discourse.org/#tag/Admin/operation/adminListUsers

이상적인 세상에서는 문서가 소스에서 자동으로 생성되어 문서의 커밋 히스토리를 보면 인터페이스의 변경 사항만 확인하면 됩니다.

이 변경 사항으로 인한 문제를 해결하려고 할 때 저 역시 이 부분에 걸려 넘어졌습니다 :confused:

이로 인해 우리가 사용하는 통합 기능도 깨졌습니다. 이 문제가 되돌려질 것으로 예상해야 하는 상황인가요?

안녕하세요, 네, 죄송합니다. 이 코드는 병합되지 말았어야 했는데 제 실수였습니다.

다행히도 8시간 전에 이미 되돌려 두었습니다: DEV: revert admin users list change (#32723) · discourse/discourse@7558e2c · GitHub

아아아아아아… (반복하며 페이드아웃)

이건 정말 나쁜 소식입니다 :cry:

우리는 또 모든 통합을 변경해야만 합니다 :exploding_head:

죄송합니다. 불행히도 되돌릴 수밖에 없었어요. 시기가 좀 안 좋게 맞았네요.

@Richie에게 PR을 보내는 좋은 이유가, 그렇게 하면 hopefully 간단한 되돌리기 버튼이 생길 수 있기 때문이다.

이것이 우리가 감수하는 리스크이며, 가장 앞선 기술(Bleeding Edge)을 사용하면서 치르는 대가입니다. :blush:

Discourse가 오픈소스라는 사실은 여전히 놀랍습니다. 정말로 그렇습니다. 내가 불평할 처지가 아니죠. :person_shrugging:

문제를 수정해 주셔서 감사합니다, @j.jaffeux. :clap: :person_bowing: