Uma medalha de prata para _cada_ 5 medalhas de bronze

Criamos um distintivo de bronze, Users Helping Users, para pessoas que tentam ajudar outros usuários. Ele é concedido manualmente (para que se possa diferenciar as tentativas de ser prestativo dos “eu também”).

Para cada 5 distintivos de bronze, queremos conceder um distintivo de prata, Invaluable.

O SQL que criei encontra os dois usuários certos, mas apenas uma vez cada:

SELECT user_id, current_timestamp AS granted_at 
FROM user_badges
WHERE badge_id = 110 -- Users Helping Users
    AND (:backfill OR user_id IN (:user_ids))
GROUP BY user_id
HAVING COUNT(*) >= 5

Estou perdendo alguma mágica :magic_wand: no meu SQL, ou o multiplicador acontece fora do SQL?

Além disso, não está nada claro para mim como a matemática funciona para que meus dois usuários não recebam novos distintivos todos os dias (isso será executado em um gatilho noturno), mesmo que eles não tenham recebido 5 novos distintivos de bronze.

Existe um guia para isso que minha pesquisa não encontrou?

Ok, pesquisas mais aprofundadas me levaram a um rastro que me deixou em o guia

A coisa do backfill ainda é um pouco nebulosa, mas decidi (óbvio!) experimentar isso em nossa instância de teste. Suponho que o backfill seja executado durante a noite, então saberei mais amanhã.

A menos que você marque ‘Pode ser concedido várias vezes’, ele não deve ser concedido mais de uma vez, mesmo que eles se qualifiquem para ele uma segunda (ou mais) vez. :+1:


Ok, eu reli sua postagem com mais atenção e acho que tenho uma ideia mais clara do que você está buscando.

Com base no SQL atual, esses usuários só receberão a insígnia de prata uma vez, mesmo que você permita que ela seja concedida várias vezes:

  • Criei as insígnias relevantes em meu site de teste (incluindo permitir várias)
  • Concedi 5 de bronze e executei o trabalho em segundo plano para conceder a insígnia (insígnia de prata concedida com sucesso :partying_face:)
  • Então executei o trabalho BadgeGrant novamente e eles não receberam a prata uma segunda vez
  • Então aumentei suas insígnias de bronze para 11 e executei o trabalho de concessão de insígnias novamente
  • Nenhuma segunda insígnia de prata foi concedida

Eu verifiquei ‘várias vezes’

mas só foi concedido uma vez, embora devesse ter sido duas vezes

1 curtida

Então… o que preciso fazer para que meu usuário, com 12 medalhas de bronze, receba as 2 de prata que ele merece?

1 curtida

Essa é uma boa pergunta para a qual não sei a resposta imediatamente. :slight_smile:

Estou pensando provisoriamente em algo usando RANK, mas posso estar me agarrando a qualquer coisa… :thinking:


Protótipo inicial...
WITH badge_count AS (

    SELECT 
        user_id,
        granted_at,
        RANK() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS rank
    FROM user_badges
    WHERE badge_id = 110

)

SELECT user_id, granted_at
FROM badge_count
WHERE rank IN (5,10,15,20,25,30,35,40,45,50)

Ok, uma segunda tentativa usando ROW_NUMBER em vez disso:

WITH badge_count AS (

    SELECT 
        user_id,
        granted_at,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS row
    FROM user_badges
    WHERE badge_id = 110

)

SELECT user_id, granted_at
FROM badge_count
WHERE row % 5 = 0

Embora, em testes adicionais, isso funcione corretamente na pré-visualização, mas não está sendo concedido várias vezes quando o trabalho real de concessão de distintivo é executado. Não tenho certeza do porquê. :thinking:

Confundi-me. Vou tomar uma xícara de chá e me reagrupar. :slight_smile:

1 curtida

Bem… dei mais 4 bronzes ao meu usuário ontem para ver se a execução noturna pelo menos adicionaria o novo distintivo que ele acabou de “ganhar”. (Eu imaginei que se eu tivesse que atualizar o resto deles manualmente, eu poderia.) Mas nem isso funcionou.

Não posso ajudar com a consulta, mas sugiro que você peça ajuda ao bot Discourse AI - selecione o ícone do bot no topo
image → GPT-4 → SQL Helper.

Achei muito bom na criação de consultas do data explorer apenas dizendo o que preciso e acho que ele pode ajudar com consultas de badges.

1 curtida

Nem todo mundo tem isso, Toni :shushing_face: Você vai deixar as pessoas com inveja. :slight_smile: (embora @ganncamp tenha, então é uma opção)

Mas… tenho quase certeza de que minha consulta está correta. Ela seleciona os corretos na Visualização, mas simplesmente não concede mais de um ao usar o gatilho ‘Atualizar Diariamente’.

Configurei outro, quase igual, para testar com base em um distintivo para ‘cada 5 posts em um tópico específico’ usando o gatilho ‘quando um usuário cria ou edita um post’ - e esse funciona perfeitamente. Estou investigando qual pode ser a diferença…

Aqui está o SQL para esse distintivo de teste para comparar, se alguém puder notar algo:

WITH post_count AS (

    SELECT 
        user_id,
        id,
        created_at,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at ASC) AS row
    FROM posts
    WHERE topic_id = 864

)

SELECT user_id, created_at granted_at, id post_id
FROM post_count
WHERE row % 5 = 0
  AND (:backfill OR id IN (:post_ids))

2 curtidas

Eu tenho acesso a ele @tpetrov, mas minhas tentativas de usá-lo foram… menos que frutíferas. Ou talvez eu seja bom em fazer perguntas difíceis? :laughing:

1 curtida

Após um pouco de exploração e consulta, parece que o concedente automático de distintivos só concederá vários distintivos se eles forem baseados em posts específicos. Portanto, esses tipos só concederão o primeiro distintivo (a visualização é enganosa :frowning:).

Acho que em casos semelhantes distintivos “escalonados” podem funcionar bem (como os Resolvidos). Então uma Prata para 30 e uma Ouro para 100, por exemplo, se essa puder ser uma alternativa viável?

Então… mesmo que os distintivos de bronze sejam concedidos com base em postagens… isso não conta, certo?

Não sei. Acho que não entendi a pergunta. :laughing:

Acho que a sugestão não é encontrar 5 distintivos, mas 5 postagens onde um distintivo foi concedido? Posso fazer isso. Eu já fiz mais ou menos isso no meu relatório “encontrar novas postagens para conceder distintivos”.

Hmmm. :thinking: Acho que entendi o que você quer dizer. Deixe-me tentar de novo…


@ganncamp - Acho que podemos ter algum sucesso… :slight_smile:

Com base no fato de que o Bronze Badge A é concedido através da ferramenta de postagem ou dando um motivo na página /admin/users/{user_id}/{username}/badges:

Então, acho que isso é realmente possível. :partying_face:

WITH badge_count AS (

    SELECT 
        user_id,
        granted_at,
        post_id,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at DESC) AS row
    FROM user_badges
    WHERE badge_id = 110
      AND post_id IS NOT NULL
)

SELECT user_id, granted_at, post_id
FROM badge_count
WHERE row % 5 = 0
  AND (:backfill OR post_id IN (:post_ids))

(Adicionar AND post_id IS NOT NULL protege contra o caso de alguém ser concedido sem um motivo, caso contrário, quebra)

Acabei de testar e avancei acionando o job em segundo plano GrantBadge e meu usuário de teste finalmente recebeu o crédito total que merece. :slight_smile:

Em seguida, concedi a ele mais 5 Badge A para 5 posts diferentes e executei novamente: :tada:

3 curtidas

Obrigado @JammyDodger! :tada: :tada: :tada:

Configurei isso na minha instância de teste (não que eu não confie em você :joy:) e espero colocá-lo em produção esta semana! :star_struck:

E… é um bom momento para pedir que o tutorial seja atualizado com as coisas que você aprendeu nesta jornada? :smiley:

Ah, com certeza. Confiar, mas verificar é definitivamente uma escolha inteligente. :slight_smile:

Vou ver se consigo adicionar um “algo a mais”. :slight_smile: :+1:

2 curtidas

Bem… quando o trabalho foi executado durante a noite,
meu usuário com 6 bronzes ganhou 1 prata :white_check_mark:
meu usuário com 13 bronzes ganhou… 1 prata :slightly_frowning_face:

Esta parte do tutorial me fez pensar que um trabalho de preenchimento separado e explícito não era necessário

Como diariamente um preenchimento completo é executado de qualquer maneira, você deve levar isso em consideração e incluir o tratamento do parâmetro :backfill.

Para usuários que já ganharam mais de 1 prata, como faço para que essas sejam concedidas? Tenho que fazer isso manualmente?

O preenchimento é o trabalho diário. O gatilho ‘Atualizar Diariamente’ é essencialmente isso, enquanto os outros gatilhos são muito mais ‘no momento’ (por exemplo, se um distintivo usasse ‘quando um usuário cria ou edita uma postagem’, não precisaria esperar a noite toda para ser concedido).\n\nVocê pode postar uma captura de tela do seu distintivo para que eu possa ver o que pode ser diferente?\n\n

Aqui está:\n\n

\n\nA propósito, algumas dessas coisas eu verifiquei porque… não sei o que estou fazendo :joy:

1 curtida

E o seu usuário com 13 ‘Badge A’ tem os motivos preenchidos quando você olha a página dele em /admin/users/{user_id}/{username}/badges?

Você tem as partes importantes iguais. :slight_smile: As outras ainda são legítimas, mas opcionais.

Você está executando isso no seu site de staging ou em um site de teste auto-hospedado?

Uau! Mistério resolvido!

Eu tinha assumido que o trabalho rodava nas primeiras horas da manhã (da minha parte).

Na verdade, eu tinha originalmente concedido distintivos a este usuário sem motivos, então ontem eu revoguei todos eles, desenterrei postagens dele e concedi novamente. O trabalho rodou no meio do meu processo de concessão.

Isso está no meu site de staging, aliás.

Suponho que o segundo distintivo será concedido em algumas horas, mas eu gostaria de ver vários distintivos concedidos de uma vez. Isso acontecerá se eu revogar o de prata? Ele receberá 2 novas pratas em… 2h?

1 curtida