Skip to content

🚗 UBER Type Transport System An endpoint is a specific URL from which an application can access a service or request. This is a direction that allows you to communicate with the server to obtain data or carry out actions.

Notifications You must be signed in to change notification settings

DanielSantiagoV/Uber_endpoint

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

🚗 Sistema de Transporte Tipo UBER


🤔 Preguntas Guía

🔗 ¿Qué entiendes por "endpoint" en una API?

Un endpoint es una URL específica donde una aplicación puede acceder a un servicio o recurso. Es como una dirección que permite comunicarse con el servidor para obtener datos o realizar acciones.

💡 Ejemplo práctico: /api/users sería un endpoint para gestionar usuarios. Cuando tu app móvil hace una petición a esta URL, el servidor responde con información de usuarios.

🔍 Explicación técnica: Los endpoints siguen el patrón REST (Representational State Transfer), donde cada URL representa un recurso específico. Por ejemplo:

  • GET /api/users → Obtener lista de usuarios
  • POST /api/users → Crear un nuevo usuario
  • GET /api/users/123 → Obtener usuario específico con ID 123

🔐 ¿Cuál es la diferencia entre un endpoint público y uno privado?

Los endpoints públicos no requieren autenticación y cualquiera puede acceder (como registro de usuarios). Los privados necesitan un token de autenticación válido para acceder.

🔒 Endpoint Público:

POST /api/v1/auth/register          // Método POST para crear algo nuevo
Content-Type: application/json      // Tipo de datos que enviamos

{
  "email": "usuario@email.com",     // Email del usuario
  "password": "miPassword123"       // Contraseña del usuario
}

🛡️ Endpoint Privado:

GET /api/v1/users/profile           // Método GET para obtener datos
Authorization: Bearer token123...   // Token de seguridad requerido

💡 Explicación: El token JWT (JSON Web Token) en el header Authorization verifica que el usuario está autenticado. Sin este token, el servidor devuelve error 401 (Unauthorized).

🚨 ¿Qué información de un usuario consideras confidencial y no debería exponerse?

Información confidencial incluye contraseñas, números de tarjetas de crédito completos, ubicación en tiempo real de otros usuarios, y datos personales como teléfonos.

🔍 Datos SENSIBLES (nunca exponer):

  • ❌ Contraseñas en texto plano
  • ❌ Números completos de tarjetas de crédito
  • ❌ Ubicación GPS de otros usuarios
  • ❌ Números de teléfono completos

✅ Datos SEGUROS (se pueden exponer):

  • ✅ Nombre y foto de perfil
  • ✅ Últimos 4 dígitos de tarjeta (ej: ****1234)
  • ✅ Ubicación general (ciudad, barrio)
  • ✅ Rating promedio

💡 Ejemplo de respuesta segura:

{
  "id": 123,                                    // ID del usuario
  "name": "Juan Pérez",                        // Nombre completo
  "photo": "https://api.com/photos/user123.jpg", // Foto de perfil
  "rating": 4.8,                               // Calificación promedio
  "phone": "***-***-1234"                      // Solo últimos 4 dígitos
}

🌐 ¿Por qué es importante definir bien los métodos HTTP (GET, POST, PUT/PATCH, DELETE)?

Cada método tiene un propósito específico y sigue convenciones estándar que todos los desarrolladores entienden.

📋 Métodos HTTP explicados:

Método 🎯 Propósito 💡 Ejemplo 🔍 Explicación
GET 📖 Leer datos GET /api/users Solo obtiene información, no modifica nada
POST ➕ Crear nuevo POST /api/users Crea un nuevo recurso (usuario, viaje, etc.)
PUT 🔄 Actualizar completo PUT /api/users/123 Reemplaza toda la información del usuario
PATCH ✏️ Actualizar parcial PATCH /api/users/123 Solo actualiza campos específicos
DELETE 🗑️ Eliminar DELETE /api/users/123 Elimina el recurso permanentemente

💡 Ejemplo práctico:

# Crear un nuevo viaje
POST /api/v1/rides/request                    // Crear viaje
{
  "pickup_location": {"lat": 40.7128, "lng": -74.0060},  // Ubicación origen
  "destination": {"lat": 40.7589, "lng": -73.9851}       // Ubicación destino
}

# Actualizar solo el estado del viaje
PATCH /api/v1/rides/456                       // Actualizar viaje específico
{
  "status": "in_progress"                     // Nuevo estado
}

🔐 ¿Qué tipo de información requiere autenticación en este sistema?

Casi toda la información requiere autenticación: datos de perfil, historial de viajes, pagos, calificaciones, y ubicación en tiempo real.

🔒 Requiere autenticación:

  • 👤 Datos de perfil personal
  • 🚗 Historial de viajes
  • 💳 Información de pagos
  • ⭐ Calificaciones y comentarios
  • 📍 Ubicación en tiempo real
  • 🚙 Estado del conductor (disponible/ocupado)

🌐 Público (sin autenticación):

  • 📝 Registro de nuevos usuarios
  • 🔑 Login de usuarios existentes
  • 📱 Información general de la app

💡 Explicación del token JWT:

{
  "header": {                    // Información del tipo de token
    "alg": "HS256",             // Algoritmo de seguridad
    "typ": "JWT"                // Tipo: JSON Web Token
  },
  "payload": {                   // Datos del usuario
    "user_id": 123,             // ID del usuario
    "role": "passenger",        // Rol: pasajero o conductor
    "exp": 1640995200           // Cuándo expira el token
  },
  "signature": "firma_digital"  // Firma de seguridad del servidor
}

🛡️ ¿Cómo protegerías la ubicación de conductores y pasajeros?

La ubicación solo se comparte entre usuarios involucrados en un viaje activo, nunca con terceros.

