Commit Graph

37 Commits

Author SHA1 Message Date
Lucas Tettamanti
6b7889ef4e Mono-tenant: resolver id una vez al boot, eliminar lookups por turno
El sistema nunca fue realmente multi-tenant en la práctica. El esquema
DB conserva las columnas tenant_id (queda lista para escalar más adelante
sin migración), pero la app ahora resuelve el tenant una sola vez al
arranque y todas las capas leen de un único punto.

- src/modules/shared/tenant.js: nuevo módulo. setTenant() en boot,
  getTenantId() lo lee desde cualquier lado.
- index.js: ensureTenant() → setTenant({ id, key }). Sin cambios externos.
- pipeline.resolveTenantId(): pasa de hacer 1-2 queries a DB por turno
  a un return sincrónico del id cacheado. Mantiene firma async para no
  romper callers.
- intake handlers (sim.js, evolution.js): usan getTenantId() directo,
  sin parsing de tenant_key del chat_id ni lookup por canal.
- wooWebhooks: ya no requiere ?tenant_key=... en la query string.
  El webhook va al único tenant configurado.
- repo.js: eliminados getTenantByKey() y getTenantIdByChannel() (no más
  callers).

Plumbing del parámetro tenantId en signatures de handlers/repos/machine
queda intacto — bajar eso es ruido de alto riesgo y no aporta hoy.
188 tests pasando.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 21:00:22 -03:00
Lucas Tettamanti
17cea4aa9e Eliminar payment + waiting (legacy): el bot toma pedidos, no cobra
El bot conversacional no maneja pagos. Su trabajo: pedidos, datos de
entrega, dejar la orden anotada en Woo (status=pending). El cobro lo
gestiona el comercio offline. Todo lo de payment_type / is_paid /
PAYMENT / WAITING_WEBHOOKS era legacy de un flow viejo que se baja.

Nuevo flow: IDLE → CART → SHIPPING → IDLE (con orden creada).
Cuando el usuario completa shipping (pickup elegido OR delivery+address),
shipping.js emite create_order y el bot cierra con order.confirmed.

- fsm.js: 4 estados (IDLE/CART/SHIPPING/AWAITING_HUMAN). hasPaymentInfo
  e isPaid eliminados. deriveNextState gira SHIPPING→IDLE en vez de
  →PAYMENT→WAITING. ALLOWED transitions actualizadas.
- orderModel.js: createEmptyOrder() sin payment_type/is_paid.
  migrateOldContext deja de leer payment_method / mp.payment_status.
- stateHandlers: payment.js y waiting.js eliminados. shipping.js gana
  finalizeOrder() que emite create_order action y vuelve a IDLE.
- replyTemplates: payment.* y waiting.* fuera. order.confirmed nuevo,
  con 3 variantes y rewriter habilitado.
- NLU openai.js + nlu/schemas.js: select_payment fuera del enum, payment_method
  fuera de entities. Prompt sin la regla de SELECCIONAR PAGO.
- nlu/router.js + nlu/index.js: dominio "payment" eliminado.
  shouldSkipRouter ya no chequea PAYMENT.
- nlu/specialists/payment.js: eliminado.
- promptsRepo.js + promptLoader.js: PROMPT_KEYS sin "payment".
- turnEngineV3.js: switch ya no dispatcha a PAYMENT/WAITING. normalizeState
  mapea estados legacy (PAYMENT/WAITING_WEBHOOKS/COMPLETED) a IDLE.
  context_patch ya no emite payment_method.
- wooOrders.createOrder: paymentMethod param eliminado. Order queda en
  status=pending sin payment_method (cobro offline).
- pipeline.js: paymentMethod fuera del create_order glue. Invariant
  "no_checkout_without_payment_link" eliminado. signal payment_selected
  reemplazado por shipping_completed.
- XState machine: top-level PAYMENT y WAITING eliminados. SELECT_PAYMENT
  event fuera. SHIPPING ahora cierra con enqueueWooCreateOrder +
  replyOrderConfirmed → IDLE. Guards hasPayment/isPaid borrados.
