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):
- Load all active alerts from the
alerts table
- For each alert, compare the latest value of
metric (avg_fee / base_fee / max_fee) against threshold using condition (ABOVE / BELOW)
- If the condition is met and
triggered = 0 → fire the alert:
- Set
triggered = 1 in SQLite
- Send email if
email is set
- 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. alerts@stellarfees.dev)
- 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
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
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
triggeredflag 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):
alertstablemetric(avg_fee / base_fee / max_fee) againstthresholdusingcondition(ABOVE / BELOW)triggered = 0→ fire the alert:triggered = 1in SQLiteemailis settriggered = 1→ reset:triggered = 0(alert is ready to fire again next time)Email via Resend
https://api.resend.com/emails)RESEND_API_KEYloaded from environment variableRESEND_FROM_ADDRESSloaded from environment variable (e.g.alerts@stellarfees.dev)⚡ Stellar Fee Alert — {metric} is {condition} {threshold} stroopsAcceptance Criteria
horizon.rsor the schedulertriggeredflag set to 1 on fire, reset to 0 when condition clearsemailfield is presentRESEND_API_KEYandRESEND_FROM_ADDRESSloaded from env; checker skips email silently if key is missing.env.exampleupdated withRESEND_API_KEYandRESEND_FROM_ADDRESSNotes
[Phase 2] feat(core): fee alerts — database schema and CRUD endpoints[Phase 2] feat(ui): dashboard — fee alerts panel