Cómo se usa la IA aquí. Los fragmentos son código real del repositorio.
Usuario a ser usado: almacen@demo.empresa.mx (contraseña Demo2026!)
Herramientas que expone a la IA (8):
consultar_existenciasconsultar_trazabilidad_lotelistar_articulos_bajo_minimolistar_movimientos_articulocrear_articuloregistrar_movimiento_inventariocrear_orden_operacioncrear_almacen
Ruta base en Nexus: /inventario-operaciones-ms/v1
01 Herramienta de lectura: consulta el servicio y devuelve datos
Herramienta de lectura: consulta el servicio y devuelve datos.
@Tool(name = "consultar_existencias",
description = "Devuelve las existencias de un artículo por almacén: cantidad, reservado y disponible. Requiere el identificador UUID del artículo.")
public String consultarExistencias(
@ToolParam(description = "Identificador UUID del artículo", required = true) String articuloId) {
RegistroHerramientasUsadas.registrar("consultar_existencias");
String cuerpo = gateway.get()
.uri(constructor -> constructor.path(RUTA_BASE + "/existencias")
.queryParam("articulo", UUID.fromString(articuloId.trim()))
.build())
.retrieve()
.body(String.class);
return FiltroDatosSensibles.redactar(cuerpo).texto();
}
Qué hace: Llama al gateway con la ruta del servicio y devuelve el resultado al modelo.
02 Herramienta de escritura: prepara la acción y NO la ejecuta
Herramienta de escritura: prepara la acción y NO la ejecuta.
@Tool(name = "registrar_movimiento_inventario",
description = "Prepara un movimiento de inventario: entrada, salida, ajuste o reserva. NO lo registra: devuelve "
+ "un resumen y un accion_id. El usuario debe confirmarlo en la aplicación. Solo ALMACEN puede usarla.")
public String registrarMovimientoInventario(
@ToolParam(description = "Identificador UUID del artículo", required = true) String articuloId,
@ToolParam(description = "Identificador UUID del almacén", required = true) String almacenId,
@ToolParam(description = "Tipo: ENTRADA, SALIDA, AJUSTE o RESERVA", required = true) String tipo,
@ToolParam(description = "Cantidad mayor a cero, hasta 3 decimales", required = true) String cantidad,
@ToolParam(description = "Lote, opcional, de hasta 60 caracteres", required = false) String lote,
@ToolParam(description = "Referencia, opcional, de hasta 100 caracteres", required = false) String referencia) {
RegistroHerramientasUsadas.registrar("registrar_movimiento_inventario");
if (acciones == null) {
return NO_DISPONIBLE;
}
UUID articulo = identificador(articuloId);
UUID almacen = identificador(almacenId);
if (articulo == null || almacen == null) {
return "El identificador del artículo y del almacén deben ser UUID válidos.";
}
String tipoNormalizado = normalizar(tipo);
if (!TIPOS_MOVIMIENTO.contains(tipoNormalizado)) {
return "El tipo debe ser ENTRADA, SALIDA, AJUSTE o RESERVA.";
}
BigDecimal cant = decimal(cantidad, 3, 9);
if (cant == null || cant.signum() <= 0) {
return "La cantidad debe ser mayor a cero, con hasta 3 decimales y 9 dígitos enteros.";
}
if (!vacio(lote) && lote.trim().length() > 60) {
return "El lote no puede tener más de 60 caracteres.";
}
if (!vacio(referencia) && referencia.trim().length() > 100) {
return "La referencia no puede tener más de 100 caracteres.";
}
Map<String, Object> cuerpo = new LinkedHashMap<>();
cuerpo.put("articuloId", articulo.toString());
cuerpo.put("almacenId", almacen.toString());
cuerpo.put("tipo", tipoNormalizado);
cuerpo.put("cantidad", cant);
if (!vacio(lote)) {
cuerpo.put("lote", lote.trim());
}
if (!vacio(referencia)) {
cuerpo.put("referencia", referencia.trim());
}
// Clave única por acción: si el movimiento se reintenta, inventario no lo aplica dos veces.
cuerpo.put("idempotencyKey", java.util.UUID.randomUUID().toString());
String resumen = "Movimiento " + tipoNormalizado + " de " + cant.stripTrailingZeros().toPlainString()
+ " del artículo " + articulo + " en el almacén " + almacen;
return guardar(AccionesPendientes.TIPO_MOVIMIENTO_REGISTRAR, cuerpo, resumen, "Movimiento preparado, no registrado.");
}
Qué hace: La acción queda pendiente hasta que la persona confirma con el código.
03 Ruta base del servicio dentro de Nexus
Ruta base del servicio dentro de Nexus.
static final String RUTA_BASE = "/inventario-operaciones-ms/v1";
Qué hace: Todas las herramientas de este módulo se construyen sobre esta ruta.
Regla del proyecto: la IA propone o prepara; la persona confirma con el código de 8 dígitos. Ninguna herramienta de escritura cambia datos por sí sola.