Files
where_woof/openspec/changes/scan-alert-hardening/proposal.md

29 lines
2.2 KiB
Markdown

## Why
The Phase 2 alert throttle prevents SMS spam from the *same spot*, but two gaps remain: (1) **multiple different finders at the same location** — each deserves to reach the owner, yet the current rule re-alerts only on movement >250 m; (2) **the same device can spam alerts** across different locations within minutes — there is no per-device throttle. This change hardens the alert path: re-alert on a *different finder phone* within the window, and block repeat alerts from the *same browser fingerprint* within 24 hours.
## What Changes
- **Different-finder re-alert** (`sms-alerting`): within the 10-minute window, an alert is also sent when the new scan carries a finder phone **different** from the last alerted scan's phone (multiple finders at the same spot each reach the owner). Same phone → no re-alert (unchanged dedup).
- **Fingerprint 24 h block** (`fingerprint-throttle`): the tag page's JS computes a lightweight browser fingerprint and sends it with every scan. If the same fingerprint was seen within the last 24 hours, the scan is recorded but **no alert is sent**. A fresh device alerts normally.
- **Schema**: `scans` gains a `fingerprint` column (idempotent ALTER); scan endpoint accepts an optional `fingerprint` + `phone`; contact flow dedups by phone within the window.
- The finder-contact form now also carries the fingerprint (same anti-spam coverage on the contact path).
## Capabilities
### New Capabilities
- `fingerprint-throttle`: JS fingerprint generation, per-device 24 h alert block, fingerprint stored on scans.
### Modified Capabilities
- `sms-alerting`: ADDED — different-finder re-alert within the window; contact-path dedup.
- `database`: ADDED — `scans.fingerprint` column.
## Impact
- **New/changed Go**: `internal/handlers/scan.go` (ScanRequest gains `phone`+`fingerprint`; `shouldAlert` gains the different-phone rule and the fingerprint check; `FinderContact` dedups + carries fingerprint), `internal/db/queries.sql` (new `GetRecentScanByFingerprint` query), regenerated sqlc.
- **Changed JS**: `templates/tag-public.html` (fingerprint computation sent with scan + contact).
- **Schema**: `scans.fingerprint` idempotent ALTER.
- No changes to auth, registry, or templates beyond the script.