Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publicações Promovidas #1491

Open
aprendendofelipe opened this issue Aug 2, 2023 · 27 comments
Open

Publicações Promovidas #1491

aprendendofelipe opened this issue Aug 2, 2023 · 27 comments
Labels
back Envolve modificações no backend front Envolve modificações no frontend novo recurso Nova funcionalidade/recurso

Comments

@aprendendofelipe
Copy link
Collaborator

Vou apenas rascunhar como imagino que poderiam ser as publicações promovidas, mas o resultado final provavelmente será diferente da ideia inicial (pode até ser completamente diferente).

As publicações promovidas terão semelhanças e diferenças com as demais publicações.

As semelhanças são:

  • Qualificações: Publicações promovidas podem receber qualificações para que tenhamos mais destaque para anúncios mais relevantes aos usuários. Então elas podem acabar saindo dos destaques, seja pelo tempo de publicação ou pelo saldo de TabCoins, assim como podem voltar aos relevantes se receberem novas interações.
  • Formato: O formato da publicação promovida nas interfaces, seja web ou API, será o mesmo das demais publicações.

As particularidades são:

  • Serão temporárias e sairão do ar ao término de sua validade.
  • Ao invés de darem TabCoins para o Autor, elas consomem TabCash ao serem publicadas.
  • Não movimentam TabCoins do autor ou do qualificador quando recebem votos.
  • Consomem TabCash do autor a cada diferente usuário que qualificar (seja voto positivo ou negativo) ou comentar, de forma a resultar em um custo maior para as publicações com mais interações (maior alcance).

Ao ter o custo em TabCash para uma publicação promovida relacionado às qualificações, uma publicação mal avaliada, que acabar saindo dos relevantes, praticamente não terá custos adicionais, enquanto outra que for bem avaliada e, consequentemente, mais visualizada, acabará resultando em um custo maior (até o limite estabelecido pelo autor).

Detalhando melhor a ideia:

  1. Ao criar uma publicação promovida, deve ser escolhida a quantidade de TabCoins promovidos e mais dois parâmetros opcionais: limite de consumo de TabCash e limite de tempo publicada.
  2. A quantidade inicial de TabCoins promovidos irá definir apenas o destaque inicial da publicação entre as demais publicações, o que irá variar normalmente conforme as qualificações recebidas e a idade da publicação.
  3. A quantidade de TabCoins promovidos terá um custo de X TabCash por cada TabCoin, onde X pode variar conforme a cotação do momento.
  4. O limite de TabCash extra define o máximo que será consumido conforme forem ocorrendo as interações, onde a cada interação será consumido mais Y TabCash. Se for deixado sem limite, a publicação ficará no ar até ser consumido todo o TabCash do autor.
  5. Para as cotações (valores de X e Y), podemos começar de forma parecida com o que fizemos com os ganhos de TabCoins ao publicar, ou seja, podemos começar com uma cotação fixa e ir ajustando manualmente conforme a necessidade. Mais para frente, quando entendermos melhor a mecânica, podemos automatizar a cotação de forma a manter uma quantidade saudável de anúncios. No início, com o grande acúmulo de TabCash atual, acho que precisamos começar com cotações bem acima de 1, pois senão pode ocasionar um excesso de anúncios nos destaques.
  6. Publicações promovidas não dão e nem retiram nenhum TabCoin do autor. Elas apenas consomem TabCash. Assim evitamos que se promova publicações pensando apenas em gerar mais TabCoins do que o investido para promover. Até por serem temporárias, nem faria sentido gerar TabCoins com elas. Mas elas podem ser uma propaganda do perfil do usuário ou de algumas de suas publicações, o que também pode trazer mais TabCoins do que o investido, mas dessa forma acredito ser aceitável.
  7. Qualquer qualificação que a publicação receber muda o saldo da publicação, consome mais Y TabCash do autor, mas não dá e nem retira TabCoins dos usuários (seja o autor ou o qualificador), fazendo assim o custo (TabCash) para o autor ter alguma relação com o alcance da publicação. O custo não será diretamente proporcional ao alcance (pois as qualificações não são), mas dessa forma existe o benefício de ficar isento de visualizações de robôs e de manipulações.
  8. Como não haverá custo para os qualificadores, as publicidades não diminuirão o saldo disponível para qualificações das demais publicações.
  9. Mesmo sem consumo de TabCoins, apenas usuários com 2 ou mais TabCoins poderão qualificar as publicações promovidas, limitado a uma qualificação por usuário/publicação. Isso deve dificultar a manipulação indevida dos custos e do ranqueamento de conteúdos promovidos.
  10. Precisamos dificultar o bloqueio das publicações promovidas, seja por extensões para navegador, seja por sistemas que usam conteúdos da API do TabNews. Por isso que acredito que não deve haver nenhuma forma de identificar que é um conteúdo promovido, a não ser após efetuar a qualificação sem consumo de TabCoins.
  11. O fato de não identificar que é uma publicação promovida também pode ajudar com uma qualificação mais isenta.
  12. A publicação promovida será despublicada quando ocorrer o primeiro entre os seguintes eventos: o autor despublicar manualmente, o limite de tempo for alcançado, o limite de TabCash for atingido ou o saldo de qualificações ficar negativo.
  13. Acho que seria saudável limitar a uma publicação promovida por autor, mas permitindo editar a publicação existente ou despublicar e criar uma nova.
@rodrigoKulb
Copy link
Contributor

Ótimo quando você fala no formato

  • Formato: O formato da publicação promovida nas interfaces, seja web ou API, será o mesmo das demais publicações.

Acho que seria importante informar que são "Patrocinadas" não? Talvez reservar os 3 primeiros lugares para elas. O time de cache diferente, pois assim que finalizar o consumo de TabCash não devem ser mais exibidas.
Sugestão
Captura de tela em 2023-08-02 21-06-00

@aprendendofelipe
Copy link
Collaborator Author

Acho que seria importante informar que são "Patrocinadas" não?

É um outro caminho, mas precisa desenvolver o restante da ideia e pensar na mecânica de funcionamento, pois quase nada da minha sugestão inicial funcionaria se for mostrar que a publicação é promovida sem o usuário precisar qualificar para descobrir isso.

Alguns pontos para pensar:

  1. Versão Web: Deixar um espaço fixo no layout para propaganda deve funcionar para o Banner de Propaganda #1492 , mas não para publicações promovidas, já que os usuários se acostumariam a ignorar aquele pedaço, e talvez a maioria nunca clicaria nessas publicações. Não funciona da mesma maneira que um feed de imagens, onde o usuário normalmente já vê o conteúdo sem precisar clicar em nada.
  2. API: Se a API do TabNews é gratuita, não podemos facilitar que sejam filtradas as publicações promovidas, pois elas não chegariam, por exemplo, nos Apps, Feeds RSS e sites que usam a API.
  3. Como as promovidas estão sujeitas às qualificações, acho que podemos deixá-las aparecerem como as demais publicações.
  4. Tem que ser mais vantajoso criar uma publicação promovida do que uma publicação normal, senão elas não fazem sentido.
  5. Usei as qualificações para fazer os custos das promovidas se basear em algo difícil de manipular. Se for destacá-las como publicidade, precisa criar outro mecanismo.
  6. Eu concordo que seria melhor se fosse possível deixar claro que são promovidas sem o usuário precisar votar para descobrir isso, mas não encontrei maneira de funcionar, então é melhor focar nos banner se não gostarem da ideia das promovidas. Mas é claro que ótimas ideias podem surgir resolvendo todos os problemas. 💪

@rodrigoKulb
Copy link
Contributor

rodrigoKulb commented Aug 3, 2023

Ótimos pontos, gosto do caminho que você está querendo seguir. Mas ainda acho importante ter a informação que aquela publicação foi "patrocinada". Mas vejo um problema quando informamos isso nas APIs correndo risco de corte dessas informações.

  • Tem que ser mais vantajoso criar uma publicação promovida do que uma publicação normal, senão elas não fazem sentido.

Se deixar sempre as 3 primeiras patrocinadas resolveria essa questão.

Poderia manter a regra de qualificação para ordenar entre as top 3 e utilização do saldo como custo.

Mas realmente é algo que precisamos pensar, porque envolve um caminho completamente diferente para o desenvolvimento.

OBS: Estou afastado do projeto um bom tempo, então ainda estou me atualizando com as informações! 😅️

@rodrigoKulb
Copy link
Contributor

@aprendendofelipe, saindo totalmente fora do planejado, somente jogando uma ideia: e se a natureza da publicação não alterasse nada, e pudéssemos utilizar os TabCash para "turbinar" a publicação por um tempo ou por visualizações? Desta forma, a publicação em si não mudaria nada. Apenas seria uma forma de "patrocinar" uma publicação normal. Assim que finalizasse o período, ela voltaria a ser uma simples publicação.

@aprendendofelipe
Copy link
Collaborator Author

aprendendofelipe commented Aug 3, 2023

Vou tentar simplificar e expor o que eu considerei, pois assim fica mais fácil de encaixar cada ideia em alguns dos resultados que podemos obter.

Dependendo das regras que criarmos, vamos chegar em uma destas 3 situações, onde apenas a segunda é desejável:

  1. Não vale a pena usar TabCash, pois não aumenta as visualizações e nem os ganhos de TabCash;
  2. Vale a pena usar TabCash apenas para aumentar o alcance (uma troca de TabCash por visualizações);
  3. Sempre vale a pena usar TabCash, pois dá mais visualizações e devolve o TabCash investido, ou porque devolve ainda mais TabCash (Farm);

Na prática, dependendo da ideia, ela vai transitar entre as opções acima dependendo de diversos fatores, como dia e horário, quantidade de TabCash investido, tipo de conteúdo etc. Mas mesmo sem chegar nesse nível de detalhamento, já é possível descartar algumas ideias que tem mais tendência de resultar nos indesejados casos extremos.

Para analisar em qual dos casos acima nós chegamos com cada configuração, podemos olhar para estes resultados:

  1. Promovendo com TabCash, a publicação tem mais visualizações do que sem usar TabCash?
  2. O autor ganha mais TabCash do que o TabCash investido para promover?

Vaja na tabela a seguir que só existe um caso desejado. Então cada sugestão precisa resultar nesse caso, em que só vale a pena usar TabCash se for para dar mais visualização a algo.

Onde cada ideia se encaixa?

Visualizações TabCash Vale a pena promover algo usando TabCash?
Diminui Diminui Nunca
Diminui Não muda Nunca
Diminui Aumenta Só serviria para farmar
Não muda Diminui Nunca
Não muda Não muda Nunca
Não muda Aumenta Sempre
Aumenta Diminui Só para melhorar o Alcance (única saudável)
Aumenta Não muda Sempre
Aumenta Aumenta Sempre

Por que descartar as outras linhas da tabela?

Os casos em que nunca vai valer a pena usar TabCash não fazem sentido, pois eliminam a razão de TabCash existir.

Já para os caso em que sempre vai valer a pena usar TabCash para promover qualquer publicação, o problema será justamente esse. Pra quem tem TabCash, não vai fazer sentido publicar algo e não promover, mas a publicação promovida não vai ter muita vantagem com relação às demais promovidas, que também serão em grande quantidade.

O único diferencial real seria negativo, ou seja, a segregação de quem não tem TabCash, como os novos usuários, que dificilmente conseguiriam ganhar seus primeiros TabCash, já que estaríamos em um caso em que as promovidas tem muito mais vantagens sobre as não promovidas.

Esse caso de valer muito a pena usar TabCash nos levaria para o paradoxo de Braess, onde cada indivíduo vai levar mais vantagem se agir de uma certa forma que não é a melhor quando se pensa no coletivo. Para quem não conhece o paradoxo, ontem à noite o Daniel Nunes postou um vídeo muito legal:

PARADOXO DE BRAESS: Construir Estradas PIORA o Trânsito?

@rodrigoKulb
Copy link
Contributor

rodrigoKulb commented Aug 3, 2023

@aprendendofelipe concordo plenamente, desta forma para resolver é simples.

Uma postagem quando patrocinada com TabCash para ganhar mais visualização, o usuário não poderia receber novas TabCoins com upvote, assim que o período de patrocínio encerrar. Voltaria normalmente.

