Updated preference files

This commit is contained in:
2026-04-03 00:56:48 -07:00
parent 9bf97c2358
commit 79fd6fd6db
5 changed files with 86 additions and 25 deletions

View File

@@ -135,6 +135,61 @@ services:
condition: service_healthy
```
## Ntfy Notifications
- All web apps must integrate Ntfy push notifications for admin-relevant events
- Use a self-hosted Ntfy instance; URL and topic stored in `.env` — never hardcoded
- Send notifications via HTTP POST using `httpx` (async) — do not add a separate Ntfy library
```python
# app/utils/notify.py
import httpx
from app.config import settings
async def notify(title: str, message: str, priority: str = "default", tags: list[str] | None = None):
headers = {
"Title": title,
"Priority": priority,
}
if tags:
headers["Tags"] = ",".join(tags)
async with httpx.AsyncClient() as client:
await client.post(
f"{settings.ntfy_url}/{settings.ntfy_topic}",
content=message,
headers=headers,
)
```
**Required `.env` variables:**
```
NTFY_URL=https://ntfy.example.com
NTFY_TOPIC=your-topic
```
**Standard events to notify on** (adapt to what the app actually does):
| Event | Priority | Tags |
|---|---|---|
| Successful admin login | high | `warning` |
| Failed admin login (threshold reached) | urgent | `rotating_light` |
| New user registration | default | `busts_in_silhouette` |
| User account deletion | default | `wastebasket` |
| Role/permission escalation | high | `shield` |
| Password reset requested | default | `key` |
| Rate limit triggered | default | `no_entry` |
| API key created or revoked | high | `key` |
| Service startup / crash recovery | default | `white_check_mark` / `x` |
| High error rate (5xx spike) | high | `rotating_light` |
| Large data export initiated | default | `outbox_tray` |
**Rules:**
- Add Ntfy to every new web app from the start — it is checked during go-live review
- Only notify on events that are genuinely useful to an admin — don't spam low-value noise
- Failed notifications must not crash the app — wrap calls in `try/except` and log the error
---
## Testing
- Do **not** create test files — I'll run the code directly to verify it works