🔐 Estrategias de protección:

  1. 🔒 Cifrado en tránsito: Todas las comunicaciones usan HTTPS
  2. ⏰ Almacenamiento temporal: Ubicaciones se borran después de 24 horas
  3. 👥 Acceso limitado: Solo pasajero y conductor del viaje activo pueden ver ubicaciones
  4. 🎯 Precisión reducida: Para terceros, solo mostrar ciudad/barrio

💡 Ejemplo de implementación:

// Respuesta para usuario del viaje activo
{
  "driver_location": {
    "latitude": 40.7128,                    // Ubicación exacta
    "longitude": -74.0060,                  // Ubicación exacta
    "accuracy": 5,                         // Precisión en metros
    "timestamp": "2024-01-15T10:30:00Z"    // Cuándo se actualizó
  }
}

// Respuesta para otros usuarios
{
  "driver_location": {
    "area": "Manhattan",                   // Solo área general
    "neighborhood": "Financial District",  // Solo barrio
    "timestamp": "2024-01-15T10:30:00Z"    // Cuándo se actualizó
  }
}

🚫 ¿Qué pasaría si no hay conductores disponibles? ¿Cómo debería responder la API?

La API debería devolver un mensaje claro con códigos de estado apropiados y sugerencias útiles.

📊 Códigos de estado HTTP:

Código 🎯 Significado 💡 Cuándo usar
404 Not Found No hay conductores en el área específica
503 Service Unavailable Servicio temporalmente no disponible
200 OK Hay conductores pero con tiempo de espera largo

💡 Ejemplo de respuesta:

{
  "error": "NO_DRIVERS_AVAILABLE",           // Tipo de error
  "message": "No hay conductores disponibles en tu área", // Mensaje claro
  "code": 404,                              // Código HTTP
  "timestamp": "2024-01-15T10:30:00Z",      // Cuándo ocurrió
  "suggestions": [                          // Sugerencias útiles
    "Intenta expandir el radio de búsqueda",
    "Espera unos minutos y vuelve a intentar",
    "Considera usar transporte público"
  ],
  "estimated_wait_time": null              // Tiempo de espera (ninguno)
}

📦 ¿Cuáles serían los recursos principales de la aplicación?

Los recursos principales organizan la API de manera lógica y facilitan el desarrollo.

🗂️ Estructura de recursos:

/api/v1/
├── 👥 users/          # Gestión de usuarios
├── 🚗 rides/          # Solicitudes y gestión de viajes  
├── 💳 payments/       # Procesamiento de pagos
├── ⭐ ratings/        # Sistema de calificaciones
├── 🚙 vehicles/       # Información de vehículos
├── 📍 locations/      # Gestión de ubicaciones
└── 👨‍💼 admin/         # Funciones administrativas

💡 Explicación de RESTful design:

  • Cada recurso tiene su propia URL base
  • Los endpoints siguen convenciones estándar
  • Fácil de entender y mantener
  • Escalable para futuras funcionalidades

🔄 ¿Qué ventajas tiene versionar la API (ejemplo /v1/...) desde el inicio?

El versionado permite evolución sin romper aplicaciones existentes.

📈 Ventajas del versionado:

  1. 🔄 Compatibilidad: Apps antiguas siguen funcionando
  2. 🚀 Evolución: Nuevas funcionalidades en v2, v3, etc.
  3. 📱 Migración gradual: Los desarrolladores pueden actualizar cuando estén listos
  4. 🛡️ Estabilidad: Cambios no afectan sistemas en producción

💡 Ejemplo de versionado:

# Versión actual (estable)
GET /api/v1/users/profile

# Nueva versión con mejoras
GET /api/v2/users/profile
# Incluye nuevos campos como "preferences", "notifications"

# Versión antigua (deprecated)
GET /api/v0/users/profile
# Aún funciona pero muestra warning de deprecación

⚠️ Manejo de deprecación:

{
  "warning": "This endpoint is deprecated. Please migrate to v2.",
  "deprecation_date": "2024-06-01",
  "sunset_date": "2024-12-01"
}

📚 ¿Por qué es importante documentar los errores y no solo las respuestas exitosas?

Documentar errores ayuda a los desarrolladores a entender qué puede salir mal y cómo manejarlo.

📋 Elementos de documentación de errores:

  1. 🔢 Códigos HTTP: Indican el tipo de problema
  2. 📝 Mensajes descriptivos: Explican qué salió mal
  3. 💡 Soluciones sugeridas: Cómo resolver el problema
  4. 🔍 Códigos de error únicos: Para debugging específico

💡 Ejemplo de documentación completa:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Los datos enviados no son válidos",
    "details": [
      {
        "field": "email",
        "message": "El formato del email es incorrecto",
        "example": "usuario@ejemplo.com"
      },
      {
        "field": "password",
        "message": "La contraseña debe tener al menos 8 caracteres",
        "min_length": 8
      }
    ],
    "http_status": 400,
    "timestamp": "2024-01-15T10:30:00Z"
  }
}

👥 Roles y Permisos

🚶 Pasajero (Passenger)

🎯 Funciones principales:

  • 📝 Registrarse y gestionar perfil personal
  • 🚗 Solicitar viajes y ver historial
  • 💳 Realizar pagos y ver recibos
  • ⭐ Calificar conductores después del viaje
  • ❌ Cancelar viajes (con restricciones de tiempo)

💡 Ejemplo de permisos en código:

function authorizePassenger(req, res, next) {  // Función para verificar pasajero
  const token = req.headers.authorization;     // Obtener token del header
  const decoded = jwt.verify(token, SECRET_KEY); // Verificar token
  
  if (decoded.role !== 'passenger') {          // Si no es pasajero
    return res.status(403).json({              // Devolver error 403
      error: 'FORBIDDEN',                      // Tipo de error
      message: 'Solo los pasajeros pueden realizar esta acción' // Mensaje
    });
  }
  
  req.user = decoded;                          // Guardar datos del usuario
  next();                                      // Continuar
}

