Files
botino/CLAUDE.md
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

5.2 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

# Development
npm run dev          # Start with nodemon auto-reload
npm start            # Production start

# Testing
npm test             # Run all tests once (vitest run)
npm run test:watch   # Watch mode
npm run test:coverage

# Run a single test file
npx vitest run src/modules/3-turn-engine/orderModel.test.js

# Database migrations (requires DATABASE_URL in .env)
npm run migrate:up
npm run migrate:down
npm run migrate:redo
npm run migrate:status
npm run seed         # Seed a tenant via scripts/seed-tenant.mjs

No lint command is configured.

Product goal

The bot must be conversational and intelligent, not a menu-driven flow. Customers reach out via WhatsApp with intent to buy — the bot's job is to:

  1. Engage in conversation — answer questions about products, prices, availability/stock; recommend; clarify.
  2. Take orders — build a cart through natural dialogue (multi-product turns, quantities, units).
  3. Collect delivery data — address, delivery vs pickup, payment method.
  4. Operate within store rules — delivery zones, days/hours, pickup windows. These config tables (delivery_zones, store schedule in tenant_settings) will be populated later; the bot has to read and respect them when present.

Repetitive, hardcoded responses are a known quality problem and the focus of the active improvement plan (see ~/.claude/plans/ok-creo-que-tiene-humming-sutton.md). The system is not yet in production — refactors that change behavior are acceptable.

Architecture

This is a multi-tenant WhatsApp e-commerce chatbot powered by Express.js. Tenants are WooCommerce store operators; their customers interact via WhatsApp to browse products, build carts, and place orders. All database operations are isolated by tenant_id.

Request flow

WhatsApp → Evolution API webhook → /webhook/evolution
                                         ↓
                              1-intake: route & normalize message
                                         ↓
                              3-turn-engine: NLU → FSM → state handler
                                         ↓
                              Response persisted to DB + sent back via Evolution API

Module structure (numbered layers)

  • src/modules/0-UI/ — Admin dashboard: REST controllers for products, conversations, settings, prompts, takeovers, recommendations, aliases. Each controller has a db/ sub-layer for persistence.

  • src/modules/1-intake/ — Message ingestion. Routes: /simulator (dev UI), /webhook/evolution (WhatsApp). Normalizes incoming messages before passing to turn engine.

  • src/modules/2-identity/ — Tenant and user management. Maps WhatsApp numbers to WooCommerce customers. Stores encrypted WooCommerce credentials per tenant in tenant_ecommerce_config. Routes WooCommerce webhooks.

  • src/modules/3-turn-engine/ — Core logic. NLU classifies intents; FSM transitions states (IDLE → CART → SHIPPING → PAYMENT → WAITING_WEBHOOKS). Two NLU versions controlled by USE_MODULAR_NLU env flag. Two turn engine versions controlled by TURN_ENGINE env flag. State handlers map to FSM states.

  • src/modules/4-woo-orders/ — WooCommerce order sync. Fetches and caches customer order history for conversation context.

  • src/modules/shared/ — DB pool (PostgreSQL via pg), SSE for real-time admin UI updates, WooSnapshot (product catalog cache), debug utilities.

Key integrations

System Purpose Config
OpenAI NLU intent classification & response generation OPENAI_API_KEY, OPENAI_MODEL
Evolution API WhatsApp send/receive EVOLUTION_API_URL, EVOLUTION_API_KEY, EVOLUTION_INSTANCE_NAME, EVOLUTION_SEND_ENABLED
WooCommerce REST API Products, orders, customers WOO_* env vars or per-tenant in DB
PostgreSQL Primary database DATABASE_URL

Database

Migrations live in db/migrations/ as timestamped SQL files managed by dbmate. Key tables:

  • tenants, tenant_config, tenant_settings, tenant_ecommerce_config, tenant_channels
  • wa_identity_map — WhatsApp ↔ WooCommerce customer mapping
  • wa_conversation_state — FSM state + context per conversation
  • wa_messages — Message history
  • woo_products_snapshot — Cached product catalog
  • prompt_templates — Versioned LLM prompts
  • human_takeovers, audit_log, conversation_runs

Feature flags (env vars)

  • TURN_ENGINE=v1|v2 — Which turn engine version to use
  • USE_MODULAR_NLU=1 — Use modular NLU (prompt templates from DB) vs. v3 hardcoded
  • EVOLUTION_SEND_ENABLED=1 — Actually send messages to WhatsApp (disable in dev/test)
  • DEBUG_PERF, DEBUG_WOO_HTTP, DEBUG_LLM, DEBUG_EVOLUTION — Granular debug logging

Local development

Copy env.example to .env and fill in values. Use docker-compose.override.yaml for local overrides. Run docker compose up to start app + Postgres + Redis. The Dockerfile runs migrations automatically on startup (migrate:up && seed && start).

Test files use Vitest with globals: true — no need to import describe, it, expect.