Bodegas
Bodegas
Prefijo: /api/bodegas
Requiere Auth: Sí
Permiso requerido: bodegas, *
Módulo de bodegas (almacenes) para asignar productos a un lugar físico de inventario. Cada tenant puede tener como máximo 3 bodegas activas.
Notas de negocio
- Límite de 3 bodegas activas por tenant:
POST /api/bodegas/responde403 Forbiddenal exceder el cupo. Eliminar una bodega (soft delete) libera el cupo. - Soft delete:
DELETEmarcadeleted_at; las bodegas eliminadas no aparecen en listados ni cuentan para el límite. - Nombre único por tenant: no puede existir otra bodega activa con el mismo
nombreen el mismo tenant (409 Conflict). - Paginación: todos los GET listados devuelven el header
X-Total-Countcon el total de registros.
GET /api/bodegas/
Descripción: Lista las bodegas activas del tenant con paginación
Requiere Auth: Sí
Permiso requerido: bodegas, leer
Parámetros query:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
skip | int | ❌ | Registros a saltar (default 0) |
limit | int | ❌ | Máximo de registros (default 100) |
Respuesta exitosa: 200 OK (+ header X-Total-Count)
Response:
[ { "id": 1, "nombre": "Bodega Central", "direccion": "Cra 1 # 2-3", "activa": true, "tenant_id": "uuid-tenant", "created_at": "2026-10-20T10:00:00" }]cURL:
curl "http://localhost/api/bodegas/?skip=0&limit=10" -H "Authorization: Bearer <token>"Python:
import httpxresp = httpx.get("http://localhost/api/bodegas/", headers={"Authorization": f"Bearer {token}"})bodegas = resp.json()JavaScript:
const resp = await fetch('http://localhost/api/bodegas/?skip=0&limit=10', { headers: {'Authorization': `Bearer ${token}`}});const bodegas = await resp.json();GET /api/bodegas/search
Descripción: Busca bodegas por nombre o dirección
Requiere Auth: Sí
Permiso requerido: bodegas, leer
Parámetros query:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
termino | string | ✅ | Término de búsqueda (nombre o dirección) |
skip | int | ❌ | Registros a saltar (default 0) |
limit | int | ❌ | Máximo de registros (default 100) |
Respuesta exitosa: 200 OK
cURL:
curl "http://localhost/api/bodegas/search?termino=central" -H "Authorization: Bearer <token>"Python:
import httpxresp = httpx.get("http://localhost/api/bodegas/search", params={"termino": "central"}, headers={"Authorization": f"Bearer {token}"})bodegas = resp.json()JavaScript:
const resp = await fetch('http://localhost/api/bodegas/search?termino=central', { headers: {'Authorization': `Bearer ${token}`}});const bodegas = await resp.json();GET /api/bodegas/:bodega_id
Descripción: Obtiene una bodega por ID
Requiere Auth: Sí
Permiso requerido: bodegas, leer
Respuesta exitosa: 200 OK
Errores: 404 (no encontrada)
cURL:
curl http://localhost/api/bodegas/1 -H "Authorization: Bearer <token>"POST /api/bodegas/
Descripción: Crea una nueva bodega (valida límite de 3 por tenant)
Requiere Auth: Sí
Permiso requerido: bodegas, crear
Request:
{ "nombre": "Bodega Central", "direccion": "Cra 1 # 2-3"}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
nombre | string | ✅ | Nombre de la bodega (máx. 80 chars, único por tenant) |
direccion | string | ❌ | Ubicación física (máx. 120 chars) |
Respuesta exitosa: 201 Created
Errores:
| Código | Causa | Solución |
|---|---|---|
403 | Límite de 3 bodegas alcanzado | Elimine una bodega existente primero |
409 | Ya existe una bodega con ese nombre en el tenant | Use otro nombre o actualice la existente |
cURL:
curl -X POST http://localhost/api/bodegas/ \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '{"nombre":"Bodega Central","direccion":"Cra 1 # 2-3"}'Python:
import httpxresp = httpx.post("http://localhost/api/bodegas/", json={"nombre": "Bodega Central", "direccion": "Cra 1 # 2-3"}, headers={"Authorization": f"Bearer {token}"})bodega = resp.json()JavaScript:
const resp = await fetch('http://localhost/api/bodegas/', { method: 'POST', headers: {'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`}, body: JSON.stringify({nombre: 'Bodega Central', direccion: 'Cra 1 # 2-3'})});PUT /api/bodegas/:bodega_id
Descripción: Actualiza una bodega
Requiere Auth: Sí
Permiso requerido: bodegas, actualizar
Request: todos los campos opcionales (parcial update)
{ "nombre": "Bodega Central Norte", "direccion": "Cra 10 # 20-30", "activa": true}Respuesta exitosa: 200 OK
Errores: 404 (no encontrada), 409 (nombre duplicado en otro registro)
cURL:
curl -X PUT http://localhost/api/bodegas/1 \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '{"nombre":"Bodega Central Norte"}'DELETE /api/bodegas/:bodega_id
Descripción: Elimina una bodega (soft delete — libera cupo del límite de 3)
Requiere Auth: Sí
Permiso requerido: bodegas, eliminar
Respuesta exitosa: 204 No Content
Errores: 404 (no encontrada)
cURL:
curl -X DELETE http://localhost/api/bodegas/1 -H "Authorization: Bearer <token>"Tabla de errores general
| Código | Causa | Solución |
|---|---|---|
401 | Token expirado o inválido | Re-login |
403 | Sin permiso bodegas, <acción> / límite de 3 bodegas | Solicitar permiso a admin / eliminar bodega |
404 | Bodega no encontrada | Verificar ID |
409 | Nombre de bodega duplicado en el tenant | Usar otro nombre |