Skip to content

Api rest - Endpoints #12

@manugbd

Description

@manugbd

Especificación de la API Técnica - Carburo v1

Esta documentación detalla los endpoints, la estructura de datos, el flujo de seguridad y la gestión de errores de la API REST v1. Todas las respuestas exitosas de la API devuelven una estructura estándar con código HTTP 200 OK.


1. Arquitectura de Seguridad

La API se divide en dos entornos de seguridad diferenciados por la ruta de acceso (requestMatchers):

Endpoints Públicos (/api/v1/public/**)

  • Mecanismo de Seguridad: Protegido globalmente por API Key.
  • Cabecera Requerida: X-API-KEY: <clave_aplicacion>
  • Filtro Aplicado: ApiKeyFilter. Si falta la clave o es incorrecta, intercepta la petición antes de llegar al controlador y retorna inmediatamente un estado HTTP 401 Unauthorized.
  • Autenticación: No requiere credenciales ni tokens de usuario.
{
    "success": false,
    "error": {
        "error": "UNAUTHORIZED",
        "message": "Invalid API key"
    },
    "timestamp": "2026-05-29T10:40:08.403471762Z"
}

Endpoints Privados/Protegidos (/api/v1/** excluyendo /public/**)

  • Mecanismo de Seguridad: Protegido por JWT (JSON Web Token) de Supabase.
  • Cabecera Requerida: Authorization: Bearer <token_jwt>
  • Filtro Aplicado: SupabaseJwtFilter. Descarga las claves públicas (JWKS) desde la URL de Supabase para validar la firma, vigencia del token (TokenExpiredException) e identidad del emisor.
  • Validación Cruzada de Propiedad (Ownership): En los endpoints que involucran un parámetro UUID en la ruta, se ejecuta el método validateOwnership(UUID requestUuid). Este extrae el JwtUser del contexto de seguridad de Spring (SecurityContextHolder) y comprueba de forma estricta que coincida con el de la petición. Si no coinciden, se lanza una excepción UnauthorizedException con el mensaje "UUID mismatch".
{
    "success": false,
    "error": {
        "error": "UNAUTHORIZED",
        "message": "Invalid token"
    },
    "timestamp": "2026-05-29T10:40:58.459608195Z"
}

2. Estructura Estándar de Respuestas

Todas las peticiones devuelven un objeto JSON con la misma estructura base parametrizada (ApiResponse):

Respuesta Exitosa

{
  "success": true,
  "data": { ... },
  "timestamp": "2026-05-29T10:32:42Z"
}

Respuesta de Error

{
  "success": false,
  "error": {
    "error": "CODIGO_DE_ERROR",
    "message": "Descripción detallada del error o causa de la excepción"
  },
  "timestamp": "2026-05-29T10:32:45Z"
}

3. Matriz de Gestión de Errores y Estados HTTP

La lógica interna intercepta excepciones globales mediante GlobalExceptionHandler mapeándolas a respuestas JSON estandarizadas:

Excepción Java Código HTTP Código Interno (error) Contexto de Activación
ResourceNotFoundException / NotFoundException 404 Not Found ERR_NOT_FOUND El recurso solicitado (Usuario, Vehículo, Combustible) no existe en BBDD.
UnauthorizedException / TokenExpiredException 401 Unauthorized ERR_UNAUTHORIZED Token JWT expirado, firma inválida, API key errónea o discrepancia de UUID (UUID mismatch).
MethodArgumentTypeMismatchException 404 Bad Request ERR_BAD_REQUEST Tipos de datos inválidos en el Path o Query Parameters (ej. un String en un ID numérico).
HttpMessageNotReadableException 400 Bad Request ERR_BAD_REQUEST El cuerpo de la petición (@RequestBody) contiene un JSON mal formado sintácticamente.
MethodArgumentNotValidException 400 Bad Request ERR_BAD_REQUEST Fallo en las restricciones de validación del DTO. Retorna el primer campo que incumpla.
InvalidUsuarioDataException / InvalidVehiculoDataException / InvalidRepostajeDataException 400 Bad Request ERR_BAD_REQUEST Datos del modelo semánticamente incorrectos o que violan reglas de negocio.
UsuarioAlreadyExistsException 409 Conflict ERR_USER_ALREADY_EXISTS Intento de registrar un UUID de usuario que ya se encuentra dado de alta en el sistema.

4. Modelos de Datos (DTOs)

GrupoCombustibleDto

  • id (short)
  • codigo (String)
  • combustibles (List<CombustibleDto>?)

CombustibleDto

  • id (short)
  • denominacion (String)
  • codigo (String)
  • id_grupo_combustible (Short?)

ComunidadAutonomaDto

  • id (short)
  • denominacion (String)
  • provincias (List<ProvinciaDto>)

ProvinciaDto

  • id (short)
  • denominacion (String)
  • id_comunidad_autonoma (short)
  • municipios (List<MunicipioDto>)

MunicipioDto

  • id (short)
  • denominacion (String)
  • id_provincia (short)

EstacionDeServicioDto

  • id (int)
  • rotulo (String)
  • horario (String)
  • direccion (String)
  • localidad (String)
  • codigo_postal (int)
  • id_municipio (short)
  • id_provincia (short)
  • latitud (double)
  • longitud (double)
  • margen (String)
  • remision (String)
  • venta (String)
  • x100BioEtanol (double)
  • x100EsterMetilico (double)
  • abierto (boolean)
  • distancia_metros (Long, opcional)
  • id_combustibles_disponibles (Set<Short>)
  • precios_de_combustibles (List<PrecioCombustibleDto>)

PrecioCombustibleDto

  • id_estacion_de_servicio (int)
  • id_combustible (short)
  • fecha (LocalDate - yyyy-MM-dd)
  • precio (double)

UsuarioDto

  • uuid (UUID)
  • id_provincia_favorita (short)
  • ids_combustibles_favoritos (Set<Short>)
  • ids_estaciones_de_servicio_favoritas (Set<Integer>)

VehiculoDto

  • id (int)
  • uuid_usuario_solicitante (UUID)
  • is_usuario_solicitante_propietario (boolean)
  • matricula (String?)
  • marca (String)
  • modelo (String)
  • odometro_actual (double)
  • capacidad_deposito (double)
  • notas (String?)
  • id_grupo_combustible (short)

RepostajeDto

  • id (int)
  • id_vehiculo (int)
  • id_combustible (short)
  • id_estacion_de_servicio (int)
  • uuid_usuario_creador (UUID)
  • fecha_repostaje (OffsetDateTime)
  • fecha_registro (OffsetDateTime)
  • cantidad (double)
  • coste_unitario (double)
  • odometro_inicial (Double?)
  • odometro_final (double)
  • deposito_lleno (boolean)
  • nota (String?)

5. Catálogo de Endpoints

5.1 Módulo Público (Seguridad: X-API-KEY)

Combustibles

  • GET /api/v1/public/combustibles
    • Descripción: Obtiene el listado maestro de combustibles del sistema.
    • Respuesta data: List<CombustibleDto>
  • GET /api/v1/public/grupos-de-combustibles
    • Descripción: Obtiene el listado maestro de grupos de combustibles del sistema.
    • Respuesta data: List<GrupoCombustibleDto>
  • GET /api/v1/public/grupos-de-combustibles/combustibles
    • Descripción: Obtiene el listado maestro de combustibles agrupados por los grupos de combustibles del sistema.
    • Respuesta data: List<GrupoCombustibleDto>

Comunidades Autónomas, Provincias y Municipios

  • GET /api/v1/public/comunidades-autonomas
    • Descripción: Obtiene las comunidades autónomas sin anidamiento profundo.
    • Respuesta data: List<ComunidadAutonomaDto>
  • GET /api/v1/public/comunidades-autonomas/provincias/municipios
    • Descripción: Devuelve todo el árbol geográfico completo (Comunidades -> Provincias -> Municipios anidados).
    • Respuesta data: List<ComunidadAutonomaDto>
  • GET /api/v1/public/provincias
    • Descripción: Obtiene el listado completo de provincias disponibles.
    • Respuesta data: List<ProvinciaDto>
  • GET /api/v1/public/municipios
    • Descripción: Obtiene el listado de todos los municipios del territorio nacional.
    • Respuesta data: List<MunicipioDto>
  • GET /api/v1/public/municipios/provincia/{id}
    • Descripción: Filtra municipios pertenecientes a una provincia específica.
    • Respuesta data: List<MunicipioDto>
  • GET /api/v1/public/municipios/provincia/{id}/con-estaciones-de-servicio
    • Descripción: Filtra municipios de una provincia que cuenten con al menos una estación de servicio activa.
    • Respuesta data: List<MunicipioDto>

Estaciones de Servicio

  • GET /api/v1/public/estaciones-de-servicio
    • Descripción: Listado global de estaciones de servicio.
    • Respuesta data: List<EstacionDeServicioDto>
  • GET /api/v1/public/estaciones-de-servicio/count
    • Descripción: Retorna el volumen totalizado de estaciones de servicio a nivel nacional.
    • Respuesta data: Long
  • GET /api/v1/public/estaciones-de-servicio/{id}
    • Descripción: Detalle de una estación. Permite calcular distancias de forma dinámica si se envían coordenadas opcionales.
    • Query Parameters:
      • latitud (Double, opcional)
      • longitud (Double, opcional)
    • Respuesta data: EstacionDeServicioDto (incluye distancia_metros si se calcularon coordenadas válidas).
  • GET /api/v1/public/estaciones-de-servicio/cercanas
    • Descripción: Geolocalización de estaciones cercanas a un punto geométrico.
    • Query Parameters (Obligatorios):
      • latitud (double): Rango válido de -90 a 90.
      • longitud (double): Rango válido de -180 a 180.
      • limite (int, opcional, por defecto 1): Capado internamente a un máximo de 10 si se excede o es inválido.
    • Respuesta data: List<EstacionDeServicioDto>
  • GET /api/v1/public/estaciones-de-servicio/municipio/{id}
    • Descripción: Estaciones ubicadas en el municipio indicado.
    • Respuesta data: List<EstacionDeServicioDto>
  • GET /api/v1/public/estaciones-de-servicio/provincia/{id}
    • Descripción: Estaciones ubicadas en la provincia indicada.
    • Respuesta data: List<EstacionDeServicioDto>
  • GET /api/v1/public/estaciones-de-servicio/comunidad-autonoma/{id}
    • Descripción: Estaciones ubicadas en la comunidad autónoma indicada.
    • Respuesta data: List<EstacionDeServicioDto>

Precios de Combustibles Históricos

  • GET /api/v1/public/estaciones-de-servicio/{id}/precios-combustibles
    • Descripción: Histórico de precios de los últimos X días para una estación específica.
    • Query Parameters: dias (int, opcional, por defecto 5).
    • Respuesta data: List<PrecioCombustibleDto>
  • GET /api/v1/public/estaciones-de-servicio/{id}/precios-combustibles/{fecha}
    • Descripción: Precios exactos registrados en una fecha determinada.
    • Path Variables: fecha (LocalDate formateado como yyyy-MM-dd).
    • Respuesta data: List<PrecioCombustibleDto>

5.2 Módulo de Usuarios (Seguridad: JWT + Ownership de UUID)

Base Path: /api/v1/usuarios

  • GET /api/v1/usuarios/{uuid}
    • Descripción: Obtiene los datos del perfil del usuario.
    • Respuesta data: UsuarioDto
  • HEAD /api/v1/usuarios/{uuid}
    • Descripción: Verificación rápida de la existencia del usuario. Retorna código HTTP 200 OK si el usuario existe o 404 Not Found en caso contrario (cuerpo vacío).
  • POST /api/v1/usuarios
    • Descripción: Registra un nuevo usuario en la base de datos centralizada. El UUID dentro del JSON del body debe validar contra el del JWT.
    • Body: UsuarioDto
    • Respuesta data: null
  • GET /api/v1/usuarios/{uuid}/provincia-favorita
    • Descripción: Obtiene la provincia de preferencia configurada por el usuario.
    • Respuesta data: Short
  • PATCH /api/v1/usuarios/{uuid}/provincia-favorita/{provinciaId}
    • Descripción: Modifica la provincia favorita.
    • Respuesta data: null
  • GET /api/v1/usuarios/{uuid}/combustibles-favoritos
    • Descripción: Conjunto de tipos de combustibles de uso común para el usuario.
    • Respuesta data: Set<Short>
  • PATCH /api/v1/usuarios/{uuid}/combustibles-favoritos
    • Descripción: Sobrescribe/reemplaza completamente la colección de combustibles preferidos.
    • Body: Set<Short>
    • Respuesta data: null
  • GET /api/v1/usuarios/{uuid}/estaciones-de-servicio-favoritas
    • Descripción: Obtiene el detalle de las estaciones guardadas como favoritas.
    • Respuesta data: List<EstacionDeServicioDto>
  • PATCH /api/v1/usuarios/{uuid}/estaciones-de-servicio-favoritas/{estacionId}
    • Descripción: Agrega una estación de servicio a su lista de favoritos.
    • Respuesta data: null
  • DELETE /api/v1/usuarios/{uuid}/estaciones-de-servicio-favoritas/{estacionId}
    • Descripción: Remueve la estación de la lista de favoritos.
    • Respuesta data: null

5.3 Módulo de Vehículos y Repostajes (Seguridad: JWT + Ownership de UUID)

Base Path: /api/v1/vehiculos

Regla de Negocio del Servicio Interno: Cualquier operación de escritura, actualización o borrado en este módulo invoca el método validateVehiculoExistsAndOwnership(uuid, idVehiculo, mustBeOwner). Éste no solo comprueba que el vehículo exista, sino que verifica en la tabla relacional (VehiculoUsuario) que el usuario esté vinculado al recurso y, si la operación lo requiere (mustBeOwner = true), exige que su rol sea estrictamente propietario para evitar manipulaciones de datos cruzados entre usuarios de la plataforma.

Gestión de Vehículos

  • GET /api/v1/vehiculos/{uuid}
    • Descripción: Recupera la flota de vehículos vinculados al usuario autenticado. No incluye la colección interna de repostajes.
    • Respuesta data: List<VehiculoDto>
  • GET /api/v1/vehiculos/{uuid}/{idVehiculo}
    • Descripción: Obtiene el detalle completo de un vehículo específico mapeando sus repostajes internos.
    • Respuesta data: VehiculoDto
  • POST /api/v1/vehiculos/{uuid}
    • Descripción: Da de alta un nuevo vehículo asignándolo al usuario.
    • Body: VehiculoDto
    • Respuesta data: Integer (ID autogenerado del vehículo creado).
  • PATCH /api/v1/vehiculos/{uuid}/{idVehiculo}
    • Descripción: Actualiza de forma parcial las propiedades permitidas de un vehículo.
    • Campos Modificables: matricula, marca, modelo, odometro_actual, capacidad_deposito, notas, ids_combustibles_utilizados.
    • Body: VehiculoDto
    • Respuesta data: null
  • DELETE /api/v1/vehiculos/{uuid}/{idVehiculo}
    • Descripción: Operación transaccional (@transactional) que elimina de forma definitiva el vehículo y purga en cascada todos los repostajes asociados en la base de datos tras verificar la propiedad legítima.
    • Respuesta data: null

Gestión de Repostajes

  • GET /api/v1/vehiculos/{uuid}/repostajes
    • Descripción: Historial consolidado de todos los repostajes recientes efectuados por el usuario, independientemente del vehículo implicado.
    • Respuesta data: List<RepostajeDto>
  • GET /api/v1/vehiculos/{uuid}/{idVehiculo}/repostajes
    • Descripción: Obtiene cronológicamente todos los repostajes asociados en exclusiva a un vehículo.
    • Respuesta data: List<RepostajeDto>
  • POST /api/v1/vehiculos/{uuid}/{idVehiculo}/repostajes
    • Descripción: Registra un nuevo repostaje. Valida previamente que el vehículo pertenezca al usuario, y la existencia tanto de la estación de servicio como del combustible seleccionado.
    • Body: RepostajeDto
    • Respuesta data: Integer (ID asignado al repostaje).
  • PATCH /api/v1/vehiculos/{uuid}/{idVehiculo}/repostajes/{idRepostaje}
    • Descripción: Actualiza los parámetros de un repostaje existente. Solamente se permite actualizar los datos de cantidad, coste unitario, odómetro inicial, odómetro final, si el depósito se llenó o no, y la nota.
    • Body: RepostajeDto
    • Respuesta data: null
  • DELETE /api/v1/vehiculos/{uuid}/{idVehiculo}/repostajes/{idRepostaje}
    • Descripción: Elimina un repostaje del sistema comprobando previamente la integridad de la jerarquía relacional de datos.
    • Respuesta data: null

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions