Skip to content

[Phase 2] feat(core): fee alerts — background checker and email delivery via Resend #87

@Tinna23

Description

@Tinna23

Overview

Add the background alert checker that runs inside the existing 10s polling loop and checks all active alert rules against the latest fee stats. When a rule fires, it updates the triggered flag in SQLite and sends an email via Resend if an email address is configured.

Alert Checker Logic

On every poll cycle (after fetching and storing latest fee stats):

  1. Load all active alerts from the alerts table
  2. For each alert, compare the latest value of metric (avg_fee / base_fee / max_fee) against threshold using condition (ABOVE / BELOW)
  3. If the condition is met and triggered = 0 → fire the alert:
    • Set triggered = 1 in SQLite
    • Send email if email is set
  4. If the condition is no longer met and triggered = 1 → reset:
    • Set triggered = 0 (alert is ready to fire again next time)

Email via Resend

  • Use Resend HTTP API (no SDK — plain HTTP POST to https://api.resend.com/emails)
  • RESEND_API_KEY loaded from environment variable
  • RESEND_FROM_ADDRESS loaded from environment variable (e.g. [email protected])
  • Email subject: ⚡ Stellar Fee Alert — {metric} is {condition} {threshold} stroops
  • Email body (plain text):
    Your fee alert has triggered.
    
    Condition: {metric} {condition} {threshold} stroops
    Current value: {current_value} stroops
    Time: {timestamp}
    
    View dashboard: https://stellarfees.dev/dashboard
    
  • If Resend call fails, log the error but do NOT crash the poll loop

Acceptance Criteria

  • Alert checker integrated into the existing poll loop in horizon.rs or the scheduler
  • Correctly evaluates ABOVE and BELOW conditions for all three metrics
  • triggered flag set to 1 on fire, reset to 0 when condition clears
  • Email sent via Resend HTTP API when email field is present
  • RESEND_API_KEY and RESEND_FROM_ADDRESS loaded from env; checker skips email silently if key is missing
  • Email send failure is logged but does not interrupt the poll loop
  • Unit tests for the condition evaluation logic (ABOVE / BELOW for all metrics)
  • .env.example updated with RESEND_API_KEY and RESEND_FROM_ADDRESS

Notes

  • Related backend issue: [Phase 2] feat(core): fee alerts — database schema and CRUD endpoints
  • Related frontend issue: [Phase 2] feat(ui): dashboard — fee alerts panel

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend / Rust core work

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions