# Compass NHS — Code Map ## Module `gitea.lab.audasmedia.com.au/sam/compass_teams_nhs` Language: Go 1.25. Database: SQLite through `modernc.org/sqlite`. Passwords use `golang.org/x/crypto/bcrypt`. There is no other direct dependency. ## Entry Point `cmd/school/main.go` holds the entry point. The first argument selects a subcommand. With no argument it starts the HTTP service. | Subcommand | Function | | :--- | :--- | | `run` (default) | Starts the HTTP service, migrates the schema and seeds the children. | | `parse` | Turns stored raw pages into items. | | `session` | Shows or clears the harness session per child. | | `scan` | Fetches and parses one child or both. | | `items` | Reads or deletes items. | | `brief` | Builds a brief. | | `notify` | Sends briefs and shows the send status. | | `calendar` | Pushes events to Home Assistant. | | `hash-password` | Prints a bcrypt hash. | | `gen-secret` | Prints a fresh secret. | | `version` | Prints the version. | ## Folders | Folder | Function | | :--- | :--- | | `cmd/school/` | One file per subcommand plus `main.go`. | | `internal/web/` | HTTP server, handlers, HTMX templates, static assets. Holds `hub_api.go`. | | `internal/auth/` | Session login with signed cookies and CSRF. | | `internal/store/` | SQLite open, migrations and queries. | | `internal/store/migrations/` | `001_init`, `002_items_parse`, `003_calendar`, `004_notifications_send`. | | `internal/parse/` | HTML to items. Readings for tasks, news, calendar and importance. | | `internal/llm/` | OmniRoute client for importance classification only. | | `internal/dashboard/` | Builds the per-child buckets. Classifies overdue and due-today. | | `internal/brief/` | Builds and delivers the morning briefs. | | `internal/apprise/` | Apprise API client. Uses tags and redacts errors. | | `internal/calendar/` | Home Assistant client and the idempotent sync. | | `internal/hub/` | The Hub contract: capabilities and read-only answers. | | `internal/config/` | Reads the environment. | | `deploy/` | Caddy snippet, n8n workflow, import and key scripts, verify scripts. | | `scripts/` | Scrapers, parse and morning-brief wrappers, calendar push. | ## The Read-Only Boundary `internal/hub` depends on a `Reader` interface. The interface has three read methods and no write method. Test `TestHubAskReadsOnly` proves that `/ask` does not change the `items`, `scans` or `notifications` row counts. ## The Scraper `scripts/compass-fetch-patchright.mjs` logs into Compass with patchright. The login POST meets a Cloudflare managed challenge. patchright, a headless Playwright build, passes the challenge. The pi-browser-harness does not. The Compass parent login required no two-factor code during the Phase 2 proof. ## Database Tables | Table | Holds | | :--- | :--- | | `children` | id, name, year, Compass id. | | `items` | Child, type, subject, teacher, title, body, due date, URL. | | `scans` | Start time, child, pages fetched, items found, error. | | `notifications` | Recipient, scope, summary, channel, status, sent time. | | `session` | Harness session state per child. | | `calendar_pushes` | Calendar write attempts, result and error. | The raw Compass pages are not in the database. The fetcher writes them to `var/raw///` on the host. Each folder holds the HTML, a meta file per page, and a manifest with a SHA-256 and a byte count per page. ## Tests Run `make test`. The suite uses standard Go tests. The tests cover the store, the parser, the dashboard buckets, the brief, the Apprise client, the calendar sync, the Hub API and the read-only rule.