gems-uff / sapos

SAPOS main goal is to ease the management of information related to graduate programs such as enrollments, courses, advisement, scholarships, requirements, among others.
http://gems-uff.github.io/sapos/
MIT License
29 stars 14 forks source link

Informações inconsistentes no histórico #448

Open leomurta opened 7 months ago

leomurta commented 7 months ago

Ao gerar o histórico para um aluno que se formou há mais tempo, algumas informações podem ficar inconsistentes. Por exemplo, se o aluno se formou quando o programa era nível 5 e agora o programa é nível 6, a informação do histórico virá como nível 6, apesar de não ser a realidade de quando houve a formatura do aluno. O mesmo pode acontecer com a instituição dos membros da banca. Se algum membro muda de instituição e nós atualizamos essa informação no Sapos, quando tirarmos o histórico de um aluno antigo, virá o membro da banca com instituição nova e não a instituição da época da defesa.

Para solucionar isso, o ideal é guardarmos os valores históricos dessas informações. Ou seja, ao invés de guardarmos somente o nível, guardaríamos a validade de cada nível, com data de início e fim. O mesmo para os dados de instituição dos membros da banca.

IgorMonardez commented 2 months ago

Professor, os modelos instituição e professor, seria então uma relação n-m pelo que foi descrito, teria então que ser feita algumas alterações no banco para conseguir acomodar tais mudanças de norma. Assim, dessa forma o modelo ficaria dessa maneira:

Instituição(idInstituicao, ...) Professor(idProfessor,...) InstituicaoProfessor(idInstituicao, idProfessor, dataInicio, dataFim)

JoaoFelipe commented 2 months ago

Acho que uma solução melhor pode ser* usar o histórico que já temos com o papertrail na hora de gerar o histórico.

Por exemplo para pegar a instituição que um professor tinha há 1 semana, dá para usar o seguinte código:

old_version = professor.versions.where("created_at < ?", 1.week.ago).order("created_at").last
old_model = old_version.reify
old_model.institution

Fiz o teste aqui agora e precisa adicionar a seguinte linha no application.rb:

config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]

* Talvez buscar no papertrail seja menos eficiente do que ter uma tabela própria para esse histórico (e menos confiável - até então tratamos o log do papertrail como algo secundário e nem migramos para homologação se não me engano). Então não tenho certeza do que realmente é melhor. A vantagem de usar o papertrail, é que em teoria temos boa parte do histórico de mudanças (desde que a gem foi adotada) e conseguimos desde já os valores necessários pra gerar os relatórios.

braganholo commented 2 months ago

Não daria para criar as tabelas e fazer um migration que puxa os dados do papertrail pra popular as mudanças passadas nessas tabelas, e a partir da entrada em produção, usar apenas as tabelas?

Vanessa

Em sex., 17 de mai. de 2024 às 16:34, João Felipe N. Pimentel < @.***> escreveu:

Acho que uma solução melhor pode ser usar o histórico que já temos* com o papertrail na hora de gerar o histórico.

Por exemplo para pegar a instituição que um professor tinha há 1 semana, dá para usar o seguinte código:

old_version = professor.versions.where("created_at < ?", 1.week.ago).order("created_at").last old_model = old_version.reify old_model.institution

Fiz o teste aqui agora e precisa adicionar a seguinte linha no application.rb:

config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]

  • Talvez buscar no papertrail seja menos eficiente do que ter uma tabela própria para esse histórico (e menos confiável - até então tratamos o log do papertrail como algo secundário e nem migramos para homologação se não me engano). Então não tenho certeza do que realmente é melhor. A vantagem de usar o papertrail, é que em teoria temos boa parte do histórico de mudanças (desde que a gem foi adotada) e conseguimos desde já os valores necessários pra gerar os relatórios.

— Reply to this email directly, view it on GitHub https://github.com/gems-uff/sapos/issues/448#issuecomment-2118254634, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALM3XT4LKYXJGAJIBO7W5DZCZLVNAVCNFSM6AAAAABALAWUBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJYGI2TINRTGQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

leomurta commented 2 months ago

Concordo que usar o papertrails para isso pode não ser legal. Vamos estar colocando uma dependência forte da nossa aplicação com o papertrails. Acho melhor incluirmos o conceito no nosso modelo. Mas concordo que, na migração, buscar o que for possível do papertrails é o ideal, pois já partimos de um histórico inicial.

@IgorMonardez sempre que fizer alteração no BD, faça migrations para que consigamos manter ao máximo a consistência do BD. O ideal é ter migração up e down, pois permite downgrade de versão sem comprometer o banco, a menos que a migração seja igual nos dois sentidos.

IgorMonardez commented 2 months ago

Beleza, Só para confirmar, criarei de acordo com o modelo relacional proposto acima(na minha mensagem) e, inicialmente, será populado de acordo com o papertrail.

Estarei atualizando de acordo com as migrations sim.

leomurta commented 2 months ago

@IgorMonardez so veja como tem sido feito e siga o mesmo estilo (ex: em inglês). Qq dúvida, pergunte.

leomurta commented 2 months ago

Outra coisa, InstituicaoProfessor tem a semântica de afiliação (um professor está afiliado a uma instituição num período), então é melhor criar com o nome semântico Affiliation.

IgorMonardez commented 2 months ago

Perfeito, utilizarei Igor Monárdez

Estudante de Ciência da Computação UFF PURO

Em sex., 17 de mai. de 2024 às 19:39, Leonardo Gresta Paulino Murta < @.***> escreveu:

Outra coisa, InstituicaoProfessor tem a semântica de afiliação (um professor está afiliado a uma instituição num período), então é melhor criar com o nome semântico Affiliation.

— Reply to this email directly, view it on GitHub https://github.com/gems-uff/sapos/issues/448#issuecomment-2118458130, or unsubscribe https://github.com/notifications/unsubscribe-auth/AU3E3EQFYWEHG7TDQUTP6D3ZC2BLVAVCNFSM6AAAAABALAWUBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJYGQ2TQMJTGA . You are receiving this because you were mentioned.Message ID: @.***>

IgorMonardez commented 1 month ago

No modelo atual, quando um professor possui, ou já possuiu, mais de uma instituição ela aparece replicado com as instituições diferentes? Pergunto pq o versions, aparentemente, não guarda todos os dados da versão, logo não teria como captar as instituições antigas de professores, apesar de ter como ver que foi alterado.

JoaoFelipe commented 1 month ago

Professor não fica replicado.

Não entendi o motivo de não ser possível pegar os dados de instituições antigas usando o versions. Imagino que o papertrail tenha algum método que ajude nisso. No pior dos casos deve dar para iterar em todas as versões de todos os professores e reconstruir com o método reify do papertrail.

IgorMonardez commented 1 month ago

Vou estudar melhor sobre o papertrail então, pode ser que seja possível mesmo e eu não saiba

IgorMonardez commented 1 month ago

Os professores só podem possuir uma instituição por vez, ou não?

leomurta commented 1 month ago

Sim.

Em qua., 22 de mai. de 2024 às 14:45, Igor Monárdez < @.***> escreveu:

Os professores só podem possuir uma instituição por vez, ou não?

— Reply to this email directly, view it on GitHub https://github.com/gems-uff/sapos/issues/448#issuecomment-2125411368, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACKM53MFEXG7QHXJNN73Z3ZDTKTPAVCNFSM6AAAAABALAWUBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRVGQYTCMZWHA . You are receiving this because you authored the thread.Message ID: @.***>

IgorMonardez commented 1 month ago

Sobre o nível, eu fiquei confuso pelo fato de haver o nível relacionado à graduação, mestrado, etc... Porém acredito que não seja esse o que está inconsistente aqui nessa ISSUE

IgorMonardez commented 1 month ago

E sobre o professor, só para confirmar, é a instituição que ele estava no dia da defesa de these, correto?

braganholo commented 1 month ago

Igor, o nível é a Nota CAPES do Programa de Pós. A CAPES avalia os programas de Pós e dá uma nota de 3 a 7 para cada programa. Essa avaliação é feita a cada 4 anos. Tem uma variável pra configurar isso no SAPOS chamada "program_level". O que ocorre é que estamos guardando apenas a nota (nível) Atual. Se na época em que um aluno defendeu a tese dele, a nota do Programa era 5, e anos depois a nota subiu pra 6, ao reimprimirmos o histórico daquele aluno, vai sair Nota 6 ao invés de 5, como deveria. Então é preciso guardar o histórico desse valor. Não vai mais dar pra ser uma simples variável. Teremos que ter uma entidade pra isso com as datas de início e fim da validade daquela nota.

