# scout-website Public recruiting site for **Cub Scout Pack 73 and Scouts BSA Troop 73** (Zieglerville / Green Lane, PA). Live at **https://greenlanescouts73.org** (NPM proxy → `scout-website` container, port 8132 on arrstack). Replaces the `scoutpoc` proof of concept (claude-workspace/stacks/scoutpoc). ## Updating the calendar (the part you'll actually do) All dates on the site (home "Next up," both program pages, the Calendar page) come from the **scout-calendar feed** (claude-workspace/stacks/scout-calendar), which serves the Radicale collection `mike/site73` as JSON: ``` EVENTS_FEED_URL ← Portainer stack env; http://scout-calendar:8000/events.json /data/events-cache.json ← last good copy, served automatically whenever the feed is down ``` Edit the calendar in any CalDAV client pointed at Radicale (or ask Claude), and the site follows within ~5 minutes. **No file edits, no rebuild, no redeploy.** The public ICS families can subscribe to is https://calendar.greenlanescouts73.org/calendar.ics. Event fields the feed emits (one object per event): ```json {"date": "2026-10-17", "end": "2026-10-18", "time": "from 4:00 PM", "title": "Fall Campout", "location": "Green Lane Park", "unit": "both", "badge": "OVERNIGHT"} ``` - `date` required (YYYY-MM-DD). `end` only for multi-day events. - `unit`: `"pack"`, `"troop"`, or `"both"` (default pack). Drives the Pack/Troop calendar filter and each page's "Next up." - `badge`: optional shouty label (`FALL OPEN HOUSE`, `OVERNIGHT`, `THE BIG ONE`). - Past events are hidden from "Next up" automatically; the Calendar page shows the whole program year. - TeamSnap (team 8198615) stays the source of truth for registered families; Radicale `mike/site73` is the source for this public site. ## Layout - `app/app.py` — FastAPI app, all five pages server-rendered (Home, /cubs, /troop, /calendar?unit=, /join). `/contact` 301s to `/join`. - `docker-compose.yml` — Portainer Repository stack definition (port 8131). - Images: **not in the repo.** Bind-mounted read-only from `/srv/scout-website-assets/img`. Source photos live on the NAS (`Scouting-Recruitment-Images`, `scouting-comms/pack-73/assets/social`); web-sized copies in `Scouting-Recruitment-Images/_web`. ## Leads `/srv/scout-website/data/leads.jsonl` — one JSON line per interest-form submission, plus an ntfy push per lead. ## Lead pipeline (self-contained) `/join` submissions write **directly** to the shared Google Sheet (`SHEET_ID` stack env, creds bind-mounted from `/srv/scout-website/secrets/service_account.json`) and push to the shared ntfy `scouting` topic (`NTFY_BASE`/`NTFY_TOPIC`/`NTFY_TOKEN`). The extra comments box lands in a new 8th sheet column, **Comments**. Every submission also appends to `/data/leads.jsonl`; if both sheet and push fail, a warning push goes to the fallback `NTFY_URL` topic. No dependency on the scoutpoc or scouting73-form containers: both can be decommissioned without breaking this site. (The flyer QR domain scouting73.thewichersfamily.com should be repointed here before its container is retired.)