Skip to content

refactor(runtime): phase 2 migrate alert + notification event state into unified runtime store #467

@Orinks

Description

@Orinks

Summary

Phase 1 (#466) added the runtime-state scaffold and regression tests around the highest-risk behavior. Phase 2 should do the real migration work: move live app-managed runtime state for alerts + notification events into the unified runtime-state store, while preserving current behavior for both installed and portable deployments.

This phase is intentionally migration-focused, not broad persistence cleanup.

Scope

Implement the runtime-state migration for:

  • alert dedupe state currently stored in alert_state.json
  • notification event state currently stored in notification_event_state.json
    • AFD discussion notification state
    • severe-risk notification state

Use the Phase 1 RuntimeStateManager rooted at:

  • <config_dir>/state/runtime_state.json

Where <config_dir> means ConfigManager.config_dir for the current runtime, so behavior is correct for both:

  • installed mode
  • portable mode
  • explicit custom config dir

Required implementation shape

  • Keep accessiweather.json as user-owned settings/config only.
  • Treat runtime_state.json as app-managed state only.
  • Wire AlertManager and NotificationEventManager to read/write through RuntimeStateManager.
  • Migrate legacy state section-by-section into the unified runtime file.
  • Migration must be idempotent and non-destructive.
  • Save must remain atomic.
  • Phase 2 should not delete or broadly reorganize unrelated files.

Compatibility requirements

1) Installed upgrades

  • Upgrading an existing installed user with legacy alert_state.json and/or notification_event_state.json must preserve notification continuity.
  • First run after upgrade must not behave like a fresh install.
  • Runtime state must resolve from the installed config root (ConfigManager.config_dir), not a mismatched alternate root.

2) Portable mode

  • Portable runtime state must also live under that portable config root: <portable_config>/state/runtime_state.json.
  • Portable mode must preserve the same migration behavior as installed mode.
  • Existing portable settings/import/export flows must continue to exclude runtime state files.
  • This issue must not change the encrypted API-key bundle behavior.

3) Alert dedupe continuity

  • If legacy alert_state.json exists, migrating to unified runtime state must preserve dedupe/no-spam behavior.
  • Existing tracked alert IDs, hashes/history, timestamps, notification counts, and last_global_notification semantics must be preserved closely enough that the first run after migration does not resend already-known alerts.
  • Alert expiry/cleanup behavior should remain unchanged unless a test proves a migration-specific bug.

4) AFD discussion notification continuity

  • If legacy notification-event state exists, the stored last discussion issuance time/text must carry forward.
  • First run after migration must not emit a discussion-update notification for the same issuance already seen before upgrade.
  • A newer issuance after migration must still notify normally.

5) Severe-risk state continuity

  • The stored severe-risk value must carry forward numerically, not just by category.
  • Same-category updates after migration must continue updating the stored numeric value without notifying.
  • Category crossings after migration must still notify correctly.

6) Legacy-file fallback behavior

  • If runtime_state.json does not yet exist, the app must fall back to legacy files and hydrate the unified runtime state from them.
  • Fallback should be per-section: missing alert section should not block notification-event migration, and vice versa.
  • If one legacy file is missing or corrupt, the other section should still migrate if valid.
  • Once unified runtime state exists for a section, that section should prefer unified state on future loads.
  • Phase 2 should leave legacy files in place as compatibility fallback / debugging evidence; cleanup or retirement policy can wait for a later phase.

TDD-first expectations

Add/adjust tests first for migration-sensitive behavior, including at minimum:

  • installed upgrade path uses ConfigManager.config_dir as the runtime-state root
  • portable mode uses the portable config root for unified runtime state
  • legacy alert_state.json -> unified runtime migration preserves dedupe on first run
  • legacy notification_event_state.json -> unified runtime migration preserves first-run no-spam discussion behavior
  • severe-risk numeric continuity across migration
  • per-section fallback when only one legacy file exists
  • corrupt/missing legacy file recovery without breaking the other state section
  • unified runtime writes remain atomic
  • portable copy/export continues excluding runtime state files

Acceptance criteria

  • AlertManager no longer depends on alert_state.json as its primary store
  • NotificationEventManager no longer depends on notification_event_state.json as its primary store
  • both managers read/write through RuntimeStateManager
  • canonical runtime-state path is <config_dir>/state/runtime_state.json using ConfigManager.config_dir
  • installed upgrade from legacy files preserves alert dedupe continuity
  • installed upgrade from legacy files preserves AFD discussion continuity
  • installed upgrade from legacy files preserves severe-risk continuity
  • portable mode uses the same unified runtime-state logic under the portable config root
  • settings export / installed->portable settings copy still exclude runtime state
  • missing/corrupt legacy files degrade safely without crashing or cross-contaminating sections
  • no broad cleanup/removal of unrelated persistence files is required to close this issue

Explicitly deferred to Phase 3+

Do not expand this issue into broader cleanup. Defer these items:

  • retiring/removing update_settings.json
  • auditing/removing old location.py / locations.json persistence
  • deciding whether noaa_radio_prefs.json should move into main settings
  • broader cache root normalization (weather_cache, GitHub release cache, downloads, logs)
  • moving other operational files like lock files or toast identity state into the unified runtime file
  • schema redesign beyond what is needed to safely migrate alerts + notification events
  • any user-visible settings/config reshuffle beyond the runtime-state migration

Notes

This should stay boring and safe:

  • practical migration work
  • compatibility first
  • tests before refactor behavior changes
  • no architecture-astronaut cleanup spree

Related:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions