--- title: Alert Changes tags: [mortgagefi, ops, notifications] type: operations status: reference updated: 2026-06-14 --- # Alert Changes Alert branch: notification and scheduling changes This branch introduces a single‑alert scheduling flow, clearer alert copy, and an ntfy email setup via Docker Compose env vars. ## Changes - Single scheduled alert per position - Replaced multi-job scheduling with `scheduleNotification(row)` that returns `{ jobId, runAt }`. - Toggle stores `{ enabled, jobId, scheduledAt }`. - Auto-rescheduler keeps a single job in sync. - Message improvements - Time window shows the configured lead offset (e.g., `~10d`) instead of remaining time at execution. - Payment guidance prioritizes Debt Remaining; fallbacks: 1.5× monthly, then current payment pending. - Collateral at risk uses the same formatting as the UI: `fmt(row.coinSize, coinDecimals, 8)` + token symbol (e.g., `0.05651738 cbBTC`). - Test alert sends email - `scheduleTestNotification()` now includes `X-Email` from settings to trigger ntfy email in addition to topic publish. - ntfy SMTP via Docker Compose - Configure Gmail/App Password or another SMTP via env vars in compose instead of a server.yml. ## Files modified - `mortgagefi-frontend/app/dapp/page.tsx` - Toggle handler uses `scheduleNotification()` and stores `{ jobId, scheduledAt }`. - `scheduleNotification()` builds improved message and schedules one Schedy job. - `mortgagefi-frontend/utils/scheduler.ts` - `scheduleTestNotification()` adds `X-Email` header. - `docker-compose.yml` (root) - ntfy service accepts SMTP settings via env vars (with defaults). You can also pass them via `env_file`. ## Configure SMTP (ntfy) Set these in `.env` or `.env.local` (compose resolves `${VAR}` from `.env` or shell; using `env_file`, list bare keys in `environment:` to pass-through values): ``` NTFY_BASE_URL=https://web.example.com/ntfy # must match your public URL & subpath NTFY_SMTP_SENDER_ADDR=smtp.gmail.com:587 # or smtp-relay / your SMTP NTFY_SMTP_SENDER_USER=your.name@gmail.com # Gmail address or relay user NTFY_SMTP_SENDER_PASS=app-password-xxxx # Gmail App Password NTFY_SMTP_SENDER_FROM=your.name@gmail.com # From address NTFY_LOG_LEVEL=info ``` Compose snippet (Option A: pass-through via env_file): ```yaml services: ntfy: image: binwiederhier/ntfy command: ["serve"] env_file: .env.local environment: - TZ=Europe/Zurich - NTFY_BASE_URL - NTFY_SMTP_SENDER_ADDR - NTFY_SMTP_SENDER_USER - NTFY_SMTP_SENDER_PASS - NTFY_SMTP_SENDER_FROM - NTFY_LOG_LEVEL ``` ## Bring up services 1) Populate `.env` or `.env.local` with: - `NEXT_PUBLIC_NTFY_URL=/ntfy` - `NEXT_PUBLIC_SCHEDY_URL=/schedy` - `NEXT_PUBLIC_SCHEDY_API_KEY=` - SMTP variables above. 2) Start stack from repo root: ``` docker compose up -d ``` 3) Access: - App: `http://localhost` - ntfy (proxied): `http://localhost/ntfy` - schedy (proxied): `http://localhost/schedy` ## Verify email path - Settings → Provider: ntfy, set Server+Topic, Email, Scheduler: Schedy + API key. - Click “Send test alert”. Expect both topic message and email. - Manual test: ``` curl -X POST -H 'Content-Type: text/plain' -H 'X-Email: your.name@gmail.com' \ https://web.example.com/ntfy/yourtopic -d 'Email test via ntfy SMTP' ``` ## Notes > [!note] > - Ensure `NTFY_BASE_URL` includes `/ntfy` if you serve ntfy under a subpath. > - For compose variable interpolation with `${VAR}`, put values in `.env` (not `.env.local`) or export them in the shell. Using `env_file`, prefer pass-through keys as shown above. ## Related [[Home]], [[Architecture]], [[API Reference]], [[Development]]