Files
compass_teams_nhs/scripts/parse-compass.sh
Sam Rolfe f6be17fe4f Phase 6: write important school events to the Home Assistant calendar
Add the Home Assistant REST calendar client and the idempotent sync that
writes important school events to Sam's Home Assistant calendar (FR-8). The
school stays read-only; the only write is to the calendar (rule 7).

- internal/calendar: HA REST client (states, create_event, get_events,
  delete_event) and the sync that selects important future events, adopts an
  existing event by its description marker, records the HA event id on the
  item, and records every attempt.
- internal/store: migration 003 (items.ha_event_uid, items.ha_pushed_at and
  the append-only calendar_pushes table), candidates, mark-synced and the
  push log.
- internal/parse: a school event is important; a routine class period is not.
- cmd/school: `school calendar entities|status|push|events`.
- web: an "Add to calendar" item action and a fail-loud calendar banner, so a
  failed write is never swallowed (FR-12).
- scripts/calendar-push.sh, Makefile target, env example, docs and tests.

The target is configurable (SCHOOL_HA_CALENDAR_ENTITY). Home Assistant has no
non-Google writable calendar today, so the entity is asked on AUD-110.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-15 18:01:30 +11:00

57 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Phase 3: parse the stored raw Compass pages for one child into SQLite.
#
# This runs the `school parse` subcommand in a one-off container that mounts the
# service's own data volume (read/write) and the stored raw pages (read-only).
# It does not restart or touch the running service.
#
# Usage:
# scripts/parse-compass.sh [--child Harry] [--run latest] [--classify auto]
#
# Environment overrides:
# IMAGE image tag (default 0.4.0-phase6)
# VOLUME SQLite volume (default compass-teams-nhs_compass-teams-nhs-data)
# RAW_ROOT host path to var/raw (default <repo>/var/raw)
# SCHOOL_TIMEZONE family timezone (default Australia/Melbourne)
# OMNIROUTE_BASE_URL OmniRoute endpoint (default http://127.0.0.1:20129/v1)
# TIMEOUT docker command timeout (default 300)
#
# Importance classification (FR-4) uses OmniRoute when OMNIROUTE_API_KEY is set;
# pass --classify none for the offline deterministic rule.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
IMAGE="${IMAGE:-compass-teams-nhs/school:0.4.0-phase6}"
VOLUME="${VOLUME:-compass-teams-nhs_compass-teams-nhs-data}"
RAW_ROOT="${RAW_ROOT:-$REPO_ROOT/var/raw}"
SCHOOL_TIMEZONE="${SCHOOL_TIMEZONE:-Australia/Melbourne}"
OMNIROUTE_BASE_URL="${OMNIROUTE_BASE_URL:-http://127.0.0.1:20129/v1}"
TIMEOUT="${TIMEOUT:-300}"
CHILD="Harry"
RUN="latest"
CLASSIFY="auto"
while [[ $# -gt 0 ]]; do
case "$1" in
--child) CHILD="$2"; shift 2 ;;
--run) RUN="$2"; shift 2 ;;
--classify) CLASSIFY="$2"; shift 2 ;;
*) echo "unknown argument: $1" >&2; exit 2 ;;
esac
done
if [[ ! -d "$RAW_ROOT" ]]; then
echo "raw pages not found at $RAW_ROOT" >&2
exit 1
fi
exec timeout "$TIMEOUT" docker run --rm --network host \
-v "$VOLUME:/data" \
-v "$RAW_ROOT:/raw:ro" \
-e SCHOOL_DB_PATH=/data/school.db \
-e SCHOOL_TIMEZONE="$SCHOOL_TIMEZONE" \
-e OMNIROUTE_API_KEY \
-e OMNIROUTE_BASE_URL="$OMNIROUTE_BASE_URL" \
"$IMAGE" parse --child "$CHILD" --run "$RUN" --raw-root /raw --classify "$CLASSIFY"