Skip to content

refactor(storage): phase 3 normalize runtime storage roots #471

@Orinks

Description

@Orinks

Summary

Now that #467 / PR #468 moved alert + notification event persistence into the unified runtime store, the main remaining refactor work is broader path/root normalization.

Today the app still has multiple active ways of deciding where writable files live:

  • ConfigManager anchors config under config_dir / app.paths.config
  • Paths still exposes independent Data/Config/Cache/Logs roots
  • some callers still bypass the runtime config root and pick paths directly

That means portable mode, --config-dir, and default installed layouts are not yet driven by one canonical runtime storage contract.

Phase 3 goal

Make all actively used writable surfaces resolve from one canonical runtime storage layout, with migration-safe behavior.

In scope

1) Define a single runtime storage contract

Touch:

  • src/accessiweather/app.py
  • src/accessiweather/app_initialization.py
  • src/accessiweather/paths.py (or replacement helper if cleaner)
  • src/accessiweather/config/config_manager.py

Expected result:

  • app startup resolves storage roots once
  • downstream code stops inferring its own roots ad hoc
  • portable mode and explicit --config-dir are honored consistently

2) Move active callers onto that contract

Touch at least:

  • src/accessiweather/app_initialization.py
    • stop deriving cache from config_dir fallback logic inline
  • src/accessiweather/single_instance.py
    • ensure lock-file location follows the same runtime storage contract
  • src/accessiweather/ui/dialogs/noaa_radio_dialog.py
  • src/accessiweather/noaa_radio/preferences.py
    • stop creating prefs from a fresh Paths().data detached from runtime overrides

Also audit any still-active callers using app.paths.* directly for persistence so they either:

  • intentionally use the canonical root, or
  • are explicitly documented as legacy and deferred

3) Keep current runtime-state/file migration behavior intact

Do not rework the Phase 2 runtime-state schema.
Keep working behavior for:

  • accessiweather.json
  • state/runtime_state.json
  • portable API-key bundles

Migration / safety constraints

  • no destructive data moves unless there is a tested read-old/write-new path
  • prefer “resolve canonically, then write there” over large one-shot migrations
  • keep user-visible storage surprises to a minimum

Tests / validation

Add focused regression coverage for:

  • installed/default layout
  • portable layout
  • explicit --config-dir
  • NOAA radio prefs honoring the same runtime root
  • single-instance lock honoring the same runtime root
  • weather cache honoring the same runtime root

Out of scope

  • deleting legacy helper modules outright
  • mass renaming on-disk folders just for style
  • changing config schema unrelated to storage-root normalization
  • broad documentation sweeps beyond what is needed to explain the new contract

Follow-up

After this lands, do a short soak / observation pass before removing legacy path fallbacks.

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