From 3c70eb5ff7a15a6e9a0a498de6d266c03025a0c9 Mon Sep 17 00:00:00 2001 From: Lucas Tettamanti Date: Sat, 2 May 2026 17:29:20 -0300 Subject: [PATCH] =?UTF-8?q?Sacar=20pesta=C3=B1a=20Test=20del=20admin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Borrado public/components/test-panel.js + su nav button + su rango de router + sus rutas /test/products-with-stock y /test/order. - Borrados handleGetProductsWithStock + handleCreateTestOrder y los api wrappers getProductsWithStock + createTestOrder. Ya no se usan en ningún flujo: pruebas de bot se hacen vía simulator. Co-Authored-By: Claude Opus 4.7 (1M context) --- public/app.js | 1 - public/components/ops-shell.js | 7 - public/components/test-panel.js | 391 ----------------------- public/lib/api.js | 12 - public/lib/router.js | 2 - src/modules/0-ui/controllers/testing.js | 34 +- src/modules/0-ui/handlers/testing.js | 51 +-- src/modules/1-intake/routes/simulator.js | 6 +- 8 files changed, 3 insertions(+), 501 deletions(-) delete mode 100644 public/components/test-panel.js diff --git a/public/app.js b/public/app.js index 77a3bc5..56f768b 100644 --- a/public/app.js +++ b/public/app.js @@ -10,7 +10,6 @@ import "./components/aliases-crud.js"; import "./components/recommendations-crud.js"; import "./components/quantities-crud.js"; import "./components/orders-crud.js"; -import "./components/test-panel.js"; import "./components/takeovers-crud.js"; import "./components/zone-map-editor.js"; import "./components/settings-crud.js"; diff --git a/public/components/ops-shell.js b/public/components/ops-shell.js index 63a6c8f..942877d 100644 --- a/public/components/ops-shell.js +++ b/public/components/ops-shell.js @@ -98,7 +98,6 @@ class OpsShell extends HTMLElement { Cantidades Pedidos Config - Test
@@ -164,12 +163,6 @@ class OpsShell extends HTMLElement {
-
-
- -
-
-
diff --git a/public/components/test-panel.js b/public/components/test-panel.js deleted file mode 100644 index a03a074..0000000 --- a/public/components/test-panel.js +++ /dev/null @@ -1,391 +0,0 @@ -import { api } from "../lib/api.js"; -import { modal } from "../lib/modal.js"; - -// Datos aleatorios para generar usuarios de prueba -const NOMBRES = ["Juan", "María", "Carlos", "Ana", "Pedro", "Laura", "Diego", "Sofía"]; -const APELLIDOS = ["García", "Rodríguez", "Martínez", "López", "González", "Fernández", "Pérez"]; -const CALLES = ["Av. Corrientes", "Av. Santa Fe", "Calle Florida", "Av. Rivadavia", "Av. Cabildo", "Av. Libertador"]; - -function randomItem(arr) { - return arr[Math.floor(Math.random() * arr.length)]; -} - -function randomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -function generateTestUser() { - const randomPhone = `549${randomInt(1000000000, 9999999999)}`; - const wa_chat_id = `${randomPhone}@s.whatsapp.net`; - const nombre = randomItem(NOMBRES); - const apellido = randomItem(APELLIDOS); - - return { - wa_chat_id, - phone: randomPhone, - name: `${nombre} ${apellido}`, - address: { - first_name: nombre, - last_name: apellido, - address_1: `${randomItem(CALLES)} ${randomInt(100, 9000)}`, - city: "CABA", - state: "Buenos Aires", - postcode: `${randomInt(1000, 1999)}`, - country: "AR", - phone: randomPhone, - email: `${randomPhone}@no-email.local`, - }, - }; -} - -class TestPanel extends HTMLElement { - constructor() { - super(); - this.attachShadow({ mode: "open" }); - this.products = []; - this.selectedProducts = []; - this.testUser = null; - this.lastOrder = null; - this.loading = false; - - this.shadowRoot.innerHTML = ` - - -
-
-
1. Generar Orden de Prueba
- -
-
- - -
-
- -
-
Productos seleccionados
-
-
Click "Generar Orden Aleatoria" para comenzar
-
-
- -
-
Datos del usuario
- -
- -
- -
- - -
-
- `; - } - - connectedCallback() { - this.shadowRoot.getElementById("btnGenerate").onclick = () => this.generateRandomOrder(); - this.shadowRoot.getElementById("btnClear").onclick = () => this.clearAll(); - this.shadowRoot.getElementById("btnCreateOrder").onclick = () => this.createOrder(); - - this.loadProducts(); - } - - async loadProducts() { - try { - const result = await api.getProductsWithStock(); - this.products = result.items || []; - console.log(`[test-panel] Loaded ${this.products.length} products with stock`); - } catch (e) { - console.error("[test-panel] Error loading products:", e); - } - } - - async generateRandomOrder() { - if (this.products.length === 0) { - await this.loadProducts(); - } - - if (this.products.length === 0) { - modal.warn("No hay productos con stock disponible"); - return; - } - - // Generar usuario aleatorio - this.testUser = generateTestUser(); - - // Seleccionar 1-3 productos aleatorios - const numProducts = randomInt(1, Math.min(3, this.products.length)); - const shuffled = [...this.products].sort(() => Math.random() - 0.5); - this.selectedProducts = []; - - for (let i = 0; i < numProducts; i++) { - const product = shuffled[i]; - const isKg = product.sell_unit === "kg"; - const quantity = isKg ? randomInt(200, 2000) : randomInt(1, 5); - - this.selectedProducts.push({ - product_id: product.woo_product_id, - name: product.name, - quantity, - unit: isKg ? "kg" : "unit", - price: product.price, - }); - } - - this.renderProductList(); - this.renderUserInfo(); - this.updateButtonStates(); - } - - renderProductList() { - const container = this.shadowRoot.getElementById("productList"); - - if (this.selectedProducts.length === 0) { - container.innerHTML = `
Click "Generar Orden Aleatoria" para comenzar
`; - return; - } - - container.innerHTML = this.selectedProducts.map((p, i) => ` -
-
${p.name}
-
${p.unit === "kg" ? `${p.quantity}g` : `${p.quantity}u`}
-
$${Number(p.price || 0).toFixed(0)}
- -
- `).join(""); - - container.querySelectorAll(".remove-btn").forEach(btn => { - btn.onclick = (e) => { - const idx = parseInt(e.target.dataset.index); - this.selectedProducts.splice(idx, 1); - this.renderProductList(); - this.updateButtonStates(); - }; - }); - } - - renderUserInfo() { - const container = this.shadowRoot.getElementById("userInfo"); - - if (!this.testUser) { - container.innerHTML = `
Se generarán automáticamente
`; - return; - } - - const addr = this.testUser.address; - container.innerHTML = ` -
Nombre: ${addr.first_name} ${addr.last_name}
-
Dirección: ${addr.address_1}
-
Ciudad: ${addr.city}, ${addr.state}
-
Teléfono: ${addr.phone}
-
Email: ${addr.email}
- `; - } - - updateButtonStates() { - const hasProducts = this.selectedProducts.length > 0; - this.shadowRoot.getElementById("btnCreateOrder").disabled = !hasProducts; - } - - async createOrder() { - if (this.loading) return; - this.loading = true; - - const btn = this.shadowRoot.getElementById("btnCreateOrder"); - btn.disabled = true; - btn.textContent = "Creando..."; - - try { - const basket = { - items: this.selectedProducts.map(p => ({ - product_id: p.product_id, - quantity: p.quantity, - unit: p.unit, - })), - }; - - const result = await api.createTestOrder({ - basket, - address: this.testUser?.address || null, - wa_chat_id: this.testUser?.wa_chat_id || null, - }); - - if (result.ok) { - this.lastOrder = result; - this.shadowRoot.getElementById("orderIdValue").textContent = `#${result.woo_order_id}`; - this.shadowRoot.getElementById("orderTotalValue").textContent = `$${Number(result.total || 0).toFixed(2)}`; - this.shadowRoot.getElementById("orderResult").style.display = "block"; - this.shadowRoot.getElementById("inputAmount").value = result.total || ""; - } else { - modal.error("Error: " + (result.error || "Error desconocido")); - } - } catch (e) { - console.error("[test-panel] createOrder error:", e); - modal.error("Error creando orden: " + e.message); - } finally { - this.loading = false; - btn.textContent = "Crear Orden en WooCommerce"; - this.updateButtonStates(); - } - } - - clearAll() { - this.selectedProducts = []; - this.testUser = null; - this.lastOrder = null; - - this.renderProductList(); - this.renderUserInfo(); - this.updateButtonStates(); - - this.shadowRoot.getElementById("orderResult").style.display = "none"; - } -} - -customElements.define("test-panel", TestPanel); diff --git a/public/lib/api.js b/public/lib/api.js index 495cf90..a8bd68f 100644 --- a/public/lib/api.js +++ b/public/lib/api.js @@ -234,18 +234,6 @@ export const api = { return this.listOrders({ page: 1, limit }); }, - async getProductsWithStock() { - return fetch("/test/products-with-stock").then(r => r.json()); - }, - - async createTestOrder({ basket, address, wa_chat_id }) { - return fetch("/test/order", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ basket, address, wa_chat_id }), - }).then(r => r.json()); - }, - // --- Prompts CRUD --- async prompts() { return fetch("/prompts").then(r => r.json()); diff --git a/public/lib/router.js b/public/lib/router.js index 3b577cc..42f25bf 100644 --- a/public/lib/router.js +++ b/public/lib/router.js @@ -16,7 +16,6 @@ const ROUTES = [ { pattern: /^\/cantidades$/, view: "quantities", params: [] }, { pattern: /^\/pedidos$/, view: "orders", params: [] }, { pattern: /^\/pedidos\/([^/]+)$/, view: "orders", params: ["id"] }, - { pattern: /^\/test$/, view: "test", params: [] }, { pattern: /^\/config-prompts$/, view: "prompts", params: [] }, { pattern: /^\/atencion-humana$/, view: "takeovers", params: [] }, { pattern: /^\/configuracion$/, view: "settings", params: [] }, @@ -33,7 +32,6 @@ const VIEW_TO_PATH = { crosssell: "/crosssell", quantities: "/cantidades", orders: "/pedidos", - test: "/test", prompts: "/config-prompts", takeovers: "/atencion-humana", settings: "/configuracion", diff --git a/src/modules/0-ui/controllers/testing.js b/src/modules/0-ui/controllers/testing.js index 62f80d5..e27e5c5 100644 --- a/src/modules/0-ui/controllers/testing.js +++ b/src/modules/0-ui/controllers/testing.js @@ -1,8 +1,4 @@ -import { - handleListOrders, - handleGetProductsWithStock, - handleCreateTestOrder, -} from "../handlers/testing.js"; +import { handleListOrders } from "../handlers/testing.js"; import { handleGetOrderStats } from "../handlers/stats.js"; export const makeListOrders = (tenantIdOrFn) => async (req, res) => { @@ -29,31 +25,3 @@ export const makeGetOrderStats = (tenantIdOrFn) => async (req, res) => { } }; -export const makeGetProductsWithStock = (tenantIdOrFn) => async (req, res) => { - try { - const tenantId = typeof tenantIdOrFn === "function" ? tenantIdOrFn() : tenantIdOrFn; - const result = await handleGetProductsWithStock({ tenantId }); - res.json(result); - } catch (err) { - console.error("[testing] getProductsWithStock error:", err); - res.status(500).json({ ok: false, error: err.message || "internal_error" }); - } -}; - -export const makeCreateTestOrder = (tenantIdOrFn) => async (req, res) => { - try { - const tenantId = typeof tenantIdOrFn === "function" ? tenantIdOrFn() : tenantIdOrFn; - const { basket, address, wa_chat_id } = req.body || {}; - - if (!basket?.items?.length) { - return res.status(400).json({ ok: false, error: "basket_required" }); - } - - const result = await handleCreateTestOrder({ tenantId, basket, address, wa_chat_id }); - res.json(result); - } catch (err) { - console.error("[testing] createTestOrder error:", err); - res.status(500).json({ ok: false, error: err.message || "internal_error" }); - } -}; - diff --git a/src/modules/0-ui/handlers/testing.js b/src/modules/0-ui/handlers/testing.js index 59c76ea..98c8d14 100644 --- a/src/modules/0-ui/handlers/testing.js +++ b/src/modules/0-ui/handlers/testing.js @@ -1,5 +1,4 @@ -import { createOrder, syncOrdersIncremental } from "../../4-woo-orders/wooOrders.js"; -import { listProducts } from "../db/repo.js"; +import { syncOrdersIncremental } from "../../4-woo-orders/wooOrders.js"; import * as ordersRepo from "../../4-woo-orders/ordersRepo.js"; /** @@ -24,51 +23,3 @@ export async function handleListOrders({ tenantId, page = 1, limit = 50 }) { }; } -/** - * Obtiene productos con stock para testing - */ -export async function handleGetProductsWithStock({ tenantId }) { - const allProducts = await listProducts({ tenantId, limit: 500 }); - const withStock = allProducts.filter(p => - p.stock_status === "instock" && - p.price && - Number(p.price) > 0 - ); - return { items: withStock }; -} - -/** - * Crea una orden de prueba en WooCommerce - */ -export async function handleCreateTestOrder({ tenantId, basket, address, wa_chat_id }) { - if (!basket?.items?.length) { - throw new Error("basket_empty"); - } - - const order = await createOrder({ - tenantId, - wooCustomerId: null, // Sin customer de Woo para testing - basket, - address, - run_id: `test-${Date.now()}`, - }); - - // Calcular total desde line_items - let total = 0; - if (order?.raw?.line_items) { - for (const item of order.raw.line_items) { - total += Number(item.total) || 0; - } - } else if (order?.raw?.total) { - total = Number(order.raw.total) || 0; - } - - return { - ok: true, - woo_order_id: order?.id || null, - total, - line_items: order?.line_items || [], - raw: order?.raw || null, - }; -} - diff --git a/src/modules/1-intake/routes/simulator.js b/src/modules/1-intake/routes/simulator.js index 38e3a58..9d1fa9e 100644 --- a/src/modules/1-intake/routes/simulator.js +++ b/src/modules/1-intake/routes/simulator.js @@ -14,7 +14,7 @@ import { makeListProductQtyRules, makeGetProductQtyRules, makeSaveProductQtyRule import { makeListPendingTakeovers, makeListAllTakeovers, makeGetTakeover, makeRespondToTakeover, makeCancelTakeover, makeCheckPendingTakeover } from "../../0-ui/controllers/takeovers.js"; import { makeGetSettings, makeSaveSettings } from "../../0-ui/controllers/settings.js"; import { makeDeleteConversation, makeDeleteUser, makeListUsers, makeRetryLast } from "../../0-ui/controllers/admin.js"; -import { makeListOrders, makeGetOrderStats, makeGetProductsWithStock, makeCreateTestOrder } from "../../0-ui/controllers/testing.js"; +import { makeListOrders, makeGetOrderStats } from "../../0-ui/controllers/testing.js"; import { getAgentMetrics } from "../../3-turn-engine/agent/runTurn.js"; function nowIso() { @@ -107,10 +107,6 @@ export function createSimulatorRouter({ tenantId }) { // --- API routes (orders) --- router.get("/api/orders", makeListOrders(getTenantId)); router.get("/api/stats/orders", makeGetOrderStats(getTenantId)); - - // --- Testing routes --- - router.get("/test/products-with-stock", makeGetProductsWithStock(getTenantId)); - router.post("/test/order", makeCreateTestOrder(getTenantId)); return router; }