JoaoFelipe commented 1 month ago

O nivel do progama aqui na issue não se refere a graduação, mestrado, etc, mas sim ao nível do conceito CAPES. No SAPOS, isso fica configurado na CustomVariable program_level


Sim, a instituição a ser usada é a que o professor estava no dia da defesa

IgorMonardez commented 1 month ago

Igor, o nível é a Nota CAPES do Programa de Pós. A CAPES avalia os programas de Pós e dá uma nota de 3 a 7 para cada programa. Essa avaliação é feita a cada 4 anos. Tem uma variável pra configurar isso no SAPOS chamada "program_level". O que ocorre é que estamos guardando apenas a nota (nível) Atual. Se na época em que um aluno defendeu a tese dele, a nota do Programa era 5, e anos depois a nota subiu pra 6, ao reimprimirmos o histórico daquele aluno, vai sair Nota 6 ao invés de 5, como deveria. Então é preciso guardar o histórico desse valor. Não vai mais dar pra ser uma simples variável. Teremos que ter uma entidade pra isso com as datas de início e fim da validade daquela nota.

Portanto haverá que criar uma outra tabela com o nivel do programa, e a data de início e fim, além de povoá-la com os valores do versions, certo?

braganholo commented 1 month ago

Exatamente!

braganholo commented 1 month ago

E também mudar a forma que esse valor é pego na hora de gerar o histórico escolar. Tem que pegar dessa tabela (na data correta) ao invés de pegar da variável program_level.

IgorMonardez commented 1 month ago

Ok, estou com um pouco de dificuldade de testar a questão do povoamento da afiliação, por conta de ter que acessar um dado antigo do professor. Mas o nivel do programa não devo ter tanta dificuldade já que não afeta no dado do CustomVariable em sim.

IgorMonardez commented 1 month ago

Além de não saber muito bem onde que essa função de popular se encaixa no nosso padrão de projeto, eu coloquei atualmente no controller, mas entendo que isso seria mais um Job, como algo a ser rodado pontualmente quando iniciar o sistema no computador local do usuário

JoaoFelipe commented 1 month ago

Acredito que a função que vai popular isso deve ficar numa migration. A partir do momento que passarmos a usar entidades separadas para nível do programa e instituições de professores (ambas com datas), não será mais necessário usar função de popular.

Quanto a dificuldade da afiliação, com o seguinte código, você consegue pegar todas as instituições que um professor já esteve (e o momento em que elas passaram a ser válidas):

start_date = professor.updated_at
end_date = nil
institution_id = professor.institution_id
institutions = []

professor = professor.paper_trail.previous_version
while professor.present?
  if professor.institution_id != institution_id
    if institution_id.present? # Não armazena afiliação em branco
      institutions << {institution_id:, start_date:, end_date:}
    end
    end_date = start_date
    start_date = professor.updated_at
    institution_id = professor.institution_id
  else
    # Atualiza data de início para data da primeira mudança em que instituição foi definida com esse valor
    start_date = professor.updated_at
  end
  professor = professor.paper_trail.previous_version
end
if institution_id.present? # Não armazena afiliação em branco
  institutions << {institution_id:, start_date:, end_date:}
end

Imagino que dê pra usar isso numa migration passando por todos professores (Professor.all.each). É um código um pouco pesado, mas sendo executado uma vez só - e para o número relativamente baixo de professores - não deve ter problema.

PS: dê uma revisada no código. Testei aqui no rails c e funcionou para um professor, mas fui fazendo sem pensar muito.

IgorMonardez commented 1 month ago

Teria alguns exemplos para colocar no meu banco para eu conseguir testar, eu cheguei a fazer um script que coloquei no affiliation controller para esse povoamento, acredito que esteja certo mas eu nao consigo testar

IgorMonardez commented 1 month ago

Pode ser até algumas informações do versions/papertrails, seria apenas para testar se está certo