VortexRadar
Dónde estamos

Barquisimeto · De la calle al dato

El precio real
empieza en la calle.

Una foto de factura o un reporte de calle puede convertirse en un precio geolocalizado aceptado en el mapa. En bolívares y dólares.

Primero la evidencia. Después la comparación.

EL RECORRIDO DEL DATO
FACTURA DE COMPRAUna compra.
Un lugar. Una fecha.
Producto y tamaño✓
Importe originalVES / USD
Tienda y ubicación↗
La foto aporta evidencia.
No publica automáticamente un precio.
Lectura · coincidencia · validación
✓ AceptadoUn precio con contextoProducto · tienda · fecha
Esquema del flujo · sin precios ni ubicaciones de usuarios.

A · Entender el proyecto

La factura no termina en una foto.

El mapa sirve para consultar hechos aceptados. Un modelo de lenguaje ayuda a leer y resolver dudas; la evidencia viene de la compra, el GPS y el comercio.

  1. 01 / CAPTURA

    Factura o reporte

    Telegram y la web reciben el aporte. La ubicación permite situar el comercio.

    Telegram / ingesta
  2. 02 / LECTURA

    Producto e importe

    El OCR extrae líneas. Alias, búsqueda aproximada y trigramas buscan el producto antes del desempate con Gemini.

    OCR → alias / fuzzy / pg_trgm
  3. 03 / CONTEXTO

    Una tienda concreta

    Nombre del comercio y GPS ayudan a asociar la tienda. H3 y PostGIS organizan la consulta geográfica.

    Tienda + ubicación
  4. 04 / MAPA

    Solo lo aceptado

    Los reportes retail aceptados, con precio normalizado, llegan a Leaflet. Los casos sin resolver requieren revisión.

    price_reports → Leaflet

Código: telegram.py · tasks.py · resolver_service.py · store_service.py · geo_service.py. La ruta está implementada; una foto no garantiza un veredicto inmediato.

Un proyecto, varias puertas

La calle es el centro.

El presupuesto ayuda a organizar lo personal. El mapa reúne la información comercial aceptada.

Telegram

Aportar una factura, registrar un gasto y consultar el plan en chat privado.

Cómo aportar

Mapa

Explorar precios con producto, tamaño, tienda y fecha. La visibilidad depende de la gobernanza del dato y del acceso.

Explorar el mapa

Presupuesto personal

Gastos, cuotas y una meta opcional. Entra con tu enlace privado de Telegram: /presupuesto_web.

Acceso por enlace privado

Cuentas Claras

Organizar el reparto de una cuenta compartida. Registrar el reparto no mueve dinero.

Ver Cuentas Claras

Qué no promete VortexRadar

No es un banco ni realiza transferencias. No inventa precios con un LLM, no garantiza encontrar siempre el precio más barato y no presenta una meta como dinero en tu cuenta. La comparación que nos interesa es la de precios, no una clasificación de personas.

B · Dónde estamos

Software construido.
Preguntas todavía abiertas.

Esta lectura corresponde al código local del repositorio. No acredita un despliegue ni una adopción real. No hay observación de campo aportada en este encargo.

Corte de revisión · 22 septiembre 2026

Hechos de código

Qué hace hoy el software

Capacidades comprobables en archivos y pruebas locales. La operación efectiva del servidor queda fuera de esta revisión.

Implementado

Un plan personal privado

Gastos en USD/VES, categorías, meta opcional y resto del plan. Sin meta no se inventa una cifra diaria; el déficit se expresa como faltante total.

personal_budget_service.py · personal_budget.py
Corregido en este encargo

Cada cuota tiene identidad

Mensual, semanal, cada 14 días y días 15/último. Vencimiento y versión identifican el registro; bloqueo de fila y unicidad impiden duplicados. Deshacer conserva el gasto revertido e invalida botones anteriores.

recurring_occurrences · tests/test_personal_budget.py
Implementado

Registrar sin transcribir todo

/disponible, /meta y /ya_pague. Alta desde un gasto, previa confirmación; hoja para ajustar pago, moneda y tasa. La foto de factura permanece accesible.

telegram.py · presupuesto.html / js / css
Código y configuración

Mapa y procesamiento separados

OCR y revisión alimentan reportes comerciales. Los pagos recurrentes solo alimentan el presupuesto: no otorgan racha, puntos de contribución, referidos ni acceso OCR.

geo_service.py · personal_budget_service.py
Guarda existente

Confianza antes del binario

Con trust_score < 3 se bloquea la descarga de la factura. Registrar fijos no eleva esa confianza ni evita la comprobación.

telegram.py · ingest.py
Configurado en el repositorio

Redis con funciones separadas

/0 Celery; /1 Telegram y acceso al presupuesto; /2 caché. La política de producción es noeviction. Este cambio no añade telemetría financiera.

config.py · docker-compose.prod.yml

Límites conocidos

Lo que todavía no podemos afirmar

Plan ≠ caja

La meta no conoce tus saldos, ingresos recibidos ni efectivo por moneda. El cálculo resta gastos y cuotas del período; puede omitir necesidades que aún no registraste. No promete liquidez.

Un mapa necesita muestra

Poca cobertura o precios antiguos limitan la comparación. No basta con que el software calcule una mediana para convertirla en una referencia sólida de toda la ciudad.

Leer no es validar

El OCR, las coincidencias y la revisión pueden demorar. Una factura no se vuelve pública al subirla. Los calendarios y pagos heredados ambiguos quedan por confirmar.

Uso no es impacto demostrado

No hay observación de campo sobre alivio, retención o más facturas causada por los fijos. Son hipótesis para contrastar. La retención existente mezcla actividad privada y aportes.

Límite de alcance: no hay abonos, saldos por bolsillo, notificaciones nuevas ni hogar compartido. Las cuotas se consultan por mes; no se promete una vista consolidada de atrasos de todos los meses. Un calendario ya materializado requiere pausar la plantilla y crear otra para cambiar sus fechas.

Autocrítica

Las tensiones no se borran con copy.

Separamos lo que dice una regla de lo que hace el código, y una apuesta comercial de un resultado observado.

TensiónLo observadoDecisión
Visibilidad del mapaLa regla 7 nombraba visibility_status también para precios. Esa columna pertenece a world_cup_venues.En retail manda price_reports.status = 'accepted', con canal retail. Ver auditoría de reglas.
«Disponible» vs. planEl cálculo parte de una meta, no de un saldo confirmado.El comando histórico de consulta explica «resto del plan». Sin datos suficientes, la cifra queda por confirmar.
Gamificación vs. evidencia físicaHay rachas y logros en el presupuesto; algunos se apoyan en actividad manual.Los recurrentes quedan fuera de esos incentivos. La señal de aporte debe medirse por separado.
~30 KB vs. dependencia externaLa visión de producto menciona ligereza y cero CDN. El presupuesto y el mapa todavía cargan Chart.js desde CDN.Esta página no carga Chart.js. No presentamos 30 KB como peso total verificado: bytes crudos, gzip y dependencias son medidas distintas.
«Presupuesto → más facturas»Existe una hipótesis de retorno; también puede desplazar la fotografía de compras.Medir contribuciones útiles y comprensión. No afirmar causalidad ni éxito sin observación de campo.

Propuestas, no promesas de lanzamiento

Qué merece el siguiente esfuerzo

P0

Proteger el significado del dato

Mantener pruebas de concurrencia, calendario, privacidad y frontera geográfica. Revisar migración y datos ambiguos antes de exponer el cambio. Preservar el circuito factura → precio aceptado.

P1

Probarlo en la calle

Observar tareas en teléfonos reales: registrar, ajustar moneda, entender el plan y volver al mapa. Medir facturas útiles por separado; el aumento de visitas no demuestra suministro.

P2

Ampliar con evidencia

Evaluar caja por moneda, conciliación y abonos solo si la necesidad está demostrada. Reducir dependencias del presupuesto cuando el coste de carga lo justifique.

Crecer sin perder la calle

Más cobertura.
Operación manejable.

La arquitectura documentada es Hetzner, Docker, PostgreSQL/PostGIS, Redis y workers separados. No se necesita otro proveedor para este cambio.

Lo que puede crecer

Alias provenientes de tickets, cobertura por tienda, calidad y frescura. Más ciudades solo después de comprobar esos criterios y la capacidad de revisión local.

El límite operativo importa

Compose fija API 4/4 y workers 2/2. Los defaults de app/db.py aún son 5/10 si faltan overrides: deuda visible, no garantía de configuración efectiva.

Lo que no debe crecer por inercia

No convertirlo en un SaaS que necesite un equipo de 15 personas para operar. No sustituir el dato por un «oráculo LLM», ni inflar Ops para justificar funciones sin evidencia.

Posicionamiento propuesto

La apuesta es el dato que hay que salir a buscar.

Estas referencias explican nuestro foco; no son una auditoría de funciones o precios de otros productos.

Al pensar en YNAB

Nuestro presupuesto es un gancho privado y acotado. La apuesta central sigue siendo el precio observado en un comercio concreto.

Al pensar en Google Maps

La unidad que queremos comparar es producto, tamaño, precio, fecha y tienda. El lugar aporta contexto a ese hecho comercial.

Al pensar en «IA de precios»

Un LLM no puede aportar por sí solo evidencia de una compra real. La IA lee o ayuda a desempatar; la factura y el comercio sostienen el dato.

USD y VES, sin fingir caja

Se conserva moneda original y equivalente histórico del pago. Una conversión no garantiza tener la moneda que exige el proveedor.

Modelo declarado · por validar

Presupuesto como gancho.
Mapa como ventaja defendible.
B2B como fuente de ingresos.

Es una tesis del proyecto. No declara ingresos, adopción ni efectos logrados.

LOOP D · Reglas frente al código

¿Las reglas todavía cubren el alcance?

El criterio es la evidencia del repositorio. La revisión por regla se incorpora aquí, sin convertir esta página en un panel administrativo.

Regla¿El código la cumple?¿Está mal nombrada?¿Falta una regla?
1 · Async y fallosEn presupuesto: endpoints síncronos ejecutados por FastAPI; SQL del bot con _run_sync. Lecturas fallidas hacen rollback y declaran el error. Las mutaciones no fingen éxito.No. «Sin datos» y «error de lectura» son estados diferentes.Explicitar esa diferencia. No certificamos todo el webhook heredado ni el fallo al adquirir una conexión.
2 · SQL y poolsCuotas consultadas y generadas en lote. Compose fija 4/4 y 2/2; los defaults de db.py siguen en 5/10. El servicio geo conserva filtros y fallback.No; la configuración efectiva necesita verificación operativa.Una comprobación de configuración por rol sería útil. No se elevan pools en este encargo.
3 · RedisÍndices 0/1/2 separados en configuración; presupuesto usa /1 para acceso privado. No añadimos caché ni instrumentación de fijos.No.Si se mide el piloto: solo /2, TTL acotado y sin importes, nombres ni contenido financiero.
4 · Tareas e idempotenciaEl código OCR tiene backoff con jitter. Los recurrentes ahora usan clave de cuota/versión, bloqueo de fila y un único gasto vigente por vencimiento.La regla anterior solo explicitaba la unicidad de reportes OCR.Sí: garantizar idempotencia financiera propia, rechazar reintentos con otros datos y probar reversión y carreras.
5 · MapaSe conserva el mapa y se añade un enlace público de 44 px. El dato comercial mantiene categoría, tamaño y unidad. No se refactoriza Leaflet.No.Extender accesibilidad a las nuevas superficies: controles táctiles, texto de estado y movimiento reducido.
6 · Cambios y pruebasEl cambio se concentra en presupuesto, su migración, pruebas y esta página. Las pruebas financieras usan PostgreSQL local real.No.Nombrar concurrencia, calendario civil y frontera privada/pública como pruebas de aceptación.
7 · Gobernanza y mediosRetail filtra price_reports.status; Mundial usa world_cup_venues.visibility_status. El acceso a fotos sigue condicionado por confianza.Sí; corregido. Se sustituyó únicamente la referencia indiscriminada a visibility_status por los campos de cada dominio.Sí: prohibir que una aserción privada de gasto se convierta en precio público o permiso para OCR.
8 · Privacidad y hostingEsta página sirve archivos locales, sin peticiones a APIs administrativas ni datos de usuarios. La validación de este encargo es local.No.Exigir chat privado antes de leer o modificar finanzas y antes de emitir enlaces privados.

Corrección factual mínima: .cursorrules, regla 7. Evidencia: las definiciones de price_reports y world_cup_venues en app/db.py; filtros retail en app/services/geo_service.py. Una propiedad de salida GeoJSON llamada visibility_status no implica que exista esa columna en reportes.

Dictamen: las reglas conservan la arquitectura y la tesis del dato físico, pero necesitan nombrar el dominio financiero privado. Esta propuesta queda para revisión; no altera silenciosamente el alcance de las reglas existentes.

Vuelve a lo comprobable

Explora el mapa.
Aporta desde la calle.

Una contribución útil necesita contexto y validación.