- Tests fsm.test.js / orderModel.test.js / machine/index.test.js
  actualizados al nuevo contrato. 188 tests pasando.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:53:19 -03:00
Lucas Tettamanti
04ac33430f Tier 2: XState statechart como motor de turno (opt-in)
Reemplaza el dispatcher en turnEngineV3.js por un statechart formal en
XState v5. La machine es pura: produce un effect log (pending_actions) +
un descriptor de reply (pending_reply) que el runner traduce afuera.

API externa intacta: runTurnV3 sigue retornando { plan, decision } con
shape compatible con pipeline.js. Snapshot persiste en
context.xstate_snapshot dentro del JSONB existente.

- machine/index.js: statechart top-level (idle/cart/shipping/payment/
  waiting/awaiting_human) + cart sub-statechart con todo el flujo
  multi-turno (searching/resolving/askingClarification/askingQuantity/
  computingFromPersonas/added/showing/pricing/researching).
- guards.js: portados de fsm.js (hasCart, wantsToAddProduct, etc).
- actions.js: assigns para mutations + reply descriptors (pending_reply
  con templateKey/vars/rawText). Las async no entran en la machine.
- actors.js: fromPromise wrappers de retrieveCandidates y getProductQtyRules.
- runner.js: boot con prev_context.xstate_snapshot o migrateOldContext.
  NLU → nluToEvent → send → settle (espera invokes) → realizeReply
  (renderReply real con rewriter) → getPersistedSnapshot → format.
- nluToEvent.js: adapter NLU intent → evento XState (1:1).

Feature flags: USE_XSTATE=1 reemplaza el path; XSTATE_SHADOW=1 corre
ambos en paralelo, devuelve legacy y loguea diffs estructurales para
validar antes de flippar prod.

16 unit tests para la machine cubren: arranque, regla universal cart-on-add,
flow de cart con strong/multi match, checkout completo (shipping/pickup/
payment/cash) y rehidratación de snapshot. 224 tests totales pasando.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:38:26 -03:00
Lucas Tettamanti
f784ddd62d Tier 1: chat quality — fuzzy aliases, reply templates, dedup, rewriter
Foco: matar repetición y adaptar respuestas. Los handlers tenían ~30 strings
hardcodeadas (3-7 lugares cada una). Aliases hacían substring exacto.

- pg_trgm + GIN indexes en product_aliases / alias_product_mappings.
  Captura plurales, diminutivos, typos sin reglas. catalogRetrieval re-busca
  el snapshot con normalized_alias cuando el query original no rinde
  (vasio→vacio→Vacío).
- reply_templates table + replyTemplates.js. 20 keys, 2-3 variantes c/u
  con DEFAULTS hardcodeados como fallback. pickVariant excluye las usadas
  en context.recent_replies (FIFO cap 8). Wired en idle/cart/cartHelpers/
  shipping/payment/waiting.
- failed_searches counter en context. count>=3 escala via humanFallback.
  Reset en cada add_to_cart exitoso.
- storeContext.js: vars derivadas de getStoreConfig (delivery_zones, hours,
  zonas) listas para inyectar en templates cuando los datos se carguen.
- replyRewriter.js: LLM call opcional (REPLY_REWRITER=1) que adapta el
  template al hilo conversacional. 1.5s timeout, fallback al template puro.
  Sólo activo en 8 slots semánticamente importantes.
- 12 unit tests para replyTemplates (rotation, recency, FIFO, vars).
  208 tests totales pasando.