🚗 Conductor (Driver)

🎯 Funciones principales:

  • 📋 Registrarse como conductor con documentos
  • 👤 Gestionar perfil y vehículo
  • 📱 Recibir y aceptar solicitudes de viaje
  • 📍 Actualizar ubicación en tiempo real
  • ⭐ Calificar pasajeros después del viaje
  • 💰 Ver ganancias y historial de viajes

💡 Ejemplo de validación de conductor:

function validateDriverAvailability(req, res, next) { // Verificar disponibilidad
  const driverId = req.user.user_id;                  // ID del conductor
  const driver = await Driver.findById(driverId);     // Buscar conductor
  
  if (driver.status !== 'available') {                // Si no está disponible
    return res.status(409).json({                     // Devolver error 409
      error: 'DRIVER_BUSY',                           // Tipo de error
      message: 'El conductor ya tiene un viaje activo', // Mensaje
      current_status: driver.status                    // Estado actual
    });
  }
  
  next();                                             // Continuar
}

👨‍💼 Administrador (Admin)

🎯 Funciones principales:

  • 👥 Gestionar usuarios y vehículos
  • 📊 Ver estadísticas y reportes
  • ⚖️ Resolver disputas y problemas
  • ⚙️ Configurar tarifas y zonas de servicio
  • 🛡️ Moderar calificaciones y comentarios
  • 🔍 Acceso completo a todos los datos del sistema

💡 Ejemplo de middleware de administrador:

function authorizeAdmin(req, res, next) {              // Verificar admin
  const token = req.headers.authorization;             // Obtener token
  const decoded = jwt.verify(token, SECRET_KEY);        // Verificar token
  
  if (decoded.role !== 'admin') {                      // Si no es admin
    return res.status(403).json({                       // Devolver error
      error: 'ADMIN_REQUIRED',                         // Tipo de error
      message: 'Esta función requiere permisos de administrador' // Mensaje
    });
  }
  
  req.admin = decoded;                                  // Guardar datos admin
  next();                                              // Continuar
}

// Endpoint solo para administradores
app.get('/api/v1/admin/users', authorizeAdmin, async (req, res) => {
  const users = await User.find({})                    // Buscar usuarios
    .select('-password')                               // Excluir contraseñas
    .limit(50);                                        // Máximo 50
    
  res.json({                                           // Devolver respuesta
    users,                                             // Lista de usuarios
    total: users.length,                               // Total encontrados
    admin_action: 'user_listing'                       // Acción realizada
  });
});

📦 Recursos Principales

🗂️ Estructura completa de la API:

Recurso 🎯 Propósito 📝 Descripción 🔗 Ejemplo de URL
👥 users Gestión de usuarios Pasajeros y conductores del sistema /api/v1/users/profile
🚗 rides Solicitudes y gestión de viajes Estados, cancelaciones, finalizaciones /api/v1/rides/request
💳 payments Procesamiento de pagos Métodos de pago, historial, recibos /api/v1/payments/process
⭐ ratings Sistema de calificaciones Evaluaciones mutuas entre usuarios /api/v1/ratings
🚙 vehicles Información de vehículos Datos de autos de conductores /api/v1/vehicles/register
📍 locations Gestión de ubicaciones GPS en tiempo real, conductores cercanos /api/v1/locations/update
👨‍💼 admin Funciones administrativas Gestión del sistema, reportes, estadísticas /api/v1/admin/users

💡 Explicación de la arquitectura REST:

const resources = {                    // Recursos de la API
  users: {                            // Recurso de usuarios
    base_url: '/api/v1/users',        // URL base
    operations: {                     // Operaciones posibles
      'GET /': 'Listar usuarios',      // Obtener lista
      'POST /': 'Crear usuario',      // Crear nuevo
      'GET /:id': 'Obtener usuario específico', // Obtener uno
      'PUT /:id': 'Actualizar usuario completo', // Actualizar todo
      'DELETE /:id': 'Eliminar usuario' // Eliminar
    }
  },
  rides: {                            // Recurso de viajes
    base_url: '/api/v1/rides',        // URL base
    operations: {                     // Operaciones posibles
      'POST /request': 'Solicitar viaje',    // Crear viaje
      'GET /available': 'Ver viajes disponibles', // Ver disponibles
      'POST /:id/accept': 'Aceptar viaje'   // Aceptar viaje
    }
  }
};

🔍 Relaciones entre recursos:

👥 User (1) ──→ (N) 🚗 Ride ──→ (1) 💳 Payment
    │                    │
    └── (N) ⭐ Rating ──→ (1) 🚗 Ride
    │
    └── (1) 🚙 Vehicle (solo conductores)

📊 Tabla de Endpoints

🔐 Autenticación y Usuarios

Método 🛣️ Ruta 📝 Descripción 📋 Parámetros 🔒 Autenticación 💡 Ejemplo
POST /api/v1/auth/register 📝 Registro de nuevo usuario email, password, name, phone, role 🌐 Público {"email": "user@email.com", "password": "pass123"}
POST /api/v1/auth/login 🔑 Inicio de sesión email, password 🌐 Público {"email": "user@email.com", "password": "pass123"}
POST /api/v1/auth/logout 🚪 Cerrar sesión - 🔑 Token Authorization: Bearer token123
GET /api/v1/users/profile 👤 Obtener perfil del usuario - 🔑 Token Respuesta: {"name": "Juan", "email": "juan@email.com"}
PUT /api/v1/users/profile ✏️ Actualizar perfil name, phone, photo 🔑 Token {"name": "Juan Pérez", "phone": "+1234567890"}
POST /api/v1/users/driver/register 🚗 Registro como conductor license, vehicle_info, documents 🔑 Token (pasajero) {"license": "ABC123", "vehicle": {...}}
GET /api/v1/users/driver/status 📊 Estado de registro como conductor - 🔑 Token (conductor) Respuesta: {"status": "approved", "documents": "complete"}

🚗 Gestión de Viajes

Método 🛣️ Ruta 📝 Descripción 📋 Parámetros 🔒 Autenticación 💡 Ejemplo
POST /api/v1/rides/request 🚗 Solicitar un viaje pickup_location, destination, ride_type 🔑 Token (pasajero) {"pickup": {"lat": 40.7128, "lng": -74.0060}}
GET /api/v1/rides/available 📱 Ver viajes disponibles location, radius 🔑 Token (conductor) ?lat=40.7128&lng=-74.0060&radius=5
POST /api/v1/rides/{id}/accept ✅ Aceptar un viaje - 🔑 Token (conductor) POST /api/v1/rides/123/accept
POST /api/v1/rides/{id}/start 🚀 Iniciar viaje - 🔑 Token (conductor) POST /api/v1/rides/123/start
POST /api/v1/rides/{id}/complete 🏁 Finalizar viaje final_location, distance 🔑 Token (conductor) {"final_location": {...}, "distance": 5.2}
POST /api/v1/rides/{id}/cancel ❌ Cancelar viaje reason 🔑 Token (participante) {"reason": "Cambio de planes"}
GET /api/v1/rides/{id} 🔍 Obtener detalles del viaje - 🔑 Token (participante) Respuesta: {"id": 123, "status": "in_progress", "driver": {...}}
GET /api/v1/rides/history 📚 Historial de viajes page, limit, status 🔑 Token ?page=1&limit=10&status=completed

📍 Ubicaciones en Tiempo Real

Método 🛣️ Ruta 📝 Descripción 📋 Parámetros 🔒 Autenticación 💡 Ejemplo
POST /api/v1/locations/update 📍 Actualizar ubicación latitude, longitude 🔑 Token (conductor) {"latitude": 40.7128, "longitude": -74.0060}
GET /api/v1/locations/nearby-drivers 🔍 Conductores cercanos latitude, longitude, radius 🔑 Token (pasajero) ?lat=40.7128&lng=-74.0060&radius=2

💳 Sistema de Pagos

Método 🛣️ Ruta 📝 Descripción 📋 Parámetros 🔒 Autenticación 💡 Ejemplo
POST /api/v1/payments/method 💳 Agregar método de pago card_token, type 🔑 Token {"card_token": "tok_123", "type": "visa"}
GET /api/v1/payments/methods 📋 Listar métodos de pago - 🔑 Token Respuesta: [{"id": 1, "type": "visa", "last4": "1234"}]
POST /api/v1/payments/process 💰 Procesar pago de viaje ride_id, amount 🔑 Token (pasajero) {"ride_id": 123, "amount": 15.50}
GET /api/v1/payments/history 📊 Historial de pagos page, limit 🔑 Token ?page=1&limit=20

⭐ Sistema de Calificaciones

Método 🛣️ Ruta 📝 Descripción 📋 Parámetros 🔒 Autenticación 💡 Ejemplo
POST /api/v1/ratings ⭐ Calificar viaje ride_id, rating, comment 🔑 Token {"ride_id": 123, "rating": 5, "comment": "Excelente servicio"}
GET /api/v1/ratings/{user_id} 👀 Ver calificaciones de usuario - 🔑 Token Respuesta: {"average": 4.8, "total": 150, "reviews": [...]}

👨‍💼 Panel de Administración

Método 🛣️ Ruta 📝 Descripción 📋 Parámetros 🔒 Autenticación 💡 Ejemplo
GET /api/v1/admin/users 👥 Listar todos los usuarios page, limit, role, status 🔑 Token (admin) ?page=1&limit=50&role=driver
PUT /api/v1/admin/users/{id}/status ⚙️ Cambiar estado de usuario status, reason 🔑 Token (admin) {"status": "suspended", "reason": "Violación de términos"}
GET /api/v1/admin/rides 📊 Estadísticas de viajes date_from, date_to 🔑 Token (admin) ?date_from=2024-01-01&date_to=2024-01-31
GET /api/v1/admin/reports 📈 Reportes del sistema type, period 🔑 Token (admin) ?type=revenue&period=monthly

💡 Explicación de códigos de autenticación:

  • 🌐 Público: No requiere autenticación
  • 🔑 Token: Requiere JWT válido en header Authorization: Bearer <token>
  • 🔑 Token (rol específico): Requiere JWT válido con rol específico (pasajero, conductor, admin)

🔄 Flujos de Uso

🚗 1. Solicitud y Finalización de un Viaje Completo

📱 Paso a paso con ejemplos de código:

1️⃣ Pasajero solicita viaje

POST /api/v1/rides/request                    // Solicitar viaje
Authorization: Bearer token123...             // Token de seguridad
Content-Type: application/json               // Tipo de datos

{
  "pickup_location": {                       // Ubicación de origen
    "latitude": 40.7128,                    // Latitud
    "longitude": -74.0060,                   // Longitud
    "address": "Times Square, NYC"           // Dirección
  },
  "destination": {                           // Ubicación de destino
    "latitude": 40.7589,                    // Latitud
    "longitude": -73.9851,                   // Longitud
    "address": "Central Park, NYC"           // Dirección
  },
  "ride_type": "standard"                    // Tipo de viaje
}

💡 Respuesta del servidor:

{
  "ride_id": 12345,                          // ID del viaje
  "status": "searching_driver",              // Estado actual
  "estimated_wait_time": "3-5 minutes",      // Tiempo estimado
  "estimated_fare": "$12.50",               // Precio estimado
  "message": "Buscando conductor cercano..."  // Mensaje para el usuario
}

