Add CLAUDE.md documenting architecture and deploy pipeline
All checks were successful
Deploy / deploy (push) Successful in 27s
All checks were successful
Deploy / deploy (push) Successful in 27s
This commit is contained in:
parent
dc40621eed
commit
83533d339d
1 changed files with 64 additions and 0 deletions
64
CLAUDE.md
Normal file
64
CLAUDE.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Lunch Notifier
|
||||
|
||||
Single-file Flask app that scrapes the daily Mariposa (Kyrene school
|
||||
district) lunch menu and texts it to a list of phone numbers via
|
||||
email-to-SMS carrier gateways (e.g. `4805551234@vtext.com` for Verizon).
|
||||
Runs as one Docker container on the user's Unraid home server.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **`app.py`** — everything: Flask web UI/API, APScheduler-style job
|
||||
scheduling (`schedule` library), and the email-to-SMS send logic
|
||||
(`smtplib` via Gmail, app password auth). The HTML/CSS/JS frontend is
|
||||
embedded as a Python string constant (`HTML`) rather than a separate
|
||||
template file — no build step, no template engine.
|
||||
- **`scraper.py`** — fetches and parses the school's published lunch menu.
|
||||
- **`scheduler.py`** — day-of-week/time scheduling helpers used by `app.py`.
|
||||
- Settings (phone numbers, send time, days, vacation date ranges) persist
|
||||
to `/data/settings.json`, not environment variables — env vars
|
||||
(`PHONE_NUMBER`, `RUN_TIME`, `RUN_DAYS`) are defaults used only the very
|
||||
first time, before a settings file exists.
|
||||
- Vacation ranges suppress sends without disabling the schedule — checked
|
||||
fresh on every run via `is_on_vacation()`.
|
||||
|
||||
## Local development
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
python3 app.py
|
||||
```
|
||||
|
||||
Needs `GMAIL_USER` and `GMAIL_APP_PASSWORD` env vars to actually send
|
||||
(a Gmail **app password**, not the account password — required since Gmail
|
||||
disallows plain SMTP auth with the real password). Visit
|
||||
`http://localhost:2323`.
|
||||
|
||||
## Deployment
|
||||
|
||||
**Target:** Unraid server, container path `/mnt/user/appdata/lunch-notifier`,
|
||||
built from `Dockerfile`/`docker-compose.yml` in this repo. Container name
|
||||
`Lunch-Notifier`, port `2323`. No reverse proxy — accessed directly via
|
||||
`http://<server-ip>:2323` on the LAN.
|
||||
|
||||
**Deploy mechanism: Forgejo push-to-deploy**, same pattern as the other
|
||||
three projects on this box (`card-grader`, `n64-tracker`, `arr-summary`) —
|
||||
see `card-grader`'s `CLAUDE.md` for the full pipeline mechanics (runner
|
||||
config, HTTPS-not-SSH git auth, known tradeoffs). In short: push to `main`
|
||||
on the `forgejo` remote (`https://git.hippofam.com/ninja_hippo/lunch-notifier.git`)
|
||||
triggers `.forgejo/workflows/deploy.yml`, which syncs into
|
||||
`/mnt/user/appdata/lunch-notifier` (excluding `.git`, `.env`, `data/`) and
|
||||
runs `docker compose up -d --build`.
|
||||
|
||||
**Persistent state, never touched by deploys:** `data/settings.json` (the
|
||||
volume-mounted `/data` inside the container) holds phone numbers, schedule,
|
||||
and vacation ranges — this is live user data, not deploy-managed. `.env`
|
||||
holds `GMAIL_USER`/`GMAIL_APP_PASSWORD`/`PHONE_NUMBER` etc. and is
|
||||
server-only, gitignored, never committed.
|
||||
|
||||
**Migration note (2026-08-25):** this container originally used a Docker
|
||||
**named volume** (`lunch-notifier_lunch-settings`) instead of a bind mount.
|
||||
That meant Unraid's Appdata Backup plugin — which only knows about
|
||||
`/mnt/user/appdata` and `/mnt/cache/appdata` as backup sources — silently
|
||||
skipped it entirely; the settings data was never included in any backup.
|
||||
Migrated to a bind mount (`./data:/data`) with the existing settings copied
|
||||
over first and verified intact before the old named volume was deleted.
|
||||
Loading…
Add table
Add a link
Reference in a new issue