Commit Graph
8 Commits
Author SHA1 Message Date
overseer c5ed4250b6 The integration no longer owns a database
The HA integration is now purely a client of the NestQuest API service
(Feature 18): the API owns the SQLite file, the migrations, and every
business rule, so keeping a second copy of that ownership inside the
integration meant two sources of truth for household state, dead
wiring (the startup backfill, the day-rollover materialization and
sweep listeners, the corrupt-DB handling, the admin-allowlist seeding)
and settings keys nothing consumes any more.

Removed the integration's re-export/DB shim modules (db, store,
migrations, schema, the five DAOs, completion, children,
quest_definitions, admin_allowlist, presence, presence_management,
materialize, recurrence, events, sweep); the bundled domain package at
custom_components/nestquest/core/ is untouched and remains the single
home of those engines.  Setup now builds only the API client, the
snapshot coordinator, and the SSE subscription, registers the one
complete_quest proxy, and forwards the platforms.  The options flow
keeps only the keys the client itself consumes (API base URL + panel
token, update interval, staleness, panel idle timeout); the horizon,
rollover, notification and admin-allowlist settings moved out with the
database (the API's settings store owns horizon/rollover, and the
automations take their behaviour from blueprint inputs).  The
integration-plane tests now script the panel route's payloads and SSE
frames instead of seeding a local database; the core-plane tests keep
their coverage with imports pointed at core directly.
2026-09-23 09:01:21 -04:00
dev_agent 1503774e85 Extract the storage layer into core/ (bundled in the integration)
Extract the storage layer into core/ (bundled in the integration)
2026-09-21 14:48:01 -04:00
Joshua King 7cde256e2a Fail-closed is_admin resolver (Feature 03, task 5)
admin_allowlist.is_admin: True only for an allowlisted HA user id;
False for non-allowlisted, unknown, empty-string, untrimmed variants,
None, non-strings (bools, lists), and an empty allowlist (nobody is
admin rather than everybody). Never raises for malformed input —
malformed means not admin; DB errors propagate for the Feature 09
gate to handle. The last-admin removal refusal (set_admin_ids) is
re-asserted as keeping the verdict sound. Tests: full verdict matrix,
empty-allowlist fail-closed, refusal persistence. Suite: 912 passed.
2026-09-15 17:35:13 -04:00
Joshua King 0e4f890ef9 Review fix: reopened-record setup closes the database when seeding fails
Review round 5 (Codex gpt-5.6-terra, MEDIUM): the reopened-runtime
setup path leaked the just-opened connection if owner lookup or
seed_setup_admin raised, so HA's setup retries could accumulate open
handles. Seeding on that path is now wrapped symmetrically with the
first-setup path: any failure closes the database before re-raising,
with a test that fails seeding on a re-setup and asserts the close.
Suite: 909 passed.
2026-09-15 17:26:53 -04:00
Joshua King 7ebd893823 Test fix: malformed owner_ids validated before the seed's early return
The seed validates candidates only when the allowlist is empty; the
test's successful first seed masked the malformed case. The rejection
now runs first. Suite: 908 passed.
2026-09-15 17:23:32 -04:00
Joshua King 068ace5693 Review fix: owner-account fallback seed for first setup
Review round 4 (Codex gpt-5.6-terra, HIGH): relying on the flow
context alone can leave first setup ownerless. seed_setup_admin gains
an owner_ids tier: when no persisted copy and no context user exist,
every HA owner account is seeded (owners can already do everything in
HA — no privilege escalation). __init__ resolves owners via
hass.auth.async_get_users on both setup paths; conftest's hass gains
the auth surface. Tests: owner fallback seeds only owners, context
user still wins over owners, owner_ids argument validation. Suite:
910 passed.
2026-09-15 17:22:39 -04:00
Joshua King d90c170460 Review fixes: persisted flow-user admin seed and real cv.multi_select
Review rounds 1-2 (Codex gpt-5.6-terra) found two HIGHs against real HA:
- entry.context is not a durable record — the config flow now persists
  the completing HA user into entry data (CONF_ADMIN_USER_IDS) and the
  seed precedence becomes: options copy (the current list) first, then
  the config flow's entry-data copy, then the context user as a last
  resort. Config-flow tests cover the persisted user and the
  context-free path; a seed-precedence test covers options > data.
- the hand-rolled closure could not serialize as an HA multi-select.
  The harness now mocks homeassistant.helpers.config_validation with a
  faithful multi_select, and the flow uses cv.multi_select exactly as
  real HA code does. Suite: 904 passed.
2026-09-15 17:13:32 -04:00
Joshua King 0d61ea2c88 Admin allowlist storage seeded with the setup user (Feature 03, task 4)
- admin_allowlist.py: list_admin_ids / set_admin_ids (atomic sync of
  the allowlist inside one transaction under the connection lock;
  refuses empty targets so the last admin can never be removed and
  the allowlist can never be emptied — fail closed) and
  seed_setup_admin (seeds ONLY an empty allowlist: stored entry-data
  copy first — disaster recovery for a lost database — else the HA
  user who completed the config flow from the entry context;
  non-empty lists are never resurrected).
- __init__.py: both setup paths (first setup and the reopened-record
  path) seed after migrations; a failed seed closes the database and
  re-raises through the existing error handling.
- options_flow.py: the admin picker is a multi-select of EXISTING HA
  users (hass.auth.async_get_users), defaulted to the current
  database allowlist, membership-checked at the schema level and
  backed up on the raw-input path; empty selections are refused
  (no_admins), unknown ids rejected (invalid_admin); the selection is
  applied to the DB when the runtime record is reachable and always
  stored on the entry as the recovery copy. Submissions without the
  key (legacy raw payloads) keep the three-key behaviour untouched.
- const.CONF_ADMIN_USER_IDS; strings + translations for the field and
  the two errors; conftest entries gain a context dict (HA's entry
  context carries the flow user).
- Tests: 20 allowlist business tests (round-trips, refusal matrix,
  seed precedence and narrowed-list persistence), 5 picker flow tests,
  3 setup-seeding lifecycle tests. Suite: 901 passed.
2026-09-15 17:03:53 -04:00