Desta forma uma postagem sempre será uma postagem, apenas entrar em uma fase de patrocinada ou não.

Temos algum problema nessa lógica?

@Gabriel-Tapes
Copy link

Gabriel-Tapes commented Aug 12, 2023

O ponto que acredito que necessite de mais atenção é esse:

Consomem TabCash do autor a cada diferente usuário que qualificar (seja voto positivo ou negativo) ou comentar

Perder TabCash para cada comentário pode desincentivar conteúdos que gerem engajamento, pois só iria gastar mais tabcash, já que comentar é de graça e ainda pode gerar tabcoins para quem comenta.

Talvez algo importante de ser lembrado é que, mesmo que seja revenue share e a publicação seja impulsionada, ainda deve seguir as regras de conduta do site, portanto o conteúdo de valor deve ser mais valorizado nesse caso. Um caminho que poderia ser seguido é que as qualificações positivas recebidas pelo post no período de impulso valham o dobro, mas de forma que o autor não as receba. Perceba que por si só, nos moldes atuais, receber mais votos positivos também é impulsionar a publicação. Aliando isso ao fato de que para votar não seria necessário gastar tabcoins, talvez fosse importante limitar esses votos para que apenas quem tem tabcoins suficientes possam votar e um limite de 1 voto por IP (como era feito antes) para evitar manipulações indevidas.

Existem três casos para a qual uma publicação provavelmente será impulsionada:

  1. Para possívelmente tirar do "limbo" uma publicação que o autor se esforçou muito ou que quer mais engajamento e destaque
  2. Para testar a funcionalidade
  3. Para divulgação

Obviamente mais casos surgirão com o tempo, mas inicialmente acredito que sempre se encaixarão nesses três casos. Em qualquer dessas situações teremos posts possivelmente irrelevantes, que não serão tão impulsionados naturalmente (seria importante que as qualificações negativas também tivessem o efeito das positivas?), mas aqueles que tiverem valor concreto seriam muito mais beneficiados, o que cumpre o objetivo do site.

Outro ponto a se atentar também é se será possível impulsionar mais vezes uma determinada publicação ou se terão formas de aumentar esse tempo de impulso.

@Rafatcb Rafatcb added front Envolve modificações no frontend back Envolve modificações no backend novo recurso Nova funcionalidade/recurso labels Dec 16, 2023
@Rafatcb
Copy link
Collaborator

Rafatcb commented Feb 29, 2024

  • Sobre impulsionar publicações.

Acho interessante a possibilidade de "impulsionar" uma publicação (seja uma publicação do tipo conteúdo + divulgação, seja apenas conteúdo), mas essa dinâmica difere um pouco do anúncio básico (não é temporário, já tem TabCoins e comentários, já tem "tempo de vida" etc.), então acredito que podemos deixar para depois, focando no que é realmente o mais simples e funcional possível agora.

De toda forma, é importante ter em mente que essa é uma possibilidade futura, então projetamos o sistema de forma que seja possível acomodar essa funcionalidade.

  • Sobre votar sem custos.

Eu não deixaria o "custo de votar" nulo em publicações promovidas. Isso pode facilitar desnecessariamente os usuários votarem negativamente em todo anúncio, e hoje temos algumas facilidades que permitem o usuário poder votar mais (como o login diário).

Apesar disso, concordo com o autor não ganhar TabCoins de votos recebidos em uma publicação promovida.

  • Sobre o espaço fixo para as publicações promovidas.

Eu concordo que um espaço fixo não é legal para isso, as publicações podem estar "misturadas" com as outras relevantes, numa ordem que faça sentido.

  • Sobre identificar as publicações promovidas.

Como dito nesse vídeo, acho importante ficar claro que aquilo é um anúncio, e que o anúncio está contribuindo com o usuário X. Esse uso de palavras pode mudar a percepção do leitor, principalmente para não chegarmos num ponto onde os usuários negativem qualquer anúncio simplesmente por ser um anúncio.

Outro ponto que citei em #1490 (comment), as "publicações promovidas" podem ser mais comerciais, e se não estiverem marcadas devidamente, os usuários podem achar que a publicação deveria ser removida. Imagino que uma publicação promovida extremamente comercial não será bem recebida, mas pode ser um pouco melhor recebida se devidamente identificada, já que a forma de avaliar pode mudar: "é uma propaganda, mas gostei da ferramenta/projeto/...".

Claro, podemos ter o problema de quem usa a API passar a ignorar isso, ou bloquearem usando uma extensão do navegador, mas acho que vale correr o risco inicialmente. Em alguns cenários de cálculo do "custo do anúncio" (para o anunciante), essa situação não implicará em um maior custo por um retorno menor. Por exemplo, se o custo for por interações (comentários/votos), ou for por visualização na página da publicação (e não no /relevantes, por exemplo). Isso muda se o cálculo for por tempo que o anúncio está no ar (o que não me parece legal) ou por visualizações no /relevantes.

Minha sugestão aqui seria "pagarmos para ver" no início.

  • Sobre como será o custo de criar e manter uma publicação promovida.

Bom, vi alguns comentários sobre "pagar" para criar, para definir uma quantidade de TabCoins iniciais, para receber votos, comentários, e para definir o tempo que ficará como promovida.

Para simplificar, eu gostaria de sugerir tirar o tempo da equação. Podemos começar de forma que toda publicação promovida fique promovida por 24 horas. Escolher o tempo traz um pouco de complexidade, e o usuário poderia ser esperto e deixar promovida apenas nos horários que há mais público, e de madrugada não teria nenhuma publicação promovida, por exemplo.

E talvez, a princípio, experimentaria não "cobrar" por receber comentários.

Edit 16/03/2024: Sugiro também que o custo de TabCoins iniciais não aumente linearmente, mas sim que, quanto mais TabCoins, mais caro. Ou seja, supondo que o primeiro TabCoin custe 1 TabCash, se eu quiser criar uma publicação com 10 TabCoins, não vou gastar 10 TabCash, mas sim 30, por exemplo (números aleatórios).

Algumas sugestões adicionais

  • Apesar dos anúncios serem temporários, é interessante deixarmos salvos e acessíveis para podermos exibir estatísticas futuramente.
  • Criação de uma feature para poder anunciar. Como mencionei em Milestone 7: Revenue Share [DRAFT] #1490 (comment), inicialmente a ideia era isso ser "comprável", mas acho que podemos começar liberando para alguns usuários como "beta fechado", mesmo que seja algo temporário.
  • Criar uma (ou mais) pergunta e resposta no FAQ na versão inicial e ir adaptando nas versões seguintes.
  • Limitar a quantidade de publicações promovidas na plataforma ao mesmo tempo. Como serão ordenadas por relevância (boost inicial + votos dos usuários), e não ficarão rotacionando, creio que podemos limitar a 3 publicações promovidas por vez (10% do total de publicações exibidas na página).
  • Talvez destacar a publicação promovida também na lista de Recentes, para caso ela saia dos Relevantes devido aos votos? Ou quando isso ocorrer a publicação deixará de ser promovida e não será mais acessível? Acho que a segunda opção adiciona mais complexidade.
  • Permitir um único voto por usuário/IP na publicação promovida, para ter um impacto mais "fidedigno". Talvez isso acabe desequilibrando, deixando mais difícil torná-la relevante, mas acho que o "boost" de TabCoins, fora a identificação visual, compensarão isso.

Agora, uma questão para elaborar mais: foi proposto que a publicação seja despublicada ao alcançar o tempo limite ou quantidade máxima de TabCash gasto pré-estabelecido. Acho o segundo caso um pouco estranho, porque digamos que foi uma propaganda que o pessoal realmente gostou, e recebeu vários votos de forma relativamente rápida: ela desapareceria em pouco tempo.

Se definirmos que a publicação ficará promovida por um tempo determinado, podemos informar isso na UI.

Fora essa última questão, e apesar de alguns poucos pontos que sugeri serem diferentes da ideia inicial, acho que dá para o sistema funcionar bem. A maior dificuldade provavelmente será encontrar o ponto de equilíbrio de TabCash.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Mar 9, 2024

Este comentário contém apenas sugestões de como uma publicação promovida pode ser destacada na UI. Trouxe várias alternativas e tentei mostrar como meu raciocínio foi evoluindo para chegar na opção que eu mais gostei.

A publicação promovida

Seguindo com a ideia que mencionei em "Sobre identificar as publicações promovidas.", no meu comentário anterior, fiz alguns testes para elaborar melhor como isso pode ficar na prática. As imagens Mobile abaixo foram simuladas numa largura de 320px.

Vale o disclaimer que as imagens que eu coloquei para exemplificar abaixo tem como nome do autor filipedeschamps, mas é uma publicação que criei em localhost copiando partes de textos de outros lugares, apenas para dar noção de algo real.

1. Label "Anúncio", ao lado do nome do usuário.

Desktop Mobile
Label ao nome do autor, amarelo, escrito "Anúncio", com o tooltip "Este anúncio está contribuindo para o usuário nome do usuário" O memso cenário que o anterior, porém numa tela menor. O texto da tooltip fica cortado.

Inicialmente pensei em destacar usando um Label com variant="attention" dentro da publicação:

No caso do exemplo Mobile, o texto da Tooltip fica cortado, mas isso poderia ser resolvido mudando para "Este anúncio está contribuindo para o autor", por exemplo. Mais para frente mostro outros exemplos com essa alternativa.

Acho que será necessário diferenciar textos para um "Anúncio" e uma "Publicação promovida", que podem funcionar exatamente da mesma forma, mas o primeiro sendo algo comercial e o segundo sendo um conteúdo. Digo isso pensando no que já mencionei anteriormente, sobre publicações (anúncios) exclusivamente comerciais. Ou, então, podemos usar o adjeitvo "patrocinado", que é mais neutro nesse cenário.

Pensando sobre o propósito do LabelGroup que existe hoje, ao lado do nome do usuário, os usos seriam coisas como: Novo usuário, Autor, Robô, Moderador etc. Tudo isso é sobre o autor. Então, podemos pensar em mostrar que a publicação é um anúncio de outra forma, para termos uma UI mais consistente.

2. Texto negrito "Publicação patrocinada", acima da linha do nome do usuário.

Desktop Mobile
Texto "Publicação patrocinada" numa linha acima do nome do usuário. O texto é amarelo, em negrito. No hover, mostra uma tooltip com o texto "Esta publicação está contribuindo para o autor" O mesmo cenário que o anterior, porém numa tela menor

Nesse caso, usei a mesma cor do <Label variant="attention">, que é color: 'attention.fg'. Continuei deixando o Tooltip, mas com o texto menor. E, como o texto principal está englobando tanto "anúncios" quanto "publicações promovidas", neutralizei o texto para "Esta publicação está contribuindo para o autor". Talvez tenha ficado muito genérico, e "Este patrocínio está contribuindo para o autor" fique melhor.

3. Texto negrito "Publicação patrocinada com TabCash", acima da linha do nome do usuário.

Desktop Mobile
Texto "Publicação patrocinada com TabCash" numa linha acima do nome do usuário. O texto é amarelo, em negrito. No hover, mostra uma tooltip com o texto "Este patrocínio está contribuindo para o autor" O mesmo cenário que o anterior, porém numa tela menor

O texto "Publicação patrocinada" é bem curto, então temos espaço para escrever "Publicação patrocinada com TabCash". Isso deixa claro o que queremos passar com os "anúncios": o TabCash tem um uso, e um desses usos é criar uma publicação patrocinada/promovida; o autor só conseguiu patrocinar a publicação porque já criou conteúdo, ganhou TabCoins e qualificou conteúdos; a plataforma não "vendeu" o espaço por dinheiro.

Também mudei o Tooltip para vocês verem como fica na prática a alternativa que sugeri anteriormente.

4. Texto negrito "Publicação patrocinada com TabCash", acima da linha do nome do usuário, com ícone.

