Taxi 24 API consiste en un conjunto de endpoints que permite a cualquier consumidor gestionar su flota de pasajeros.
- Node.js (versión 18.6.0)
- MongoDB (versión 6)
- Docker compose (Opcional para ejecutar las pruebas de integración)
- Clona el repositorio:
git clone https://github.com/diangogav/taxi24-code-challenge.git
- Instala las dependencias:
cd taxi24-code-challenge
npm install
- Configura las variables de entorno:
Crea un archivo .env
en la raíz del proyecto y configura las variables de entorno necesarias, como la URL de conexión a la base de datos MongoDB, puertos, claves de API, etc. Tomar el archivo .env.example como referencia.
- Seeds
Teniendo la base de datos iniciada.
Puedes poblar la base de datos con datos iniciales usando el comando:
npm run seeds
Esto creará un conjunto de datos de drivers
y passenger
en sus respectivas colecciones.
- Iniciar la aplicación:
npm start
La aplicación estará disponible en http://localhost:3000 (o el puerto especificado en las variables de entorno).
- Pruebas automáticas
Todas las pruebas automáticas.
npm run tests
Pruebas unitarias.
npm run test:unit
Pruebas de integración.
Para ejecutar las pruebas de integración es necesario tener docker compose para iniciar la base de datos
npm run test:integration
Alternativamente se puede usar docker compose
para ejecutar la base de datos de la aplicación.
También se puede usar el Dockerfile para realizar una imagen de docker de la aplicaciónn y ejecutarla.
docker build -t <image-name>
docker run -p <local-port>:<docker-port> <docker container name>
La estructura del proyecto sigue los principios de la Arquitectura Hexagonal para promover la escalabilidad y la realización de pruebas automáticas (unitarias, integración y e2e). Además de tener las ventajas de separar la lógica de negocio de la infraestructura y facilitar la reutilización de componentes. A continuación se muestra la estructura de directorios del proyecto:
├── src
│ ├── app.ts
│ ├── config
│ ├── modules
│ │ ├── bill
│ │ │ ├── application
│ │ │ ├── domain
│ │ │ └── infrastructure
│ │ ├── driver
│ │ │ ├── application
│ │ │ ├── domain
│ │ │ └── infrastructure
│ │ ├── passenger
│ │ │ ├── application
│ │ │ ├── domain
│ │ │ └── infrastructure
│ │ ├── shared
│ │ │ ├── criteria
│ │ │ ├── database
│ │ │ ├── errors
│ │ │ ├── event-bus
│ │ │ ├── location
│ │ │ └── value-objects
│ │ └── trip
│ │ ├── application
│ │ ├── domain
│ │ └── infrastructure
│ └── server
│ └── routes
└── tests
├── docker-compose.yaml
├── globalSetup.ts
├── globalTeardown.ts
├── integration
│ └── trip
└── unit
├── location
└── trip
GET /drivers/{driverId}
Endpoint para obtener información detallada de un conductor específico.
driverId
(string, requerido): ID del conductor.
Código de estado: 200 (OK)
Ejemplo de respuesta exitosa:
{
"id": "5bdb2b99-8040-41bd-84bd-a01037b70753",
"name": "Ning Bailey",
"isAvailable": false,
"location": {
"longitude": -43.749,
"latitude": -68.817
}
}
GET /drivers
Endpoint para obtener una lista de todos los conductores
Código de estado: 200 (OK)
[
{
"id": "e222297f-d6ce-4ab0-987a-943c4280e88d",
"name": "Lalita Ólafsson",
"isAvailable": true,
"location": {
"longitude": 90,
"latitude": 85
}
},
{
"id": "0c373af4-4980-4a7f-b8ea-a86c625dd307",
"name": "Vladimir Sigurðardóttir",
"isAvailable": false,
"location": {
"longitude": 125.262,
"latitude": 52.069
}
}
]
GET /drivers/availables
Endpoint para obtener una lista de conductores disponibles en función de la ubicación proporcionada.
latitude
(number, requerido): Latitud de la ubicación actual.
longitude
(number, requerido): Longitud de la ubicación actual.
NOTA: si ejecutaste los seeders, puedes usar los siguientes datos ya acomodados para que generen una respuesta válida
?latitude=40.712&longitude=-74.006
Código de estado: 200 (OK)
[
{
"id": "e222297f-d6ce-4ab0-987a-943c4280e88d",
"name": "Lalita Ólafsson",
"isAvailable": true,
"location": {
"longitude": 90,
"latitude": 85
}
},
{
"id": "0c373af4-4980-4a7f-b8ea-a86c625dd307",
"name": "Vladimir Sigurðardóttir",
"isAvailable": true,
"location": {
"longitude": 125.262,
"latitude": 52.069
}
}
]
GET /passengers
Endpoint para obtener una lista de pasajeros.
Código de estado: 200 (OK)
[
{
"id": "86bf0eaa-1696-488a-850a-c7e5282b9c23",
"name": "Somkiat Böttcher"
},
{
"id": "8136f1e8-a122-4e9a-aac6-ed8311348534",
"name": "Miykhael Novák"
},
]
GET /passengers/{passengerId}
Endpoint para buscar un pasajero específico por su ID.
passengerId
(string, requerido): ID del pasajero.
Código de estado: 200 (OK)
{
"id": "86bf0eaa-1696-488a-850a-c7e5282b9c23",
"name": "Somkiat Böttcher"
}
GET /passengers/{passengerId}/drivers
Endpoint para obtener una lista de máximo 3 conductores disponibles para un pasajero en función de la ubicación proporcionada.
passengerId
(string, requerido): ID del pasajero.
latitude
(number, requerido): Latitud de la ubicación actual del pasajero.
longitude
(number, requerido): Longitud de la ubicación actual del pasajero.
Código de estado: 200 (OK)
[
{
"id": "2edefb8c-8903-4cd8-87d5-cd4e9489d190",
"name": "John Óskarsson",
"_isAvailable": true,
"_location": {
"longitude": -74.006,
"latitude": 40.7128
}
},
{
"id": "104e33e3-eb9c-469b-bcd9-d95572e2a75a",
"name": "Hideo Mohammed",
"_isAvailable": true,
"_location": {
"longitude": -74.007,
"latitude": 40.7125
}
},
{
"id": "9f769012-a565-4969-8861-90dcc037e21f",
"name": "Kiran Pétursdóttir",
"isAvailable": true,
"location": {
"longitude": -74.0055,
"latitude": 40.711
}
}
]
POST /trips
Endpoint para crear un nuevo viaje.
Body
Ejemplo de solicitud:
{
"driverId": "e222297f-d6ce-4ab0-987a-943c4280e88d",
"passengerId": "86bf0eaa-1696-488a-850a-c7e5282b9c23",
"longitude": 45,
"latitude": 45
}
Código de estado: 200 (OK)
Cuerpo de respuesta: Respuesta vacía (objeto vacío {}).
POST /trips/{tripId}/complete
Endpoint para marcar un viaje como completado.
tripId
(string, requerido): ID del viaje.
Coordenadas de la ubicación de finalización del viaje en formato JSON. Ejemplo de solicitud:
{
"latitude": 37.3352,
"longitude": -121.8811
}
Código de estado: 200 (OK) Cuerpo de respuesta: Respuesta vacía (objeto vacío {}).
GET /trips
Endpoint para obtener una lista de viajes.
status
(string): Estado del viaje para filtrar la lista de viajes (opciones: "pending", "completed", "cancelled").
Código de estado: 200 (OK)
[
{
"id": "trip1",
"passengerId": "12345",
"driverId": "67890",
"status": "completed"
},
{
"id": "trip2",
"passengerId": "54321",
"driverId": "09876",
"status": "pending"
}
]