Skip to content

MarsoL4/geosense-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

180 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GeoSense API

GeoSense API é uma solução RESTful desenvolvida em .NET para o gerenciamento de motos, vagas, pátios e usuários em ambientes de manutenção e estacionamento. O projeto utiliza arquitetura em camadas, Entity Framework Core, Oracle como banco de dados e documentação completa via Swagger/OpenAPI.


👥 Integrantes

  • Enzo Giuseppe Marsola – RM: 556310, Turma: 2TDSPK
  • Rafael de Souza Pinto – RM: 555130, Turma: 2TDSPY
  • Luiz Paulo F. Fernandes – RM: 555497, Turma: 2TDSPF

🏗 Justificativa do Domínio e Arquitetura

O domínio foi escolhido para atender à necessidade de controle eficiente do fluxo de motos em pátios de manutenção, oficinas ou estacionamentos. O sistema permite cadastro, alocação e histórico de motos, gestão de vagas, controle de usuários com diferentes permissões.

A arquitetura segue boas práticas REST, separação de responsabilidades (camadas Controller, Service, Repository), e utiliza recursos avançados como paginação, HATEOAS, DTOs e exemplos interativos no Swagger.


🚀 Instruções de Execução

  1. Clonar o Repositório:

    git clone https://github.com/MarsoL4/geosense-api.git
    cd geosense-api
  2. Configurar o Banco de Dados:
    Edite o arquivo GeoSense.API/appsettings.json com sua string de conexão Oracle em "ConnectionStrings:Oracle".

  3. Restaurar os Pacotes e Compilar:

    dotnet restore
    dotnet build
  4. Aplicar Migrations no Banco de Dados:

    dotnet ef database update --project GeoSense.API
  5. Executar a API:

    dotnet run --project GeoSense.API

    Acesse a documentação Swagger em:
    http://localhost:5194/swagger ou https://localhost:7150/swagger

  6. Rodar Testes Automatizados:

    dotnet test

🧪 Testes Automatizados

O projeto inclui:

  • Testes unitários (xUnit) abrangendo lógica de negócio e fluxo de controle principal das entidades.
  • Testes de integração reais com WebApplicationFactory garantindo funcionamento dos principais endpoints.
  • Para rodar todos os testes, utilize o comando acima; não é necessário banco externo (os testes usam banco in-memory).

🔑 Segurança

  • Todos os endpoints (exceto /swagger e /health) exigem a inclusão do header de API Key:
    GeoSense-Api-Key: SEGREDO-GEOSENSE-123 (valor configurado em appsettings.json).
  • Para propósitos de testes e demonstração local, a chave está mantida no arquivo de configuração do repositório.

🩺 Health Checks

  • Endpoint de health check disponível em:
    GET /health
    
  • Resposta em JSON exibindo o status da aplicação e do banco.
  • Exemplo de resposta esperada:
{
  "status": "Healthy",
  "totalDuration": "00:00:01.1203756",
  "entries": {
    "Database": {
      "status": "Healthy",
      "duration": "00:00:01.0069991",
      "tags": []
    }
  }
}

🔄 Versionamento de API

  • Endpoints versionados por URL, no padrão:
    /api/v1/[controller]
    

🔑 Principais Entidades

  • Moto: Controle de motos cadastradas, informações de placa, chassi, modelo e vaga alocada.
  • Vaga: Gerenciamento de vagas disponíveis em pátios, incluindo status e tipo.
  • Usuário: Cadastro de usuários do sistema, com controle de papéis (administrador, mecânico) e autenticação.
  • Pátio: Cadastro e gestão dos pátios onde as vagas são distribuídas.

📑 Endpoints e Exemplos de Uso

🛵 MotoController

Listar Motos (Paginação + HATEOAS)

  • GET /api/v1/moto?page=1&pageSize=10
  • Resposta:
    {
      "items": [
        {
          "id": 1,
          "modelo": "Honda CG 160",
          "placa": "ABC1D23",
          "chassi": "9C2JC4110JR000001",
          "problemaIdentificado": "Motor com ruído excessivo",
          "risco": "ALTO",
          "vagaId": 1
        }
      ],
      "totalCount": 1,
      "page": 1,
      "pageSize": 10,
      "links": [
        { "rel": "self", "method": "GET", "href": "/api/v1/moto?page=1&pageSize=10" }
      ]
    }

Buscar Moto por ID

  • GET /api/v1/moto/{id}
  • Resposta:
    {
      "id": 1,
      "modelo": "Honda CG 160",
      "placa": "ABC1D23",
      "chassi": "9C2JC4110JR000001",
      "problemaIdentificado": "Motor com ruído excessivo",
      "risco": "ALTO",
      "vagaId": 1
    }

Criar Moto

  • POST /api/v1/moto
  • Payload de exemplo:
    {
      "modelo": "Honda CG 160",
      "placa": "ABC1D23",
      "chassi": "9C2JC4110JR000001",
      "problemaIdentificado": "Motor com ruído excessivo",
      "vagaId": 1
    }
  • Resposta:
    {
      "mensagem": "Moto cadastrada com sucesso.",
      "dados": {
        "id": 1,
        "modelo": "Honda CG 160",
        "placa": "ABC1D23",
        "chassi": "9C2JC4110JR000001",
        "problemaIdentificado": "Motor com ruído excessivo",
        "risco": "ALTO",
        "vagaId": 1
      }
    }

Atualizar Moto

  • PUT /api/v1/moto/{id}
  • Payload igual ao POST
  • Resposta:
    {
      "mensagem": "Moto atualizada com sucesso.",
      "dados": {
        "id": 1,
        "modelo": "Honda CG 160",
        "placa": "ABC1D23",
        "chassi": "9C2JC4110JR000001",
        "problemaIdentificado": "Motor com ruído excessivo",
        "risco": "ALTO",
        "vagaId": 1
      }
    }

Remover Moto

  • DELETE /api/v1/moto/{id}
  • Resposta:
    {
      "mensagem": "Moto deletada com sucesso."
    }

🅿️ VagaController

Listar Vagas (Paginação + HATEOAS)

  • GET /api/v1/vaga?page=1&pageSize=10
  • Resposta:
    {
      "items": [
        {
          "id": 1,
          "numero": 101,
          "tipo": 0,
          "status": 0,
          "patioId": 1,
          "motoId": 2
        }
      ],
      "totalCount": 1,
      "page": 1,
      "pageSize": 10,
      "links": [
        { "rel": "self", "method": "GET", "href": "/api/v1/vaga?page=1&pageSize=10" }
      ]
    }

Buscar Vaga por ID

  • GET /api/v1/vaga/{id}
  • Resposta:
    {
      "id": 1,
      "numero": 101,
      "tipo": 0,
      "status": 0,
      "patioId": 1,
      "motoId": 2
    }

Criar Vaga

  • POST /api/v1/vaga
  • Payload de exemplo:
    {
      "numero": 101,
      "tipo": 0,
      "status": 0,
      "patioId": 1
    }
  • Resposta:
    {
      "mensagem": "Vaga cadastrada com sucesso.",
      "dados": {
        "id": 1,
        "numero": 101,
        "tipo": 0,
        "status": 0,
        "patioId": 1,
        "motoId": null
      }
    }

Atualizar Vaga

  • PUT /api/v1/vaga/{id}
  • Payload igual ao POST
  • Resposta:
    {
      "mensagem": "Vaga atualizada com sucesso.",
      "dados": {
        "id": 1,
        "numero": 101,
        "tipo": 0,
        "status": 1,
        "patioId": 1,
        "motoId": 2
      }
    }

Remover Vaga

  • DELETE /api/v1/vaga/{id}
  • Resposta:
    {
      "mensagem": "Vaga deletada com sucesso."
    }

🏢 PatioController

Listar Pátios (Paginação + HATEOAS)

  • GET /api/v1/patio?page=1&pageSize=10
  • Resposta:
    {
      "items": [
        {
          "id": 1,
          "nome": "Pátio Central"
        }
      ],
      "totalCount": 1,
      "page": 1,
      "pageSize": 10,
      "links": [
        { "rel": "self", "method": "GET", "href": "/api/v1/patio?page=1&pageSize=10" }
      ]
    }

Buscar Pátio por ID (com vagas)

  • GET /api/v1/patio/{id}
  • Resposta:
    {
      "id": 1,
      "nome": "Pátio Central",
      "vagas": [
        {
          "id": 1,
          "numero": 101,
          "tipo": 0,
          "status": 0,
          "patioId": 1,
          "motoId": null
        }
      ]
    }

Criar Pátio

  • POST /api/v1/patio
  • Payload de exemplo:
    {
      "nome": "Pátio Central"
    }
  • Resposta:
    {
      "mensagem": "Pátio cadastrado com sucesso.",
      "dados": {
        "id": 1,
        "nome": "Pátio Central"
      }
    }

Atualizar Pátio

  • PUT /api/v1/patio/{id}
  • Payload igual ao POST
  • Resposta:
    {
      "mensagem": "Pátio atualizado com sucesso.",
      "dados": {
        "id": 1,
        "nome": "Pátio Central"
      }
    }

Remover Pátio

  • DELETE /api/v1/patio/{id}
  • Resposta:
    {
      "mensagem": "Pátio deletado com sucesso."
    }

👤 UsuarioController

Listar Usuários (Paginação + HATEOAS)

  • GET /api/v1/usuario?page=1&pageSize=10
  • Resposta:
    {
      "items": [
        {
          "id": 1,
          "nome": "Rafael de Souza Pinto",
          "email": "rafael.pinto@exemplo.com",
          "senha": "12345678",
          "tipo": 0
        }
      ],
      "totalCount": 1,
      "page": 1,
      "pageSize": 10,
      "links": [
        { "rel": "self", "method": "GET", "href": "/api/v1/usuario?page=1&pageSize=10" }
      ]
    }

Buscar Usuário por ID

  • GET /api/v1/usuario/{id}
  • Resposta:
    {
      "id": 1,
      "nome": "Rafael de Souza Pinto",
      "email": "rafael.pinto@exemplo.com",
      "senha": "12345678",
      "tipo": 0
    }

Criar Usuário

  • POST /api/v1/usuario
  • Payload de exemplo:
    {
      "nome": "Rafael de Souza Pinto",
      "email": "rafael.pinto@exemplo.com",
      "senha": "12345678",
      "tipo": 0
    }
  • Resposta:
    {
      "mensagem": "Usuário cadastrado com sucesso.",
      "dados": {
        "id": 1,
        "nome": "Rafael de Souza Pinto",
        "email": "rafael.pinto@exemplo.com",
        "senha": "12345678",
        "tipo": 0
      }
    }

Atualizar Usuário

  • PUT /api/v1/usuario/{id}
  • Payload igual ao POST
  • Resposta:
    {
      "mensagem": "Usuário atualizado com sucesso.",
      "dados": {
        "id": 1,
        "nome": "Rafael de Souza Pinto",
        "email": "rafael.pinto@exemplo.com",
        "senha": "12345678",
        "tipo": 0
      }
    }

Remover Usuário

  • DELETE /api/v1/usuario/{id}
  • Resposta:
    {
      "mensagem": "Usuário deletado com sucesso."
    }

🧩 DashboardController

Dados agregados do sistema para o dashboard

  • GET /api/v1/dashboard
  • Resposta:
    {
      "totalMotos": 10,
      "motosComProblema": 2,
      "vagasLivres": 5,
      "vagasOcupadas": 5,
      "totalVagas": 10
    }

🧩 Swagger/OpenAPI

  • Todos os endpoints possuem descrição, parâmetros documentados, exemplos de payload (POST/PUT) e modelos de dados.
  • Acesse /swagger para explorar e testar a API interativamente.

About

API do projeto GeoSense do Challenge de 2025 da FIAP em parceria com a Mottu utilizando .NET

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages