Revogar um selo de nível inferior quando um superior é alcançado?

Como excluir direitos a um emblema personalizado se um nível superior já foi concedido? O objetivo é conceder apenas o nível mais alto para o qual um determinado usuário é elegível…

Digamos que eu tenha 3 emblemas:

Nível 1: 5 curtidas dadas, 5 recebidas
Nível 2: 100 curtidas dadas, 100 recebidas
Nível 3: 250 curtidas dadas, 250 recebidas

O código abaixo é para o Nível 2. Outros níveis não têm nada diferente além do número ‘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))
1 curtida

Nas configurações /admin/badges/BADGE-ID, basta marcar a opção Executar consulta de revogação diariamente. O distintivo será removido se o usuário não atender mais aos critérios SQL.

Você também pode querer definir a opção Atualizar diariamente para que a concessão/revogação ocorra aproximadamente ao mesmo tempo (meia-noite, horário local da sua instância, eu acho).

3 curtidas

Obrigado, Nathan. Vou dar uma olhada.

1 curtida

Isso também precisaria de uma linha extra no SQL do emblema para equilibrar? Algo como:

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))

(possivelmente usar um BETWEEN ou similar, embora eu ainda não tenha testado isso :slight_smile:)

E então, quando a consulta for executada, ela concederá o emblema para 100 curtidas pela primeira vez, o ignorará para 101 a 249 e, em seguida, o revogará em 250 (de onde o próximo emblema continuará).


Atualização: Pratiquei um pouco com BETWEEN e algo como isto parece capturar todas as pessoas certas no teste de amostra:

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

Portanto, algo como isto deve funcionar se convertido em um emblema acionado:

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))
3 curtidas

Isso está quase perfeito. Um evento raro pode ocorrer: o usuário entrega demais em ‘dado’ enquanto fica para trás em ‘recebido’ (ou vice-versa), então o distintivo pode ser perdido antes que o próximo seja concedido (rotina de revogação).

Pesquisei e descobri uma propriedade interessante: something.badge_id = 123 onde ‘something’ é a variável definida pelo usuário e ‘123’ o ID de outro distintivo. Vou tentar e complementar os SQLs originais do Nível 1 e Nível 2 com verificações de desqualificação contra os distintivos de nível superior.

2 curtidas

Esse é um ponto muito interessante que eu não havia considerado. :slightly_smiling_face: A natureza dupla o torna um pouco mais complicado. :thinking:

Gosto da ideia de incorporar uma verificação contra os outros distintivos, isso pode ser útil.

1 curtida