Add settings UI, Discord notifications, and alert detail improvements
- Settings modal (gear icon) lets you configure all service URLs and API keys from the dashboard; values persist to data/settings.json with process.env as fallback so existing .env.local setups keep working - Per-service Test button hits each service's status endpoint and reports the version on success - Discord webhook support: structured embeds per alert category (requesters, approval age, episode progress, watch-rate stats) sent on new/reopened alerts only — already-open alerts don't re-notify - Alert detail page restructured: prose descriptions replaced with labelled fields, episode progress bar for partial TV, watch-rate stat block, View in Radarr/Sonarr/Seerr action buttons, requester names link to Overseerr profiles, timestamps moved inline with status - Tab state is pure client state (no ?tab= in URL); router.back() used on alert detail for clean browser history Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
46
README.md
46
README.md
@@ -10,6 +10,8 @@ Built with Next.js 16, TypeScript, and Tailwind CSS.
|
||||
|
||||
- **Leaderboard** — per-user request count, total storage, average GB per request, and optional Tautulli watch stats (plays, watch hours), each ranked against the full userbase
|
||||
- **Alerting** — automatic alerts for stalled downloads, neglected requesters, and abusive patterns, with open/close state, notes, and auto-resolve when conditions clear
|
||||
- **Discord notifications** — posts a structured embed to a webhook whenever a new alert opens or a resolved one returns
|
||||
- **Settings UI** — configure all service URLs and API keys from the dashboard; no need to touch `.env.local` after initial setup
|
||||
- **SWR caching** — stats are cached server-side for 5 minutes and seeded from localStorage on the client, so the dashboard is instant on return visits
|
||||
|
||||
---
|
||||
@@ -24,9 +26,21 @@ cd OverSnitch
|
||||
npm install
|
||||
```
|
||||
|
||||
### 2. Configure environment
|
||||
### 2. Configure
|
||||
|
||||
Create `.env.local` in the project root:
|
||||
**Option A — Settings UI (recommended)**
|
||||
|
||||
Start the app and click the gear icon in the top-right corner. Enter your service URLs and API keys, hit **Test** to verify each connection, then **Save**.
|
||||
|
||||
```bash
|
||||
npm run dev # or: npm run build && npm start
|
||||
```
|
||||
|
||||
Settings are written to `data/settings.json` (gitignored).
|
||||
|
||||
**Option B — Environment variables**
|
||||
|
||||
Create `.env.local` in the project root. Values here are used as fallbacks when `data/settings.json` doesn't exist or doesn't contain an override.
|
||||
|
||||
```env
|
||||
# Required
|
||||
@@ -43,22 +57,38 @@ SONARR_API=your_sonarr_api_key
|
||||
TAUTULLI_URL=http://tautulli:8181
|
||||
TAUTULLI_API=your_tautulli_api_key
|
||||
|
||||
# Optional — Discord webhook for new-alert notifications
|
||||
DISCORD_WEBHOOK=https://discord.com/api/webhooks/...
|
||||
|
||||
# Optional — if your services use self-signed certs
|
||||
# NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||
```
|
||||
|
||||
### 3. Run
|
||||
---
|
||||
|
||||
```bash
|
||||
npm run dev # development
|
||||
npm run build && npm start # production
|
||||
```
|
||||
## Discord Notifications
|
||||
|
||||
When configured, OverSnitch posts a structured embed to your Discord channel whenever an alert is newly opened or reopens after being resolved. Already-open alerts refreshing their data do not re-notify.
|
||||
|
||||
Each embed is formatted by category:
|
||||
|
||||
| Category | Fields shown |
|
||||
|---|---|
|
||||
| Not Downloaded | Requested by · Approved N ago · Status |
|
||||
| Incomplete Download | Requested by · Approved N ago · Downloaded X/Y episodes |
|
||||
| Pending Approval | Requested by · Waiting N days |
|
||||
| Ghost Requester | User · description |
|
||||
| Low Watch Rate | User · Watch rate · Plays · Requests |
|
||||
|
||||
Configure the webhook URL in the Settings UI or via `DISCORD_WEBHOOK` in `.env.local`. Use the **Test** button to send a sample embed before saving.
|
||||
|
||||
---
|
||||
|
||||
## Alerts
|
||||
|
||||
Alerts are generated on every stats refresh and persisted in `data/alerts.json` (gitignored). They have two states — **Open** and **Closed** — and can be manually closed with a per-category cooldown, or auto-resolved when the underlying condition clears.
|
||||
Alerts are generated on every stats refresh and persisted in `data/alerts.db` (SQLite, gitignored). They have two states — **Open** and **Closed** — and can be manually closed with a per-category cooldown, or auto-resolved when the underlying condition clears.
|
||||
|
||||
The alert detail page shows structured metadata (requesters, age, episode progress bars, watch-rate stats), direct links to the item in Radarr/Sonarr, a link to the Overseerr/Jellyseerr media page, and a comment thread for notes.
|
||||
|
||||
### Content alerts
|
||||
|
||||
|
||||
Reference in New Issue
Block a user