[BUG] Correção nos Campos 'created_at' e 'updated_at'
Closed this issue · 1 comments
Descreva o erro
Foi identificado um comportamento no banco de dados do módulo que pode ser aprimorado. O problema está relacionado aos campos created_at
e updated_at
na tabela mod_nfeio_si_serviceinvoices
.
Atualmente, o campo created_at
está sendo atualizado para o timestamp atual (current_timestamp()) toda vez que uma atualização ocorre em um registro. Isso resulta em um alteração indevida do campo created_at
sempre que um registro é modificado.
`created_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
Para corrigir tal comportamento, sugere-se uma alteração na definição do campo created_at
para eliminar a atualização automática a cada modificação do registro.
Aqui está o comando SQL que se propõe para essa alteração:
ALTER TABLE mod_nfeio_si_serviceinvoices
CHANGE created_at created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
Com essa correção, o campo created_at se manterá constante após a criação de um registro, independentemente de quaisquer alterações subsequentes.
Além disso, sugere-se uma melhoria para a coluna updated_at
. Recomenda-se que essa coluna seja alterada para receber um timestamp atual a cada atualização que ocorrer em um registro. Isso proporciona uma maneira precisa de acompanhar quando a última alteração em um registro foi feita.
Para fazer esta alteração, pode-se usar a seguinte declaração:
ALTER TABLE mod_nfeio_si_serviceinvoices
CHANGE updated_at updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Uma vez estas alterações sendo implementadas, aumentarão a precisão das informações de timestamp e simplificarão a rastreabilidade dos registros.
Como reproduzir
Qualquer atualização de registro realizada pelo módulo reproduz este comportamento.
Comportamento esperado
Informação da coluna created_at
não deve ser alterada quando atualizado registro no banco.
Ambiente e versões:
- Versão do módulo: 2.1.8
- Versão do WHMCS: N/A
- Versão do PHP: N/A
Realizando uma análise mais detalhada, verifiquei que nas versões mais recentes do MySQL, se você definir o primeiro campo TIMESTAMP
na tabela sem outro valor default, ele será automaticamente alterado para CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP. Isso acontece devido à diretiva explicit_defaults_for_timestamp
do MySQL ser desativada por padrão.
No módulo, na criação da tabela, os campos created_at
e updated_at estão especificados como TIMESTAMP (o que está correto) como mostrado abaixo:
Como created_at é o primeiro campo TIMESTAMP na tabela, o MySQL automaticamente impõe uma regra ON UPDATE CURRENT_TIMESTAMP
se a diretiva explicit_defaults_for_timestamp
estiver desativada.
Você pode verificar isso executando o seguinte comando SQL no seu banco de dados MySQL:
SHOW VARIABLES LIKE 'explicit_defaults_for_timestamp';
A imagem abaixo exemplifica os valores dos campos logo após o registro da NF na fila de emissão:
Após o retorno da emissao na API, o valor de created_at
é substituido quando realizado atualizacao do status conforme exemplificado na imagem a seguir:
NOTA: Esta condicao não ocorre na atualizacao do registro quando o retorno é proveniente do webhook pois o callback está preservando manualmente o valor atual de created_at
:
Causa
A possível causa deste comportamento nas colunas created_at
e updated_at
pode ser pelo fato de inexistir uma definicao do padrao para o tipo timestamp
na aplicacao, levando a imposicao automatica da regra explicit_defaults_for_timestamp
de acordo com o definido pelo servico.
Esta condicao ocorre em todos os campos do tipo TIMESTAMP
da aplicacao onde não exista uma definicao de valor padrao quando da sua criacao no banco de dados.
Conclusão
Em conclusão, este não é um problema do MySQL/MariaDB, já que se trata de uma parametrizacão de ambiente e poderá variar conforme configuracão do servico e que deve ser tratado pela aplicacao (módulo).
Solucão
Uma possível solucão para este comportamento seria atribuir a todos os campos created_at
e updated_at
um valor padrão em sua criacão no banco (e também a qualquer outra coluna do tipo TIMESTAMP
).
Sugestão 1
Atribuir as colunas como nulas, evitando a imposicão da diretriz pelo banco de dados:
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
Sugestão 2
Definir as colunas com condicoes especificas de atribuicao de valores para insercao e atualizacao:
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrentOnUpdate();
As tabelas existentes deverão receber alteracão dos atributos.
Referências
- https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html
- https://mariadb.com/kb/en/server-system-variables/#explicit_defaults_for_timestamp
- https://stackoverflow.com/a/57832212/15132546
- https://experienceleague.adobe.com/en/docs/commerce-operations/installation-guide/prerequisites/database-server/mysql#configuring-the-database-instance