Creator prompt
The idea behind this presentation
presenta para vender la solucion, el problema es Las PYMES rurales y de pueblo enfrentan una pérdida silenciosa de ingresos y eficiencia porque la información de sus productos, precios, disponibilidad y políticas internas está fragmentada en múltiples canales no sistematizados: la memoria del dueño, hojas de Excel desactualizadas, mensajes de WhatsApp perdidos y papelitos con anotaciones. Esta dependencia de procesos manuales para consultar catálogos y tomar pedidos genera respuestas lentas que ahuyentan clientes, errores de captura que desencadenan devoluciones y reclamos, y una sobrecarga operativa que obliga al personal a dedicar horas diarias a tareas repetitivas en lugar de actividades productivas. La app soluciona este caos automatizando todo el ciclo comercial: centraliza el catálogo en una base de conocimiento local, atiende consultas y PQRS al instante, estructura los pedidos sin errores, confirma cada transacción por escrito y genera reportes para logística, eliminando la fuga de clientes, los reclamos por desinformación y la saturación del equipo, mientras el negocio mantiene disponibilidad 24/7 sin depender de internet constante. y la solucion esCon gusto. Vamos a desglosar el proyecto en detalle, cubriendo su arquitectura interna, flujos de trabajo, mecanismos de seguridad de datos y opciones de configuración.
---
### 1. Propósito y flujo de trabajo principal
El bot está diseñado para **tres tipos de interacción** con el cliente, priorizadas de la siguiente manera:
- **Consultas de inventario (detección inteligente)**: Cuando el usuario escribe un mensaje libre (ej. *"¿Tienes queso?"* o *"Cuánto vale la leche"*), el bot ejecuta un motor de búsqueda en el CSV de inventario usando **stopwords** (elimina palabras vacías como "el", "la", "tienes" para quedarse con las claves). Si encuentra una coincidencia, responde con el precio y el stock disponible, y **siempre** añade un recordatorio de que puede escribir `/ordenar` para comprar. Si no detecta nada relacionado con productos, pasa al siguiente paso.
- **Flujo de pedido guiado (comando `/ordenar`)**: Es un asistente paso a paso basado en el estado de la conversación (usando `context.user_data`).
1. **Paso 1**: Pide al usuario que escriba el nombre del producto que desea.
2. **Paso 2**: Valida que el producto exista y tenga stock > 0. Si es así, pide la cantidad deseada.
3. **Paso 3**: Muestra un resumen de la compra (producto, cantidad, precio unitario y total) y pide confirmación (sí/no). Al confirmar, se ejecuta la transacción final.
- **Fallback con IA local**: Si el mensaje no es un comando y no coincide con ningún producto del inventario, el bot envía el texto del usuario al modelo de Ollama (por defecto `qwen2.5:0.5b`), inyectándole **todo el inventario actual** como contexto. Así, la IA puede responder preguntas generales del negocio (ej. *"¿Qué quesos recomiendas para una bandeja?"* o *"¿Tienen descuentos?"*) basándose en los datos reales de la tienda.
---
### 2. La joya de la corona: Consistencia y Transacciones Seguras (Evita sobreventas)
El archivo `servicios.py` contiene la función `confirmar_pedido()`, que está construida como una **transacción ACID a nivel de archivo**, pensada para evitar que dos ventas simultáneas (escenario real con múltiples usuarios) corrompan los datos:
1. **Bloqueo exclusivo con `fcntl.flock`**: Antes de tocar los archivos, el proceso adquiere un bloqueo exclusivo sobre un archivo `.lock`. Si otro pedido está en curso, este espera (bloqueo) hasta que el primero termine. Esto elimina las "carreras críticas" (race conditions).
2. **Re-lectura del stock desde disco (Fresh Read)**: Aunque el usuario haya visto el stock hace 5 minutos, al momento de confirmar la compra, el bot vuelve a leer el archivo `inventario.csv` desde cero. Esto asegura que, si otro cliente compró el último producto en ese intervalo, el sistema lo detecte y rechace la venta actual.
3. **Escritura atómica con doble archivo (`.tmp` + `os.replace`)**: Para actualizar el inventario y guardar el pedido, el bot escribe los nuevos datos en un archivo temporal (ej. `inventario.csv.tmp`). Solo cuando toda la escritura ha sido exitosa, usa `os.replace()`, que en sistemas Unix/Windows es una operación atómica a nivel del sistema de archivos. **Beneficio**: Si el programa se cae a mitad de la escritura, el archivo original queda intacto y sin truncar (nunca quedan archivos a medio escribir o con datos mezclados).
4. **IDs secuenciales y trazabilidad**: El número de pedido tiene formato `P000001`, `P000002`, etc., calculado leyendo el último ID del CSV de pedidos. Además, registra el `chat_id`, el nombre de usuario de Telegram (o su nombre real) y la fecha/hora exacta, facilitando la auditoría.
---
### 3. Estructura interna del código (Responsabilidades)
El proyecto está modularizado para mantener separada la lógica de negocio de la interacción con el bot:
- **`bot.py`**: Es el orquestador. Contiene los *handlers* de comandos (`/start`, `/help`, `/ordenar`, `/cancelar`) y el manejador de mensajes de texto. Aquí se gestiona la máquina de estados del pedido (usando `ConversationHandler` de `python-telegram-bot`) y la decisión de redirigir a inventario o a Ollama.
- **`inventario.py`**: El motor de búsqueda. Tiene funciones para:
- Cargar el CSV completo.
- Buscar productos por palabra clave (limpia el texto con stopwords).
- Formatear la respuesta en un mensaje bonito con emojis y el recordatorio de `/ordenar`.
- Actualizar el stock (restar cantidades) durante la compra.
- **`servicios.py`**: La capa de persistencia y transacciones. Contiene `confirmar_pedido()`, la lógica de bloqueo de archivos, re-validación y guardado atómico.
- **`config.py`**: Centro de configuración. Define las rutas de los archivos (tomando variables de entorno), configura el `logging` rotativo (5 MB por archivo, con 3 copias de respaldo para no saturar el disco) y carga el token de Telegram.
---
### 4. Esquemas de datos (CSV)
El bot se alimenta de dos archivos CSV con formatos muy específicos:
- **Inventario** (ubicado por defecto en `../docs/inventario.csv` - fuera del proyecto, compartido con otra documentación):
```csv
Nombre_Producto,Precio_Venta,Cantidad_Unidades
Queso Fresco,16000,20
Leche Fresca Entera,6500,30
```
*Nota: El bot solo lee las columnas por su índice (0, 1, 2) y no depende del nombre de las cabeceras, aunque estas existen para legibilidad humana.*
- **Pedidos** (raíz del proyecto: `pedidos.csv`):
```csv
id,fecha,producto,cantidad,precio_unitario,total,usuario
P000001,2026-08-21T17:05:00,Leche Fresca Entera,6,6500.0,39000.0,juan_p
```
Este archivo funciona como historial de ventas; el bot lo usa para calcular el siguiente ID y para posibles reportes futuros.
- **Histórico (`pedidos_antiguo.csv`)**: Está presente como respaldo de un esquema anterior, pero ya no se escribe; sirve solo como referencia.
---
### 5. Entorno de ejecución y variables configurables
El bot está preparado para ejecutarse en entornos de producción o desarrollo mediante variables de entorno (archivo `.env`):
| Variable | Valor por defecto | Impacto |
| :--- | :--- | :--- |
| `TELEGRAM_TOKEN` | *(Obligatorio)* | Clave única del bot proporcionada por @BotFather. |
| `OLLAMA_MODEL` | `qwen2.5:0.5b` | Modelo a usar. Puedes cambiarlo a `llama3`, `mistral`, etc., si tu hardware lo soporta. |
| `OLLAMA_URL` | `http://localhost:11434/api/chat` | Endpoint de la API de Ollama (útil si corre en otro servidor). |
| `INVENTARIO_CSV` | `../docs/inventario.csv` | Para pruebas unitarias, puedes redirigir a un CSV de prueba dentro de la carpeta `tests/`. |
| `PEDIDOS_CSV` | `pedidos.csv` | Igual, permite aislar archivos de prueba. |
| `LOCK_FILE` | `inventario.lock` | Archivo de bloqueo. Se crea automáticamente en la raíz. |
**Requisitos técnicos**:
- Python 3.12 o superior (se probó en 3.14).
- Tener Ollama instalado y ejecutándose en segundo plano (servicio local).
- Dependencias exactas: `python-telegram-bot==22.8`, `requests==2.34.2`, `python-dotenv==1.2.3`.
---
### 6. Comandos y experiencia de usuario
Además de la conversación natural, el bot responde a estos comandos explícitos:
- **`/start`**: Saludo con introducción y presentación del negocio.
- **`/help`**: Enumeración de todos los comandos disponibles.
- **`/contacto`**: Muestra información de contacto humano (teléfono/correo, definido en el código).
- **`/ordenar`**: Inicia el asistente de compras.
- **`/cancelar`**: Aborta el flujo de pedido en cualquier paso, limpiando la memoria del usuario.
- **Texto libre**: Gatilla la búsqueda en inventario o la IA, según corresponda.
---
### 7. Hoja de ruta (Fase 3 propuesta por el README)
El proyecto no está cerrado; tiene planificadas mejoras para convertirlo en un sistema de gestión completo:
- **`/catalogo`**: Mostrar todos los productos con precios en un solo mensaje formateado.
- **Carrito multi-producto**: Permitir añadir varios productos antes de finalizar la compra, en lugar de una sola línea de pedido.
- **Captura de datos de entrega**: Preguntar dirección, nombre completo y horario preferido durante el flujo de pedido.
- **Alertas de stock bajo**: Notificar automáticamente a los administradores (o al cliente) cuando un producto esté por agotarse.
- **FAQs y promociones**: Leer archivos `.txt` de la carpeta `../docs/` para responder preguntas frecuentes sobre envíos, tiempos de entrega u ofertas especiales.
- **Comandos de administración**: Visibilidad de las ventas del día y opciones para ajustar stock desde el propio Telegram.
---
### 8. Pruebas y mantenimiento
El README incluye instrucciones muy pragmáticas para mantener el sistema:
- Usar `python -m py_compile bot.py inventario.py servicios.py config.py` para verificar sintaxis sin ejecutar.
- Ejecutar `python inventario.py` para probar la carga de datos de forma aislada.
- Los logs quedan en `logs/bot.log` con rotación automática, lo que facilita depurar errores de venta o caídas del servicio de Ollama.
En resumen, es un bot robusto, pensado para un negocio real, que combina **interacción conversacional**, **seguridad transaccional** y **flexibilidad de configuración**, todo envuelto en un código limpio y modular.
Follow Design: {"palette":["Graphite ink #121212 — dominant typography and precise mechanical borders","Blueprint cobalt #1D4ED8 — core system architecture and data conduits","Industrial kraft #EAE4D9 — raw tactile field background","Safety orange #EA580C — critical pain points and manual failure callouts","Muted zinc #71717A — secondary technical metadata and captions"],"fonts":{"Space Grotesk":"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300..700&display=swap","IBM Plex Sans":"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&display=swap","IBM Plex Mono":"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"},"type":"Space Grotesk in uppercase and bold for structural engineering-style slide titles; IBM Plex Sans for clean utilitarian explanatory text; IBM Plex Mono for CSV schemas, IDs, and transactional steps.","layout":"Structured modular blueprint grid with clear 1px borders, asymmetric data cards, fixed metadata header zones, and chronological flow diagrams across a 4-beat horizontal sequence.","framework_treatment":"Monospaced data tables with crisp grid lines, technical block diagram cards, schema inspection windows, stamp-like verification seals for ACID guarantees, and zero-distraction flat geometry.","feels_like":"An industrial engineering schematic meets a direct, no-nonsense commercial proposal"}