propuesta · ago 2026
Finanzas · captura en campo

Lo que se gasta, en el momento.

Hoy el comprobante llega por WhatsApp o en papel, y Finanzas lo reconstruye días después: ¿de qué cuenta salió?, ¿de qué empresa?, ¿cuánto era en dólares? Mogos Caja lo captura donde ocurre, con la cuenta real, la empresa y la foto, y lo deja listo para conciliar con el banco.

Por registro
3 toques + foto
Pantallas
5 vistas
Gastos
0 tablas nuevas
Plataforma
PWA

Hoy: la libreta llega tarde

WhatsApp · papel · Excel

Un chofer paga un flete, un almacén compra insumos, alguien cubre una tasa bancaria. El comprobante se fotografía y se manda al grupo, o se guarda en la guantera. Finanzas lo recibe tres días después, sin cuenta, sin empresa y sin tasa del día, y lo reconstruye a mano en un Excel antes de poder cruzarlo con lo que dice el banco.

Hoy

Foto por WhatsApp, Excel, y «¿de qué cuenta salió?»

  1. La foto no sabe nada. Ni cuenta, ni empresa, ni tasa: todo se pregunta después.
  2. El Excel es la fuente. Finanzas transcribe y el error de tipeo ya no se puede rastrear.
  3. La conciliación empieza en cero. El movimiento del banco llega y nadie sabe a qué gasto corresponde.
Latencia
3 días
Preguntas
3+
Fuente
Excel
Con Caja

Registrado con cuenta, empresa y comprobante en tres toques

  • 10:12Flete navieroMercantil USD · comprobante−1.240,00USD
  1. El monto nace con contexto. Cuenta real, empresa y tasa BCV del momento, sin preguntar nada.
  2. El comprobante va pegado. Foto obligatoria cuando la cuenta lo exige; nada de buscar en el chat.
  3. Finanzas concilia, no transcribe. El egreso ya existe; solo se cruza con el movimiento del banco.
Latencia
0 días
Preguntas
0
Fuente
Egreso

La app: cinco vistas

PWA · Supabase Auth

Una app pequeña para gente que está de pie. Cada vista existe porque quita algo del trabajo; ninguna pide más de lo que el teléfono ya sabe. Desliza para ver las cinco.

01EntrarCorreo y clave con Supabase, como las demás apps. Desaparece: pedir acceso al Excel compartido.
02HoyEl total del día arriba y la cola offline avisando aquí, no escondida en Perfil. Desliza una fila para repetirla, editarla o eliminarla. Desaparece: «¿cuánto llevo hoy?» por mensaje.
03Nuevo movimientoUna pantalla, sin asistente por pasos. Monto, cuenta, foto, Guardar. Desaparece: el mensaje al grupo.
04DetalleTodo lo capturado, en texto llano. Repetir prellena un Nuevo — el peaje de cada día queda en dos toques. Editar y Eliminar viven aquí hasta conciliar; Eliminar confirma en una hoja con el monto y la cuenta, nunca un aviso del navegador. Desaparece: «¿ya lo cargaron?».
05PerfilQuién soy, mi empresa por defecto y lo que falta por subir cuando no hubo señal. Desaparece: perder un registro por falta de datos.
vista 1 / 5

Nuevo movimiento: anatomía

POST /finance/egresos

La pantalla que justifica la app. El camino honesto: dígitos → cuenta → foto → Guardar — tres toques más la foto cuando la cuenta la exige. Todo lo demás viene recordado (empresa), prellenado (fecha, tasa), filtrado (cuentas) o es opcional (categoría, referencia, nota). Cada número en la maqueta remite a una decisión.

  1. Gasto / Ingreso, un toggle

    Dos estados, no un menú. El rojo se usa solo aquí, para el gasto; la lima solo para el ingreso. Por defecto arranca en Gasto: es lo que más se registra en campo.

  2. El monto es el objeto

    Neue Haas 900, cifras tabulares, teclado propio de 12 teclas — coma y borrar al tamaño del pulgar — con formateo de miles en vivo. La moneda no se elige: la fija la cuenta y el rótulo junto al monto solo la refleja (MoneyAccount.currency es una sola).

  3. Equivalente escogible, tasa a la vista

    El equivalente muestra siempre otra moneda y rota al tocarlo (Bs → CNY → EUR…); la app recuerda tu elección. La etiqueta dice la fuente del par — BCV 36,52 · editada 41,00 · 1 : 1 · sin tasa · agrégala — y el lápiz edita solo la tasa, recalculando en vivo. Al guardar se congelan la tasa aplicada y el equivalente canónico en USD (patrón budgetAppliedRate); sin tasa, el guardado nunca se bloquea. Y es tu control de magnitud: un ≈ Bs 452.848 bajo un monto que debía ser 124 grita solo.

  4. Empresa = Company

    Selector con las empresas reales (GET /companies/mine) y memoria de la última usada. La empresa no es un texto: filtra las cuentas por su financialEntity.

  5. Fecha de pago: hoy, editable

    Prellenada con hoy y guardada en spentAt. Se cambia cuando el comprobante se registra después del pago; cambiarla es opcional y los tres toques quedan intactos.

  6. Cuenta real, no canal

    Chips filtrados por entidad: Bancamiga Bs · Mercantil USD · Zelle · Binance · Caja chica. Se guarda accountId de MoneyAccount, nunca «transferencia» o «efectivo» a secas: es lo que permite conciliar con el banco. Elegirla fija la moneda del monto: «Bs desde Mercantil USD» no puede existir.

  7. Categoría opcional

    Tres chips por historial del operador y «Más…» para el resto del EgresoCategoryEnum. Sin toque, el registro nace UNCLASSIFIED y Finanzas clasifica donde le toca: la categoría es de Finanzas, no del chofer.

  8. La foto, obligatoria cuando la cuenta lo exige

    Cámara o galería, subida a proof-upload-url. Si la cuenta tiene requiresProof (o el monto supera proofThresholdUsd), Guardar se bloquea hasta adjuntarla. Sin foto el registro nace en MISSING_PROOF.

  9. Guardar → «Registrado» → Hoy

    Un solo botón, a 44 px del borde. Toast breve y vuelta a la lista. Sin señal, el registro va a la cola offline y se sube solo.

Empresa y cuenta: el mapeo con el banco

Company → MoneyAccount → Egreso

La cadena que hace que un gasto capturado en la calle termine cruzado con una línea del banco. La app solo toca los tres primeros eslabones; la conciliación es de admin/finanzas.

1 · en la appCompany La empresa que paga. Mogos C.A. o Mogos Logistics, de GET /companies/mine. MOGOS_VEMOGOS_CN
2 · derivafinancialEntity La entidad financiera de la empresa. Filtra qué cuentas se muestran. VEUS_LLCnull · Logistics
3 · en la appMoneyAccount La cuenta real de donde salió el dinero: banco, saldo en proveedor, caja o wallet. Trae requiresProof. BANKPROVIDER_BALANCECASHWALLET
4 · se creaEgreso Monto, moneda, categoría, foto, referencia y nota. Nace con status y sin movementId. UNCLASSIFIEDMISSING_PROOFREADY
5 · en adminConciliación Finanzas cruza el egreso con el MoneyMovement que llegó del banco y fija movementId. La app lo muestra como «Conciliado». movementId
Lo que falta hoy

Mogos Logistics tiene financialEntity: null. Con la regla «las cuentas se filtran por entidad», Logistics no tendría cuentas y no podría registrar nada. Antes de la fase 1 hay que asignarle una entidad (y sus MoneyAccount) o no aparece en el selector: solo las empresas con entidad se listan.

La primera vez tampoco se improvisa: la empresa por defecto la asigna admin al crear al operador; con una sola elegible, el selector llega resuelto; y Hoy vacío invita — «Registra tu primer movimiento».

Escritorio: dos columnas

≥ 1024 px · mismos componentes

Responsive-first no quiere decir móvil-solo. En computadora las mismas vistas se acomodan en dos columnas: la lista de Hoy a la izquierda, el formulario a la derecha. Nada nuevo: los mismos chips, la misma tarjeta, el mismo botón. Quien la usa no es el chofer: es compras u oficina pagando desde la computadora, con el mismo alcance y cero funciones extra.

