Skip to content

chore: retro-review PR #85 — refactor(integration): typed runtime data via PriceHawkData (Phase 7 PR-1)#117

Closed
Artic0din wants to merge 1 commit into
claude-retro/pr-85-basefrom
claude-retro/pr-85-head
Closed

chore: retro-review PR #85 — refactor(integration): typed runtime data via PriceHawkData (Phase 7 PR-1)#117
Artic0din wants to merge 1 commit into
claude-retro/pr-85-basefrom
claude-retro/pr-85-head

Conversation

@Artic0din

Copy link
Copy Markdown
Owner

Synthetic retro-review of merged PR #85. Diff = original 7a504c2..6984c4b (same as original PR). Do NOT merge; close after @claude review posts.

…PR-1)

Retire ``hass.data[DOMAIN][entry_id]`` for coordinator storage. Introduce
``custom_components/pricehawk/data.py`` with ``PriceHawkData`` dataclass and
``PriceHawkConfigEntry = ConfigEntry[PriceHawkData]`` type alias. The coordinator
now lives on ``entry.runtime_data``.

Bundled architectural fixes surfaced by the migration:

* ``async_unload_entry`` reordered: ``async_unload_platforms`` runs FIRST. On
  failure, coordinator + runtime_data are left intact so HA can retry. Previously
  the coordinator was torn down before checking whether platform-unload succeeded.

* Multi-entry service deregistration is now sourced from
  ``hass.config_entries.async_entries(DOMAIN)`` with explicit filter of the
  unloading entry. The previous sentinel (``if not hass.data.get(DOMAIN)``)
  became unreachable garbage after ``hass.data[DOMAIN]`` was removed —
  production-breaking for any user with two PriceHawk entries.

* Service handlers (``analyze_csv``, ``backfill_history``, ``rank_alternatives``)
  now re-resolve the coordinator via ``_resolve_coordinator()`` on every
  invocation, instead of closing over the setup-scope ``coordinator`` local.
  Pre-existing latent bug: ``OptionsFlowWithReload`` (HA 2026.3+) replaces the
  entry's coordinator on options-save reload, but a closure-captured handler
  kept pointing at the dead instance. Now version-safe across reloads.

* ``sensor.py`` uses ``assert data is not None`` to narrow ``Optional[PriceHawkData]``
  for mypy and loud-fail any test fixture that violates the platform-setup
  lifecycle.

No user-facing change. Foundation for Phase 8 Silver-compliance handlers
(reauth, reconfigure, diagnostics) which all consume ``entry.runtime_data``.

7 regression tests added in ``tests/test_runtime_data.py``:
* ``test_setup_writes_runtime_data``
* ``test_unload_runs_platform_unload_first``
* ``test_unload_does_not_touch_hass_data``
* ``test_multi_entry_service_lifecycle``
* ``test_options_flow_reload_cycle``
* ``test_service_handlers_resolve_fresh_coordinator``
* ``test_no_legacy_hass_data_reads`` (static grep against legacy patterns)

Test suite: 808 → 815 passed.

Decisions logged: D-P7-1 (typed-entry alias), D-P7-2 (handler re-resolution),
D-P7-3 (unload reorder), D-P7-4 (multi-entry sentinel).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Artic0din

Copy link
Copy Markdown
Owner Author

@claude review

@claude

claude Bot commented May 23, 2026

Copy link
Copy Markdown

Claude encountered an error after 7m 38s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented May 23, 2026

Copy link
Copy Markdown

Claude encountered an error after 14m 4s —— View job


PR #85 Retro-Review — refactor(integration): typed runtime data via PriceHawkData

  • Gather context and read changed files
  • Analyze diff and review code quality
  • Post comprehensive review findings

@Artic0din

Copy link
Copy Markdown
Owner Author

Retro-review complete. Findings (if any) tracked in fix/retro-review-batch (#143) or noted in .planning/retro-review-findings.md. Closing synthetic PR + cleaning branches.

@Artic0din Artic0din closed this May 23, 2026
@Artic0din Artic0din deleted the claude-retro/pr-85-head branch May 23, 2026 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant