Desarrollado por: Andrés Arévalo
Tecnología: ASP.NET Core Web API (.NET 6)
Propósito: Prueba técnica para el rol de Desarrollador .NET
Repositorio: MilesCarRental.VehicleSearch
Este proyecto implementa un sistema de búsqueda de vehículos para Miles Car Rental, permitiendo a los usuarios consultar la disponibilidad de autos según:
- Localidad de recogida
- Localidad de devolución
- Ubicación del cliente (mercado)
La aplicación filtra los vehículos disponibles según las reglas de negocio definidas y devuelve solo aquellos válidos para el mercado y las localidades seleccionadas.
- .NET 6 (C#)
- ASP.NET Core Web API (Minimal APIs)
- Inyección de dependencias (DI)
- Swagger / OpenAPI
- Arquitectura en capas (Domain, Application, Infrastructure, API)
MilesCarRental.VehicleSearch │ ├── Domain │ └── Entities │ ├── Vehicle.cs │ └── Location.cs │ ├── Application │ ├── DTOs │ │ ├── VehicleSearchRequest.cs │ │ └── VehicleResponse.cs │ └── Services │ ├── IVehicleSearchService.cs │ └── VehicleSearchService.cs │ ├── Infrastructure │ └── Repositories │ ├── IVehicleRepository.cs │ ├── ILocationRepository.cs │ ├── InMemoryVehicleRepository.cs │ └── InMemoryLocationRepository.cs │ └── Program.cs
-
Clonar el repositorio:
git clone https://github.com/AndyCoderMachine/MilesCarRental.VehicleSearch.git cd MilesCarRental.VehicleSearch
Restaurar dependencias:
bash Copiar código dotnet restore Ejecutar la aplicación:
bash Copiar código dotnet run Abrir Swagger UI:
bash Copiar código https://localhost:5001/swagger **Lógica del negocio **El servicio VehicleSearchService realiza los siguientes pasos:
Valida que las localidades (recogida, devolución, cliente) existan.
Determina el mercado con base en la localidad de recogida y el país del cliente.
Filtra los vehículos activos pertenecientes a ese mercado.
Devuelve solo los vehículos que permiten recogida y devolución en las localidades indicadas.
** Ejemplos de uso (Swagger o Postman) **✅ Caso exitoso (mercado válido) json Copiar código { "pickupLocationId": 1, "dropoffLocationId": 2, "customerLocationId": 1 } Respuesta (200 OK):
json Copiar código [ { "id": "guid", "brand": "Toyota", "model": "Corolla", "category": "Economy", "seats": 5, "transmission": "Automatic", "marketCode": "US-MIA" } ] ❌ Localidad de recogida inexistente json Copiar código { "pickupLocationId": 999, "dropoffLocationId": 2, "customerLocationId": 1 } Respuesta (400 Bad Request):
json Copiar código { "message": "Pickup location not found" } ❌ Localidad de devolución inexistente json Copiar código { "pickupLocationId": 1, "dropoffLocationId": 999, "customerLocationId": 1 } Respuesta (400 Bad Request):
json Copiar código { "message": "Dropoff location not found" } ❌ Localidad del cliente inexistente json Copiar código { "pickupLocationId": 1, "dropoffLocationId": 2, "customerLocationId": 999 } Respuesta (400 Bad Request):
json Copiar código { "message": "Customer location not found" } ❌ Cliente pertenece a otro mercado json Copiar código { "pickupLocationId": 1, "dropoffLocationId": 2, "customerLocationId": 3 } Respuesta (400 Bad Request):
json Copiar código { "message": "Customer location and pickup location belong to different markets." } ❌ Sin vehículos disponibles json Copiar código { "pickupLocationId": 4, "dropoffLocationId": 1, "customerLocationId": 3 } Respuesta (404 Not Found):
json Copiar código { "message": "No vehicles found for the given criteria." } Ejemplo de entidades (datos en memoria) Localidades iniciales:
Id Name City CountryCode MarketCode 1 Miami Airport Miami US US-MIA 2 Orlando Downtown Orlando US US-MIA 3 Bogotá Aeropuerto Bogotá CO CO-BOG 4 Medellín Poblado Medellín CO CO-BOG
Vehículos iniciales:
Brand Model Category Seats Transmission MarketCode Pickups Dropoffs Toyota Corolla Economy 5 Automatic US-MIA 1,2 1,2 Ford Explorer SUV 7 Automatic US-MIA 1 1,2 Chevrolet Onix Economy 5 Manual CO-BOG 3,4 3,4 Renault Duster SUV 5 Manual CO-BOG 3 3,4
**Mejores prácticas aplicadas **Separación de responsabilidades (Domain / Application / Infrastructure).
Inyección de dependencias (DI).
Respuestas HTTP semánticas (200, 400, 404).
Código extensible y testeable.
Uso de Swagger para documentación automática.
** Posibles mejoras futuras **Persistencia con Entity Framework Core (SQL Server o PostgreSQL).
Filtros adicionales: categoría, transmisión, rango de fechas.
Autenticación JWT.
Manejo de logs con Serilog o NLog.
Tests unitarios con xUnit y Moq.