feat(alerts): avisos remotos de consumo y reinicio de límites

Abierto
#245 1 comentario 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@ludevdot ya está trabajando en esto.

Desde el 6/11/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

status:approved type:feature
Pre-flight checks
  • I searched existing issues and found no duplicate.
  • I understand that this proposal requires product review before implementation.
Problem to solve

Al alejarse del ordenador, una persona puede perder el aviso de que su consumo ha alcanzado un umbral o de que una ventana se ha reiniciado y vuelve a tener capacidad disponible. Los avisos locales no cubren ese momento; recibir un email permitiría consultarlo desde el móvil con su cliente habitual, sin otra aplicación de push.

El problema es el seguimiento del consumo, no detectar la finalización de agentes.

Proposed solution

Se recomienda Resend para una primera fase, con cuenta y API key propias, tras compararlo con un webhook HTTP genérico y ntfy. La elección del canal queda pendiente de revisión de producto: Resend no se presenta como una decisión cerrada.
Los detalles y criterios siguientes describen el alcance recomendado si se acepta, si se prefiere otro canal, se ajustarán antes de implementar.

La primera fase añadiría únicamente la configuración del canal concreto en Ajustes, sin proponer una nueva sección Integraciones. Las reglas y umbrales seguirían en Alertas, la ubicación exacta de los controles se concretará durante la revisión.
No se construyen registro genérico de proveedores, framework de plugins ni tarjetas para servicios futuros. Si llegan otras integraciones, se extraerá entonces lo común.

  • Email desactivado por defecto; activación con consentimiento explícito sobre los datos enviados.
    Guardar configuración no lo activa. Desactivar conserva la clave; eliminarla impide nuevos envíos.
  • Configurar API key oculta, remitente y destinatario, con acción explícita de email de prueba y aceptación/error sanitizado visible. La prueba requiere consentimiento y configuración válida, puede usarse con Alertas global desactivado y no activa el envío automático.
  • Reutilizar secrets/keyring, sus comandos y SecretInput, con una clave propia de Resend.
    Sin clave en JSON, logs o lectura del valor guardado desde el frontend, sin fallback a texto plano.
  • Enviar por HTTP desde Rust/Tauri, sin ampliar la CSP. Reutilizar los eventos de alerts.ts despachados por Widget.tsx, conservando su semántica de umbral, reinicio y memoria. El envío automático requiere Alertas global y email habilitados, con configuración válida, el interruptor de notificación nativa solo gobierna el aviso local.
  • Un intento por evento, no por consulta de polling. Suprimir solicitudes repetidas del mismo evento, sin confundirlas con una nueva ocurrencia, concretar identidad y límites antes de implementar. Pedimos evitar reintentos en bucle. Como simplificación adicional para esta primera fase, se recomienda no realizar ningún reintento automático ni añadir cola o replay, esta restricción más estricta queda pendiente de aprobación.

No se garantiza entrega exactamente una vez, un timeout puede dejar incierto si Resend aceptó la solicitud. El fallo nunca bloquea avisos locales.

Mostrar antes de activar esta advertencia en la UI:

Los avisos por email requieren Quorb abierto, el ordenador despierto y conexión a Internet. Con Quorb cerrado o el equipo suspendido no se consulta el consumo ni se detectan o envían avisos. La aceptación de Resend no garantiza la entrega del correo.

El contenido se limitaría a proveedor, medidor/ventana, porcentaje y tipo de evento (umbral o reinicio). Resend también procesa remitente y destinatario, que son datos personales.

Explicarlo antes del consentimiento. Sin prompts, código, identificadores de cuenta, usuarios, secretos ni contenido de sesiones, no exportar objetos completos ni registrar direcciones o payloads.

Distinguir pruebas de producción: según los errores oficiales de Resend, el 403 validation_error indica «You can only send testing emails to your own email address».
Se puede probar al email de la propia cuenta sin dominio verificado, usando el remitente de pruebas admitido. Para otros destinatarios se requiere dominio verificado y un from autorizado.

Confirmar el remitente exacto vigente antes de implementar, no prometer remitentes arbitrarios ni convertir el modo de pruebas en una garantía permanente de producción.

Mostrar «Solicitud aceptada por Resend», no «entregado en la bandeja de entrada»

Affected area

Application behavior

Scope and non-goals

Criterios de aceptación del alcance recomendado con Resend, condicionados a su aprobación y pendientes de verificación:

  • Una única integración en la primera fase (Resend como recomendación), con configuración concreta en Ajustes, sin nueva sección «Integraciones» ni capa genérica; opt-in, configuración y prueba explícita con resultado visible. Guardar no activa, desactivar conserva la clave y eliminarla impide enviar.
  • Consentimiento, datos mínimos y advertencia local visibles antes de activar, restricciones de pruebas al email propio y de dominio/remitente para otros destinatarios explicadas.
  • Credenciales reutilizan el flujo existente sin exposición ni fallback, envío Rust y CSP intacta.
  • Umbral, reinicio y memoria conservan la semántica actual, global + email controlan el envío, independientemente del aviso nativo. Un fallo remoto no bloquea alertas locales.
  • Consultas o solicitudes repetidas del mismo evento no duplican intentos dentro de los límites documentados, una nueva ocurrencia puede enviar. Sin reintentos en bucle ni promesa de entrega única, la recomendación adicional de omitir todos los reintentos automáticos y colas debe aprobarse.
  • Aceptación, configuración incompleta y errores se distinguen sin revelar datos sensibles; el payload y el sobre respetan la minimización descrita.

Fuera del alcance recomendado para esta primera fase: implementar varios canales a la vez, ntfy o webhook si se acepta Resend, selector por regla, detección de agentes, monitorización con el equipo apagado, servidor intermediario propio de Quorb para gestionar los envíos, clave compartida de Quorb, seguimiento de entrega y reorganización general de la interfaz.

Plan de pruebas futuro: datos sintéticos y HTTP simulado, sin envíos reales: comprobar opt-in/prueba/desactivación/eliminación, combinaciones de interruptores, restricciones de Resend, fallos de credenciales/red/API y timeout, regresión de umbral/reinicio y repetición de eventos y ausencia de secretos o datos extra en payloads y diagnósticos. Este borrador no prueba ejecución.
Verificaciones técnicas pendientes: reutilizar secrets.rs y keyring para guardar la API key. Actualmente, secrets::get() convierte los errores de lectura en ausencia de valor, por lo que secret_status: false no distingue una clave inexistente de un fallo de acceso al llavero. Antes de implementar, concretar cómo comunicar esa situación sin exponer secretos ni alterar otros proveedores. En Linux también debe confirmarse el mecanismo de almacenamiento efectivo y sus garantías: está habilitado linux-native, pero la documentación existente en docs/build-linux.md mezcla referencias a keyutils y Secret Service/libsecret. No se da por validado su funcionamiento en todos los entornos ni se permite recurrir a texto plano si falla el almacén.

Alternatives considered
Alternativa Ventaja Coste o límite frente al objetivo
Resend (recomendada) Correo habitual en el móvil, sin otra app; pruebas al email propio sin verificar dominio. Cuenta/API key; otros destinatarios requieren dominio y remitente autorizados. Sujeto a filtrado y retrasos del correo.
Webhook HTTP genérico Un POST al endpoint correspondiente permite activar avisos móviles mediante servicios como Discord, Telegram o ntfy. No existe un POST universal: cada servicio requiere su formato, autenticación y configuración. Validar URLs y proteger frente a SSRF amplía seguridad y soporte.
ntfy Push dedicado al móvil mediante un POST sencillo; el servicio público permite uso sin cuenta. Para alguien lejos del ordenador puede ser más directo que el email. Requiere configurar la suscripción y los permisos en el móvil. Sin ACL, el topic público no es privado: su nombre actúa como secreto de acceso.

Aunque el push puede ser más útil para recibir un aviso inmediato al estar lejos, se recomienda Resend para una primera fase por permitir usar el correo habitual sin instalar/configurar otra app de push y probar el envío a la propia cuenta sin dominio verificado.

Se acepta como contrapartida el posible retraso o filtrado del email, no se promete push inmediato. La comparación permite @egdev6 aceptar esa recomendación o priorizar otro canal antes de implementar. Diferir los canales restantes hasta una necesidad concreta, sin anticipar una capa común.

Referencias de la comparación: publicación de ntfy y FAQ de ntfy. No se han probado entregas en móviles ni se afirman precios.

Lenguaje dominante
TypeScript
Estrellas
10
Forks
2
Merge medio
7 h 51 min
PR fusionados (30 d)
129

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de egdev6/quorb

Todos los issues de egdev6/quorb

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.