Ícone Desktop Mobile
Megafone Texto "Publicação patrocinada com TabCash" numa linha acima do nome do usuário. O texto é amarelo, em negrito, e com um ícone de megafone antes dele. No hover, mostra uma tooltip com o texto "Este patrocínio está contribuindo para o autor" O mesmo cenário que o anterior, porém numa tela menor
Ad Texto "Publicação patrocinada com TabCash" numa linha acima do nome do usuário. O texto é amarelo, em negrito, e com um ícone escrito "Ad" antes dele. No hover, mostra uma tooltip com o texto "Este patrocínio está contribuindo para o autor" O mesmo cenário que o anterior, porém numa tela menor

O ícone pode dar um destaque extra. Eu estava em dúvida se seria uma adição positiva, porque a opção 3 já me parecia um destaque interessante no topo da publicação, mas decidi testar. Usei size={14}.

Vendo assim, reforço minha opinião de que não precisamos adicionar um ícone.

5. Texto negrito "Publicação patrocinada com TabCash", acima da linha do nome do usuário, mantendo o alinhamento dos TabCoins com o título.

Desktop Mobile
Texto "Publicação patrocinada com TabCash" numa linha acima do nome do usuário e dos TabCoins da publicação. O texto é amarelo, em negrito. No hover, mostra uma tooltip com o texto "Este patrocínio está contribuindo para o autor" O mesmo cenário que o anterior, porém numa tela menor

Quando montei os outros exemplos, não tinha percebido que eu deixei de "alinhar os TabCoins com o título", então criei esse para terem noção de como ficaria "do jeito certo".

Se quiser ver uma captura de tela completa para ter noção de como esse texto fica junto do conteúdo, clique aqui. Coloquei o modo escuro também.

Desktop:

Publicação inteira no Desktop, conforme o exemplo 5

Publicação inteira no Desktop, conforme o exemplo 5, no modo escuro

Mobile:

Publicação inteira no Mobile, conforme o exemplo 5

Publicação inteira no Mobile, conforme o exemplo 5, no modo escuro

A lista de conteúdos

O exemplo do @rodrigoKulb me inspirou para as experimentações que fiz no tópico anterior, então decidi adaptar a ideia do tópico anterior para a lista de conteúdos, não deixando as publicações promovidas fixas num local.

1. Texto negrito "Publicação patrocinada com TabCash", acima do título do conteúdo.

Desktop Mobile
Texto "Publicação patrocinada com TabCash" numa linha acima do título do conteúdo. O texto é amarelo, em negrito. O mesmo cenário que o anterior, porém numa tela menor

Mesmo padrão que mostrei no conteúdo. Também podemos ter a Tooltip aqui.

2. Texto negrito "Publicação patrocinada com TabCash", numa linha acima do título do conteúdo e do número da posição.

Desktop Mobile
Texto "Publicação patrocinada com TabCash" numa linha acima do título do conteúdo e do número da lista. O texto é amarelo, em negrito. O mesmo cenário que o anterior, porém numa tela menor

Aqui só mudei o alinhamento do número da lista. Aproveitei para tirar o print numa janela anônima, sem ter visitado o link, para vocês verem a diferença.

Acho melhor manter o número alinhado com o título para a leitura continuar fácil, "batendo o olho" o leitor consegue entender. Fiquei em dúvida se esse espaçamento entre os itens é pequeno demais a ponto de confundir a pessoa sobre qual é a publicação patrocinada.

Se quiser ver uma captura de tela completa para ter noção de como isso fica na lista de conteúdos, clique aqui. Coloquei imagens do modo escuro também

Desktop:

Captura da tela inteira no Desktop, conforme o exemplo 2

Captura da tela inteira no Desktop, conforme o exemplo 2, no modo escuro

Mobile:

Captura da tela inteira no Mobile, conforme o exemplo 2

Captura da tela inteira no Mobile, conforme o exemplo 2, no modo escuro

3. Com o texto e destacando o "fundo" do item da lista.

Desktop Texto "Publicação patrocinada com TabCash" numa linha acima do título do conteúdo. O texto é amarelo, em negrito. Fundo do item em amarelo claro.
Mobile O mesmo cenário que o anterior, porém numa tela menor

Trouxe esse exemplo para ver como ficava. É algo similar ao que o Google fazia anos atrás. Para a cor de fundo, usei attention.subtle.

Não gostei dessa alternativa. Não é terrível, ela é viável, mas acho que está dando destaque demais aos anúncios (mesmo a cor de fundo sendo clara), e precisaríamos ter uma atenção extra aos contrastes. Além disso, com os Banners causará uma poluição maior ainda. Outro ponto é que nossos olhos se acostumarão a ignorar isso (banner blindness).

@aprendendofelipe
Copy link
Collaborator Author

Ótimos estudos Rafa!

Vendo os resultados, eu acho que não é necessário algo tão chamativo para deixar claro que é um conteúdo promovido.

O que acham de algo assim?

Conteúdo Lista
Conteúdo Patrocinado Conteúdo Patrocinado na lista

@Rafatcb
Copy link
Collaborator

Rafatcb commented Mar 10, 2024

@aprendendofelipe eu gostei do uso do verde, já que é a cor do TabCash. Na lista de conteúdos, não sei se teríamos casos "muito ruins", onde o nome do usuário ficaria "r...", principalmente considerando a duração sendo algo como "22 minutos atrás", que é um texto mais longo.

Na publicação em si, você não acha que pode ter aquele problema que mencionei, dos Labels serem mais relacionados ao autor do que ao conteúdo? Uma alternativa pode ser como ficou na lista de conteúdo, escrito em texto normal, colorido e sem a borda.

Eu esbocei mais algumas ideias, agora no fluxo de criar uma publicação promovida. Eu comecei a criar estes exemplos antes do seu comentário, por isso estão similares ao meu comentário anterior, mas obviamente aqui seguiríamos o padrão adotado (cores e termos escolhidos).

Uma nova pergunta, acha melhor usarmos "Patrocinar/Patrocinado" ao invés de "Promover/Promovida" em todo lugar? Eu acho que faz sentido, mas nos exemplos que criei abaixo está uma mistura, a depender do local onde o texto é exibido.

Como criar uma publicação promovida

Informações necessárias

Com base nos comentários anteriores, esse processo pode exibir algumas informações e demandar outras do usuário. Além do necessário para criar uma publicação normal, a criação de uma publicação promovida provavelmente envolverá:

  • Informar para o usuário:
    • Custo em TabCash para criar.
    • Duração (informar, caso seja um valor fixo).
  • Obter os dados:
    • TabCoins promovidos (valor inicial em TabCoins).
    • Limite de TabCash a ser gasto.
    • Duração (obter, caso o usuário possa escolher a duração).

UI

Seguindo com algumas elaborações de UI, estou colocando aqui mais algumas ideias justamente para outras pessoas poderem opinar e já termos algo mais trabalhado na hora de chegar na implementação (ou seja, ninguém ser pego de surpresa ao avaliar um PR).

Independente de onde for adicionado esse fluxo, imagino que a opção de criar uma publicação promovida deve estar visível apenas caso o usuário tenha a feature, e habilitada apenas caso o usuário possa realmente criar, por exemplo, se o limite de publicações promovidas for X, e já terem X publicações promovidas, então a ação ficaria desabilitada com uma explicação próxima. Algo como:

Não é possível criar uma publicação promovida agora, saiba mais (link para uma pergunta do FAQ que explica isso).

Ou mesmo algo específico já dizendo o motivo de não poder criar a publicação promovida.

1. Adicionar um Checkbox na página /publicar e exibir os campos específicos quando ele estiver marcado

Um checkbox no fim do formulário de campos para criar uma publicação, escrito "Promover publicação. Saiba mais.", onde o "Saiba mais" é um link

Essa foi a primeira ideia que passou pela minha cabeça. Podemos exibir um Checkbox para os usuários que já possuem a feature de "promover publicação". Para dar contexto, poderia ter um link Saiba mais (ou outro texto) direcionando para a pergunta do FAQ sobre publicações promovidas.

É uma solução simples e discreta. O aviso para o estado disabled pode ser assim:

Texto "Não é possível criar uma publicação promovida agora. Saiba mais." abaixo do Checkbox. O "Saiba mais" é um link

Aqui, o Saiba mais também é um link para o FAQ (outra pergunta). Usei o FormControl.Caption para exibir a mensagem.

Os campos relacionados à uma publicação promovida podem ser exibidos ao marcar o Checkbox:

Desktop Mobile
Abaixo do checkbox "Promover publicação. Saiba mais" marcado, três campos na mesma linha: "TabCoins promovidos" com a legenda "Sua publicação iniciará com 1 TabCoin.", "Limite de TabCash" com a legenda "Ao atingir o limite, a publicação será removida." e "Limite de tempo (em horas)" com a legenda "Tempo máximo que a publicação ficará visível.", seguido por "Custo inicial: 32 TabCash" numa nova linha, em negrito, amarelo. O mesmo cenário da imagem anterior, mas numa tela pequena. Cada campo fica numa linha diferente.

Não consegui pensar numa boa exibição para os campos, já que eles tem valores curtos. Tentei buscar um equilíbrio entre o tamanho do Label e do Caption para os campos serem auto-explicativos. Nos exemplos acima, a largura dos TextInputs está em 100px e os dois primeiros FormControls estão com sx={{ flex: '1 1 160px' }}, e o terceiro sx={{ flex: '1 1 204px' }}.

Depois de ter visto o exemplo do @aprendendofelipe , tive uma outra ideia de como exibir o custo, que acho mais consistente com nossa UI:

fontSize não especificado Texto "Custo inicial: 32 TabCash" sem negrito e na cor preta normal, mas com o ícone do TabCash
fontSize: 1 Mesma imagem que a anterior, porém com o texto menor

Sem especificar o fontSize, o texto fica maior do que o resto da página (Labels, Captions e o texto dos campos obrigatórios), então coloquei também uma imagem com o fontSize: 1.

2. Nova página para criar publicação promovida, com link dentro do próprio perfil

Desktop Mobile
Perfil do usuário, numa tab escrita "Publicações promovidas", mostrando uma lista de publicações. A primeira está com um texto negrito amarelo "Publicação patrocinada com TabCash", a segunda não. O mesmo cenário da imagem anterior, mas numa tela pequena.

Outra opção é criar uma publicação promovida numa página própria. Isso não é totalmente necessário, mas foi a única alternativa ao exemplo anterior que consegui pensar. Eu havia pensado nisso inicialmente para evitar que o usuário criasse uma promovida sem querer, por exemplo, mas como ele precisará preencher novos campos, não acho que isso é um problema.

Essa nova página pode ser acessada através de uma tab no próprio perfil onde o usuário pode ver as publicações promovidas (ativas ou inativas) e mais detalhes sobre elas, já que o seu histórico de publicações promovidas não ficará disponível na aba "Publicações" do perfil (lá pode ser exibida a publicação promovida que está ativa).

Além das publicações que já foram promovidas, a lista pode conter todos os tipos de anúncios, e o botão "Criar publicação" pode ser um botão com o ícone de três pontos (KebabHorizontalIcon), onde exibirá o ActionMenu com opções para criar uma publicação promovida, um banner etc. A princípio, apenas o próprio usuário teria acesso à essa página, mas podemos criar uma permissão para que moderadores vejam o histórico de anúncios de outros usuários.

Ao clicar no botão "Criar publicação", redirecionaríamos para uma página /publicar-promovida, por exemplo, que seria parecida com a /publicar, porém com um texto mais claro de que está criando uma publicação promovida. Talvez a única diferença acabasse sendo o h1 e não ter um checkbox. Depois de ter feito a opção 1, acho que não precisamos de uma página específica para criar uma publicação promovida.

3. Aba de publicações promovidas dentro do próprio perfil, com link para /publicar

Também podemos optar por uma mistura da opção 1 e 2, onde existirão dois caminhos para criar uma publicação promovida:

  1. Indo direto para /publicar; ou
  2. Indo no perfil, vendo as publicações promovidas/anúncios e clicando no botão Criar publicação, que redirecionará para /publicar, mas com o Checkbox "Promover publicação. Saiba mais." marcado.

@aprendendofelipe
Copy link
Collaborator Author

@aprendendofelipe eu gostei do uso do verde, já que é a cor do TabCash.

