Tikvah POS — Documentación Interna
Visión general
Tikvah POS es un sistema de punto de venta (POS) SaaS chileno desarrollado por SIRUF, orientado a pequeñas y medianas empresas (PYMEs). Funciona como aplicación web progresiva (PWA) con soporte offline, pensada para funcionar en cualquier dispositivo — celular, tablet o computador — sin instalación.
🏪 Tipos de negocio
- Almacén / tienda — módulo Caja
- Restaurante — módulo Mesas y Comandas
- Gimnasio — módulo Socios y Clases
👥 Roles de usuario
- Dueño — acceso total
- Admin — acceso total excepto super-admin
- Cajero — solo caja y ventas
💰 Modelo de negocio
- SaaS por suscripción mensual/anual
- Planes: Básico, Profesional, Empresa
- Pago via MercadoPago Chile
Stack tecnológico
| Capa | Tecnología | Versión | Uso |
|---|---|---|---|
| Frontend | React + Vite | 18 / 7 | SPA, routing, estado |
| Routing | React Router | v6 | Rutas del SPA |
| Iconos | Lucide React | — | Todos los íconos del sistema |
| Backend | Node.js + Express | ESM | API REST en server/ |
| Base de datos | Supabase (PostgreSQL) | — | Todos los datos |
| Autenticación | JWT custom via Supabase | — | Login de usuarios |
| PWA | Service Worker custom | — | Offline + instalación |
| Caché offline | IndexedDB (idb.js) | — | Ventas y productos offline |
| Pagos | MercadoPago | — | Suscripciones mensuales |
| Servidor web | Nginx | — | Proxy reverso + SSL |
| SSL | Let's Encrypt | — | HTTPS automático |
| DNS | Netlify DNS | — | A record → 68.183.163.176 |
Arquitectura del sistema
Flujo de autenticación
- Usuario envía
POST /api/auth/logincon email + password - El servidor verifica en Supabase (
pos_usuarios) con bcrypt - Si válido, devuelve un JWT firmado (payload:
id, negocio_id, rol) - El cliente guarda el JWT en
localStoragecomopos_token - Cada request del frontend incluye
Authorization: Bearer <token> - El middleware
authMiddlewareen Express verifica el token en cada ruta protegida
Deploy y producción
Servicio:
tikvah-pos (systemd) — reinicia automáticamenteURL: https://pos.siruf.cl
Pasos para deploy
# 1. Compilar el frontend (desde /home/siruf/tikvah-pos)
NODE_OPTIONS='--max-old-space-size=512' npx vite build
# 2. Reiniciar el servicio Node.js (sin sudo)
TPID=$(systemctl show tikvah-pos -p MainPID --value) && kill -TERM $TPID
# El servicio se reinicia solo con systemd y sirve el nuevo build
Variables de entorno (.env)
| Variable | Uso |
|---|---|
SUPABASE_URL | URL del proyecto Supabase |
SUPABASE_SERVICE_ROLE_KEY | Clave de servicio (admin) |
JWT_SECRET | Firma de tokens JWT |
MP_ACCESS_TOKEN | MercadoPago para suscripciones |
ADMIN_TOKEN | tikvah-admin-siruf-2026 — admin panel |
PORT | 3001 (default) |
Service Worker (PWA)
El archivo public/sw.js implementa cache-first para assets y network-first para la API. Cada deploy incrementa automáticamente CACHE_VERSION para invalidar el caché del navegador. Los usuarios ven un banner "Nueva versión disponible" cuando hay update.
Páginas y módulos del frontend
El frontend es un SPA con React Router. Todas las rutas están bajo el componente Layout que incluye el sidebar de navegación. Las rutas se definen en src/App.jsx.
| Ruta | Componente | Descripción | Roles |
|---|---|---|---|
/caja | Caja.jsx | Punto de venta principal | Todos |
/mesas | Mesas.jsx | Restaurante: mesas y comandas | Todos |
/gimnasio | Gimnasio.jsx | Gym: socios, clases, planes | Todos |
/productos | Productos.jsx | Catálogo de productos | Admin/Dueño |
/inventario | Inventario.jsx | Stock y movimientos | Todos |
/ventas | Ventas.jsx | Historial de ventas | Admin/Dueño |
/dashboard | Dashboard.jsx | Estadísticas y reportes | Admin/Dueño |
/merma | Merma.jsx | Registro de pérdidas | Todos |
/gastos | Gastos.jsx | Gastos del negocio | Admin/Dueño |
/impuestos | Impuestos.jsx | IVA, PPM y Renta Chile | Admin/Dueño |
/salud | Salud.jsx | Diagnóstico financiero | Admin/Dueño |
/suscripcion | Suscripcion.jsx | Planes y pagos | Dueño |
/metricas | Metricas.jsx | Métricas avanzadas | Admin/Dueño |
/soporte | Soporte.jsx | Chat con Kira AI | Todos |
/config | Configuracion.jsx | Usuarios, caja, apariencia | Todos |
Módulo: Caja
Archivo: src/pages/Caja.jsx
Es el módulo más crítico del sistema. Permite registrar ventas en tiempo real con soporte completo offline.
Funciones principales
- Búsqueda de productos — por nombre, SKU o código de barras. Búsqueda en tiempo real mientras el usuario escribe.
- Modo rápido (escáner) — al activarlo, agrega el producto automáticamente al detectar un código exacto. Ideal con lectores físicos USB/Bluetooth.
- Escáner de cámara — usa la cámara del dispositivo para leer códigos QR y de barras (componente BarcodeScanner.jsx).
- Carrito de venta — lista de productos seleccionados con cantidad ajustable. Controla que no se supere el stock disponible.
- Métodos de pago — efectivo, tarjeta, transferencia, mixto.
- Descuentos — se puede ingresar un monto fijo de descuento.
- Nota de venta — campo de texto libre para observaciones.
- Ticket de confirmación — pantalla de éxito con el total cobrado tras completar la venta.
Modo offline
Cuando no hay conexión a internet, la caja sigue funcionando:
- Productos cargados desde
IndexedDB(caché local) - Ventas guardadas localmente en una cola (
idb.pushVenta()) - Stock descontado localmente para evitar sobreventas
- Al recuperar conexión,
sincronizarAhora()sube todas las ventas pendientes a Supabase - Banner amarillo en la pantalla cuando está offline
- Indicador de "N ventas pendientes de sincronizar"
Requisito previo: Sesión de caja
Antes de vender, debe haber una sesión de caja abierta (POST /api/sesiones/abrir). Si no hay sesión, la caja muestra el modal para abrirla con el monto de apertura en efectivo. Las sesiones registran apertura y cierre con montos para el cuadre de caja.
Módulo: Productos
Archivo: src/pages/Productos.jsx
Funciones
- Catálogo completo — lista de todos los productos del negocio con búsqueda y filtro por categoría.
- Crear/editar producto — nombre, precio de venta, costo, stock inicial, stock mínimo, unidad, categoría, SKU, código de barras, fecha de vencimiento y días de alerta.
- Desactivar producto — los productos no se eliminan, se marcan como inactivos (
activo = false). - Categorías — el usuario puede crear sus propias categorías de producto.
- Importación masiva Excel — sube un archivo .xlsx con múltiples productos. El sistema procesa columnas: nombre, precio, costo, stock, unidad, SKU, barcode, categoría, descripción.
- Alertas de vencimiento — productos próximos a vencer se marcan en amarillo; los vencidos en rojo.
Módulo: Inventario
Archivo: src/pages/Inventario.jsx
Funciones
- Stock actual — tabla con todos los productos, su stock actual, mínimo, estado (ok/bajo/agotado) y fecha de vencimiento.
- Filtros — por estado: todos, ok, bajo, agotado, por vencer.
- Ajuste de stock — modal con buscador live de productos. Tipos: entrada (suma stock) o ajuste (puede ser negativo). Registra nota del motivo.
- Historial de movimientos — tabla cronológica de todos los cambios de stock con usuario responsable.
- SIRUF Trueque — botón "Ofrecer SIRUF" en productos vencidos, por vencer o agotados. Publica la oferta en trueque.siruf.cl para intercambio con otras PYMEs.
Módulo: Ventas
Archivo: src/pages/Ventas.jsx
Funciones
- Historial — listado de todas las ventas con fecha, cajero, método de pago, total y estado.
- Filtros — por rango de fechas y estado (completada/anulada).
- Detalle de venta — modal con desglose de ítems vendidos.
- Anular venta — devuelve el stock automáticamente. Requiere confirmación.
- Exportar CSV — descarga el listado filtrado en formato CSV compatible con Excel. Incluye BOM UTF-8 para caracteres en español.
Módulo: Gastos
Archivo: src/pages/Gastos.jsx
Funciones
- Registro de gastos — categoría, tipo (variable/permanente), monto, descripción y fecha.
- Categorías — arriendo, servicios, insumos, personal, marketing, otro.
- Tipo de gasto — Variable: compra puntual. Permanente: se repite mensualmente (arriendo, sueldos).
- Filtros interactivos — por fecha y categoría. Los chips de resumen son clickeables para filtrar.
- Resumen por categoría — total del período y desglose por cada categoría.
- Editar/eliminar — cualquier gasto puede ser modificado o eliminado.
- Exportar CSV — descarga el listado en CSV para el contador.
Módulo: Merma
Archivo: src/pages/Merma.jsx
Registra las pérdidas de inventario que no son ventas: productos vencidos, dañados, robados o errores de ingreso.
Motivos de merma
vencimiento— producto expiradodaño— producto roto o deterioradorobo— hurto de mercaderíaerror— error de ingreso o conteootro— cualquier otra causa
Al registrar una merma, el stock del producto se descuenta automáticamente mediante un movimiento de inventario negativo.
Módulo: Dashboard
Archivo: src/pages/Dashboard.jsx
Panel de estadísticas y reportes del negocio. Consume múltiples endpoints del API.
Métricas incluidas
- Ventas totales del día, semana y mes
- Número de transacciones
- Ticket promedio
- Top 10 productos más vendidos
- Ventas por día (gráfico de barras)
- Distribución por método de pago
- Alertas de stock bajo
Módulo: Impuestos
Archivo: src/pages/Impuestos.jsx
Módulo específico para el sistema tributario chileno. Ayuda al dueño a preparar las declaraciones mensuales y anuales.
Funciones
- IVA Débito — calculado sobre las ventas del período (19% del monto neto).
- IVA Crédito — crédito fiscal de facturas de compra registradas. El sistema calcula el 19% automáticamente del monto neto ingresado.
- IVA a pagar — diferencia entre débito y crédito. Si el crédito supera el débito, hay remanente para el mes siguiente.
- PPM (Pagos Provisionales Mensuales) — porcentaje configurable sobre las ventas (default 0.25%).
- Estimación de Renta anual — proyección de impuesto anual según régimen tributario.
- Configuración tributaria — régimen (ProPyme/General/RTS), RUT, razón social, actividad económica.
- Histórico mensual — resumen de cada mes del año para ver tendencias.
Regímenes soportados
- 14 D N°8 — ProPyme Transparente
- 14 D N°3 — ProPyme (25%)
- 14 A — Régimen General (27%)
- RTS — Régimen de Tributación Simplificada
Módulo: Salud Financiera
Archivo: src/pages/Salud.jsx
Diagnóstico automático del estado financiero del negocio. Analiza la relación entre ingresos, gastos y margen bruto para detectar alertas temprana.
Módulo: Suscripción
Archivo: src/pages/Suscripcion.jsx
Planes disponibles
| Plan | Precio mensual | Características |
|---|---|---|
| Básico | $9.990 | Caja, productos, inventario, ventas básico |
| Profesional | $24.990 | + Dashboard, gastos, impuestos, merma |
| Empresa | $64.990 | + Restaurante/Gimnasio, métricas avanzadas, multi-caja |
Flujo de pago
- Usuario selecciona plan y período (mensual/anual)
- Click en "Activar 7 días gratis" →
POST /api/suscripciones/trial - Redirige a MercadoPago para registrar tarjeta
- Al día 8 del trial, se cobra automáticamente
- Webhook de MP notifica el pago → activa o suspende la cuenta
Módulo: Configuración
Archivo: src/pages/Configuracion.jsx
Secciones
- Mi cuenta — nombre, email, rol, negocio. Botón para cambiar contraseña.
- Caja — estado de la sesión activa. Historial de últimas 10 sesiones. Botón para cerrar caja (solo admin/dueño).
- Usuarios — solo visible para admin/dueño. Lista de usuarios del negocio con rol y estado. Crear nuevos usuarios (cajero/admin). Cambiar contraseña de cualquier usuario.
- Apariencia — selector de tamaño de letra: Pequeña (14px), Normal (16px), Grande (19px), Muy grande (22px). Se guarda en
localStoragey persiste entre sesiones.
Módulo Restaurante (Mesas y Comandas)
Archivos: src/pages/Mesas.jsx | Backend: server/routes/mesas.js, comandas.js
tipo = 'restaurante' en la tabla pos_negocios. El ícono de Caja en el nav se reemplaza por Mesas con ícono de tenedor.
Funcionamiento
- Mapa de mesas — grid visual con todas las mesas del local. Mesas libres (verde) y ocupadas (amarillo con total de la comanda).
- Seleccionar mesa — click en una mesa abre el panel de comanda a la derecha.
- Abrir comanda — si la mesa está libre, crea una nueva comanda.
- Agregar productos — buscador live de productos. Click agrega el ítem a la comanda. Cada ítem muestra cantidad y subtotal.
- Cobrar comanda — cierra la comanda, genera una venta y libera la mesa. Soporta descuento y método de pago.
- Cancelar comanda — descarta todos los ítems sin cobrar.
- Crear/gestionar mesas — el administrador puede crear mesas con número, nombre personalizado y capacidad.
- Auto-refresh — las mesas se actualizan cada 30 segundos para reflejar cambios de otros dispositivos.
Módulo Gimnasio (Socios y Clases)
Archivo: src/pages/Gimnasio.jsx | Backend: server/routes/socios.js, clases.js
tipo = 'gimnasio'. El nav muestra "Socios" con ícono de mancuerna.
Pestañas
- Check-in — busca socios por nombre o email y registra la asistencia del día. Muestra lista de quiénes ya entraron hoy. Indica si la membresía está activa, por vencer o vencida.
- Socios — listado de todos los socios con estado de membresía. Crear/editar socios (nombre, email, teléfono, nacimiento, notas). Asignar membresía con cobro automático de venta.
- Clases — programación semanal de clases (spinning, yoga, etc.) con instructor, día, hora y cupo máximo.
- Planes — planes de membresía configurables con nombre, duración en días y precio.
Módulo: Soporte / Kira AI
Archivo: src/pages/Soporte.jsx + src/components/KiraWidget.jsx
Kira es la asistente de IA de SIRUF. En el POS aparece de dos formas:
- Página /soporte — chat completo con Kira, especializada en resolver dudas sobre el sistema.
- Widget flotante — botón en la esquina inferior derecha disponible en todas las páginas para consultas rápidas.
Conecta con el backend de Kira en https://api.siruf.cl/api/chat.
API REST — Resumen
Todas las rutas requieren Authorization: Bearer <jwt> excepto /api/auth/login.
Endpoints: Caja y Sesiones
{caja, monto_apertura}{monto_cierre, notas}limitEndpoints: Productos e Inventario
q, categoria_id, activo{csv} o {xlsx_base64}{producto_id, cantidad, tipo, nota}. Tipos: entrada, ajustelimitEndpoints: Ventas
desde, hasta, estado{sesion_id, items, metodo_pago, descuento, nota}{motivo}Endpoints: Gastos y Merma
desde, hasta, categoria{categoria, tipo, monto, descripcion, fecha}vencimiento, daño, robo, error, otroEndpoints: Dashboard y Reportes
Endpoints: Admin y Pagos
X-Admin-Token: tikvah-admin-siruf-2026{plan_codigo, periodo}Base de datos — Tablas principales
| Tabla | Descripción | Columnas clave |
|---|---|---|
pos_negocios | Un registro por negocio cliente | id, nombre, tipo (almacen/restaurante/gimnasio), plan_codigo |
pos_usuarios | Usuarios del sistema | id, negocio_id, nombre, email, password_hash, rol, activo |
pos_productos | Catálogo de productos | id, negocio_id, nombre, precio, costo, stock, stock_minimo, unidad, sku, barcode, activo, fecha_vencimiento |
pos_categorias | Categorías de producto | id, negocio_id, nombre |
pos_sesiones | Sesiones de caja | id, negocio_id, usuario_id, caja, estado, monto_apertura, monto_cierre, opened_at, closed_at |
pos_ventas | Cabecera de venta | id, negocio_id, sesion_id, usuario_id, total, descuento, metodo_pago, estado, nota |
pos_venta_items | Ítems de cada venta | id, venta_id, producto_id, nombre_producto, cantidad, precio_unitario, subtotal |
pos_movimientos_stock | Historial de cambios de stock | id, producto_id, tipo, cantidad, stock_antes, stock_despues, usuario_id, nota |
pos_gastos | Gastos del negocio | id, negocio_id, usuario_id, categoria, tipo (variable/permanente), monto, descripcion, fecha |
pos_merma | Pérdidas de inventario | id, negocio_id, producto_id, cantidad, motivo, descripcion, usuario_id |
pos_suscripciones | Suscripciones SaaS | id, negocio_id, plan_codigo, estado, periodo_inicio, periodo_fin, mp_subscription_id |
pos_planes | Definición de planes | id, codigo, nombre, precio_mensual, precio_anual, modulos (array) |
pos_config_tributaria | Config fiscal del negocio | id, negocio_id, regimen, rut_negocio, razon_social, tasa_ppm, tasa_renta, precios_con_iva |
pos_credito_iva | Facturas de compra para crédito IVA | id, negocio_id, proveedor, folio_factura, monto_neto, iva, fecha, concepto |
pos_mesas | Mesas del restaurante | id, negocio_id, numero, nombre, capacidad, activa |
pos_comandas | Comandas abiertas | id, mesa_id, usuario_id, estado, total, descuento, metodo_pago |
pos_comanda_items | Ítems de comanda | id, comanda_id, producto_id, nombre_producto, cantidad, precio_unitario, subtotal |
pos_socios | Socios del gimnasio | id, negocio_id, nombre, email, telefono, fecha_nacimiento, notas |
pos_membresias | Membresías de socios | id, socio_id, plan_id, fecha_inicio, fecha_fin, estado, metodo_pago |
pos_membresia_planes | Planes de membresía del gym | id, negocio_id, nombre, duracion_dias, precio |
pos_clases | Clases del gimnasio | id, negocio_id, nombre, instructor, dia_semana, hora_inicio, hora_fin, cupo_max |
pos_checkins | Asistencia al gimnasio | id, socio_id, fecha, clase_id (opcional) |
Roles y permisos
| Acción | Dueño | Admin | Cajero |
|---|---|---|---|
| Registrar ventas | ✅ | ✅ | ✅ |
| Ver historial de ventas | ✅ | ✅ | ❌ |
| Anular ventas | ✅ | ✅ | ❌ |
| Crear/editar productos | ✅ | ✅ | ❌ |
| Ajustar inventario | ✅ | ✅ | ✅ |
| Ver Dashboard | ✅ | ✅ | ❌ |
| Registrar gastos | ✅ | ✅ | ❌ |
| Ver impuestos | ✅ | ✅ | ❌ |
| Gestionar usuarios | ✅ | ✅ | ❌ |
| Cerrar caja ajena | ✅ | ✅ | ❌ |
| Ver suscripción/planes | ✅ | ❌ | ❌ |
Integración: MercadoPago
Flujo de suscripción
- Trial — el usuario registra su tarjeta en MP sin cargo inmediato (
PreApproval). Al día 8 MP cobra automáticamente. - Upgrade directo — genera una
Preferencede pago. MP redirige de vuelta con el resultado. - Webhook
authorized— activa la suscripción en la BD, actualizaperiodo_fin. - Webhook
cancelled/paused— suspende el acceso. El usuario ve banner rojo.
Integración: SIRUF Trueque
URL: https://trueque.siruf.cl | Repo: sirufchile/siruf-trueque
SIRUF Trueque es una red de intercambio entre PYMEs. Permite mover inventario próximo a vencer o estancado sin pérdida monetaria. El POS se conecta en dos puntos:
- Inventario — botón "Ofrecer SIRUF" en productos con problemas (vencidos, por vencer, agotados). Publica la oferta via
POST /api/siruf/ofertas. - PromoServicios — banner informativo en todas las páginas invitando a registrarse en trueque.siruf.cl (plan gratuito disponible).
La plataforma Trueque tiene un algoritmo de cadena que detecta intercambios multilaterales (A le da a B, B le da a C, C le da a A).
Integración: Kira AI
URL: https://api.siruf.cl | Repo: sirufchile/kira-agent
Kira es el asistente de IA de SIRUF, basado en Claude (Anthropic). En el POS aparece como:
- Página
/soporte— chat completo especializado en el POS - Widget flotante — disponible en todas las páginas
El frontend envía mensajes a POST https://api.siruf.cl/api/chat con el slug = "tikvah-pos". Kira tiene acceso al contexto del sistema y puede responder preguntas sobre cómo usar cada módulo.
PWA y funcionamiento offline
Instalación
El sistema puede instalarse como app nativa en cualquier dispositivo. En móvil aparece un banner "Instalar Tikvah POS" que usa el evento beforeinstallprompt. Una vez instalado, funciona como app independiente sin barra del navegador.
Caché y versiones
- Cada build incrementa
CACHE_VERSIONenpublic/sw.js - El Service Worker detecta la nueva versión y muestra el banner "Nueva versión disponible — Actualizar"
- Al hacer click, recarga la página con el nuevo caché
Sincronización
- Las ventas offline se guardan en
IndexedDBbajo la claveventas_pendientes - Al recuperar conexión,
sincronizarAhora()procesa cada venta pendiente - El contador de ventas pendientes se actualiza cada 2 segundos en la Caja
- Si una venta falla al sincronizar (ej. producto eliminado), se marca como error
Archivos clave del frontend
src/lib/api.js— todas las llamadas al backendsrc/lib/auth.js— contexto de autenticación, token JWTsrc/lib/idb.js— operaciones IndexedDB (offline)src/lib/sync.js— sincronización de ventas offlinesrc/lib/format.js— formateo de precios (CLP), fechas, unidadespublic/sw.js— Service Worker completoindex.html— script inline que aplica tamaño de fuente guardado antes de React
tikvah-pos, kira-agent, siruf-trueque.
Tikvah POS — Documentación interna SIRUF · Actualizado marzo 2026