2️⃣ Sistema encuentra conductores disponibles

GET /api/v1/locations/nearby-drivers?lat=40.7128&lng=-74.0060&radius=2  // Buscar conductores cercanos
Authorization: Bearer conductor_token...                                // Token del conductor

💡 Respuesta con conductores cercanos:

{
  "available_drivers": [                    // Lista de conductores disponibles
    {
      "driver_id": 789,                     // ID del conductor
      "name": "Carlos",                     // Nombre del conductor
      "rating": 4.8,                        // Calificación promedio
      "distance": 0.8,                      // Distancia en km
      "estimated_arrival": "2 minutes",    // Tiempo estimado de llegada
      "vehicle": {                          // Información del vehículo
        "make": "Toyota",                   // Marca
        "model": "Camry",                  // Modelo
        "color": "White",                  // Color
        "license_plate": "ABC-123"         // Placa
      }
    }
  ]
}

3️⃣ Conductor acepta el viaje

POST /api/v1/rides/12345/accept              // Aceptar viaje específico
Authorization: Bearer conductor_token...     // Token del conductor

💡 Respuesta de aceptación:

{
  "ride_id": 12345,                          // ID del viaje
  "status": "driver_assigned",               // Estado: conductor asignado
  "driver": {                                // Información del conductor
    "name": "Carlos",                        // Nombre
    "phone": "+1234567890",                  // Teléfono
    "rating": 4.8,                           // Calificación
    "vehicle": {...}                         // Datos del vehículo
  },
  "estimated_arrival": "2 minutes"           // Tiempo de llegada
}

4️⃣ Conductor llega e inicia el viaje

POST /api/v1/rides/12345/start              // Iniciar viaje
Authorization: Bearer conductor_token...     // Token del conductor

5️⃣ Viaje finaliza

POST /api/v1/rides/12345/complete            // Finalizar viaje
Authorization: Bearer conductor_token...     // Token del conductor
Content-Type: application/json               // Tipo de datos

{
  "final_location": {                        // Ubicación final
    "latitude": 40.7589,                     // Latitud
    "longitude": -73.9851                    // Longitud
  },
  "distance": 2.3,                           // Distancia recorrida (km)
  "duration": 15                             // Duración (minutos)
}

6️⃣ Pago automático se procesa

POST /api/v1/payments/process               // Procesar pago
Authorization: Bearer passenger_token...    // Token del pasajero
Content-Type: application/json              // Tipo de datos

{
  "ride_id": 12345,                         // ID del viaje
  "amount": 12.50,                          // Monto a pagar
  "payment_method_id": 1                    // Método de pago
}

7️⃣ Calificaciones mutuas

# Pasajero califica al conductor
POST /api/v1/ratings                        // Enviar calificación
Authorization: Bearer passenger_token...   // Token del pasajero
Content-Type: application/json             // Tipo de datos

{
  "ride_id": 12345,                        // ID del viaje
  "rated_user_id": 789,                    // ID del conductor
  "rating": 5,                             // Calificación (1-5)
  "comment": "Excelente conductor, muy puntual" // Comentario
}

# Conductor califica al pasajero
POST /api/v1/ratings                        // Enviar calificación
Authorization: Bearer conductor_token...   // Token del conductor
Content-Type: application/json             // Tipo de datos

{
  "ride_id": 12345,                        // ID del viaje
  "rated_user_id": 456,                    // ID del pasajero
  "rating": 5,                             // Calificación (1-5)
  "comment": "Pasajero muy amable"         // Comentario
}

❌ 2. Cancelación de un Viaje

📱 Flujo de cancelación con diferentes escenarios:

🚨 Cancelación temprana (sin penalización)

POST /api/v1/rides/12345/cancel              // Cancelar viaje
Authorization: Bearer passenger_token...     // Token del pasajero
Content-Type: application/json              // Tipo de datos

{
  "reason": "Cambio de planes",              // Motivo de cancelación
  "cancelled_by": "passenger"                // Quién cancela
}

💡 Respuesta:

{
  "ride_id": 12345,                          // ID del viaje
  "status": "cancelled",                     // Estado: cancelado
  "cancellation_fee": 0,                     // Sin tarifa de cancelación
  "refund_amount": 0,                        // Sin reembolso
  "message": "Viaje cancelado sin penalización" // Mensaje
}

⚠️ Cancelación tardía (con penalización)

POST /api/v1/rides/12345/cancel              // Cancelar viaje
Authorization: Bearer passenger_token...     // Token del pasajero
Content-Type: application/json              // Tipo de datos

{
  "reason": "Ya no necesito el viaje",       // Motivo de cancelación
  "cancelled_by": "passenger"                // Quién cancela
}

💡 Respuesta con penalización:

{
  "ride_id": 12345,                          // ID del viaje
  "status": "cancelled",                     // Estado: cancelado
  "cancellation_fee": 5.00,                  // Tarifa de cancelación
  "refund_amount": 7.50,                     // Reembolso parcial
  "message": "Se aplicó tarifa de cancelación por cancelar después de 2 minutos" // Mensaje
}

🔄 Procesamiento de reembolso automático

async function processCancellationRefund(rideId, cancellationFee) { // Función para reembolso
  const ride = await Ride.findById(rideId);                        // Buscar viaje
  const originalAmount = ride.estimated_fare;                       // Precio original
  const refundAmount = originalAmount - cancellationFee;            // Calcular reembolso
  
  if (refundAmount > 0) {                                          // Si hay reembolso
    await processRefund(ride.passenger_id, refundAmount);          // Procesar reembolso
    await sendNotification(ride.passenger_id, {                    // Enviar notificación
      type: 'refund_processed',                                    // Tipo de notificación
      amount: refundAmount,                                        // Monto reembolsado
      message: `Reembolso de $${refundAmount} procesado`          // Mensaje
    });
  }
}

⭐ 3. Sistema de Calificaciones Mutuas

📱 Flujo completo de calificaciones:

🎯 Después de completar un viaje

GET /api/v1/rides/12345                      // Ver detalles del viaje
Authorization: Bearer passenger_token...     // Token del pasajero

💡 Respuesta:

{
  "ride_id": 12345,                          // ID del viaje
  "status": "completed",                     // Estado: completado
  "can_rate": true,                           // Puede calificar
  "rating_deadline": "2024-01-16T10:30:00Z", // Fecha límite para calificar
  "driver": {                                // Información del conductor
    "id": 789,                               // ID del conductor
    "name": "Carlos",                        // Nombre
    "rating": 4.8                            // Calificación actual
  }
}

Pasajero califica al conductor

POST /api/v1/ratings                         // Enviar calificación
Authorization: Bearer passenger_token...    // Token del pasajero
Content-Type: application/json              // Tipo de datos

{
  "ride_id": 12345,                          // ID del viaje
  "rated_user_id": 789,                      // ID del conductor
  "rating": 5,                               // Calificación general (1-5)
  "comment": "Excelente conductor, muy puntual y amable", // Comentario
  "categories": {                            // Calificaciones específicas
    "punctuality": 5,                        // Puntualidad
    "cleanliness": 5,                        // Limpieza
    "friendliness": 5,                       // Amabilidad
    "driving": 4                             // Manejo
  }
}

Conductor califica al pasajero

POST /api/v1/ratings                         // Enviar calificación
Authorization: Bearer conductor_token...    // Token del conductor
Content-Type: application/json              // Tipo de datos

{
  "ride_id": 12345,                          // ID del viaje
  "rated_user_id": 456,                       // ID del pasajero
  "rating": 5,                                // Calificación general (1-5)
  "comment": "Pasajero muy respetuoso",       // Comentario
  "categories": {                            // Calificaciones específicas
    "punctuality": 5,                         // Puntualidad
    "respectfulness": 5,                      // Respeto
    "communication": 4                        // Comunicación
  }
}

📊 Actualización automática de ratings

async function updateUserRating(userId, newRating) { // Función para actualizar rating
  const user = await User.findById(userId);          // Buscar usuario
  const currentRating = user.average_rating;          // Rating actual
  const totalRatings = user.total_ratings;            // Total de calificaciones
  
  const newAverage = ((currentRating * totalRatings) + newRating) / (totalRatings + 1); // Calcular nuevo promedio
  
  await User.findByIdAndUpdate(userId, {             // Actualizar usuario
    average_rating: newAverage,                       // Nuevo promedio
    total_ratings: totalRatings + 1                   // Incrementar contador
  });
  
  if (newAverage < 3.0) {                            // Si rating muy bajo
    await scheduleDriverReview(userId);              // Programar revisión
  }
}

🔍 Verificar calificaciones de un usuario

GET /api/v1/ratings/789                      // Ver calificaciones del usuario 789
Authorization: Bearer any_valid_token...    // Cualquier token válido

💡 Respuesta:

{
  "user_id": 789,                            // ID del usuario
  "average_rating": 4.8,                     // Calificación promedio
  "total_ratings": 150,                       // Total de calificaciones
  "recent_ratings": [                        // Calificaciones recientes
    {
      "rating": 5,                            // Calificación
      "comment": "Excelente conductor",        // Comentario
      "date": "2024-01-15T10:30:00Z",        // Fecha
      "ride_id": 12345                        // ID del viaje
    }
  ],
  "rating_breakdown": {                      // Desglose por estrellas
    "5_stars": 120,                          // 5 estrellas
    "4_stars": 25,                           // 4 estrellas
    "3_stars": 3,                            // 3 estrellas
    "2_stars": 1,                            // 2 estrellas
    "1_star": 1                              // 1 estrella
  }
}

🎯 Decisiones de Diseño

🔐 Seguridad y Privacidad

🛡️ Autenticación JWT (JSON Web Token):

const token = {                              // Estructura del token
  header: {                                 // Información del token
    "alg": "HS256",                         // Algoritmo de seguridad
    "typ": "JWT"                            // Tipo: JSON Web Token
  },
  payload: {                                // Datos del usuario
    "user_id": 123,                         // ID del usuario
    "role": "passenger",                    // Rol: pasajero/conductor
    "exp": 1640995200,                      // Cuándo expira
    "iat": 1640908800                       // Cuándo se creó
  },
  signature: "firma_digital_del_servidor"   // Firma de seguridad
};

function authenticateToken(req, res, next) { // Función para verificar token
  const authHeader = req.headers['authorization']; // Obtener header
  const token = authHeader && authHeader.split(' ')[1]; // Extraer token
  
  if (!token) {                             // Si no hay token
    return res.status(401).json({ error: 'ACCESS_DENIED' }); // Error 401
  }
  
  jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => { // Verificar token
    if (err) return res.status(403).json({ error: 'INVALID_TOKEN' }); // Error 403
    req.user = user;                        // Guardar datos del usuario
    next();                                 // Continuar
  });
}

🔒 Cifrado de datos sensibles:

const crypto = require('crypto');                    // Librería de cifrado

function encryptLocation(latitude, longitude) {     // Función para cifrar ubicación
  const cipher = crypto.createCipher('aes-256-cbc', process.env.LOCATION_KEY); // Crear cifrador
  let encrypted = cipher.update(`${latitude},${longitude}`, 'utf8', 'hex'); // Cifrar datos
  encrypted += cipher.final('hex');                  // Finalizar cifrado
  return encrypted;                                  // Devolver datos cifrados
}

