Pular para conteúdo

Remoção do Relacionamento TipoFamilia da Entidade Liga

Versão: 1.0 Data: 2025-10-27 Status: ✅ Implementado Tarefa: NH-85


Visão Geral

Este documento registra a decisão arquitetural de remover o relacionamento entre as entidades Liga e TipoFamilia, eliminando a foreign key TipoFamiliaId da tabela Liga. Esta mudança simplifica o modelo de domínio e resolve problemas de duplicação de códigos de liga.


Contexto

Problema Identificado

No módulo de Cadastro de Mercadorias (Liga/Norma/Composição/Propriedade/Aplicação), identificou-se que o campo TipoFamiliaId na entidade Liga estava causando problemas:

  1. Duplicação de Códigos: O mesmo código de liga podia ser cadastrado múltiplas vezes com diferentes tipos de família, causando inconsistências
  2. Complexidade Desnecessária: O relacionamento com TipoFamilia não era utilizado em outras partes do sistema
  3. Acoplamento Excessivo: A dependência entre Liga e TipoFamilia não trazia benefícios ao modelo de negócio

Telas Afetadas

  • /cadastros/lista-liga - Listagem de ligas (incluía coluna "Tipo de Família")
  • /cadastros/adicionar-liga - Formulário de adição (incluía campo "Tipo de Família")
  • /cadastros/atualizar-liga/{id} - Formulário de edição (incluía campo "Tipo de Família")

Análise de Impacto

Foi realizada análise completa do codebase e confirmado que: - ✅ O campo TipoFamiliaId não era usado em regras de negócio - ✅ Não havia dependências em outros módulos - ✅ A remoção simplificaria o modelo sem perda de funcionalidade - ✅ O código da liga por si só é suficiente para identificação única


Decisão

Remover completamente o relacionamento entre Liga e TipoFamilia, incluindo:

  1. Foreign key TipoFamiliaId da tabela Liga
  2. Propriedade de navegação TipoFamilia do modelo Liga
  3. Coleção de navegação Ligas do modelo TipoFamilia
  4. Validações relacionadas a TipoFamiliaId em LigaValidation
  5. Configurações EF Core em LigaConfiguration
  6. Includes desnecessários em LigaRepository
  7. Campo TipoFamiliaId de ViewModels e Controllers
  8. Exibição de "Tipo de Família" nas views (Index, Create, Edit, Details)

Implementação

1. Alterações no Modelo de Domínio

Arquivo: src/Nelmetais.SGE.Business/Models/Cadastros/Liga.cs

// REMOVIDO:
public int TipoFamiliaId { get; set; }
public virtual TipoFamilia? TipoFamilia { get; set; }

Arquivo: src/Nelmetais.SGE.Business/Models/Cadastros/TipoFamilia.cs

// REMOVIDO:
public virtual IEnumerable<Liga>? Ligas { get; set; }

2. Validações

Arquivo: src/Nelmetais.SGE.Business/Validations/Cadastros/LigaValidation.cs

Removidas validações do campo TipoFamiliaId: - Verificação de obrigatoriedade - Validação de valor maior que zero

3. Configuração EF Core

Arquivo: src/Nelmetais.SGE.Data/Configurations/Cadastros/LigaConfiguration.cs

Removida configuração de relacionamento:

// REMOVIDO:
builder.HasOne(l => l.TipoFamilia)
    .WithMany(tf => tf.Ligas)
    .HasForeignKey(l => l.TipoFamiliaId);

4. Repository

Arquivo: src/Nelmetais.SGE.Data/Repositories/Cadastros/LigaRepository.cs

Removidos includes desnecessários:

// REMOVIDO:
.Include(l => l.TipoFamilia)

5. Controllers e ViewModels

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Cadastros/Controllers/LigaController.cs

Removidas: - Propriedade TipoFamiliaId do ViewModel - População de ViewBag.TipoFamilias - Validação do campo no método Create/Edit

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Cadastros/ViewModels/LigaViewModel.cs

// REMOVIDO:
[Display(Name = "Tipo de Família")]
[Required(ErrorMessage = "O campo {0} é obrigatório")]
public int TipoFamiliaId { get; set; }

[Display(Name = "Tipo de Família")]
public string? TipoFamiliaNome { get; set; }

6. Views

Removido campo "Tipo de Família" de todas as views: - Index.cshtml - Coluna na tabela de listagem - _LigaCreateEditPartial.cshtml - Campo select no formulário - _Details.cshtml - Campo de exibição nos detalhes

7. Migration de Banco de Dados

Arquivo: src/Nelmetais.SGE.Data/Migrations/20251027185653_RemoverTipoFamiliaIdDeLiga.cs

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.DropForeignKey(
        name: "FK_Liga_TipoFamilia_TipoFamiliaId",
        table: "Liga");

    migrationBuilder.DropIndex(
        name: "IX_Liga_TipoFamiliaId",
        table: "Liga");

    migrationBuilder.DropColumn(
        name: "TipoFamiliaId",
        table: "Liga");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AddColumn<int>(
        name: "TipoFamiliaId",
        table: "Liga",
        type: "integer",
        nullable: false,
        defaultValue: 0);

    migrationBuilder.CreateIndex(
        name: "IX_Liga_TipoFamiliaId",
        table: "Liga",
        column: "TipoFamiliaId");

    migrationBuilder.AddForeignKey(
        name: "FK_Liga_TipoFamilia_TipoFamiliaId",
        table: "Liga",
        column: "TipoFamiliaId",
        principalTable: "TipoFamilia",
        principalColumn: "Id",
        onDelete: ReferentialAction.Cascade);
}

8. Ajustes de UI

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Cadastros/Views/Liga/Index.cshtml

Ajustadas as larguras das colunas para melhor aproveitamento do espaço após remoção da coluna "Tipo de Família": - Coluna "Código": 10% → 12% - Coluna "Nome": 15% → 18% - Coluna "Aplicação": 15% → 18%


Commits Relacionados

  1. 224d7b3c - refactor: Remove TipoFamiliaId relationship from Liga entity
  2. Remove propriedades e navegações
  3. Remove validações e configurações
  4. Remove campos de controllers, viewmodels e views

  5. 67720184 - build: Add database migration to remove TipoFamiliaId from Liga

  6. Migration para remover FK e coluna do banco de dados

  7. 9f28a8d7 - fix: Correct view directory names for Linux case sensitivity

  8. Correção de case sensitivity em nomes de views

  9. 596e4ad6 - style: Adjust column widths in Liga listing table

  10. Ajuste de larguras das colunas após remoção

Consequências

Positivas ✅

  1. Modelo Simplificado: Entidade Liga mais enxuta e focada em sua responsabilidade
  2. Sem Duplicação: Impossível ter múltiplas ligas com mesmo código (mas tipos de família diferentes)
  3. Menos Acoplamento: Liga não depende mais de TipoFamilia
  4. Performance: Menos joins no banco de dados ao carregar ligas
  5. Manutenibilidade: Menos código para manter em validações, configurações e views
  6. Código Único: O código da liga agora é verdadeiramente único no sistema

Negativas ⚠️

  1. Perda de Informação: Não é mais possível categorizar ligas por tipo de família
  2. Mitigação: Esta informação não era utilizada em regras de negócio

  3. Reversão Requer Migration: Se necessário reverter, será necessário:

  4. Executar migration Down
  5. Repopular dados de TipoFamiliaId manualmente
  6. Restaurar código removido

Alternativas Consideradas

Alternativa 1: Manter Campo Como Opcional

  • Prós: Menor impacto de mudança
  • Contras: Campo inútil permaneceria no modelo, aumentando complexidade

Alternativa 2: Adicionar Constraint Único Composto (Código + TipoFamiliaId)

  • Prós: Permitiria duplicação controlada
  • Contras: Não resolve o problema de fundo (campo desnecessário)

