Como personalizar o algoritmo de pontuação de hot topic com um plugin?

O algoritmo de classificação por popularidade integrado é muito simples e pode não ser adequado para diferentes casos de uso. Pelo meu entendimento básico da base de código do Discourse, atualmente não há configurações do site voltadas para o usuário nem um ponto de injeção de plugin apropriado para personalizar o algoritmo de classificação por popularidade. Existe um evento topic_hot_scores_updated, mas ele é chamado após as pontuações serem atualizadas, o que serve ao propósito de notificação sem a capacidade de substituir as pontuações de popularidade integradas. Existem duas configurações do site, hot_topics_gravity e hot_topics_recent_days, mas elas têm hidden: true definido e não são visíveis na interface de administração.

Estamos considerando escrever um plugin para substituir o algoritmo de pontuação de popularidade integrado. Qual abordagem seria melhor em termos de compatibilidade e facilidade de atualização do Discourse no futuro? Algumas das minhas ideias estão listadas abaixo:

  • Fazer monkey-patch em TopicHotScore e atualizar o banco de dados de acordo com nosso algoritmo personalizado.
  • Criar uma tabela separada para armazenar as pontuações de popularidade dos tópicos e executar um background job separado para atualizá-las. Adicionar outra rota (em vez de /hot) para nossa listagem personalizada de tópicos populares.
  • Ou talvez a base de código do Discourse possa ser melhorada para suportar tal caso de uso?

Mais fácil, mas pode ser limitado dependendo do que você deseja fazer.

Viável, mas mais complexo. Dê uma olhada em como o TopicQuery implementa listas

e especificamente

  def list_hot
    create_list(:hot, unordered: true, prioritize_pinned: true) do |topics|
      topics = remove_muted(topics, user, options)
      topics.joins("JOIN topic_hot_scores on topics.id = topic_hot_scores.topic_id").order(
        "topic_hot_scores.score DESC",
      )
    end
  end

Você pode adicionar um extra com relativa facilidade, embora haja muitas partes móveis que você precisa levar em consideração. Eu fiz isso no meu plugin ‘homepage-filter’ e isso pode ser um bom ponto de partida.