Plan completo: ~/.claude/plans/ok-creo-que-tiene-humming-sutton.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 19:29:02 -03:00
Lucas Tettamanti
525679cf8b local dev setup + OPENAI_BASE_URL support + dashboard fix
- CLAUDE.md con arquitectura y comandos del proyecto
- env.example: agregar LIMIT_CONVERSATIONS, MAX_CHARS_PER_MESSAGE, OPENAI_BASE_URL
- docker-compose.override: puerto 3001, extra_hosts para modelo local en Linux
- OpenAI clients: soporte OPENAI_BASE_URL para apuntar a modelo local compatible
- stats.js: sync de órdenes en background, dashboard no bloquea al cargar
- package-lock: dbmate movido a prod dependencies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 18:32:22 -03:00
Lucas Tettamanti
5e79f17d00 20260204 2026-02-04 16:06:51 -03:00
Lucas Tettamanti
df9420b954 dashboard 2026-01-27 02:41:39 -03:00
Lucas Tettamanti
493f26af17 corregidos bugs de: ret, vs delivery, efectivo vs link, charsets, price query 2026-01-26 23:27:47 -03:00
Lucas Tettamanti
53293ce9b3 badges on the right, evolution api sender 2026-01-26 01:21:08 -03:00
Lucas Tettamanti
e85afab3e6 vitest 2026-01-26 00:13:03 -03:00
Lucas Tettamanti
b1c8a3685c refactor stateHandlers 2026-01-25 23:58:56 -03:00
Lucas Tettamanti
debad78781 borrado de articulos del carrito 2026-01-25 23:43:00 -03:00
Lucas Tettamanti
bd63d92c50 modificando el patron del sistema, orientado mas al usuario 2026-01-25 22:32:58 -03:00
Lucas Tettamanti
93e331535f correjido unidades y kgs 2026-01-25 21:08:23 -03:00
Lucas Tettamanti
bb947ea75e remove users, chats, etc 2026-01-25 21:04:54 -03:00
Lucas Tettamanti
a489ec66a2 modularizado de prompts 2026-01-25 20:51:33 -03:00
Lucas Tettamanti
b91ece867b routes updated 2026-01-18 20:28:27 -03:00
Lucas Tettamanti
9754347a36 pedidos 2026-01-18 20:07:40 -03:00
Lucas Tettamanti
23c3d44490 audit and sync 2026-01-18 19:00:49 -03:00
Lucas Tettamanti
c7c56ddbfc productos, equivalencias, cross-sell y cantidades 2026-01-18 18:28:28 -03:00
Lucas Tettamanti
8cc4744c49 carrito semi saneado 2026-01-17 15:20:32 -03:00
Lucas Tettamanti
204403560e mejoras en el modelo de clarificacion de productos 2026-01-17 06:31:49 -03:00
Lucas Tettamanti
63b9ecef61 ux improved 2026-01-17 04:13:35 -03:00
Lucas Tettamanti
98e3d78e3d modules/0-ui 2026-01-15 22:53:37 -03:00
Lucas Tettamanti
ea62385e3d separated in modules 2026-01-15 22:45:33 -03:00
Lucas Tettamanti
eedd16afdb added Mercado Pago integration with new payment handling functions and updated app routing 2026-01-15 13:06:37 -03:00
Lucas Tettamanti
29fa2d127e added NLU v3 functionality with JSON schema validation and error handling in OpenAI service 2026-01-14 18:16:59 -03:00
Lucas Tettamanti
47ba68049f separado en routes 2026-01-14 13:03:11 -03:00
Lucas Tettamanti
2d01972619 travel to another computer 2026-01-10 12:39:32 -03:00
Lucas Tettamanti
ce96df9e30 no more debu legacy 2026-01-06 23:42:12 -03:00
Lucas Tettamanti
8bb21b4edb mejoras varias en frontend, separacion de intent y state, pick de articulos 2026-01-06 15:50:02 -03:00
Lucas Tettamanti
dab52492b4 implementando openAI y busqueda de productos en woo 2026-01-05 11:15:56 -03:00
Lucas Tettamanti
829823ac3d styling and create customer woo bug handled 2026-01-05 10:58:54 -03:00
Lucas Tettamanti
4de68dc996 resuelto el problema, el post para crear customer creaba pero no emitia respuesta, se deja en 2 segundos y se usa un get por email para traer la data 2026-01-02 19:59:03 -03:00
Lucas Tettamanti
303c3daafe woocommerce integration, controllers and handlers ready, evolution api simulator ready 2026-01-02 16:49:35 -03:00
Lucas Tettamanti
947b0bd1ee skeleton of the core app 2026-01-02 00:21:46 -03:00
Lucas Tettamanti
5e9cc8fe1a openai service and basic tables with migrations 2026-01-01 23:20:13 -03:00