Integración con la API - FactoriaF5-Asturias/project-p5-digital-academy-team3-restaurant-frontend GitHub Wiki

Descripción de cómo el frontend se comunica con el backend: servicios, autenticación, manejo de errores y endpoints consumidos.


URL base

Todas las peticiones se construyen a partir de la variable de entorno VITE_API_URL, definida en el archivo .env del proyecto:

VITE_API_URL=http://localhost:8080

Se accede desde el código con import.meta.env.VITE_API_URL. En desarrollo se usa el backend local. En producción, esta variable se sustituye por la URL real del backend desplegado.


Servicios

Los servicios encapsulan las peticiones a la API. Viven en src/services/ y cada uno agrupa las operaciones de un dominio. Todos usan fetch con la URL base.

AuthService.js

Gestión de la sesión.

Función Método HTTP Endpoint Auth
login(username, password) POST /api/v1/auth/token No
changePassword(username, currentPassword, newPassword) POST /api/v1/auth/change-password No

Devuelve { token } en ambos casos. Los errores incluyen status para que el componente pueda diferenciar entre 401, 409, etc.

ProductService.js

Catálogo de productos y categorías.

Función Método HTTP Endpoint Auth
getProducts() GET /api/v1/products No
getCategories() GET /api/v1/categories No
getAdminProducts(token) GET /api/v1/admin/products Sí (Bearer)
createProduct(productData) POST /api/v1/products Sí (Bearer)
updateProducts(productId, productData) PUT /api/v1/products/:id Sí (Bearer)
deleteProduct(productId) DELETE /api/v1/products/:id Sí (Bearer)

CartService.js

Creación de pedidos.

Función Método HTTP Endpoint Auth
createOrder({ items, orderTypeName, paymentMethodName, tabletId }) POST /api/v1/orders No

Devuelve el pedido creado, incluyendo su id.

OrderService.js

Listado y gestión de pedidos (uso interno del panel de admin y del dashboard de cocina).

Función Método HTTP Endpoint Auth
fetchOrders() GET /api/v1/orders Sí (Bearer)
updateOrderStatus(orderId, statusName) PUT /api/v1/orders/:id/status Sí (Bearer)

ReportService.js

Informes de ventas y descarga de PDF.

Función Método HTTP Endpoint Auth
fetchSalesSummary(period) GET /api/v1/invoices/totals + /api/v1/invoices Sí (Bearer)
fetchReportDocuments() GET /api/v1/invoices/totals Sí (Bearer)
downloadReportPdf(url, fileName) GET /api/v1/invoices/report/pdf?period=... Sí (Bearer)
openReportPdf(url) GET /api/v1/invoices/report/pdf?period=... Sí (Bearer)

fetchSalesSummary combina dos peticiones para construir el resumen y los datos del gráfico. Los periodos disponibles son day, month, quarter y year.


Autenticación

El backend usa JWT con firma HMAC-SHA512. El login devuelve un token que el frontend guarda en localStorage bajo la clave giacobello-token.

Obtención del token

  1. El cliente envía POST /api/v1/auth/token con usuario y contraseña.
  2. El backend responde con { token } si las credenciales son válidas.
  3. useAuth guarda el token en localStorage y decodifica su payload para extraer sub (username), roles y exp.

Envío del token

Los endpoints protegidos requieren la cabecera:

Authorization: Bearer <token>

Cada servicio que necesita autenticación lee el token de localStorage y construye la cabecera. El patrón es el siguiente:

function getAuthHeaders() {
    const token = localStorage.getItem('giacobello-token')
    return token ? { Authorization: `Bearer ${token}` } : {}
}

Borrado del token

logout() en useAuth elimina el token de localStorage y limpia el estado. El guard del router, al no encontrar token, redirige a /login en la siguiente navegación a una ruta protegida.


Manejo de errores

Los servicios comprueban response.ok después de cada petición. Si el status no está en el rango 2xx, lanzan un Error.

Para errores que el componente necesita diferenciar (login, cambio de contraseña), el Error incluye el status HTTP:

if (!response.ok) {
    const error = new Error('Login failed')
    error.status = response.status
    throw error
}

En los componentes se maneja con un try/catch:

  • 401 Unauthorized: credenciales incorrectas.
  • 400 Bad Request: datos inválidos (por ejemplo, nueva contraseña igual a la actual).
  • 409 Conflict: conflicto de estado (contraseña que requiere cambio, producto duplicado).
  • 403 Forbidden: sin permisos para el recurso.
  • 404 Not Found: recurso inexistente.
  • 500 Internal Server Error: error del servidor.

Los servicios que no requieren esta granularidad lanzan errores con un mensaje descriptivo:

throw new Error(`Error al cargar productos: ${response.status}`)

Endpoints consumidos

Resumen de endpoints que el frontend consume. Para el detalle completo de request y response, consultar el repositorio del backend.

Autenticación

Método Endpoint Auth
POST /api/v1/auth/token No
POST /api/v1/auth/change-password No

Productos y categorías

Método Endpoint Auth
GET /api/v1/products No
GET /api/v1/admin/products Bearer
POST /api/v1/products Bearer
PUT /api/v1/products/:id Bearer
DELETE /api/v1/products/:id Bearer
GET /api/v1/categories No

Pedidos

Método Endpoint Auth
POST /api/v1/orders No
GET /api/v1/orders Bearer
GET /api/v1/orders/:id Bearer
PUT /api/v1/orders/:id/status Bearer

Facturas e informes

Método Endpoint Auth
GET /api/v1/invoices Bearer
GET /api/v1/invoices/totals Bearer
GET /api/v1/invoices/report/pdf?period=... Bearer

Imágenes

Las imágenes de producto se sirven desde el backend en /images/**. En el frontend, el ProductCard prefija la imageUrl relativa con VITE_API_URL para construir la URL completa.


CORS y proxy

El backend permite peticiones desde http://localhost:5173 (el puerto por defecto de Vite). El CORS se configura en SecurityConfig.java del backend.

El frontend, además, tiene un proxy de Vite configurado en vite.config.js para las rutas /api e /images. Las peticiones a esas rutas desde el navegador se redirigen automáticamente al backend en http://localhost:8080. Esto permite usar rutas relativas en desarrollo y evita problemas de CORS en algunos casos.

En producción, si el frontend y el backend están en dominios distintos, la variable VITE_API_URL apunta a la URL absoluta del backend y el proxy de Vite deja de ser necesario.

⚠️ **GitHub.com Fallback** ⚠️