Closed andyboli closed 3 years ago
Sugiro começarmos pela definição do module de suggestions: Acho que precisamos pensar em que tipo de interações os roles vão poder ter com uma suggestion né? O que um usuário vai poder fazer sobre um recurso que ele criou, e sobre recursos que outros criaram, e isso dependendo do cargo dele;
Acho que o de stats seria bem similar, porém só precisamos expor uma busca, já que a consolidação e quem vai salvar isso no banco provavelmente vai ser um microserviço (sim, um terceiro).
Sugiro começarmos pela definição do module de suggestions: Acho que precisamos pensar em que tipo de interações os roles vão poder ter com uma suggestion né? O que um usuário vai poder fazer sobre um recurso que ele criou, e sobre recursos que outros criaram, e isso dependendo do cargo dele;
Acho que o de stats seria bem similar, porém só precisamos expor uma busca, já que a consolidação e quem vai salvar isso no banco provavelmente vai ser um microserviço (sim, um terceiro).
Todas as roles vão poder criar, atualizar e deletar suas proprias sugestoes e ratear sugestoes suas e dos outros apenas uma vez(cada sugestao) em projetos publicos.
Todas as roles vão poder criar, atualizar e deletar suas proprias sugestoes e ratear sugestoes suas e dos outros apenas uma vez(cada sugestao) em projetos privados, desde que, essas roles tenham permissão no projeto.
Todas as roles, exceto collaborator, podem aprovar qualquer sugestão(Até sua propria??).
Todas as roles, exceto collaborator, podem deletar qualquer sugestão que julgue necessário, para evitar casos de brincadeiras e falsas traduções.
Todas as roles, exceto collaborator, podem aprovar qualquer sugestão(Até sua propria??).
Colaborator e viewer, bom não esquecer q depois vamos ter um role abaixo do colaborator (pra não fazero codigo != colab e o viewer acabar com permissão de aprovar..).
Acho que a própria pessoa (com exceção de colaborador pra baixo) pode sim aprovar sua própria sugestão.
E eu queria entender quais vão ser as principais diferenças entre um projeto público e privado (não só na parte de suggestions).
Galera, pensei um pouco na modelagem das novas entidades do Tradulab e cheguei nesta conclusão. Acho que Rate pode ser uma nova entidade, Rate esta para User e Suggestions assim como Role esta para User e Project. Como um usuário pode ter uma role em um projeto, um usuário pode ter uma avaliação em uma sugestão. Além do mais, tenho algunas motivos para acreditar que o approveProgress e o translateProgress devem serem calculados, em resolvers, a partir das entidades existes, ao invés de serem explicitamente expressos no banco de dados. Os progressos são calculados(o que já indica que é uma operação, não uma propriedade) considerando o total de files que existe, quantas phrases foram aprovadas (approvelProgress), quantos phrases tem suggestions (translateProgress). Esses processos podem ser feitos já com a entidade que temos, podemos implementar um resolver que entregue o approveProgress e o translateProgress para ser usado (atualizado) no momento de renderização. Se implementarmos uma nova entidade no banco, vamos ter fazer muitas consultas neste para atualizar a informação, sendo que o que queremos de fato é um cálculo a partir de outras entidades. approvelProgress : Files -> Phrases by Language -> approvedSuggestions / totalPhrases translateProgress: Files -> Phrases by Language -> suggestions / totalPhrases
Gostei desse seu esquema acho ficou muito bom!!! Agora em relação aos calculos, nesse jeito que vc ta falando pra fazer o calculo a gente precisaria fazer uma consulta no banco trazendo todas as frases e todas as sugestoes daquela frase para fazer o calculo neh e isso seria feito toda hora que a pessoa entrasse na aba de files acredito eu. Minha duvida é se a gente fizesse esse calculo no proprio banco de dados será que seria mais rapido, por ex fazendo uma funçao do proprio banco na hora que salvar uma sugestão, nesse caso, sempre q salvasse a sugestão ele faria essa conta e atualizaria os valores no banco. Qual seria a melhor abordagem eu não sei, teria que calcular qto tempo que demoraria pra isso.
@Wxhbr , então, ao meu ver (tem que ver a opinião do Uriell ou Rogério), calcular esses valores no momento em que eles forem solicitados me parece a maneira mais correta. Não vejo nenhum ganho salvando esse valor no banco de dados, ele teria que ser atualizado em outros processos como alterar um arquivo ou remover uma suggestion, o único benefício que teriamos é no momento de chamar este recurso (approvelProgess e translateProgress), chamariamos de uma forma mais direta, com uma única consulta, mas em decorrência dos outros processos que alterariam estes valores serem mais frequentes que a quantidades de vezes exibidas, creio que é melhor ele ser calculado toda vez que chamado do que atualizado sempre que uma operação o modificar (Como remover um file, remover uma suggestion, alterar a suggestions approved - vai ter só uma approved??). Dessa forma as operações ficam mais separadas também, estamos removendo um file, não removendo um file e alterando o seu approvelProgress. Agora estamos chamando o approvelProgess para renderizar na página, é nessa hora que ele tem que ser calculado, com base as entidades atuais no banco, dessa vez a forma como é chamado o recurso é mais complexa, além de termos que fazer mais consultas ao banco de dados para buscar as entidades consideradas no cálculo, mas compensa pelos fatores que citei no texto, fora que o que queremos é um resultado de um cálculo, não um valor intrínseco.
Eu acho que faz sentido o que vc falou sim, eu só não tenho muito conhecimento de banco de dados pra afirmar que seria melhor fazer do seu jeito. Na minha mente parece que ficaria mais otimizado dessa forma que vc falou de calcular somente qndo precisasse. Eu vou pesquisar um pouco sobre operacoes no banco de dados pra ver sobre isso aqui.
Eu dei uma pesquisada rapida aqui e acho melhor fazer sim da forma como vc propos, principalmente, pq a gente ta usando Mongo e não SQL como tava na minha mente kkkkkk. Pelo que eu li não é interessante fazer operações javascript dentro do MongoDB e ele não possui aqueles triggers/viwers e talz do SQL, então, realmente não teria sentido isso ser calculado dentro do banco de dados. Agora a questão é será realmente desnecessário ter esses campos dentro do banco de dados de approval progress e translate progress, nunca vai ser necessário que eles estejam no banco será?
Minha sugestão de salvar isso é por receio de uma operação cara como uma agregação ser repetida livremente toda vez que alguém acessa. Num projeto muito grande essa agregação pode ficar lenta, e ser realizada desnecessariamente quando o resultado final não mudou. Lembrem que a gente quer entregar um % de tradução e aprovação pra cada idioma distinto, somado a partir das N files disponiveis.
Pra exemplo, hoje o dashboard tem ~2000 phrases, e a gente nem migrou 20% do que o CRM tem pra lá.. Pensem que suggestions vão ter muito mais documentos do que phrases.
Depois que definirmos o modelo de suggestion e phrases, sugiro fazer um script que vai popular 10k de registros de frases e 7.5k de registros de suggestions (75% das phrases teriam tradução, as 2.5k restantes seriam incrementadas como sugestões "extra" de alguma frase já traduzida). Isso seria pra um idioma, e a partir daí a gente repete isso pra ~100 idiomas, totalizando 1M de documentos no banco que teriam que ser percorridos e agregados pra cada visita na tela.
E rodar algumas queries de agregação pra ver a performance. Se não me engano, seriam três counts no banco:
SELECT COUNT(DISTINCT id) total_phrases FROM phrases WHERE project_id = "____"
;SELECT language, COUNT(DISTINCT phrase_id) FROM suggestions WHERE project_id = "____" AND approved = TRUE GROUP BY language
;SELECT language, COUNT(DISTINCT phrase_id) FROM suggestions WHERE project_id = "____" GROUP BY language
Essas seriam as agregações que precisariamos fazer (eu escrevi SQL mas pq não sei de cabeça como fazer no MongoDB). Se quiserem eu posso fazer esse teste com vocês mas acho que não vale o esforço pra já se precaver dessa preocupação.
Eu gostei da sugestão de fazer o Rating como entidade separada. O que você acha disso, @UriellViana ? Considerando inclusive essas questões de consultas ao banco de dados, teria alguma diferença?
Sobre o Rating, eu acho que poderia ser feito isso mais tarde, a solução de array de ids como só "+1" é a mais rápida de fazer, consideramos que queremos uma primera versão logo.
O Model de Suggestion está pronto para o review. Pensei em continuar esse módulo, fazendo os resolvers, porém acho que não vai dar muito certo sem ter feito a parte de Phrase antes, porque toda suggestion referencia uma phrase. O que vocês acham?
@UriellViana então, você sugere que approvelProgess e TranslateProgess sejam propriedades da entidade File, certo? Você pode descrever pra mim quais seriam os processos que atualizariam estas informaçẽos em Files e qual seria a complexidade destas operações?. Como um exemplo vamos considerar o caso de uso de atualizar um File, neste modelo de dados, nesta operação seria necessário atualizar o valor de approvelProgress e translateProgress, as operações necessária para realizar esta atualização não exigiriam uma iteração para se achar o total de Files, o total de Pharses (lembrando que pharses podem ser deletadas), o total de Suggestions, da mesma forma? E em outros casos, como dar uma suggestion, não exigiria também um recálculo de translateProgress, ou seja, mais iteração, mais consulta. Fora que ambos os casos fica completamente implicito a atualização do translateProgress. Eu achei sua resposta foda, entendi super a complexidade da consulta, eu só ainda preciso de um esclarecimento maior, em nível de código, do outro lado da moeda. Talvez em meio este tanto de requisição tem como fazer o usuário enviar mais informação, logo exigiria menos consultas, mas ainda não consigo ver isso claramente.
@UriellViana mas o que achou da ideia do Rating, esta correta? Eu entendo que talvez levaria mais tempo, talvez para definir os resolvers, mas eu acho que compensa mais modelar esta entidade de uma vez, para uma primeira versão ter um banco de dados bem definido pode ser valioso para o futuro, não? mas isso se a ideia tiver coesa. Rate esta para User e Suggestions assim como Role esta para User e Project, isso é verdade?
você sugere que approvelProgess e TranslateProgess sejam propriedades da entidade File, certo?
não, já invalidamos essa idéia porque queremos ter os progressos por idioma, e só existe um file.. é a entidade stats que eu mencionei anteriormente.
como dar uma suggestion, não exigiria também um recálculo de translateProgress, ou seja, mais iteração, mais consulta
sim e não, não temos necessidade de atualizar "real time" os progressos de tradução e aprovação.. não dá pra fazer muito trabalho em curto espaço de tempo, então algo como uma atualização a cada hora já serviria..
quais seriam os processos que atualizariam estas informaçẽos
eu imagino que um microserviço seria mais adequado pra esse tipo de consolidação
Eu gostei da sugestão de entidade Rating, mas ainda acho que não é necessário no momento
compensa mais modelar esta entidade de uma vez, para uma primeira versão ter um banco de dados bem definido pode ser valioso para o futuro, não?
não acho que tem necessidade de ser modelado no banco nesse momento, o esforço é baixo pra introduzir isso mais tarde
Rate esta para User e Suggestions assim como Role esta para User e Project, isso é verdade?
o relacionamento está certo
Modules Backend Phrases { Processamento de um arquivo (json) _id do arquivo key content } Suggestions { _id phrase language user text score: [_id user] } Create Suggestion Rate Suggestion Delete Suggestions (Role ? ) Stats { _id file language translation progress approvel progress }