En escritorio el comprobante se sube como archivo; la cámara es del teléfono. La columna derecha alterna: Nuevo por defecto, clic en una fila la vuelve Detalle, y Guardar limpia el formulario resaltando la fila recién creada. El resto es idéntico, componente por componente.

Decisiones

10 decisiones · 2026-08-24

Lo que quedó aprobado, por qué, y la alternativa que se descartó — para que nadie la vuelva a abrir sin saber por qué se cerró.

DecisiónPor quéAlternativa descartada
01Usuario: operador en campo Chofer, almacén y compras registran en el momento, de pie y con una mano. Se optimiza para tres toques. Finanzas carga desde el escritorio — es lo de hoy, con tres días de latencia.
02Alcance: capturar y ver lo mío La app registra y muestra los movimientos propios. La conciliación vive en admin/finanzas, donde está el banco. Conciliar desde el teléfono — requiere ver los movimientos bancarios, que no son del operador.
03Campos: los que concilian Tipo, monto (la moneda la fija la cuenta), equivalente escogible, empresa, fecha, cuenta, categoría opcional, foto, referencia y nota. Beneficiario, centro de costo, proyecto — se clasifican en admin si hacen falta.
04Método de pago = cuenta real MoneyAccount es lo que el banco reporta. Con «transferencia» a secas no hay nada que cruzar. Elegirla fija además la moneda del monto. Canal genérico (efectivo, transferencia, Zelle) — vuelve a la pregunta «¿de qué cuenta?».
05Empresa = Company, filtra cuentas Las cuentas se muestran según financialEntity. No se agrega país: la entidad ya lo implica. Campo país en Company — dato redundante; Logistics necesita entidad, no país.
06Dirección A · Libreta clara Hueso, monto en marino 900, chips con hairline, tarjeta marino con el total. Lima solo para ingresos, rojo solo para gastos. Dirección oscura tipo terminal — pierde la lectura al sol y el tono de libreta.
07Nombre: Mogos Caja Es lo que hace: la caja del día. Corto, en español, sin explicar. Mogos Gastos — deja fuera los ingresos que también se capturan.
08Corregible hasta conciliar Tasa recomendada pero editable, fecha de pago prellenada con hoy y cambiable, Editar y Eliminar a un toque en el Detalle. Con movementId fijado, todo se bloquea. Registro inmutable — castiga el error de dedo del operador y ensucia la conciliación con duplicados.
09Equivalente escogible, USD canónico El equivalente rota por toque a la moneda que quieras; la etiqueta dice la fuente del par (BCV 36,52 · editada 41,00 · 1 : 1) y al guardar se congelan la tasa aplicada y el equivalente en USD. Dropdown de par de monedas — dos controles, dos verdades persistidas y una pantalla menos simple.
10Repetir y outbox desde la fase 1 El pago repetido queda en dos toques y ningún registro espera por señal; la cola avisa en Hoy, no en Perfil. Offline en fase 3 — la señal intermitente es la condición base del chofer, no un caso raro.

Lo que se reutiliza en el sistema

apps/api · finance

Casi todo existe. Para los gastos la app es un cliente nuevo de endpoints que ya están en producción; la única pieza sin decidir es el ingreso manual.

Datos · existen

Gasto → Egreso tal cual

  • Egreso: entity, accountId, amount, currency, category, note, proofUrl, status, spentAt, createdById, movementId?.
  • Referencia bancaria en beneficiary o un externalRef nuevo — la única columna en discusión.
  • EgresoCategoryEnum: los once chips salen del enum, sin tabla nueva.
  • CurrencyEnum: USD · BS · EUR · USDT · CNY; ExchangeRate con fuente BCV o manual. USDT no existe en ExchangeRate: el peg 1 : 1 con USD es explícito en la etiqueta, nunca «BCV».
  • Nuevo al guardar: appliedRate + equivalentUsd + rateSource congelados (patrón budgetAppliedRate); los demás equivalentes son display derivado, nunca persistido.
Datos · existen

MoneyAccount y Company

  • MoneyAccount: name, type (BANK · PROVIDER_BALANCE · CASH · WALLET), entity, currency, requiresProof, proofThresholdUsd.
  • Company: tradeName, defaultCurrency, financialEntity?. Sembradas MOGOS_VE (VE) y MOGOS_CN (null).
  • Regla nueva: financialEntity obligatorio para aparecer en el selector de la app.
Endpoints · existen

La app los consume, no los crea

  • POST /finance/egresos — crear el gasto.
  • POST /finance/egresos/proof-upload-url — URL firmada para la foto.
  • GET /finance/accounts — cuentas, filtradas en cliente por entidad.
  • GET /companies/mine — empresas del usuario.
  • GET /exchange-rates/latest — tasa BCV para el equivalente.
  • Nuevo: GET /finance/egresos/mine con filtros de periodo y empresa, para Hoy / Semana / Mes.
Pendiente de decidir

Ingreso manual

  • No existe un modelo de ingreso manual. Lo más cercano: MoneyMovement con ingestSource: MANUAL y direction: CREDIT, estado UNMATCHED.
  • Opción A: usar ese MoneyMovement manual — cero tablas, pero mezcla capturas con líneas del banco.
  • Opción B: un Ingreso espejo de Egreso — una tabla más, simetría total con la app y la conciliación.
  • Se decide en goal-phases, fase 2. La fase 1 no lo necesita.

Fases

1 → 4

Cuatro fases con superficie de verificación propia. La primera ya sirve en la calle y no toca el esquema.

  1. 1

    La app y los gastos

    0 migraciones

    Nueva app apps/caja (Next.js, PWA) con Entrar, Hoy, Nuevo, Detalle y Perfil. Solo gastos: POST /finance/egresos + foto por proof-upload-url, cuentas filtradas por entidad, categorías del enum. Endpoint GET /finance/egresos/mine. Entidad asignada a Mogos Logistics como dato, no como migración. Incluye el outbox mínimo: registro y foto esperan en el teléfono y se suben solos al volver la señal — la señal intermitente es la condición base del campo, no un caso raro.

  2. 2

    Ingresos y tasa

    0–1 migración

    El toggle Ingreso cobra vida con la decisión de la sección 07 (MoneyMovement manual o Ingreso). Equivalente USD a tasa BCV guardado con el registro, moneda CNY y USDT probadas de punta a punta.

  3. 3

    Offline e instalación

    0 migraciones

    Manifest e instalación a la pantalla de inicio en iOS y Android, con acceso directo «Nuevo gasto». El outbox de la fase 1 se gradúa a service worker completo: caché de la app, reintentos con backoff, fotos grandes. Sin tienda, sin React Native.

  4. 4

    Estado de conciliación

    0 migraciones

    El Detalle lee movementId y muestra «Conciliado» con la fecha; la edición se bloquea. Hoy marca los movimientos conciliados en la lista. Y llega el estado «Devuelto · motivo»: si Finanzas encuentra un problema (foto ilegible, monto que no cruza), la fila vuelve al operador con Editar activo — sin WhatsApp.

Qué no hacemos

alcance

Cinco cosas que se discutieron y quedan fuera, con la razón.

Conciliar Ver movimientos de otros Reportes Editar cuentas o categorías React Native
  • Conciliar — exige ver el banco; es de admin/finanzas. La app solo muestra el estado en texto.
  • Ver movimientos de otros — el operador ve lo suyo. El consolidado por empresa ya vive en Finanzas.
  • Reportes — Hoy / Semana / Mes son vistas de control personal, no un informe. Los reportes salen del admin.
  • Editar cuentas o categorías — son datos maestros de Finanzas; la app los consume del enum y de MoneyAccount.
  • React Native — PWA instalable: cámara, offline y pantalla de inicio sin tienda ni build nativo.

Tres toques y el gasto ya existe, con cuenta y con foto.

Mogos Caja convierte el comprobante perdido en un registro que Finanzas solo tiene que cruzar. Lo que se gasta, en el momento; lo que llega del banco, con nombre.