Alternativa 3: Remover Apenas da UI

  • Prós: Dados preservados no banco
  • Contras: Campo fantasma no modelo, confusão para desenvolvedores

Procedimento de Deploy

Ambientes de Desenvolvimento/Homologação

# Aplicar migration automaticamente
dotnet ef database update --project src/Nelmetais.SGE.Data \
    --startup-project src/Nelmetais.SGE.WebApp

Ambiente de Produção (UAT)

  1. Backup do banco de dados
  2. Gerar script SQL da migration:
    dotnet ef migrations script <previous-migration> RemoverTipoFamiliaIdDeLiga \
        -o migration-nh85.sql \
        --startup-project src/Nelmetais.SGE.WebApp
    
  3. Validar script manualmente
  4. Executar script no banco UAT:
    psql -h 192.168.3.140 -p 54432 -U postgres -d NelmetaisDBUAT -f migration-nh85.sql
    
  5. Verificar se a coluna foi removida:
    SELECT column_name
    FROM information_schema.columns
    WHERE table_name = 'Liga' AND column_name = 'TipoFamiliaId';
    -- Deve retornar 0 linhas
    

Impacto em Dados Existentes

⚠️ ATENÇÃO: Esta migration remove dados da coluna TipoFamiliaId.

Dados Perdidos

  • Relacionamentos entre ligas existentes e seus tipos de família
  • Não há dados dependentes (nenhuma outra tabela referencia esta FK)

Recuperação

Se necessário recuperar os dados após a migration: 1. Restaurar backup do banco de dados 2. Exportar dados de TipoFamiliaId antes de aplicar migration 3. Reverter migration: dotnet ef database update <previous-migration> 4. Reimportar dados se necessário


Monitoramento Pós-Deploy

Checklist de Validação

  • [ ] Migration aplicada com sucesso no banco de dados
  • [ ] Coluna TipoFamiliaId removida da tabela Liga
  • [ ] Foreign key FK_Liga_TipoFamilia_TipoFamiliaId removida
  • [ ] Tela de listagem (/cadastros/lista-liga) funcionando sem erros
  • [ ] Formulário de adição (/cadastros/adicionar-liga) funcionando sem campo Tipo Família
  • [ ] Formulário de edição (/cadastros/atualizar-liga/{id}) funcionando sem campo Tipo Família
  • [ ] Tela de detalhes não exibe Tipo de Família
  • [ ] Validações de código único funcionando corretamente
  • [ ] Não há erros de missing includes no log da aplicação

Testes Funcionais

  1. Criar Nova Liga
  2. Acessar /cadastros/adicionar-liga
  3. Preencher código, nome e outros campos
  4. Verificar que não aparece campo "Tipo de Família"
  5. Salvar e confirmar sucesso

  6. Editar Liga Existente

  7. Acessar /cadastros/lista-liga
  8. Clicar em editar qualquer liga
  9. Verificar que não aparece campo "Tipo de Família"
  10. Editar outros campos
  11. Salvar e confirmar sucesso

  12. Visualizar Detalhes

  13. Na listagem, clicar em detalhes de uma liga
  14. Confirmar que "Tipo de Família" não é exibido

  15. Validação de Código Único

  16. Tentar criar liga com código já existente
  17. Confirmar que validação de unicidade funciona

Referências

  • Tarefa: NH-85
  • Branch: fix/remove-tipo-familia-from-liga-NH-85
  • Pull Request: [Pendente]
  • Migration: 20251027185653_RemoverTipoFamiliaIdDeLiga
  • Documentação de Migrations: docs/CORRECAO-MIGRATIONS.md
  • Documentação de UAT: docs/ATUALIZACAO-BANCO-UAT.md

Histórico de Revisões

Versão Data Autor Descrição
1.0 2025-10-27 Bruno Martins Documentação inicial da mudança

Aprovações

  • [x] Desenvolvedor: Bruno Martins
  • [ ] Revisor Técnico: _
  • [ ] Product Owner: _
  • [ ] DBA/Infra: _