function getLocationForUser(rideId, userId, requesterRole) { // Función para obtener ubicación
  const ride = await Ride.findById(rideId);         // Buscar viaje
  
  if (requesterRole === 'admin') {                  // Si es administrador
    return ride.driver_location;                    // Ubicación completa
  } else if (isParticipantInRide(userId, rideId)) { // Si es participante del viaje
    return ride.driver_location;                    // Ubicación completa
  } else {                                          // Si es otro usuario
    return {                                        // Solo área general
      area: getGeneralArea(ride.driver_location),  // Área general
      neighborhood: getNeighborhood(ride.driver_location) // Barrio
    };
  }
}

⚡ Rate Limiting para prevenir abuso:

const rateLimit = require('express-rate-limit');     // Librería para límites

const generalLimiter = rateLimit({                  // Límite general
  windowMs: 15 * 60 * 1000,                         // Ventana: 15 minutos
  max: 100,                                          // Máximo 100 requests
  message: {                                         // Mensaje de error
    error: 'TOO_MANY_REQUESTS',                      // Tipo de error
    message: 'Demasiadas peticiones, intenta más tarde' // Mensaje
  }
});

const strictLimiter = rateLimit({                   // Límite estricto
  windowMs: 15 * 60 * 1000,                         // Ventana: 15 minutos
  max: 5,                                            // Solo 5 intentos
  message: {                                         // Mensaje de error
    error: 'LOGIN_ATTEMPTS_EXCEEDED',               // Tipo de error
    message: 'Demasiados intentos de login, espera 15 minutos' // Mensaje
  }
});

app.use('/api/v1/auth/login', strictLimiter);       // Aplicar límite estricto al login
app.use('/api/v1/', generalLimiter);                // Aplicar límite general a toda la API

🔄 Versionado de la API

📈 Estrategia de versionado:

const apiVersions = {                        // Versiones disponibles
  v1: {                                      // Versión 1
    status: 'stable',                        // Estado: estable
    endpoints: ['/auth', '/users', '/rides', '/payments'], // Endpoints disponibles
    deprecation_date: null                   // Sin fecha de deprecación
  },
  v2: {                                      // Versión 2
    status: 'beta',                          // Estado: beta
    endpoints: ['/auth', '/users', '/rides', '/payments', '/notifications'], // Más endpoints
    deprecation_date: null,                  // Sin fecha de deprecación
    new_features: ['real_time_notifications', 'advanced_ratings'] // Nuevas funcionalidades
  }
};

function apiVersioning(req, res, next) {     // Función para verificar versión
  const version = req.path.split('/')[2];    // Extraer versión de la URL
  
  if (!apiVersions[version]) {               // Si la versión no existe
    return res.status(404).json({            // Error 404
      error: 'VERSION_NOT_FOUND',            // Tipo de error
      available_versions: Object.keys(apiVersions), // Versiones disponibles
      message: 'La versión de API solicitada no existe' // Mensaje
    });
  }
  
  req.apiVersion = version;                  // Guardar versión
  next();                                    // Continuar
}

function deprecatedEndpoint(req, res, next) { // Función para endpoints deprecados
  res.setHeader('Deprecation', 'true');      // Marcar como deprecado
  res.setHeader('Sunset', '2024-12-31T23:59:59Z'); // Fecha de eliminación
  
  res.json({                                 // Respuesta
    warning: 'Este endpoint está deprecado', // Advertencia
    message: 'Por favor migra a la nueva versión', // Mensaje
    alternative: '/api/v2/users/profile',    // Alternativa
    sunset_date: '2024-12-31T23:59:59Z'     // Fecha de eliminación
  });
}

⚠️ Manejo de Errores Robusto

📊 Códigos HTTP y su significado:

const errorCodes = {                         // Códigos de error
  200: 'OK - Operación exitosa',             // Éxito
  201: 'Created - Recurso creado exitosamente', // Creado
  
  400: 'Bad Request - Datos inválidos o faltantes', // Error del cliente
  401: 'Unauthorized - Token inválido o expirado', // No autorizado
  403: 'Forbidden - Sin permisos para la operación', // Prohibido
  404: 'Not Found - Recurso no encontrado',  // No encontrado
  409: 'Conflict - Conflicto con estado actual', // Conflicto
  
  500: 'Internal Server Error - Error interno del servidor', // Error del servidor
  503: 'Service Unavailable - Servicio temporalmente no disponible' // No disponible
};

function errorHandler(err, req, res, next) { // Función para manejar errores
  console.error('Error:', err);             // Log para debugging
  
  if (err.name === 'ValidationError') {     // Si es error de validación
    return res.status(400).json({           // Error 400
      error: 'VALIDATION_ERROR',            // Tipo de error
      message: 'Los datos enviados no son válidos', // Mensaje
      details: err.errors,                  // Detalles del error
      timestamp: new Date().toISOString()   // Timestamp
    });
  }
  
  if (err.name === 'JsonWebTokenError') {   // Si es error de token
    return res.status(401).json({           // Error 401
      error: 'INVALID_TOKEN',               // Tipo de error
      message: 'Token de autenticación inválido', // Mensaje
      timestamp: new Date().toISOString()   // Timestamp
    });
  }
  
  res.status(500).json({                    // Error genérico 500
    error: 'INTERNAL_SERVER_ERROR',         // Tipo de error
    message: 'Error interno del servidor',  // Mensaje
    timestamp: new Date().toISOString(),    // Timestamp
    request_id: req.id                      // ID de la petición
  });
}

🔄 Graceful Degradation:

