Ir para o conteúdo principal

Análise técnica sobre a dependência do SID da API antiga do E-Estado

Data de elaboração

16/12/2022

Responsável pelo estudo

José Lucas da Silva Costa (Analista de Desenvolvimento Full-Stack)


Equipe do estudo

João Pedro Rocha Brito (Assessor)

Jônatas Neves Legal (Técnico em Tecnologia da Informação e Comunicação) 

José Henrique dos Santos Nogueira (Assessor)

Alvo SID/E-Estado
Origem

Melhoria: Descontinuação da API do e-estado no SID

Objetivo

Migração da API do e-estado nova no SID
Documentação Correlata Sem documentação.

Observações

Sem observações.

1. Glossário de Termos

  1. API Application Programming Interface (interface de Programação de Aplicações).
  2. SETIC - Superintendência Estadual de Tecnologia da Informação e Comunicação.
  3. SID - Sistema Integrado de Descanso.

1. Introdução


Atualmente o SID possui algumas comunicações com a API antiga do E-Estado e há a necessidade de efetuar a migração antes da descontinuação da API antiga. Para melhor análise do problema se faz necessário este estudo para planejar a migração com menor impacto.

2. Desenvolvimento


2.1. Levantamento das funcionalidades que ainda utilizam a API Antiga do E-Estado

A API a ser migrada do E-estado não possui o cenário favorável as mudanças e migração, pois foram feitas implementações específicas em cima de resultados específicos, em que a API nova não irá atender totalmente, vejamos os pontos código que possui dependências com o E-estado antigo:

using System;
using RestSharp;
using System.Linq;
using SID.API.Models;
using System.Threading.Tasks;
using SID.API.Models.Constants;
using SID.API.Repositories.CRUD;
using System.Collections.Generic;
using SID.API.Models.Construtores;
using SID.API.Models.DTO.Servidor;
using SID.API.Repositories.Interfaces;
using Microsoft.Extensions.Configuration;
using SID.API.Models.DTO.Servidor.EEstadoServidores;

namespace SID.API.Repositories
{
    public class ServidorRepository : ConsumirRepository, IServidorRepository
    {
        public ServidorRepository(IConfiguration config)
        {
            Url = new Uri(config["UrlEEstadoApi"]);
            UrlServidores = new Uri(config["UrlServidores"]);
            AuthorizationKey = config["ServidoresAccessKey"];
            Origin.Add("Origin", config["UrlOrigin"]);
        }

        private Uri Url { get; set; }
        private Uri UrlServidores { get; set; }
        public string AuthorizationKey { get; set; }
        public IDictionary<string, string> Origin { get; set; } = new Dictionary<string, string>();

        public async Task<Servidor> BuscarPorMatricula(string matricula)
        {
            var rota = $"api/movimentacoes/matricula/{matricula}";

            var resultado = await Buscar<List<ServidorDto>>(Url, rota, Method.GET);

            var servidorDTO = resultado.FirstOrDefault(x => x.DepartamentoPadrao);

            if (servidorDTO != null)
            {
                ParamentrosDoServidor paramentrosDoServidor = new ParamentrosDoServidor
                {
                    Nome = servidorDTO.Nome,
                    Cpf = servidorDTO.Cpf,
                    Matricula = servidorDTO.Matricula,
                    Cargo = servidorDTO.Cargo,
                    Departamento = servidorDTO.NomeDoDepartamento,
                    DepartamentoId = servidorDTO.CodigoDoDepartamento.GetValueOrDefault(),
                    CodigoDaUnidadeOrcamentaria = Convert.ToInt32(servidorDTO.codigoDaUnidadeGestoraDoDepartamento),
                    UnidadeOrcamentaria = servidorDTO.UnidadeOrcamentaria,
                    DataDeAdmissao = servidorDTO.DataDeAdmissao.Value,
                    AtividadePrivativaNoCargo = servidorDTO.AtividadePrivativaNoCargo
                };
                return new Servidor(paramentrosDoServidor);
            }
            return null;
        }

        public async Task<Servidor> BuscarPorMatriculaComOuSemDepartamentoPadrao(string matricula)
        {
            var rota = $"api/movimentacoes/matricula/{matricula}";

            var resultado = await Buscar<List<ServidorDto>>(Url, rota, Method.GET);

            var servidorDTO = resultado.FirstOrDefault();

            if (servidorDTO != null)
            {
                ParamentrosDoServidor paramentrosDoServidor = new ParamentrosDoServidor
                {
                    Nome = servidorDTO.Nome,
                    Cpf = servidorDTO.Cpf,
                    Matricula = servidorDTO.Matricula,
                    Cargo = servidorDTO.Cargo,
                    Departamento = servidorDTO.NomeDoDepartamento,
                    DepartamentoId = servidorDTO.CodigoDoDepartamento.GetValueOrDefault(),
                    CodigoDaUnidadeOrcamentaria = Convert.ToInt32(servidorDTO.codigoDaUnidadeGestoraDoDepartamento),
                    UnidadeOrcamentaria = servidorDTO.UnidadeOrcamentaria,
                    DataDeAdmissao = servidorDTO.DataDeAdmissao.Value,
                    AtividadePrivativaNoCargo = servidorDTO.AtividadePrivativaNoCargo
                };
                return new Servidor(paramentrosDoServidor);
            }
            return null;
        }

        public async Task<IList<ServidorDto>> BuscarServidor(string nomeCpf)
        {
            var rota = $"api/movimentacoes/nomeOuCpf/{nomeCpf}";

            var resultado = await Buscar<List<ServidorDto>>(Url, rota, Method.GET);

            return resultado.Where(x => x.DataDeRescisao == null && x.DepartamentoPadrao).OrderBy(x => x.Nome).ToList();
        }

        public async Task<List<ServidorDto>> BuscarServidoresDoDepartamento(int departamentoId)
        {
            var rota = $"api/movimentacoes/departamentoId/{departamentoId}";

            var resultado = await Buscar<List<ServidorDto>>(Url, rota, Method.GET);

            var res = resultado.Where(x => x.DataDeRescisao == null && x.DepartamentoPadrao).OrderBy(x => x.Nome).ToList();

            return res;
        }

        public async Task<List<ServidorDto>> BuscarServidoresDaUnidadeOrcamentaria(int unidadeOrcamentariaId)
        {
            var rota = $"api/movimentacoes/unidadeDoDepartamentoId/{unidadeOrcamentariaId}";

            var resultado = await Buscar<List<ServidorDto>>(Url, rota, Method.GET);

            return resultado.Where(x => x.DataDeRescisao == null && x.DataDeAdmissao != null && x.DepartamentoPadrao).OrderBy(x => x.Nome).ToList();
        }

        public async Task<List<ServidorDto>> BuscarProfessoresDaUnidadeOrcamentaria(int unidadeOrcamentariaId, params int[] listaDepartamentoId)
        {
            var rota = $"api/movimentacoes/servidoresComCargoDeProfessorEatividadePrivativaNoCargo/{unidadeOrcamentariaId}";

            var resultado = await Buscar<List<ServidorDto>>(Url, rota, Method.GET);
            List<ServidorDto> novaListaServidores = FiltrarBuscarDosProfessores(listaDepartamentoId, resultado);
            return novaListaServidores;
        }

        public async Task<List<ServidorDto>> PesquisarProfessoresDaUnidadeOrcamentaria(int unidadeOrcamentariaId, string pesquisa, params int[] listaDepartamentoId)
        {
            var rota = $"api/movimentacoes/servidoresComCargoDeProfessorEatividadePrivativaNoCargo/{unidadeOrcamentariaId}";

            var resultado = await Buscar<List<ServidorDto>>(Url, rota, Method.GET);
            List<ServidorDto> novaListaServidores = FiltrarBuscarDosProfessores(listaDepartamentoId, resultado, pesquisa);
            return novaListaServidores;
        }

        private static List<ServidorDto> FiltrarBuscarDosProfessores(int[] listaDepartamentoId, List<ServidorDto> resultado, string pesquisa = "")
        {
            var novaListaServidores = new List<ServidorDto>();
            if (listaDepartamentoId.All(departamentoId => departamentoId != 0))
            {
                foreach (var departamentoId in listaDepartamentoId)
                    novaListaServidores.AddRange(resultado.Where(x => x.CodigoDoDepartamento == departamentoId).ToList());

                if (!string.IsNullOrEmpty(pesquisa))
                    novaListaServidores = novaListaServidores.Where(x => x.Nome.Contains(pesquisa)).ToList();
            }
            else 
                novaListaServidores = resultado;

            return novaListaServidores;
        }

        public async Task<List<AssentamentoDto>> BuscarAssentamentosPorMatricula(string matricula)
        {
            var rota = $"api/assentamento/matricula/{matricula}";

            var resultado = await Buscar<List<AssentamentoDto>>(Url, rota, Method.GET);

            var assentamentosFiltrados = new List<AssentamentoDto>();
            var codigosAssentamentos = AssentamentosConstants.codigosAssentamentosEspeciais;

            assentamentosFiltrados.AddRange(resultado.Where(y => codigosAssentamentos.Any(x => x == y.Codigo)));
            return assentamentosFiltrados;
        }

        public async Task<AssentamentoDto> BuscarAssentamentoPorMatricula(string matricula, string codigo, DateTime dataInicial)
        {
            var rota = $"api/assentamento/matricula/{matricula}";

            var resultado = await Buscar<List<AssentamentoDto>>(Url, rota, Method.GET);

            return resultado.FirstOrDefault(x => x.DataInicial.GetValueOrDefault().Date == dataInicial.Date && x.Codigo.Contains(codigo));
        }

        public async Task<ListaDeMatriculasDoServidorDto> BuscarPorCpf(string cpf)
        {
            var rota = $"?cpf={cpf}";

            var resultado = await BuscarComHeaders<ListaDeMatriculasDoServidorDto>(UrlServidores, rota, Method.GET, AuthorizationKey, Origin.FirstOrDefault());

            return resultado;
        }

        public async Task<ListaDeMatriculasDoServidorDto> BuscarServidoresDaUnidadeOrcamentariaPelaRotaPaginada(int unidadeOrcamentariaId, int pagina, double limit)
        {
            var rota = $"?unidade_trabalho_id={unidadeOrcamentariaId}&page={pagina}&apenas_ativos=true&limit=${Convert.ToInt32(limit)}";
            return await BuscarComHeaders<ListaDeMatriculasDoServidorDto>(UrlServidores, rota, Method.GET, AuthorizationKey, Origin.FirstOrDefault());
        }

        public async Task<DetalhesDoServidorDto> BuscarFichaFuncionalDoServidor(string matricula)
        {
            var rota = $"matricula/{matricula}/ficha-funcional";
            return await BuscarComHeaders<DetalhesDoServidorDto>(UrlServidores, rota, Method.GET, AuthorizationKey, Origin.FirstOrDefault());
        }

        public async Task<List<DepartamentoDto>> BuscarDetalhesDoServidor(int servidorId)
        {
            var rota = $"{servidorId}";
            var detalhesDoServidor = await BuscarComHeaders<DepartamentosDoServidorDto>(UrlServidores, rota, Method.GET, AuthorizationKey, Origin.FirstOrDefault());

            var departamentos = detalhesDoServidor.Departamentos.Select(x => x.Departamento).ToList();

            departamentos.ForEach(x => x.Padrao = detalhesDoServidor.Departamentos.First(y => y.Departamento.Id.Equals(x.Id)).Padrao);
            return departamentos;
        }
    }
}

Percebemos pelo código acostado que os métodos que dependem do E-Estado antigo são centralizados, então provável que a nova API seja implementada sem dificuldades, o único problema é na verdade a falta de sincronismo entre as funcionalidades, nem todas as funções que o E-estado antigo fazia estão acopladas na nova.


2.2. Valor agregado

Atualizações de plataformas sempre são bem vindas, no cenário da SETIC melhoria inclusive as situações de manunteção, utilizar plataformas mais atualizadas tendem a ser mais fácil a manunteção. Então, será de muita serventia que as dependências do SID sejam atualizadas em conjunto.


3. Conclusão


O presente ESTUDO TÉCNICO PRELIMINAR, elaborado pelos integrantes TÉCNICOS do time TITÃS, considerando a análise dos desafios técnicos envolvidos e citados, conclui PELA DESCONTINUAÇÃO DA API ANTIGA DO E-ESTADO NO SID, uma vez que foram considerados a análise técnica dos serviços envolvidos, principalmente potenciais problemas que afetem a disponibilidade e desempenho do serviço. Em complemento, os contratempos identificados são administráveis, pelo que RECOMENDAMOS A REVISÃO E SUBSTITUIÇÃO DA ANTIGA API PELA NOVA, uma vez que, os projetos podem parar de funcionar.

4. Referências