Add ntfy push notifications with action buttons for meal reminders
CI / test-and-package (push) Successful in 37s

- ntfy.py: send_meal_reminder() with Home/Out HTTP action buttons, test helper
- models.py: new columns ntfy_url, ntfy_token, callback_token on users table
- meals.py: /api/ntfy-callback (public, token-authenticated), /ntfy-settings, /ntfy-test
- app.py: flask send-reminders CLI command (cron-schedulable)
- Dashboard: ntfy config form in Account Settings
- i18n: translations for all ntfy strings (en/fr/de)
- Dockerfile: include ntfy.py in COPY
- tests: 15 new tests covering callback, settings, and auth
- docs: updated AGENTS.md and doc/index.md
This commit is contained in:
agentbox
2026-08-01 06:17:26 +00:00
parent 7bf00ee2e3
commit 3681f9dfce
10 changed files with 650 additions and 4 deletions
+4 -2
View File
@@ -14,9 +14,10 @@ Flask web app for tracking household meal attendance. Users register into househ
|---|---|
| `app.py` | Flask factory (`create_app()`), registers blueprints and i18n |
| `auth.py` | Auth blueprint: `/login`, `/register`, `/logout`. Session-based. |
| `meals.py` | Meals blueprint: `/dashboard`, `/respond`, `/history`, `/delete-account`, `/admin/*` |
| `models.py` | All DB access. SQLite via `sqlite3`. 4 tables: `households`, `users`, `meal_periods`, `responses`. |
| `meals.py` | Meals blueprint: `/dashboard`, `/respond`, `/history`, `/delete-account`, `/admin/*`, `/ntfy-settings`, `/ntfy-test`, `/api/ntfy-callback` |
| `models.py` | All DB access. SQLite via `sqlite3`. 4 tables: `households`, `users`, `meal_periods`, `responses`. Ntfy helpers in `# Ntfy / notifications` section. |
| `i18n.py` | Translation module. `t(key)` helper for en/fr/de. Detects `Accept-Language`, session override via `?lang=`. All user-visible strings flow through `t()`. |
| `ntfy.py` | Ntfy notification helpers. `send_meal_reminder()` sends push with Home/Out HTTP action buttons. `send_test_notification()` verifies config. |
| `templates/` | Jinja2: `base.html` (nav, lang footer), `login.html`, `register.html`, `dashboard.html` |
| `static/style.css` | All CSS (no framework) |
| `tests/` | Pytest suite (47 tests): `conftest.py` sets up in-memory DB per test |
@@ -33,6 +34,7 @@ Flask web app for tracking household meal attendance. Users register into househ
- **i18n:** Every user-visible string in templates uses `{{ t('English text') }}`. In Python, `flash(t("message"), "category")`. Translations live in `TRANSLATIONS` dict in `i18n.py`. English string is the key; only non-English translations stored. When adding new user-facing text, add it to `TRANSLATIONS` for fr/de.
- **DB:** All access through `get_db()` context manager in `models.py`. Returns `sqlite3.Row` objects accessed as dicts. Path via `DB_PATH` env var (defaults to `/data/meals.db` in Docker, `./meals.db` locally).
- **CSS:** No framework. Variables in `:root`. Use existing utility classes (`.btn`, `.chip`, `.badge`, etc.).
- **Ntfy:** Per-user topic URL + Bearer token stored in `users` table. Callback token auto-generated on first ntfy setup. `/api/ntfy-callback` is unauthenticated (uses callback token). Send reminders via `flask send-reminders [--date] [--meal] [--base-url]`. Schedule with cron.
## Common Pitfalls