상위 배지를 달성하면 하위 배지를 취소해야 하나요?

더 높은 티어가 이미 부여된 경우, 커스텀 배지의 권한을 어떻게 제외할 수 있을까요? 특정 사용자가 자격을 갖춘 가장 높은 티어에만 권한을 부여하는 것이 목표입니다…

예를 들어, 다음과 같은 3개의 배지가 있다고 가정해 보겠습니다.

Tier 1: 5회 좋아요 제공, 5회 좋아요 받음
Tier 2: 100회 좋아요 제공, 100회 좋아요 받음
Tier 3: 250회 좋아요 제공, 250회 좋아요 받음

아래 코드는 Tier 2에 대한 것입니다. 다른 티어들은 숫자 '100’을 제외하고는 차이가 없습니다.

SELECT us.user_id, current_timestamp AS granted_at 
FROM user_stats AS us
WHERE us.likes_received >= 100 
AND us.likes_given >= 100
AND (:backfill OR us.user_id IN (:user_ids))

/admin/badges/BADGE-ID 설정에서 Run revocation query daily 옵션에 단순히 체크를 하시면 됩니다. 사용자가 더 이상 SQL 조건을 충족하지 않으면 배지가 제거됩니다.

또한 Update Daily 옵션도 함께 활성화하면, 부여와 철회가 대략 같은 시간대(인스턴스의 로컬 시간 자정쯤)에 이루어지도록 할 수 있습니다.

고마워, 네이선. 한번 볼게.

이 경우에도 균형을 맞추기 위해 배지 SQL에 한 줄을 더 추가해야 할까요? 다음과 같은 형태로요:

SELECT us.user_id, current_timestamp AS granted_at 
FROM user_stats AS us
WHERE us.likes_received >= 100 
AND us.likes_given >= 100
AND us.likes_given < 250
AND (:backfill OR us.user_id IN (:user_ids))

(아직 테스트해 보지는 않았지만, BETWEEN 또는 유사한 구문을 사용할 수도 있을 것 같습니다 :slight_smile:)

그리고 쿼리가 실행되면 100 Likes를 처음 달성했을 때 배지를 부여하고, 101부터 249까지는 무시한 채 250에서 회수하게 됩니다(다음 배지가 이 지점부터 이어지도록요).


업데이트: BETWEEN으로 조금 연습해 본 결과, 다음과 같은 쿼리가 샘플 테스트에서 올바른 대상자들을 모두 잡아내는 것 같습니다:

SELECT us.user_id
FROM user_stats AS us
WHERE us.likes_received BETWEEN 100 AND 249 
ORDER BY us.likes_received DESC

따라서 다음과 같은 쿼리를 트리거형 배지로 변환하면 작동할 것입니다:

SELECT us.user_id, current_timestamp AS granted_at 
FROM user_stats AS us
WHERE us.likes_received BETWEEN 100 AND 249
AND us.likes_given BETWEEN 100 AND 249
AND (:backfill OR us.user_id IN (:user_ids))

거의 완벽합니다. 드물게 발생할 수 있는 한 가지 경우가 있습니다: ‘given’ 항목에서 과잉 제공을 하는 반면 ‘received’ 항목에서 뒤처지는 경우(또는 그 반대)로, 다음 배지가 부여되기 전에 현재 배지가 취소될 수 있습니다(취소 루틴).

주변을 둘러보다가 흥미로운 특성을 발견했습니다: something.badge_id = 123에서 'something’은 사용자 정의 변수이고, '123’은 다른 배지의 ID입니다. 한 번 시도해 보고, Tier 1과 Tier 2의 기존 SQL 쿼리에 상위 티어 배지에 대한 자격 상실 확인 로직을 추가해 보겠습니다.

제가 고려하지 못했던 매우 흥미로운 지적입니다. :slightly_smiling_face: 이중적인 성격 때문에 조금 더 까다로워지긴 하네요. :thinking:

다만 다른 배지들과의 충돌을 확인하는 체크를 내장하는 아이디어는 좋다고 생각합니다. 유용할 수 있겠네요.