async function getRideWithFallback(rideId) { // Función con respaldo
  try {                                      // Intentar obtener datos completos
    const ride = await Ride.findById(rideId).populate('driver passenger'); // Buscar con relaciones
    return ride;                             // Devolver datos completos
  } catch (error) {                         // Si hay error
    console.error('Error getting ride:', error); // Log del error
    
    try {                                   // Intentar datos básicos
      const basicRide = await Ride.findById(rideId).select('status pickup destination'); // Solo campos básicos
      return {                              // Devolver datos básicos
        ...basicRide,                       // Datos del viaje
        degraded_mode: true,                // Modo degradado activado
        message: 'Algunos datos pueden no estar disponibles' // Mensaje de advertencia
      };
    } catch (fallbackError) {               // Si también falla el respaldo
      throw new Error('Servicio temporalmente no disponible'); // Error final
    }
  }
}

⚠️ Manejo de Errores

📊 Códigos HTTP Comunes y su Uso

Código 🎯 Significado 💡 Cuándo usar 🔍 Ejemplo de contexto
200 ✅ OK Operación exitosa GET exitoso, actualización completada
201 ➕ Created Recurso creado exitosamente Usuario registrado, viaje solicitado
400 ❌ Bad Request Datos inválidos o faltantes Email mal formateado, campos requeridos faltantes
401 🔐 Unauthorized Token inválido o expirado Token expirado, credenciales incorrectas
403 🚫 Forbidden Sin permisos para la operación Pasajero intenta aceptar viaje
404 🔍 Not Found Recurso no encontrado Usuario inexistente, viaje no encontrado
409 ⚠️ Conflict Conflicto con estado actual Usuario ya existe, viaje ya cancelado
422 📝 Unprocessable Entity Datos válidos pero lógicamente incorrectos Pago con tarjeta vencida
500 🔥 Internal Server Error Error interno del servidor Error de base de datos, servicio externo caído
503 🚧 Service Unavailable Servicio temporalmente no disponible Mantenimiento programado, sobrecarga

🚨 Ejemplos de Errores

1️⃣ Usuario no encontrado

{
  "error": "USER_NOT_FOUND",
  "message": "El usuario con ID 123 no existe",
  "code": 404,
  "timestamp": "2024-01-15T10:30:00Z"
}

💡 Qué significa: Intentaste acceder a un usuario que no existe. Verifica que el ID sea correcto.

2️⃣ Token expirado

{
  "error": "TOKEN_EXPIRED",
  "message": "El token de autenticación ha expirado",
  "code": 401,
  "timestamp": "2024-01-15T10:30:00Z"
}

💡 Qué significa: Tu sesión expiró. Necesitas hacer login nuevamente.

3️⃣ Sin conductores disponibles

{
  "error": "NO_DRIVERS_AVAILABLE",
  "message": "No hay conductores disponibles en tu área",
  "code": 404,
  "timestamp": "2024-01-15T10:30:00Z",
  "suggestion": "Intenta expandir el radio de búsqueda"
}

💡 Qué significa: No hay conductores cerca. Puedes esperar un poco o buscar en un área más amplia.

4️⃣ Pago fallido

{
  "error": "PAYMENT_FAILED",
  "message": "El pago no pudo ser procesado",
  "code": 422,
  "timestamp": "2024-01-15T10:30:00Z",
  "details": "Fondos insuficientes en la tarjeta"
}

💡 Qué significa: Tu tarjeta no tiene suficiente dinero. Verifica tu saldo o usa otra tarjeta.

5️⃣ Viaje ya cancelado

{
  "error": "RIDE_ALREADY_CANCELLED",
  "message": "Este viaje ya ha sido cancelado",
  "code": 409,
  "timestamp": "2024-01-15T10:30:00Z"
}

💡 Qué significa: Este viaje ya fue cancelado antes. Si necesitas transporte, solicita un nuevo viaje.


🚀 Propuestas de Mejora

📱 1. Sistema de Notificaciones Push

Implementar notificaciones en tiempo real para informar sobre cambios de estado de viajes, mensajes de conductores, y promociones. Esto mejoraría significativamente la experiencia del usuario al mantenerlos informados sin necesidad de refrescar la aplicación.

💡 Ejemplo simple: Cuando un conductor acepta tu viaje, recibes una notificación inmediata en tu teléfono.

🗺️ 2. Integración con Mapas Avanzados

Agregar funcionalidades como navegación integrada, estimación de tráfico en tiempo real, y rutas optimizadas. Esto ayudaría a conductores a tomar mejores decisiones de ruta y mejorar la eficiencia del servicio.

💡 Ejemplo simple: El conductor ve la mejor ruta considerando el tráfico actual, no solo la distancia más corta.

💬 3. Sistema de Chat en Tiempo Real

Permitir comunicación directa entre pasajero y conductor durante el viaje activo. Esto facilitaría la coordinación de encuentros y resolvería dudas sin necesidad de llamadas telefónicas.

💡 Ejemplo simple: El pasajero puede escribir "Estoy en la puerta azul" y el conductor lo ve inmediatamente.

🎁 4. Programa de Fidelidad y Recompensas

Implementar un sistema de puntos que los usuarios puedan acumular por viajes frecuentes y canjear por descuentos o beneficios. Esto aumentaría la retención de usuarios y fomentaría el uso regular de la plataforma.

💡 Ejemplo simple: Por cada viaje ganas puntos, y con 100 puntos puedes obtener un viaje gratis.

🤖 5. Análisis Predictivo y Machine Learning

Usar datos históricos para predecir demanda, optimizar precios dinámicos, y sugerir mejores ubicaciones para conductores. Esto mejoraría la eficiencia operativa y la satisfacción tanto de conductores como pasajeros.

💡 Ejemplo simple: El sistema aprende que en el centro a las 5 PM siempre hay mucha demanda, entonces sugiere a los conductores ir ahí.

Developed with ❤️
🔥 Visit my GitHub 🚀

About

🚗 UBER Type Transport System An endpoint is a specific URL from which an application can access a service or request. This is a direction that allows you to communicate with the server to obtain data or carry out actions.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published