--- title: Basketball Team Manager type: note status: active proposed_folder: 200 projects/Tools Software WebUI proposed_toc: "100 Table of Contents/Projects.md → Tools & Software" proposed_tags: - project - architecture - go - htmx - basketball - showcase confidence: 0.69 approved: false proposed_for: 97b2f145f8be created: "2026-10-27" tags: - project - basketball - showcase aliases: [] skills: - Go web service - HTMX - Python data tooling - GraphQL API reverse engineering - WhatsApp automation - Caddy reverse proxy and basic auth - systemd user services tools: - Go 1.26 - HTMX 2 - Python 3 - Node.js - Baileys - Caddy - PlayHQ API - Apprise --- # Basketball Team Manager — Overview ## 💡 What is this project? A parent volunteers to run the score sheet roster for an under-18 basketball team. Eight families take turns. One parent fills in the paper score sheet at each game. This project does the bookkeeping. It keeps the season fixtures, works out whose turn it is, and writes the messages that go into the team WhatsApp group. It shows the same information on a small private website, so any parent can check the roster from a phone. The club does not publish a usable fixture feed for parents. PlayHQ holds the data, so the project reads it from the PlayHQ API and fills in the time, venue and opponent. The volunteer does not retype anything. ## 🌟 Key Highlights (Portfolio & Employment) - **Concept**: A small service that turns a weekly volunteer chore into an automatic roster, plus a published web page and group messages. - **Tools & Skills Showcase**: One Go binary with HTMX and no build step. Python owns the rules and the Go layer only renders. The PlayHQ GraphQL endpoint was found from the public site bundle. WhatsApp posting uses a linked-device client behind a small HTTP bridge, so other tools can post through it. Deployed behind Caddy with basic auth and systemd user units. - **Practical value**: The roster, the messages and the website cannot disagree, because one Python module builds all three. A swap between parents is recorded once, and the roster moves the people automatically. ## 📐 Architecture & Flow ```mermaid flowchart LR Phone[Parent on phone] --> Caddy[Caddy .35 - basic auth] Caddy --> Site[Go + HTMX site .13:8420] Site --> Plan[tools/plan.py] Plan --> Data[(data JSON files)] Site -->|record result| Data Site -. copy draft .-> Bridge[WhatsApp bridge .13:8421] Bridge --> Group[Team WhatsApp group] Apprise[Apprise or cron] --> Bridge PlayHQ[PlayHQ API] --> Fetch[tools/fetch_fixtures.py] Fetch --> Data EDJBA[EDJBA season dates] --> Data ``` ## 🔗 Related Notes & Links - Live site: https://basketball.lab.audasmedia.com.au (basic auth, user `sam`) - WhatsApp bridge: https://wa.lab.audasmedia.com.au - Interactive map: [Archify map](https://maps.lab.audasmedia.com.au/basketball_team_manager/docs/) - Gitea repo: https://gitea.lab.audasmedia.com.au/sam/basketball-team-manager (private) - Deploy notes: `DEPLOY.md`. Weekly schedule: `ROUTINES.md`. - AI context (Outline): not created yet