# Changelog

All notable changes to the Disaster Alerts plugin are documented here.

---

## [1.0.0] — 2026-04-19

Initial release.

### Added

#### Core Monitoring
- Device-scoped monitors: each monitor belongs to the currently selected WhatsApp device and is auto-attached from the session on creation
- Three data sources: **USGS Earthquake** (free, default), **GDACS** (free), and **Custom API**
- Country-scoped filtering using ISO country code + country name (matched against USGS `place` text, passed as `country` param to GDACS)
- Minimum magnitude threshold per monitor
- Independent toggles for earthquake and tsunami events
- Per-monitor polling interval (minutes); minimum 1, maximum 1440
- Active / inactive status toggle

#### Scheduler & Dispatch
- `disaster-alerts:check` Artisan command registered on the scheduler as `everyMinute()->withoutOverlapping()`
- `isDueForCheck()` gate so a monitor only polls when `last_checked_at + check_interval` has elapsed
- Automatic re-check after the `start:blast` command finishes, via a `CommandFinished` event listener
- Optional `--setting=ID` flag to process a single monitor (used for manual/testing runs)

#### Latest-Event Delivery
- `pickLatestEvent()` sorts fetched events by `occurred_at` descending and returns only the most recent one — prevents old events from being broadcast on subsequent polls and avoids recipient flooding
- Per-event deduplication via `DisasterAlertLog` (`setting_id` + `event_id`): the same event is never dispatched twice
- `last_event_id` on the setting is updated after each dispatched event

#### Message Templating
- Default templates for earthquake and tsunami with safety footer
- Custom template per monitor with placeholders: `{place}`, `{title}`, `{magnitude}`, `{time}`, `{url}`, `{country}`, `{type}`, `{latitude}`, `{longitude}`
- Time is formatted as `Y-m-d H:i`; missing fields fall back to `-` or empty string

#### Recipients Management
- Free-text entry split on new line, comma, or semicolon
- File upload supporting `.csv`, `.xlsx`, `.xls`, `.txt`
  - Spreadsheets parsed via Maatwebsite/Excel (`RecipientsImport`)
  - Plain text files read and split the same way as free text
  - A `number` header row is ignored
- Phone numbers normalized to digits only, deduplicated, and filtered (min 8 digits)
- On edit, submitting an empty recipients block preserves the existing list

#### Test Dispatch
- **Test** action on each monitor card sends a sample earthquake payload (M 5.2, current time, current country) to every configured recipient
- Returns success/failure count in a JSON response displayed via browser alert

#### UI
- Stats row: Total Monitors, Active Monitors, Alerts Today, Total Alerts Sent — all scoped to the current user + selected device
- Monitors displayed as responsive cards showing country, event-type badges, magnitude, API source, check interval, recipient count, and last-checked timestamp
- Breadcrumb navigation on all pages
- Per-monitor alert logs page with paginated table: event title/link, type badge, magnitude, location, occurred time, recipient count, delivery status, sent-at timestamp
- Two-step confirmation modal for deletion
- Device-required guard (`@if (!session()->has('selectedDevice'))`) on all three views prevents interaction without a selected device
- `requires_device: true` in the plugin nav definition so the menu item only appears after a device is selected

#### Security
- All user-facing data scoped by `user_id` and (where relevant) selected `device_id`
- Only `api_url` and `api_key` from the request are persisted, and only when `api_source = custom`
- `country_code` is uppercased before saving; `min_magnitude` bounded `0..10`; `check_interval` bounded `1..1440`
- Phone numbers stripped of non-digits before storage
- CSRF token sent on all state-changing requests from the UI

#### Internationalization
- `lang/en.json` covering every UI string, including default message templates, status labels, and validation messages

---

## License

This plugin is licensed under the **Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)**.

> Full license text: https://creativecommons.org/licenses/by-nc-nd/4.0/
