{"id":48217596,"url":"https://github.com/theycallmeerick/testetecnicoeffecti-","last_synced_at":"2026-04-04T19:01:37.474Z","repository":{"id":302369917,"uuid":"1011607132","full_name":"TheyCallMeErick/TesteTecnicoEffecti-","owner":"TheyCallMeErick","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-02T02:17:48.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-02T03:26:33.049Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheyCallMeErick.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-01T04:47:20.000Z","updated_at":"2025-07-02T02:17:51.000Z","dependencies_parsed_at":"2025-07-02T03:26:52.423Z","dependency_job_id":"bb51b8df-5f60-4167-b38d-ac001cc1223d","html_url":"https://github.com/TheyCallMeErick/TesteTecnicoEffecti-","commit_stats":null,"previous_names":["theycallmeerick/testetecnicoeffecti-"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TheyCallMeErick/TesteTecnicoEffecti-","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheyCallMeErick%2FTesteTecnicoEffecti-","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheyCallMeErick%2FTesteTecnicoEffecti-/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheyCallMeErick%2FTesteTecnicoEffecti-/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheyCallMeErick%2FTesteTecnicoEffecti-/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheyCallMeErick","download_url":"https://codeload.github.com/TheyCallMeErick/TesteTecnicoEffecti-/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheyCallMeErick%2FTesteTecnicoEffecti-/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31409471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-04T19:01:36.611Z","updated_at":"2026-04-04T19:01:37.451Z","avatar_url":"https://github.com/TheyCallMeErick.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Scrapper do comprasNET\n\nEste projeto faz parte de um teste técnico para a vaga de Desenvolvedor Pleno. O sistema tem como objetivo capturar e exibir licitações públicas, com backend em C# (.NET), banco de dados MySQL, frontend em Vue.js, e ambiente de testes via Docker.\n\n# Rodando o Projeto Localmente\n\nEste projeto utiliza **Docker** e **Docker Compose** para facilitar a execução local dos serviços.\n\n## Instruções para Rodar\n\n1. Clone este repositório:\n   ```bash\n   git clone https://github.com/TheyCallMeErick/TesteTecnicoEffecti-\n   ```\n2. Acesse a pasta do projeto:\n   ```bash\n   cd TesteTecnicoEffecti-\n   ```\n\n3. Execute os containers com:\n   ```bash\n   docker-compose up\n   ```\n\n🧱 Estrutura dos Serviços\n- Frontend\n  - Local: ./Frontend\n  - Disponível em: http://localhost:8080\n- Backend\n  - Local: ./Backend\n  - Disponível em: http://localhost:5041\n- Banco de Dados\n  - MySQL (versão 9.3.0)\n  - Banco: teste_tecnico_effecti\n  - Usuário root / Senha: 123\n## Funcionalidades Implementadas\n\n### Backend (.NET)\n- Foi desenvolvida uma API REST em C# com ASP.NET Core\n- Scrapper dos dados do ComprasNet\n- A definição das rotas e do backend pode ser encontrada [aqui](./docs/definition.yaml)\n- Dados retornados em JSON.\n- Testes automatizados com xUnit.\n- Validação de entradas, tratamento de erros e arquitetura por camadas (Controller, Service...).\n\n\n### Modelagem do dos dados\n- A estruturação dos dados e normalização ficou assim\n```mermaid\nclassDiagram\n    class Licitacao {\n        Guid Id\n        string Orgao\n        string Instituicao\n        string CodigoUASG\n        string NumeroPregao\n        string Objeto\n        DateTime DataDisponibilizacaoEdital\n        TimeSpan HoraInicioEdital\n        TimeSpan HoraFimEdital\n        string EnderecoEntrega\n        string Telefone\n        string Fax\n        DateTime DataEntregaProposta\n        TimeSpan HoraEntregaProposta\n        List~ItemLicitacao~ Itens\n    }\n\n    class ItemLicitacao {\n        Guid Id\n        string Nome\n        string Descricao\n        string TratamentoDiferenciado\n        string Aplicabilidade7174\n        string AplicabilidadeMargemPreferencia\n        int Quantidade\n        string UnidadeFornecimento\n        Guid LicitacaoId\n        Licitacao? Licitacao\n    }\n\n    Licitacao \"1\" --\u003e \"0..*\" ItemLicitacao : contém\n```\n### Endpoints disponíveis\n\n### GET /api/Licitacao/apply-migrations\n\nAplica as migrations no banco de dados, criando todas as tabelas definidas nas entidades.\n\n- Resposta 200: Migrations aplicadas com sucesso.\n- Resposta 500: Erro interno ao aplicar as migrations.\n\n### GET /api/Licitacao/sync\n\nSincroniza as licitações com fontes externas, importando dados e salvando no banco.\n\n- Resposta 200: Sincronização realizada com sucesso.\n- Resposta 500: Erro interno ao sincronizar os dados.\n\n### GET /api/Licitacao\n\nConsulta paginada de licitações com filtros opcionais.\n\n#### Parâmetros de query:\n\n- `Uasg`: (string) Código da UASG.\n- `Pregao`: (string) Número do pregão.\n- `Page`: (int) Número da página (padrão: 1).\n- `PageSize`: (int) Tamanho da página (padrão: 10).\n\n#### Respostas:\n\n- 200 OK: Lista paginada de licitações no formato `PaginatedResultDTOOfResponseLicitacaoDTO`.\n- 400 Bad Request: Problemas de validação nos parâmetros.\n\n## Estrutura dos dados\n\n### ResponseLicitacaoDTO\n\nRepresenta uma licitação individual.\n\n| Campo                        | Tipo     | Descrição                                        |\n|-----------------------------|----------|--------------------------------------------------|\n| id                          | string   | Identificador único                              |\n| uasg                        | string   | Código da UASG                                   |\n| pregao                      | string   | Número do pregão                                 |\n| objeto                      | string   | Descrição do objeto da licitação                 |\n| orgao                       | string   | Nome do órgão responsável                        |\n| instituicao                 | string   | Nome da instituição                              |\n| dataDisponibilizacaoEdital | date-time| Data de publicação do edital                     |\n| horaInicioEdital           | string   | Horário de início (com padrão regex)             |\n| horaFimEdital              | string   | Horário de fim (com padrão regex)                |\n| dataEntregaProposta        | date-time| Data limite para entrega de propostas            |\n| horaEntregaProposta        | string   | Horário limite para entrega de propostas         |\n| enderecoEntrega            | string   | Endereço para entrega                            |\n| telefone                   | string   | Telefone de contato                              |\n| fax                        | string   | Número de fax                                    |\n| itens                      | array    | Lista de itens da licitação                      |\n\n### ResponseItemLicitacaoDTO\n\nRepresenta um item da licitação.\n\n| Campo                        | Tipo     | Descrição                                        |\n|-----------------------------|----------|--------------------------------------------------|\n| id                          | string   | Identificador do item                            |\n| nome                        | string   | Nome do item                                     |\n| descricao                   | string   | Descrição detalhada do item                      |\n| tratamentoDiferenciado      | string   | Informação sobre tratamento diferenciado         |\n| aplicabilidade7174          | string   | Informação sobre aplicabilidade da Lei 7174      |\n| aplicabilidadeMargemPreferencia | string | Informação sobre margem de preferência           |\n| quantidade                  | integer  | Quantidade solicitada                            |\n| unidadeFornecimento         | string   | Unidade de fornecimento                          |\n\n## Erros\n\nEm caso de erro, a API retorna um objeto do tipo `ProblemDetails` com os seguintes campos:\n\n- `type`: Tipo do problema\n- `title`: Título do erro\n- `status`: Código HTTP\n- `detail`: Descrição técnica\n- `instance`: Caminho do recurso\n\n\n### Frontend (Vue.js)\nAplicação que consome a API e exibe os dados.\n- Filtros:\n    - Código da UASG.\n    - Número do Pregão.\n- Paginação\n- Mensagem amigável para \"sem resultados\".\n- Estilização básica com CSS.\n\n## Discussões Técnicas\n### Linguagem e Framework\n- C# com ASP.NET Core foi escolhido por preferencia pessoal, a experiência foi interessante considerando nunca ter feito scapping com C#, foi utilizada a biblioteca HtmlAgilityPack.\n\n### Otimizações realizadas\n- Os dados retornados pela API são paginados, evitando sobrecarga ao lidar com grandes volumes de informações.\n- O scrapping foi implementado como um serviço assíncrono, configurado para rodar a cada 8 horas (embora, na prática, não seja utilizado continuamente devido ao teste), sendo assim, devido ao cenário do teste, foi implementado apenas um botão para disparar essa ação, isso leva um certo tempo.\n- Foram criados índices nos principais campos de busca das licitações para otimizar as consultas ao banco de dados.\n- O HTML instável do site foi tratado com lógica de fallback para prevenir quebras, no entanto podem ocorrer situações inesperadas.\n- Devido ao fato do site fazer uma consulta diária, ao verificar as 00:00, não há registros, esse cenário foi previsto e tratado.\n\n### Banco de dados\n- As tabelas foram normalizadas, no entanto cabem melhorias, pela duração do teste tudo foi feito da maneira mais rápida possível.\n\n### Boas práticas aplicadas\n- Separação clara de responsabilidades.\n- DTOs para comunicação entre camadas.\n- Validações e exceções customizadas.\n- Testes unitários para serviços.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheycallmeerick%2Ftestetecnicoeffecti-","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheycallmeerick%2Ftestetecnicoeffecti-","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheycallmeerick%2Ftestetecnicoeffecti-/lists"}