Apariencia
Tipos de Servicio
Endpoint
GET /api/v2/typesDescripción
Retorna la lista completa de tipos de servicio disponibles en el ecosistema TSALVA con sus identificadores de integración y requisitos específicos.
Información proporcionada:
- 🆔 ID único para usar en otras operaciones
- 📝 Nombre descriptivo del tipo de servicio
- 📍 Indicadores de si requiere origen y/o destino
Uso recomendado:
Consultar antes de crear ofertas para validar tipos de servicio disponibles y sus requisitos.
Autenticación
Authorization: Basic <credentials>Parámetros
Este endpoint no requiere parámetros en el body ni query string.
Respuesta
Éxito (200 Correcto)
json
[
{
"id": 1,
"type": "Conductor elegido",
"required_origin": true,
"required_destination": false
},
{
"id": 2,
"type": "Grúa Liviana",
"required_origin": true,
"required_destination": true
},
{
"id": 3,
"type": "Grúa Pesada",
"required_origin": true,
"required_destination": true
},
{
"id": 4,
"type": "Ambulancia Básica",
"required_origin": true,
"required_destination": true
},
{
"id": 5,
"type": "Mecánico en Sitio",
"required_origin": true,
"required_destination": false
}
]Estructura de Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | integer | Identificador único del tipo de servicio |
type | string | Nombre descriptivo del tipo de servicio |
required_origin | boolean | Si es obligatorio especificar punto de origen |
required_destination | boolean | Si es obligatorio especificar punto de destino |
Tipos de Servicio Comunes
Servicios de Grúa
| ID | Tipo | Origen | Destino | Descripción |
|---|---|---|---|---|
2 | Grúa Liviana | Sí | Sí | Para vehículos hasta 2.5 toneladas |
3 | Grúa Pesada | Sí | Sí | Para vehículos de gran tonelaje |
6 | Grúa Cama Baja | Sí | Sí | Para vehículos especiales |
Servicios Mecánicos
| ID | Tipo | Origen | Destino | Descripción |
|---|---|---|---|---|
5 | Mecánico en Sitio | Sí | No | Reparación en el lugar |
7 | Cambio de Llanta | Sí | No | Servicio de llanta ponchada |
8 | Carga de Batería | Sí | No | Asistencia eléctrica |
Servicios Médicos
| ID | Tipo | Origen | Destino | Descripción |
|---|---|---|---|---|
4 | Ambulancia Básica | Sí | Sí | Traslado médico básico |
9 | Ambulancia UCI | Sí | Sí | Cuidados intensivos móvil |
Servicios de Transporte
| ID | Tipo | Origen | Destino | Descripción |
|---|---|---|---|---|
1 | Conductor elegido | Sí | No | Conductor para vehículo del cliente |
10 | Taxi de Emergencia | Sí | Sí | Transporte alternativo |
Ejemplos de Código
cURL
bash
curl -X GET "[URL_API]/api/v2/types" \
--user "tu_usuario:tu_password" \
-H "Content-Type: application/json"JavaScript
javascript
const obtenerTiposServicio = async () => {
const response = await fetch('[URL_API]/api/v2/types', {
method: 'GET',
headers: {
'Authorization': `Basic ${btoa('usuario:password')}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Error HTTP: ${response.status}`);
}
return await response.json();
};
// Uso
obtenerTiposServicio()
.then(tipos => {
console.log('Tipos disponibles:');
tipos.forEach(tipo => {
console.log(`${tipo.id}: ${tipo.type}`);
console.log(` Origen requerido: ${tipo.required_origin}`);
console.log(` Destino requerido: ${tipo.required_destination}`);
});
})
.catch(error => console.error('Error:', error));Python
python
import requests
from requests.auth import HTTPBasicAuth
def obtener_tipos_servicio():
response = requests.get(
'[URL_API]/api/v2/types',
auth=HTTPBasicAuth('usuario', 'password')
)
response.raise_for_status()
return response.json()
# Uso
try:
tipos = obtener_tipos_servicio()
print("Tipos de servicio disponibles:")
for tipo in tipos:
print(f"ID {tipo['id']}: {tipo['type']}")
print(f" Origen: {'Requerido' if tipo['required_origin'] else 'Opcional'}")
print(f" Destino: {'Requerido' if tipo['required_destination'] else 'Opcional'}")
print()
except requests.exceptions.RequestException as e:
print(f"Error: {e}")Validación de Requisitos
Validar antes de crear oferta
javascript
async function validarTipoServicio(tipoId, tieneDestino) {
const tipos = await obtenerTiposServicio();
const tipoSeleccionado = tipos.find(t => t.id === parseInt(tipoId));
if (!tipoSeleccionado) {
throw new Error(`Tipo de servicio ${tipoId} no existe`);
}
if (tipoSeleccionado.required_destination && !tieneDestino) {
throw new Error(`Tipo "${tipoSeleccionado.type}" requiere punto de destino`);
}
return tipoSeleccionado;
}
// Uso en creación de oferta
const crearOferta = async (datosOferta) => {
// Validar tipo de servicio
await validarTipoServicio(
datosOferta.tipoServicio,
!!(datosOferta.latitudDestino && datosOferta.longitudDestino)
);
// Proceder con la creación...
};Helper para UI/Forms
javascript
// Filtrar tipos según necesidades
function filtrarTiposPorRequisitos(tipos, soloOrigen = false) {
if (soloOrigen) {
return tipos.filter(tipo =>
tipo.required_origin && !tipo.required_destination
);
}
return tipos;
}
// Generar opciones para select/dropdown
function generarOpcionesSelect(tipos) {
return tipos.map(tipo => ({
value: tipo.id,
label: tipo.type,
requiresDestination: tipo.required_destination
}));
}Cache de Tipos de Servicio
Los tipos de servicio cambian raramente, por lo que es recomendable implementar cache:
Implementación con TTL
javascript
class TiposServicioCache {
constructor(ttlMinutos = 60) {
this.cache = null;
this.lastFetch = null;
this.ttl = ttlMinutos * 60 * 1000; // convertir a ms
}
async obtenerTipos() {
const ahora = Date.now();
// Verificar si cache es válido
if (this.cache && this.lastFetch && (ahora - this.lastFetch < this.ttl)) {
return this.cache;
}
// Obtener datos frescos
try {
this.cache = await obtenerTiposServicio();
this.lastFetch = ahora;
return this.cache;
} catch (error) {
// Si hay error pero tenemos cache, devolver cache
if (this.cache) {
console.warn('Error obteniendo tipos, usando cache:', error);
return this.cache;
}
throw error;
}
}
invalidarCache() {
this.cache = null;
this.lastFetch = null;
}
}
// Uso
const tiposCache = new TiposServicioCache(30); // 30 minutos TTL
async function obtenerTiposCacheados() {
return await tiposCache.obtenerTipos();
}Casos de Uso por Tipo
Ejemplo: Validación dinámica en formulario
javascript
// React/Vue component example
const FormularioOferta = () => {
const [tipoSeleccionado, setTipoSeleccionado] = useState(null);
const [mostrarDestino, setMostrarDestino] = useState(false);
const handleTipoChange = (tipoId) => {
const tipo = tipos.find(t => t.id === parseInt(tipoId));
setTipoSeleccionado(tipo);
setMostrarDestino(tipo?.required_destination || false);
};
return (
<form>
<select onChange={(e) => handleTipoChange(e.target.value)}>
{tipos.map(tipo => (
<option key={tipo.id} value={tipo.id}>
{tipo.type}
</option>
))}
</select>
{/* Origen - siempre visible */}
<input placeholder="Dirección de origen" required />
{/* Destino - condicional */}
{mostrarDestino && (
<input placeholder="Dirección de destino" required />
)}
</form>
);
};Recomendación
Consulta este endpoint al inicializar tu aplicación y guarda los tipos en cache local. Los tipos de servicio raramente cambian durante el día.
Importante
Siempre valida que el tipo de servicio seleccionado por el usuario exista y cumpla con los requisitos de origen/destino antes de crear una oferta.