Pensei no verde por esse motivo mesmo, mas para exemplificar usei o padrão do label ao invés de usar a mesma cor do TabCash. Escolhendo o verde mesmo, que por mim está legal, podemos ver qual tom fica melhor.


Na lista de conteúdos, não sei se teríamos casos "muito ruins", onde o nome do usuário ficaria "r...", principalmente considerando a duração sendo algo como "22 minutos atrás", que é um texto mais longo.

Sim, isso iria ocorrer em telas muito pequenas, onde acho que poderíamos omitir o saldo de TabCoins para ficar melhor.

E pensando em omitir o saldo de TabCoins, me ocorreu agora que talvez faça sentido omitir sempre o saldo dos promovidos na lista de conteúdos, já que o número em si será algo artificial. Podemos talvez mostrar o detalhamento dos votos junto dos TabCoins promovidos no mesmo Tooltip. Algo a se pensar...

Ficaria como abaixo, onde também já coloquei o tom verde de TabCash, pois me pareceu melhor, principalmente no modo dark:

Conteúdo patrocinado

Na publicação em si, você não acha que pode ter aquele problema que mencionei, dos Labels serem mais relacionados ao autor do que ao conteúdo? Uma alternativa pode ser como ficou na lista de conteúdo, escrito em texto normal, colorido e sem a borda.

Acho que os labels não precisam ser somente sobre o autor. Acho que podem ser também sobre o conteúdo, mas vamos ver como fica sem a borda. 👍


Uma nova pergunta, acha melhor usarmos "Patrocinar/Patrocinado" ao invés de "Promover/Promovida" em todo lugar? Eu acho que faz sentido, mas nos exemplos que criei abaixo está uma mistura, a depender do local onde o texto é exibido.

Como palavra única que já expressa o que queremos, eu acabei gostando mais de "patrocinado" do que "promovido", mas para o verbo gosto mais de "promover" do que de "patrocinar".

Talvez para deixar ainda mais claro, e menos repetitivo, pode mudar o Tooltip para "Promovido com TabCash", mesmo mantendo a palavra "Patrocinado" no destaque me verde. Eu acho melhor se der para unificar, mas é mais importante deixar claro, então é melhor saber outras opiniões sobre isso...


Gostei das sugestões para criar a publicação, e acho que é bom deixar mais de um caminho para chegar até lá.

O endereço da página pode ser o mesmo de publicar qualquer conteúdo, pois acho que isso facilita para os usuários. Caso contrário teremos que criar um modo fácil do usuário migrar os dados de uma página para a outra, caso ele tenha começado a criar no lugar errado.

Uma alternativa legal para se testar é usar um Dialog com os campos extras.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Mar 17, 2024

@aprendendofelipe não sei se você já começou a implementar algo. Eu estou apenas pensando em como poderia ser feito. Como parece que os campos mencionados nos comentários anteriores seriam o suficiente para criar um anúncio, comecei a pensar na parte da API e do banco de dados.

Neste comentário já vou colocar alguns nomes de campos, propriedades e tabela do banco de dados, então se terem sugestões melhores, podem falar.

Tem bastante informação aqui, e eu acabei escrevendo num "vai e volta", complementando conforme percebia detalhes, então se algo ficou incompleto ou inconsistente, me avise também.

Criação de uma publicação patrocinada

API: POST /api/v1/contents

Como (muito provavelmente) usaremos a mesma tela para criar uma publicação normal e uma publicação patrocinada, podemos usar o mesmo endpoint, adicionando uma funcionalidade sem quebrar o comportamento atual.

{
  title: string,
  body: string,
  status: 'published' | 'draft',
  source_url: string | undefined,
+   sponsor: {
+     initial_tabcoins: number,
+     max_tabcash: number,
+     max_hours: number,
+   }
}

Pensando sobre, eu gostei da ideia de adicionar um novo atributo (no caso, sponsor) que conterá todas as informações necessárias para criar um conteúdo patrocinado (ou, futuramente, promover um conteúdo existente). Assim, deixamos essa funcionalidade "encapsulada", facilitando a validação e deixando claro que os atributos aninhados (initial_tabcoins, max_tabcash e max_hours) estão relacionados à essa funcionalidade.

Banco de dados

Hoje, em contents, temos id, parent_id, owner_id, slug, title, body, status, source_url, published_at, created_at, updated_at, deleted_at e path.

Pensando numa flexibilidade em tratar diferentes tipos de anúncio de uma forma parecida, me parece compensar criar uma tabela para eles. Talvez advertisements. Acho o nome um pouco complicado mas não consegui pensar em algo melhor (ads?).

Essa nova tabela poderia armazenar informações úteis sobre todo tipo de anúncio.

Levando em consideração o que é importante para a criação de uma publicação promovida (initial_tabcoins, max_tabcash e max_hours), a primeira informação ficará armazenada em balance_operations, então sobram max_tabcash e max_hours.

Ambas são relevantes para o caso de um anúncio de custo variável. Temos que pensar também que um outro tipo de anúncio pode ter um custo inicial X e nenhum custo variável.

Dito isso, o que seria interessante de ter numa tabela de anúncios?

  • id: Identificador do anúncio.
  • deactivate_at: Horário que o anúncio sairá do ar, calculado a partir do max_hours. Talvez esse não seja o melhor nome porque, no caso de publicações promovidas, poderá sair do ar antes (o custo é variável e o TabCash do autor pode acabar, ou o autor pode desativar o anúncio manualmente), mas isso pode ser relevante para estatísticas futuras, por exemplo, o usuário planejou desativar um anúncio após 3 dias, mas ele foi desativado em 1 dia.
  • max_tabcash: Para a publicação promovida, isso é definido. Para um anúncio de custo fixo, poderia ser o próprio custo ou null. Esse detalhe pode ser discutido no issue específico do anúncio de gasto fixo, o importante aqui é só definir se faz sentido ter essa coluna considerando os cenários possíveis.
  • type: Como poderão existir diferentes tipos de anúncio, como banner e publicação promovida, especificar o tipo aqui pode ser útil. Imagino que também podemos usar isso para diferenciar uma publicação temporária patrocinada de uma publicação permanente, o que mudará o que acontece após o término do patrocínio. Podemos ter, por exemplo, sponsored_content e sponsored_temporary_content como tipos.
  • created_at, updated_at, deactivated_at: Faz sentido armazenarmos esses campos também? Note que aqui optei por deactivated_at ao invés de deleted_at. Essa nomenclatura me parece fazer mais sentido para o cenário de anúncios, mas é algo debatível.
  • status: active, deactivated. Faz sentido?
  • content_id: Pensando em relacionar o anúncio com a publicação, essa foi a única forma que me veio na cabeça (além de criar um evento e procurar por lá, o que seria custoso). Os outros tipos de anúncio teriam que salvar este valor como null, então gostaria de mais opiniões em como tratar isso de forma adequada.

A quantidade de TabCash gasto no anúncio, seja ele fixo ou variável, pode ser obtida pelo balance_operations, como é feito com os TabCoins de conteúdos e usuários, e com o TabCash de usuários.

PS: deactivate_at e deactivated_at são nomes bem parecidos e podem causar confusão na hora de programar e na revisão do código.

Eventos

Hoje, ao criar uma publicação, criamos um evento e depois atualizamos ele com metadata:

{
  type: 'create:content:text_root',
  originatorUserId: string,
  originatorIp: string,
  metadata: {
    id: string
  }
}

Agora que já refleti sobre quais dados poderíamos armazenar especificamente sobre a publicação patrocinada na tabela própria de anúncios, consigo pensar melhor sobre o que armazenar no evento.

Procurando manter o padrão, podemos armazenar apenas o id do anúncio. Saindo do padrão, podemos armazenar também a quantidade de TabCash que o usuário tinha no momento de criação da publicação patrocinada. Não sei se isso faz sentido.

A partir daqui, vejo duas opções ao criar uma publicação patrocinada:

1. Armazenar novos dados no evento criado.

Podemos armazenar os dados discutidos acima no metadata do evento create:content:text_root:

{
  type: 'create:content:text_root',
  originatorUserId: string,
  originatorIp: string,
  metadata: {
    id: string,
    advertisement_id: string,
    user_tabcash: number
  }
}

2. Criar o evento create:content:text_root, mas também criar um novo evento específico (sponsor:text_root).

Outra opção é criar, além do create:content:text_root, um novo evento para um conteúdo patrocinado, já tendo em mente que futuramente poderemos promover um conteúdo já publicado, onde criaríamos este evento também.

Acredito que assim facilitará a busca desse tipo de evento (conteúdo patrocinado) sem precisar buscar por algo armazenado no metadata.

Os dados armazenados em metadata seriam os mesmos da opção 1, com uma leve mudança, já que o metadata.id seria o identificador do anúncio, e não do conteúdo:

{
  type: 'sponsor:text_root',
  originatorUserId: string,
  originatorIp: string,
  metadata: {
    id: string,
    content_id: string,
    user_tabcash: number
  }
}

Podemos seguir esse mesmo raciocínio com outros tipos de anúncio, como o anúncio em banner (que é outro issue) que poderia ser sponsor:banner, por exemplo.

Não sei se vale a pena diferenciar o tipo aqui também, como mencionei na tabela advertisement, criando um tipo sponsor:text_root:temporary e outro sponsor:text_root.

Atualização do saldo

Precisaríamos criar um registro em balance_operations sobre o gasto de TabCash do usuário, assim como já ocorre ao ganhar TabCoins/TabCash e ao perder Tabcoins.

Em balanceType existem os tipos user:tabcoin, user:tabcash, content:tabcoin:initial, content:tabcoin:credit e content:tabcoin:debit. O amount pode ser um valor positivo ou negativo. Dito isso, não teríamos nenhuma novidade:

{
  balanceType: 'user:tabcash',
  recipientId: string, // id do usuário
  amount: number, // negativo, valor gasto para promover a publicação
  originatorType: 'event',
  originatorId: string // id do evento `create:content:text_root` (opção 1) ou `sponsor:text_root` (opção 2) 
}

O custo de TabCash não foi definido ainda.

Voto em publicação patrocinada

API: POST /api/v1/contents/[username]/[slug]/tabcoins

Nada muda na interface.

O comportamento será diferente. Ao invés de dar TabCash ao autor do conteúdo, irá consumir. Se o autor ficar sem TabCash, a publicação deve deixar de ser patrocinada.

Sobre o consumo de TabCoins para votar e o limite de votos, não foi definido (eu dei uma opinião em #1491 (comment) diferente do que havia sido sugerido em outros comentários).

Eventos

Hoje o evento criado é:

{
  type: 'update:content:tabcoins',
  originatorUserId: string,
  originatorIp: string,
  metadata: {
    transaction_type: 'credit' | 'debit',
    from_user_id: string,
    content_owner_id: string,
    content_id: string,
    amount: 2
  }
}

A mudança no evento acima dependerá de uma mudança do comportamento, isto é, se haverá cobrança de TabCoins ou não (amount = 2 ou 0). Fora o amount, acredito que o resto permaneça igual.

Atualização do saldo

Hoje acontecem quatro atualizações no saldo:

  1. user:tabcoin: quem votou, perde 2 TabCoins.
  2. user:tabcash: quem votou, ganha 1 TabCash.
  3. user:tabcoin: o autor da publicação ganha ou perde 1 TabCoin.
  4. content:tabcoin:credit ou content:tabcoin:debit: o conteúdo ganha ou perde 1 TabCoin.

Deverá ser atualizado para:

  1. user:tabcoin: com a mudança de comportamento, pode continuar igual ou não existir mais.
  2. user:tabcash: com a mudança de comportamento, pode continuar igual ou não existir mais.
  3. user:tabcash: depende da mudança de comportamento. Talvez o autor perca TabCash apenas se for um voto positivo, talvez perca sendo positivo ou negativo. Imagino que o valor será 1 TabCash (não me lembro de ter visto um comentário sugerindo outro valor).
  4. content:tabcoin:credit ou content:tabcoin:debit: o conteúdo ganha ou perde 1 TabCoin. (sem mudanças)

Obter publicação patrocinada

API: GET /api/v1/contents/[username]/[slug] e GET /api/v1/contents/[username]/[slug]

Aqui será necessário verificar se a publicação é patrocinada.

Na API, imagino que poderíamos passar um is_sponsored: true. O que acham? Para isso, vou colocar duas opções que consegui imaginar:

1. Realizar um JOIN para verificar se a publicação existe na tabela advertisements, e se o registro mais recente ainda está ativo. Talvez isso "pese" nas consultas.

2. Criar uma coluna a mais na tabela contents que indica se está patrocinada ou não. Ainda precisaríamos verificar em algum momento se a publicação está patrocinada para atualizar o valor dessa coluna.

Atualizar publicação patrocinada

API: PATCH /api/v1/contents/[username]/[slug]

Além do que já existe hoje, podemos permitir o usuário alterar o gasto máximo de TabCash e o tempo de duração caso seja uma publicação patrocinada e ativa. Podemos continuar passando o objeto sponsor, como na criação, mas apenas com max_tabcash e max_hours.

Acredito que não devemos ter nenhuma restrição ao atualizar um conteúdo patrocinado: tudo bem atualizar o título, corpo e fonte, e também atualizar o status para deleted, sem reembolsar o TabCash gasto.

No caso de deleted, já podemos atualizar a tabela advertisements, caso a criemos.

Caso seja uma publicação não patrocinada, eu sugiro permitir promovê-la, mas não agora, para não deixar a primeira fase de implementação ainda mais complexa. Nesse caso, só precisaria passar o objeto sponsor que sugeri no tópico sobre a criação da publicação, com max_tabcash, max_hours e initial_tabcoins.


Dúvidas

O que fazer quando acabar o período de uma publicação temporária patrocinada?

Considerando que vamos criar a publicação na tabela contents, após o período ela ficará como deleted?

E quando isso será verificado?

Terá um tipo de cronjob, além de uma verificação quando a publicação receber votos (para verificar se o autor ainda possui TabCash disponível), ou será verificado sempre que ter um GET na lista de conteúdos para ver se o tempo acabou?


Uma forma de burlar ao promover uma publicação "permanente"

Futuramente, ao permitirmos promover uma publicação existente, surgirá uma preocupação: a pessoa usar os Tabcoins iniciais para impulsionar e depois remover o patrocínio. Assim, a publicação terá destaque em Relevantes por causa dos TabCoins, mas não aparecerá como patrocinada e nem custará TabCash quando o autor receber votos positivos.

Estou colocando isso aqui apenas para não esquecer desse detalhe. De início, não será uma preocupação porque a publicação desaparecerá, já que é temporária.

@aprendendofelipe
Copy link
Collaborator Author

Ótimos pontos @Rafatcb! 💪

Você focou, mas acho melhor focarmos ainda mais nas publicações promovidas, sem querer já deixar "preparado" para outros tipos de anúncios, pois depois podem (ou não) ser criadas tabelas/formulários/fluxos totalmente diferentes para cada tipo. Um único tipo de anúncio já é complexidade suficiente, e já vai exigir quebrar o problemas em diversos menores.

Publicações promovidas

Eu pensei nesse nome "publicação promovida" para aproveitarmos o que der do que já foi pensado para as publicações, além de mostrar eles na lista de conteúdos, mas não pensando em poder realmente promover um conteúdo. Anúncios serão anúncios, apenas poderão ter um formato parecido com o dos conteúdos, ou seja, um título, o corpo em markdown e um link destacado no final (que provavelmente não será uma fonte, mas uma chamada para ação).

Dito isso, acho que não precisamos (nem devemos) deixar preparado para lidar com transformação de publicação em anúncio e vice-versa, e nem salvar nada dos anúncios na tabela de conteúdos. Os eventos e endpoints provavelmente serão apenas parecidos com os dos conteúdos.

Tabela Balance Operations

Acho que compensa colocar como pré-requisito a separação em diferentes tabelas antes de começarmos as transações com TabCash.

Ou só eu que enxergo TabCoins de conteúdos, TabCoins de usuários e TabCash como três ativos completamente diferentes? Eles nunca precisarão ser computados juntos.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Mar 17, 2024

e nem salvar nada dos anúncios na tabela de conteúdos

Entendi. Então, publicações patrocinadas (anúncios) e promovidas ("normais impulsionadas") serão duas coisas diferentes mesmo, apesar de terem algumas características em comum.

Ou só eu que enxergo TabCoins de conteúdos, TabCoins de usuários e TabCash como três ativos completamente diferentes? Eles nunca precisarão ser computados juntos.

Eu enxergo como três coisas diferentes também, mas os TabCoins e TabCash do usuário são computados juntos para retornar com os dados do usuário, além do caso do voto, que muda o saldo de TabCoin e TabCash do mesmo usuário. Acha que vale a pena separar em três tabelas mesmo?

@aprendendofelipe
Copy link
Collaborator Author

Entendi. Então, publicações patrocinadas (anúncios) e promovidas ("normais impulsionadas") serão duas coisas diferentes mesmo, apesar de terem algumas características em comum.

Sim, e pode ser até que as impulsionadas nunca sejam implementadas.

Ou só eu que enxergo TabCoins de conteúdos, TabCoins de usuários e TabCash como três ativos completamente diferentes? Eles nunca precisarão ser computados juntos.

Eu enxergo como três coisas diferentes também, mas os TabCoins e TabCash do usuário são computados juntos para retornar com os dados do usuário, além do caso do voto, que muda o saldo de TabCoin e TabCash do mesmo usuário.

Mas não é junto no sentido de se beneficiar dos dados estarem na mesma tabela.

Acha que vale a pena separar em três tabelas mesmo?

Acredito que sim 👍

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 10, 2024

@aprendendofelipe imagino que a próxima etapa seja elaborar o esquema da nova tabela para esse tipo de anúncio, conforme as necessidades que foram discutidas acima, certo?

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 15, 2024

Banco de dados

Tabela para publicações patrocinadas

Pensando no banco de dados e reaproveitando algumas coisas que comentei em #1491 (comment), podemos ter uma tabela sponsored_posts para representar as publicações patrocinadas. As colunas seriam:

  • id
  • owner_id: Usuário que criou a publicação patrocinada.
  • title
  • body: Acho interessante ser obrigatório; não me parece que uma publicação patrocinada sem texto seria bem recebida.
  • link: O link que está sendo patrocinado (parecido com a fonte de uma publicação). Obrigatório.
  • deactivate_at: Horário que o anúncio sairá do ar, calculado a partir do "tempo máximo" informado pela UI/API.
  • max_tabcash_cost: Quantidade limite de TabCash que o anúncio consumirá até sair do ar.
  • created_at
  • updated_at
  • deactivated_at: O anúncio pode ser desativado antes do deactivate_at de forma manual, pelo limite de consumo de TabCash ou por falta de TabCash do autor.
  • status: active ou deactivated.

O initial_tabcoins, que será um dado informado ao criar uma publicação patrocinada, pode ser obtido através da tabela de saldos.

Saldo

Eu sugeri que os votos em publicações patrocinadas continuem consumindo TabCoins de quem votou. Pelo o que me lembro, ninguém concordou nem discordou. Se essa sugestão for aceita, então será criado um debit em content_tabcoin_operations como já é feito em "votos normais" hoje.

Entretanto, do lado do autor da publicação, ao invés de ganhar TabCash, perderá. Se formos seguir o padrão de content_tabcoin_operations, então podemos criar uma coluna balance_type na tabela user_tabcash_operations com os tipos credit e debit. Após a migração, todos os valores existentes hoje seriam do tipo credit.

Ao criar uma publicação patrocinada, o autor também perde TabCash, e acredito que podemos seguir o mesmo raciocínio do parágrafo anterior.

Por fim, temos o saldo de TabCoins da publicação patrocinada. O comportamento é muito parecido com o de contents, com os valores initial, credit e debit, mas a publicação patrocinada está na tabela sponsored_posts, e não contents, e recentemente fizemos uma separação de balance_operations para três tabelas diferentes, cada uma sobre um tipo de saldo específico. Dito isso, me parece ser necessário criar uma tabela sponsored_post_tabcoin_operations.

Então aqui teríamos:

  • user_tabcash_operations: Nova coluna balance_type
  • sponsored_post_tabcoin_operations: Nova tabela, igual a content_tabcoin_operations.
  • get_sponsored_post_balance_credit_debit: Nova função, para obter créditos e débitos na publicação patrocinada.
  • get_sponsored_post_current_tabcoins: Nova função, para obter o total de TabCoins da publicação patrocinada.

Eventos

Ao criar uma publicação patrocinada:

{
  type: 'create:sponsored_post',
  originator_user_id: string,
  originator_ip: string,
  metadata: {
    id: string,
    user_tabcash: number
  }
}

Ao votar numa publicação patrocinada:

{
  type: 'update:sponsored_post:tabcoins',
  originator_user_id: string,
  originator_ip: string,
  metadata: {
    amount: number,
    sponsored_post_id: string,
    from_user_id: string,
    sponsored_post_owner_id: string,
    transaction_type: 'credit' | 'debit'
  }
}

Ao editar uma publicação patrocinada:

{
  type: 'update:sponsored_post',
  originator_user_id: string,
  originator_ip: string,
  metadata: {
    id: string,
    updated_fields: string[] // similar à edição do perfil
  }
}

Ao desativar uma publicação patrocinada:

{
  type: 'deactivate:sponsored_post',
  originator_user_id: null | string,
  originator_ip: null | string,
  metadata: {
    id: string,
    trigger: 'owner' | 'moderator' | 'max_tabcash_cost' | 'time_expired' | 'not_enough_tabcash'
  }
}

Esse último evento sai do padrão que temos em outras ações (criação de conteúdo, edição etc.), mas acredito ser relevante. Não sei se o motivo (metadata.trigger) da publicação patrocinada ter sido "desativada" deve estar em events ou outro lugar, mas parece útil guardar essa informação.

  • owner: o autor desativou de forma manual.
  • moderator: um moderador desativou por ferir os termos de uso.
  • max_tabcash_cost: atingiu o custo máximo de TabCash estipulado pelo autor.
  • time_expired: chegou no tempo limite que foi estipulado pelo autor.
  • not_enough_tabcash: o autor gastou/perdeu TabCash por algum motivo (outro anúncio, voto desfeito por causa do firewall ou outra que pode surgir no futuro) e não tem TabCash o suficiente para receber mais um voto na publicação.

Me corrijam se algo estiver errado e digam se esqueci de algo ou se possuem sugestões de melhoria.

@aprendendofelipe
Copy link
Collaborator Author

Pensando no banco de dados e reaproveitando algumas coisas que comentei em #1491 (comment), podemos ter uma tabela sponsored_posts para representar as publicações patrocinadas.

Por que mudar o padrão de contents para posts? Não acha melhor sponsored_contents?

As colunas seriam:

  • body: Acho interessante ser obrigatório; não me parece que uma publicação patrocinada sem texto seria bem recebida.

Concordo. O caso sem o body poderia ser um outro tipo de anúncio para pensarmos no futuro, onde, ao clicar no título, já direciona diretamente para fora do TabNews, mas precisa ficar claro que isso irá acontecer, e é algo bem diferente do discutido aqui, já que não teria qualificações (nem a página específica do anúncio para receber votos), ou seja, aqui o body precisa ser obrigatório mesmo.

  • link: O link que está sendo patrocinado (parecido com a fonte de uma publicação). Obrigatório.

O que você pensa como justificativa para o link ser obrigatório? Talvez fizesse sentido se fosse proibido colocar links no corpo do anúncio, mas não sei se nesse momento precisamos nos preocupar com isso.

  • max_tabcash_cost: Quantidade limite de TabCash que o anúncio consumirá até sair do ar.

Melhor deixar isso para a tabela com o balanço de TabCash dos anúncios. Daí, para definir os anúncios que serão mostrados, não será preciso consultar o saldo do usuário, mas apenas do anúncio, assim como as qualificações também só precisarão movimentar o saldo dos anúncios.

Na publicação/edição, o autor vai reservar certa quantidade de Tabcash que poderá ser consumida, e isso entra no balanço do anúncio. O autor poderá editar o anúncio para disponibilizar mais TabCash, e até poderia retirar o anúncio do ar e resgatar o saldo remanescente, uma possibilidade que não precisa existir na primeira versão, se isso complicar algo.

Com isso evitamos que a soma dos limites de TabCash dos anúncios de um mesmo usuário fique acima do saldo disponível desse usuário. Esse detalhe é algo importante se formos liberar mais de um anúncio ao mesmo tempo para o usuário. E mesmo se formos limitar a um anúncio, acredito que o limite seria por tipo de anúncio, então isso ainda será importante.

Falando sobre limitar a quantidade de anúncios ativos de um mesmo usuário, pode ser suficiente limitarmos os anúncios exibidos ao mesmo tempo, sem precisar limitar a quantidade ativa, pois assim permitimos a criação de campanhas com diferentes anúncios que se revezam.

  • deactivate_at: Horário que o anúncio sairá do ar, calculado a partir do "tempo máximo" informado pela UI/API.
  • deactivated_at: O anúncio pode ser desativado antes do deactivate_at de forma manual, pelo limite de consumo de TabCash ou por falta de TabCash do autor.

Entendi, mas acho que não há necessidade das duas colunas. A deactivate_at seria equivalente à deleted_at da tabela contents, e a publish_at seria equivalente à published_at, com a diferença que no momento da criação (created_at) ou edição (updated_at) do anúncio, o autor pode escolher os horários de início e término do anúncio. E acho que faz mais sentido o autor definir diretamente as datas e horários do que escolher um limite de tempo em horas.

Se o autor decidir retirar o anúncio antes da hora definida anteriormente, basta ele editar a publicação, alterando o deactivate_at, e isso ficará registrado nos eventos. Ele pode até não definir deactivate_at e, nesse caso, o que vai definir se o anúncio continua disponível é o saldo de TabCoins/TabCash do anúncio. O saldo insuficiente também vai impedir a exibição do anúncio mesmo que ainda esteja dentro da faixa de tempo entre publish_at e deactivate_at.

O initial_tabcoins, que será um dado informado ao criar uma publicação patrocinada, pode ser obtido através da tabela de saldos.

Esse initial_tabcoins é sobre o que eu falei dos TabCoins promovidos, certo? Não tenho certeza sobre a forma exata que pensei quando rascunhei a descrição da issue, mas agora penso que isso não deve alterar o saldo que aparece para os usuários. Acho que os usuários deveriam ver apenas o saldo das qualificações. Talvez seja ainda melhor mostrar apenas a quantidade de qualificações positivas, mesmo que começando sempre em 1, como é o padrão dos conteúdos.

O TabCash consumido inicialmente, e que vai definir o destaque inicial da publicidade entre as demais publicidades, não poder ser confundido com o saldo de qualificações.

Então TabCoins promovidos e initial_tabcoins não são bons nomes para isso. Seria melhor usar um nome relacionado à TabCash, que é o que realmente será utilizado. Então esse destaque inicial seria dependente da quantidade de TabCash que foi "gasta" pelo autor de forma permanente ao criar a publicação, sem contar a parte que pode ser consumida com as qualificações (e futuramente com as visualizações). E isso vai na tabela de balanço de TabCash dos anúncios.

Uma simplificação que pode fazer sentido na versão inicial, é não separar o que é consumido de forma definitiva e o que poderia ser resgatado. Deixa o consumo de TabCash ao criar a publicidade como sendo permanente, e esse valor contribui ao mesmo tempo em qual é o posicionamento inicial (pois ainda não há qualificações), e quantas qualificações o anúncio poderá receber.

Será que quem vota em anúncios deveria ganhar TabCash? Para incentivar os votos em anúncios, acho que será preciso dar TabCash. Nesse caso, o custo mínimo em TabCash para o autor do anúncio tem que ser maior do que 1 TabCash por voto recebido.

Eu sugeri que os votos em publicações patrocinadas continuem consumindo TabCoins de quem votou. Pelo o que me lembro, ninguém concordou nem discordou. Se essa sugestão for aceita, então será criado um debit em content_tabcoin_operations como já é feito em "votos normais" hoje.

Continuo achando que votos em anúncios não devem consumir TabCoins, pois isso restringe menos os usuários que podem votar, e não compete com as qualificações dos conteúdos. É importante incentivar mais os votos em anúncios, pois enquanto não estivermos computando as visualizações, o alcance será medido/cobrado (TabCash) pelas qualificações.

Acho que será normal alguns tipos de anúncios receberem mais votos negativos, e podemos usar isso na classificação deles, diminuindo o alcance dos mais negativados, mas sem retirar totalmente do ar, e sim fazer com que o investimento para sua exibição seja maior.

E isso dos votos negativos é o que mais me faz pensar que talvez seja interessante mostrar apenas os votos positivos dos anúncios.

Acho que é consenso que devemos limitar a um voto por usuário, e tudo isso facilita armazenar os votos já que podemos usar uma CONSTRAINT UNIQUE composta pelo id do anúncio e do usuário que votou. Isso faz a modelagem dos votos dos anúncios ficar ainda mais diferente dos conteúdos, mas deve ser bem diferente mesmo.

Entretanto, do lado do autor da publicação, ao invés de ganhar TabCash, perderá.

Dá a impressão que você está dizendo que hoje, nos conteúdos "normais", o autor ganha TabCash ao receber votos positivos, mas, por enquanto, o autor nunca ganha TabCash. Quem ganha Tabcash é quem vota nos conteúdos.

A nova funcionalidade permite usar TabCash, que será consumido em certa quantidade no momento de criar/editar um anúncio. O autor de uma publicidade poderá "ganhar" TabCash se implementarmos um resgate do que não foi consumido pelo anúncio, mas isso pode até ficar para outro momento.

Se formos seguir o padrão de content_tabcoin_operations, então podemos criar uma coluna balance_type na tabela user_tabcash_operations com os tipos credit e debit. Após a migração, todos os valores existentes hoje seriam do tipo credit.

Será que você quis dizer sponsored_tabcash_operations? Não consegui enxergar a necessidade da coluna balance_type na tabela user_tabcash_operations.

Ao criar uma publicação patrocinada, o autor também perde TabCash,

Consumir e perder não são sinônimos. Melhor usar a palavra "perder" apenas em casos de "erros" ou "punições". A princípio, o autor do anúncio apenas "consome" seu TabCash. É claro que ele estará "perdendo" TabCash se não estiver consumindo de forma inteligente, mas isso deveria ser a excessão, não a regra.

e acredito que podemos seguir o mesmo raciocínio do parágrafo anterior.

Pelo jeito você falava mesmo da tabela user_tabcash_operations, então não ficou clara qual seria a necessidade de balance_type. Não vejo necessidade de alterar a tabela atual.

Por fim, temos o saldo de TabCoins da publicação patrocinada. O comportamento é muito parecido com o de contents, com os valores initial, credit e debit, mas a publicação patrocinada está na tabela sponsored_posts, e não contents, e recentemente fizemos uma separação de balance_operations para três tabelas diferentes, cada uma sobre um tipo de saldo específico. Dito isso, me parece ser necessário criar uma tabela sponsored_post_tabcoin_operations.

Então aqui teríamos:

  • user_tabcash_operations: Nova coluna balance_type

Ainda não entendi qual é a necessidade da nova coluna.

  • sponsored_post_tabcoin_operations: Nova tabela, igual a content_tabcoin_operations.

Não acho que seria igual, mas apenas parecida.


Massa @Rafatcb, pensar sobre o assunto para fazer os comentários acima me deu uma clareza bem maior sobre como podemos chegar na primeira versão.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 20, 2024

Por que mudar o padrão de contents para posts? Não acha melhor sponsored_contents?

Mencionei o posts por ser algo específico de "conteúdos raiz", e não qualquer conteúdo (e pensando em conteúdos raiz ao invés de publicação, faria mais sentido sponsored_root_contents, que é bem verboso). Podemos seguir com sponsored_contents sem problemas.

O que você pensa como justificativa para o link ser obrigatório? Talvez fizesse sentido se fosse proibido colocar links no corpo do anúncio, mas não sei se nesse momento precisamos nos preocupar com isso.

Me parece estranho a pessoa criar um anúncio sem o CTA (call to action). Pensando em algumas situações que podem ocorrer (e que envolvem ao menos um link): divulgar um projeto, site, produto ou serviço, portfólio, vaga de emprego, perfil de rede social, blog... Você pensou em algum cenário de anúncio sem link?

O que pensei agora é realizar uma "pesquisa de mercado" ou algo do tipo pelos comentários, e o motivo de fazer isso num anúncio ao invés de numa publicação normal seria a possibilidade de ter um impulsionamento inicial. Pode fazer sentido permitir isso.

Melhor deixar isso para a tabela com o balanço de TabCash dos anúncios. Daí, para definir os anúncios que serão mostrados, não será preciso consultar o saldo do usuário, mas apenas do anúncio, assim como as qualificações também só precisarão movimentar o saldo dos anúncios.

Na publicação/edição, o autor vai reservar certa quantidade de Tabcash que poderá ser consumida, e isso entra no balanço do anúncio. O autor poderá editar o anúncio para disponibilizar mais TabCash, e até poderia retirar o anúncio do ar e resgatar o saldo remanescente, uma possibilidade que não precisa existir na primeira versão, se isso complicar algo.

Hm, não havia pensado numa tabela de saldo de TabCash dos anúncios. Você pensou nela como tendo esse saldo inicial investido pelo autor, e depois cada tipo de interação seria como um débito nessa tabela? Parece uma boa forma de lidar com isso, melhor do que retirar aos poucos do autor. No fim do tempo limite do anúncio, podemos reembolsar o autor se houver TabCash não utilizado.

deactivate_at seria equivalente à deleted_at da tabela contents, e a publish_at seria equivalente à published_at

Eu não havia sugerido uma publish_at 😅 , não pensei na possibilidade de "agendar" um anúncio numa primeira versão, mas entendi seu comentário.

O saldo insuficiente também vai impedir a exibição do anúncio mesmo que ainda esteja dentro da faixa de tempo entre publish_at e deactivate_at.

Sim, mas não teremos em sponsored_contents o horário exato que o anúncio foi desativado. Faz sentido manter o deactivated_at como um dado a mais para o autor? Possibilitaria um raciocínio como "Criei um anúncio com X TabCash esperando que fosse durar N dias, mas durou M", ou mesmo uma verificação sobre qual foi a duração de cada anúncio que ele criou.

Mesmo que optemos por não ter o deactivated_at agora e optemos por criar ele em outro momento, esse dado poderia ser "calculado" com base na data do último saldo de TabCash que a publicação patrocinada "gastou", mas pensei ser uma informação útil de já armazenar no sponsored_contents.

Esse initial_tabcoins é sobre o que eu falei dos TabCoins promovidos, certo?

Sim, eu havia interpretado dessa forma.

Não tenho certeza sobre a forma exata que pensei quando rascunhei a descrição da issue, mas agora penso que isso não deve alterar o saldo que aparece para os usuários. Acho que os usuários deveriam ver apenas o saldo das qualificações. Talvez seja ainda melhor mostrar apenas a quantidade de qualificações positivas, mesmo que começando sempre em 1, como é o padrão dos conteúdos.

O TabCash consumido inicialmente, e que vai definir o destaque inicial da publicidade entre as demais publicidades, não poder ser confundido com o saldo de qualificações.

Então, vamos supor que o autor impulsione com 10 TabCash. Para facilitar o entendimento aqui, vamos dizer que 1 TabCash equivale a 1 TabCoin (na hora da implementação, muito provavelmente será diferente).

  • Autor investiu 10 TabCash.
  • A publicação exibe 1 TabCoin, mas está numa posição do rank como se tivesse 10 TabCoins.
  • Alguém votou positivamente, a publicação exibe 2 TabCoins, mas está numa posição do rank como se tivesse 11 TabCoins.
  • Alguém votou negativamente, a publicação exibe 2 TabCoins, e volta para a posição do rank como se tivesse 10 TabCoins.

É assim que você pensou? E no hover, exibiria que tipo de detalhes sobre os votos? +1 | -1 ou também exibiria a quantidade de TabCash de impulsionamento (no exemplo acima, 10)?

Acredito que podemos experimentar não contar os negativos no somatório. Outra opção que também podemos experimentar é não exibir o somatório de TabCoins que a publicação tem, e nesse cenário não sei se exibiríamos os dados no hover ou apenas usaríamos para calcular a posição no rank. Um exemplo mais ou menos assim é o Hacker News:

Seis publicações no Hacker News, uma não é possível votar, e não exibe a quantidade de votos

A publicação 10 não possui votos e nem a seta para votar porque é um anúncio. No nosso caso, permitiríamos votar.

Um ponto que considero positivo em esconder os votos é evitar a manada que ocorre de vez em quando, quando um conteúdo tem muitos votos positivos ou negativos, e acaba acumulando mais simplesmente por já ter muitos. Vejo isso com mais frequência em conteúdos negativados.

Será que quem vota em anúncios deveria ganhar TabCash?
...
Continuo achando que votos em anúncios não devem consumir TabCoins, pois isso restringe menos os usuários que podem votar, e não compete com as qualificações dos conteúdos. É importante incentivar mais os votos em anúncios, pois enquanto não estivermos computando as visualizações, o alcance será medido/cobrado (TabCash) pelas qualificações.

Enxergo dois problemas em dar TabCash e não cobrar TabCoins:

  1. Isso incentivará o usuário a votar em todos os anúncios, mesmo sem prestar atenção, apenas para ganhar 1 TabCash.
  2. Isso pode desequilibrar o sistema, de forma que alguém que nunca fez uma publicação consiga acumular TabCash até conseguir fazer uma publicação patrocinada.

Acho positivo limitar a um voto por usuário, mas continuamos com os problemas acima. Lembrando o issue #352, o fluxo completo imaginado na época era:

  1. Você gera TabCoins através de conteúdos com valor concreto.
  2. Depois gasta essas TabCoins qualificando outros conteúdos, e com isso gerando TabCash.
  3. Depois gasta esses TabCash em anúncios (e no futuro outras coisas, como features, ou qualquer outra coisa massa que conseguirmos inventar).

Se formos deixar sem custo de TabCoins para votar, acredito que a pessoa deva ter algum tipo de reputação (digamos, uma quantidade mínima de TabCoins ou TabCash), mas talvez isso limite ainda mais a quantidade de pessoas que podem interagir do que se mantivéssemos a cobrança de 2 TabCoins. Podemos considerar cobrar 1 TabCoin. O que acha de tudo o que mencionei aqui? Te fez pensar em algo diferente?

Entretanto, do lado do autor da publicação, ao invés de ganhar TabCash, perderá.

Dá a impressão que você está dizendo que hoje, nos conteúdos "normais", o autor ganha TabCash ao receber votos positivos, mas, por enquanto, o autor nunca ganha TabCash. Quem ganha Tabcash é quem vota nos conteúdos.

Me confundi no texto. Quis dizer que ao invés de ganhar TabCoin, perderia TabCash, mas conforme concordei com você neste comentário, o TabCash já estaria reservado para isso e essa reserva seria consumida conforme a publicação patrocinada recebesse votos, com uma possível implementação de devolver a reserva não utilizada (mesmo que não tenhamos o reembolso num primeiro momento, acho importante termos em algum momento).

Se formos seguir o padrão de content_tabcoin_operations, então podemos criar uma coluna balance_type na tabela user_tabcash_operations com os tipos credit e debit. Após a migração, todos os valores existentes hoje seriam do tipo credit.

Será que você quis dizer sponsored_tabcash_operations? Não consegui enxergar a necessidade da coluna balance_type na tabela user_tabcash_operations.

Não, quis dizer user_tabcash_operations mesmo. Enxergo duas opções:

  • Com a coluna balance_type, criar credit (quando o usuário vota e ganha TabCash) e debit (quando ele cria uma publicação patrocinada), com amount respectivamente positivo e negativo.
  • Sem a coluna balance_type, apenas definir o amount com o valor positivo e negativo.

A tabela content_tabcoin_operations funciona da primeira forma (mas também tem o balance_type initial). Não sei se temos algum benefício em criar o balance_type em user_tabcash_operations, mencionei apenas como possibilidade de seguir o padrão de content_tabcoin_operations.

sponsored_post_tabcoin_operations: Nova tabela, igual a content_tabcoin_operations.

Não acho que seria igual, mas apenas parecida.

Com base no seu comentário, fiquei em dúvida em como isso seria armazenado, visto que teremos tanto o TabCash que impulsionou a publicação patrocinada quanto os TabCoins de votos recebidos. Seriam duas tabelas, sponsored_content_tabcoin_operations e sponsored_content_tabcash_operations?

@aprendendofelipe
Copy link
Collaborator Author

Comentários

Mencionei o posts por ser algo específico de "conteúdos raiz", e não qualquer conteúdo

Falando nisso, a princípio penso que as publicações patrocinadas também receberão comentários. Ou será que é melhor não?

Chegou a pensar em armazenar os comentários das patrocinadas na tabela de conteúdos normais? Isso pode exigir alguma mudança na tabela.

Link obrigatório/opcional

O que você pensa como justificativa para o link ser obrigatório? Talvez fizesse sentido se fosse proibido colocar links no corpo do anúncio, mas não sei se nesse momento precisamos nos preocupar com isso.

Me parece estranho a pessoa criar um anúncio sem o CTA (call to action). Pensando em algumas situações que podem ocorrer (e que envolvem ao menos um link): divulgar um projeto, site, produto ou serviço, portfólio, vaga de emprego, perfil de rede social, blog... Você pensou em algum cenário de anúncio sem link?

Não acho estranho, mas, assumindo que seja, por que não poderíamos deixar o usuário criar o anúncio sem o link se ele preferir assim?

O que pensei agora é realizar uma "pesquisa de mercado" ou algo do tipo pelos comentários, e o motivo de fazer isso num anúncio ao invés de numa publicação normal seria a possibilidade de ter um impulsionamento inicial. Pode fazer sentido permitir isso.

A pesquisa seria para responder qual dúvida?

Tabelas de saldos

Hm, não havia pensado numa tabela de saldo de TabCash dos anúncios. Você pensou nela como tendo esse saldo inicial investido pelo autor, e depois cada tipo de interação seria como um débito nessa tabela? Parece uma boa forma de lidar com isso, melhor do que retirar aos poucos do autor.

Eu acho que o caminho é por aí.

A tabela content_tabcoin_operations funciona da primeira forma (mas também tem o balance_type initial). Não sei se temos algum benefício em criar o balance_type em user_tabcash_operations, mencionei apenas como possibilidade de seguir o padrão de content_tabcoin_operations.

O initial é uma razão para armazenarmos balance_type em content_tabcoin_operations. A outra razão é para poder anular um voto sem precisar criar um novo voto contrário, ou seja, +1 credit e -1 credit = 0 de saldo e considerado nenhum voto, pois 1 foi desfeito, o que é diferente de +1 credit e -1 debit = 0 de saldo, mas são 2 votos contrários.

Com base no seu comentário, fiquei em dúvida em como isso seria armazenado, visto que teremos tanto o TabCash que impulsionou a publicação patrocinada quanto os TabCoins de votos recebidos. Seriam duas tabelas, sponsored_content_tabcoin_operations e sponsored_content_tabcash_operations?

Dá para criar duas tabelas, ou uma só, tem vantagens e desvantagens em cada caso.

O saldo insuficiente também vai impedir a exibição do anúncio mesmo que ainda esteja dentro da faixa de tempo entre publish_at e deactivate_at.

Sim, mas não teremos em sponsored_contents o horário exato que o anúncio foi desativado. Faz sentido manter o deactivated_at como um dado a mais para o autor? Possibilitaria um raciocínio como "Criei um anúncio com X TabCash esperando que fosse durar N dias, mas durou M", ou mesmo uma verificação sobre qual foi a duração de cada anúncio que ele criou.

Mesmo que optemos por não ter o deactivated_at agora e optemos por criar ele em outro momento, esse dado poderia ser "calculado" com base na data do último saldo de TabCash que a publicação patrocinada "gastou", mas pensei ser uma informação útil de já armazenar no sponsored_contents.

Acho mais útil o usuário poder consultar um histórico do anúncio, como um extrato das qualificações e do TabCash. Mas não precisa disso no primeiro momento.

Mecânica

Então, vamos supor que o autor impulsione com 10 TabCash. Para facilitar o entendimento aqui, vamos dizer que 1 TabCash equivale a 1 TabCoin (na hora da implementação, muito provavelmente será diferente).

  • Autor investiu 10 TabCash.
  • A publicação exibe 1 TabCoin, mas está numa posição do rank como se tivesse 10 TabCoins.
  • Alguém votou positivamente, a publicação exibe 2 TabCoins, mas está numa posição do rank como se tivesse 11 TabCoins.
  • Alguém votou negativamente, a publicação exibe 2 TabCoins, e volta para a posição do rank como se tivesse 10 TabCoins.

É assim que você pensou?

É por aí.

E no hover, exibiria que tipo de detalhes sobre os votos? +1 | -1 ou também exibiria a quantidade de TabCash de impulsionamento (no exemplo acima, 10)?

Para as publicidades, acho melhor não mostrar a quantidade de votos negativos. Uma opção seria mostrar apenas a quantidade de votos positivos e o saldo de TabCash. O pior caso para uma publicidade seria chegar em 0 TabCash (quando sairá do ar) sem ter saído de 1 Tabcoin, ou seja, ela só teve votos negativos.

Na situação ideal de competição das publicidades, em que haja algumas mais bem recebidas do que outras, esse pior caso nunca deveria ser atingido, já que o alcance seria bem reduzido antes de chegar nesse poço, dando a oportunidade do autor rever sua estratégia.

Será que quem vota em anúncios deveria ganhar TabCash?
...
Continuo achando que votos em anúncios não devem consumir TabCoins, pois isso restringe menos os usuários que podem votar, e não compete com as qualificações dos conteúdos. É importante incentivar mais os votos em anúncios, pois enquanto não estivermos computando as visualizações, o alcance será medido/cobrado (TabCash) pelas qualificações.

Enxergo dois problemas em dar TabCash e não cobrar TabCoins:

  1. Isso incentivará o usuário a votar em todos os anúncios, mesmo sem prestar atenção, apenas para ganhar 1 TabCash.
  2. Isso pode desequilibrar o sistema, de forma que alguém que nunca fez uma publicação consiga acumular TabCash até conseguir fazer uma publicação patrocinada.

Acho que precisamos exigir algum saldo de TabCoins (talvez 2) para poder qualificar as publicidades, mesmo que não consuma o saldo. Mas também serão necessárias outras medidas contra abuso, que só saberemos ao certo quando eles começarem a ocorrer.

Acho positivo limitar a um voto por usuário, mas continuamos com os problemas acima. Lembrando o issue #352, o fluxo completo imaginado na época era:

  1. Você gera TabCoins através de conteúdos com valor concreto.
  2. Depois gasta essas TabCoins qualificando outros conteúdos, e com isso gerando TabCash.
  3. Depois gasta esses TabCash em anúncios (e no futuro outras coisas, como features, ou qualquer outra coisa massa que conseguirmos inventar).

O fluxo pensado incialmente é uma idealização, é a base que estamos evoluindo para chegar em algo real e viável. Quanto mais evoluirmos, mais coisas diferentes teremos que lidar. Não aparecia na ideia original a necessidade de incentivar a qualificação de publicidades, assim como não era visível que precisamos de uma quantidade muito maior de qualificações do que de criação de conteúdos.

Se formos deixar sem custo de TabCoins para votar, acredito que a pessoa deva ter algum tipo de reputação (digamos, uma quantidade mínima de TabCoins ou TabCash), mas talvez isso limite ainda mais a quantidade de pessoas que podem interagir do que se mantivéssemos a cobrança de 2 TabCoins. Podemos considerar cobrar 1 TabCoin. O que acha de tudo o que mencionei aqui? Te fez pensar em algo diferente?

Quanto mais ideias para estudarmos, melhor.

Uma outra ideia é o usuário votante ganhar 1 TabCoin (e não TabCash), assim ele ainda precisará participar pelo menos da qualificação dos demais conteúdos antes de ganhar TabCash.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 23, 2024

Chegou a pensar em armazenar os comentários das patrocinadas na tabela de conteúdos normais? Isso pode exigir alguma mudança na tabela.

Não havia pensado nesse ponto. Creio que as publicações patrocinadas devam receber comentários sim. Uma possível diferença desses comentários para os realizados em "publicações normais" é que talvez eles não devessem entrar no cálculo de "prestígio" do usuário, já que ficarão visíveis por menos tempo. Faz sentido? Se formos considerar no cálculo de prestígio, suspeito que não teríamos problemas em armazenar na tabela contents.

A pesquisa seria para responder qual dúvida?

Foi só um exemplo de situação que o próprio autor gostaria de investir o TabCash sem colocar um link numa publicação patrocinada. Podemos deixar o link opcional.

Acho que precisamos exigir algum saldo de TabCoins (talvez 2) para poder qualificar as publicidades, mesmo que não consuma o saldo. Mas também serão necessárias outras medidas contra abuso, que só saberemos ao certo quando eles começarem a ocorrer.

Sim, podemos começar de um jeito simples e acompanhar as interações.

@aprendendofelipe
Copy link
Collaborator Author

Chegou a pensar em armazenar os comentários das patrocinadas na tabela de conteúdos normais? Isso pode exigir alguma mudança na tabela.

Não havia pensado nesse ponto. Creio que as publicações patrocinadas devam receber comentários sim. Uma possível diferença desses comentários para os realizados em "publicações normais" é que talvez eles não devessem entrar no cálculo de "prestígio" do usuário, já que ficarão visíveis por menos tempo. Faz sentido? Se formos considerar no cálculo de prestígio, suspeito que não teríamos problemas em armazenar na tabela contents.

Independente desses comentários contarem ou não para o "prestígio", não é só isso que exigiria adaptar a tabela contents, mas também o fato de que parent_id e path podem passar a conter ids que nem sempre serão de outros itens de contens. Isso pode tornar mais complexas as consultas das diferentes listas de conteúdos.

Acho que vai compensar criar uma tabela só para os comentários das publicidades. Uma vantagem de deixar para criar a tabela separada é que dá para isolar bem a implementação dos comentários nas publicidades, assim como as publicidades em si já estarão bem isoladas dos conteúdos normais.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 27, 2024

@aprendendofelipe as publicações patrocinadas aparecerão entre as normais, então acredito que o GET /api/v1/contents deva retornar elas em todas as estratégias (ou seja, mesmo ao listar por "Recentes" e em GET /api/v1/contents/rss). Concorda?

Continuando o raciocínio, os seguintes endpoints devem também funcionar para uma publicação patrocinada, visando facilitar a compatibilidade dos aplicativos e interfaces existentes hoje?

  • GET /api/v1/contents/[username]/[slug]
  • PATCH /api/v1/contents/[username]/[slug]
  • POST /api/v1/contents/[username]/[slug]: apenas para criação de comentários (falo sobre criação da publicação em outro parágrafo). Também tem a ver com a compatibilidade com UIs existentes, e o dado de um comentário numa publicação patrocinada é o mesmo de uma publicação normal (o corpo).
  • GET /api/v1/contents/[username]/[slug]/children
  • GET /api/v1/contents/[username]/[slug]/parent
  • GET /api/v1/contents/[username]/[slug]/root
  • GET /api/v1/contents/[username]/[slug]/thumbnail
  • POST /api/v1/contents/[username]/[slug]/tabcoins

Ou acredita que essas funcionalidades devem funcionar para publicações patrocinadas apenas em /api/v1/sponsored_contents/...? Minha opinião é de que essa compatibilidade é um ponto positivo, mesmo precisando de um tratamento no lado do servidor para verificar se o conteúdo [username]/[slug] é uma publicação patrocinada ou uma publicação comum.

Como a publicação patrocinada tem alguns dados específicos que podem ser alterados, como por exemplo até quando ela será exibida, podemos ter a rota PATCH /api/v1/sponsored_contents/[username]/[slug] mesmo se aceitarmos atualizações de título, corpo e fonte pelo PATCH /api/v1/contents/[username]/[slug]. Edit: se formos criar apenas os status active e deactivated como mencionei em outro comentário, podemos tratar a atualização para deleted, ou acha melhor criar um terceiro tipo para deleted? E o published é motivo de preocupação aqui?

No caso de criação da publicação patrocinada, imagino que a rota mais adequada seja POST /api/v1/sponsored_contents por causa dos campos necessários que não existem numa publicação normal, por isso não mencionei na lista acima.


Edit: Existe algum motivo para ter originator_type nas tabelas de saldo? Estava avaliando para ver o que a tabela sponsored_content_tabcoin_operations precisará, mas me parece que o originator_type sempre é event (a não ser em algumas funções de teste, que fica orchestrator).

Edit 2: Me parece que, mesmo criando uma tabela para os comentários de publicações patrocinadas, podemos usar a tabela content_tabcoin_operations para armazenar os saldos deles. Faz sentido?

@aprendendofelipe
Copy link
Collaborator Author

@aprendendofelipe as publicações patrocinadas aparecerão entre as normais, então acredito que o GET /api/v1/contents deva retornar elas em todas as estratégias (ou seja, mesmo ao listar por "Recentes" e em GET /api/v1/contents/rss). Concorda?

Quando rascunhei a ideia, pensava em devolver as patrocinadas no meio dos conteúdos "normais" também pela API. Pensei isso justamente para dificultar o bloqueio das promovidas.

Agora que a ideia tomou o caminho de as promovidas serem um pouco diferentes das normais (CTA ao invés de fonte), e por querer deixar claro que são promovidas, isso vai exigir adaptar as interfaces dos Apps, então não deve ser interessante retornar elas no mesmo endpoint (pelo menos não como default).

Por isso, para as primeiras versões, eu não acho necessário se preocupar em como devolver as patrocinadas em forma de lista pela API (e nem no feed RSS). Elas podem começar aparecendo apenas na home (relevantes), e depois vemos como posicionar nas outras interfaces.

Aproveitando que meu usuário foi marcado... Para não afastar ninguém do debate, vamos tentar evitar marcar usuários específicos nos pedidos de ideias e opiniões. 🤝

Continuando o raciocínio, os seguintes endpoints devem também funcionar para uma publicação patrocinada, visando facilitar a compatibilidade dos aplicativos e interfaces existentes hoje?

  • GET /api/v1/contents/[username]/[slug]
  • PATCH /api/v1/contents/[username]/[slug]
  • POST /api/v1/contents/[username]/[slug]: apenas para criação de comentários (falo sobre criação da publicação em outro parágrafo). Também tem a ver com a compatibilidade com UIs existentes, e o dado de um comentário numa publicação patrocinada é o mesmo de uma publicação normal (o corpo).

Quis dizer POST /api/v1/contents, certo? Ou está pensando em adicionar essa forma de criar comentários?

  • GET /api/v1/contents/[username]/[slug]/children
  • GET /api/v1/contents/[username]/[slug]/parent
  • GET /api/v1/contents/[username]/[slug]/root
  • GET /api/v1/contents/[username]/[slug]/thumbnail
  • POST /api/v1/contents/[username]/[slug]/tabcoins

Ou acredita que essas funcionalidades devem funcionar para publicações patrocinadas apenas em /api/v1/sponsored_contents/...? Minha opinião é de que essa compatibilidade é um ponto positivo, mesmo precisando de um tratamento no lado do servidor para verificar se o conteúdo [username]/[slug] é uma publicação patrocinada ou uma publicação comum.

Vai facilitar bastante se pudermos usar os mesmos endpoints, mas um problema é ter de fazer verificações extras em todos os GETs, mas também nos POSTs/PATCHs, já que não poderíamos permitir a criação de uma publicação normal e outra patrocinada do mesmo usuário/slug. Hoje usamos o erro UNIQUE_CONSTRAINT_VIOLATION do banco (UNIQUE ("owner_id", "slug")), mas isso não seria mais suficiente, já que estariam em tabelas diferentes.

Será que então compensa deixar os conteúdos patrocinados na mesma tabela? Talvez criar um status sponsored e criar outra tabela com os demais campos específicos dos patrocinados?

Existe algum motivo para ter originator_type nas tabelas de saldo? Estava avaliando para ver o que a tabela sponsored_content_tabcoin_operations precisará, mas me parece que o originator_type sempre é event (a não ser em algumas funções de teste, que fica orchestrator).

Não sei se essa coluna foi criada pensando em algo que acabou não sendo implementado. Não parece necessária nem para os testes.

Me parece que, mesmo criando uma tabela para os comentários de publicações patrocinadas, podemos usar a tabela content_tabcoin_operations para armazenar os saldos deles. Faz sentido?

Dependendo até podemos, mas não sei se faz sentido.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 29, 2024

Para não afastar ninguém do debate, vamos tentar evitar marcar usuários específicos nos pedidos de ideias e opiniões. 🤝

Certo.

Agora que a ideia tomou o caminho de as promovidas serem um pouco diferentes das normais (CTA ao invés de fonte), e por querer deixar claro que são promovidas, isso vai exigir adaptar as interfaces dos Apps, então não deve ser interessante retornar elas no mesmo endpoint (pelo menos não como default).

Entendo que o ideal é ressaltar quando a publicação é patrocinada e quando não é, mas tenho a impressão que não retornar as publicações patrocinadas por padrão, juntos dos conteúdos, faz com que os consumidores das APIs precisem "aprender" que "devem exibir as publicações patrocinadas".

Quis dizer POST /api/v1/contents, certo? Ou está pensando em adicionar essa forma de criar comentários?

Sim, acabei me confundindo enquanto editava a lista.

(...) já que não poderíamos permitir a criação de uma publicação normal e outra patrocinada do mesmo usuário/slug (...)

Será que então compensa deixar os conteúdos patrocinados na mesma tabela? Talvez criar um status sponsored e criar outra tabela com os demais campos específicos dos patrocinados?

Pensei sobre isso também. Uma solução que encontrei para continuar mantendo em duas tabelas separadas é ter uma VIEW que consolida ambas, algo similar ao proposto nessa resposta do Stack Overflow. Não fui mais a fundo para ver o quão viável isso é ou se faz sentido no nosso caso.

Acredito que ter um status sponsored pode ser uma boa alternativa, e permitiria manter os comentários de publicações patrocinadas na mesma tabela (contents), certo?

Me parece que, mesmo criando uma tabela para os comentários de publicações patrocinadas, podemos usar a tabela content_tabcoin_operations para armazenar os saldos deles. Faz sentido?

Dependendo até podemos, mas não sei se faz sentido.

Mas como você pensa que faz sentido? Manter três tabelas de "tabcoins" separadas (conteúdos normais, publicações patrocinadas e comentários em publicações patrocinadas) ou duas, uma para os conteúdos normais e outra para as publicações patrocinadas e seus comentários? Ou ainda uma outra opção que não pensei?

E, se os comentários de publicações patrocinadas ficarem em contents com status que já temos hoje, complicará identificar qual função deve ser chamada para calcular o saldo de TabCoins e os créditos e débitos.

Na minha cabeça, os comentários de publicações patrocinadas me parecem "a mesma coisa" de comentários de publicações comuns. Não sei se você pensou em comportamentos diferentes.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Jun 9, 2024

Criei o PR #1719 com a implementação da API. Algumas partes da implementação ficaram diferentes do que foi discutido, como o fato de eu não ter criado uma tabela para os comentários de publicações patrocinadas, já que do meu ponto de vista, não teria nada para armazenar lá ou dificultaria a implementação sem um benefício que eu tenha visualizado. De toda forma, com a implementação fica mais fácil de identificar os pontos a serem melhorados.

Quem quiser, pode revisar o PR, mesmo que parcialmente, visto que ele ficou grande.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
back Envolve modificações no backend front Envolve modificações no frontend novo recurso Nova funcionalidade/recurso
Projects
None yet
Development

No branches or pull requests

4 participants