Skip to content

refactor(REF-003): extract status panel + parameter controls from app.py#99

Merged
DoRmAmMu1997 merged 1 commit into
mainfrom
refactor/ref-003-app-extraction
Jul 11, 2026
Merged

refactor(REF-003): extract status panel + parameter controls from app.py#99
DoRmAmMu1997 merged 1 commit into
mainfrom
refactor/ref-003-app-extraction

Conversation

@DoRmAmMu1997

Copy link
Copy Markdown
Owner

Ticket scope (REF-003)

Goal: third app.py slimming pass (after REF-001's page extraction and REF-002's #97 scan-view/fundamentals extraction). app.py drops from 1,127 → 822 lines and is now orchestration-only.

In scope

  • Move the pre-run system-status card (show_status_panel, render_universe_table) and its four 30-second @st.cache_data helpers (cache_summary, _universe_mtime, _cached_universe_status, _cached_all_universe_statuses) → new ui/status_panel.py.
  • Move the sidebar parameter-override plumbing (_param_state_key, _render_parameter_overrides, _apply_param_overrides) → new ui/parameter_controls.py.
  • One behavior rider (the only non-verbatim change): cache_summary(cache_dir: Path = DAILY_CACHE_DIR) froze the config path at import time; now Path | None, resolved in the body per call. Locked by a test that fails against the old signature.
  • app.py re-exports every moved helper so app.<name> imports and the test_app_orchestration.py monkeypatch seams keep working. Function identity is preserved, so refresh_universes_and_invalidate() (stays in app.py) still clears the same cache objects — new identity assertions lock this.
  • Render tests for both new modules, 100% coverage each — the direct lesson from refactor(REF-002): extract fundamentals panel + scan view from app.py #97, where an untested extraction dipped repo coverage.
  • Update the universe-table laziness test to patch ui.status_panel (house pattern: patch the module that actually reads st); update the app-orchestration LLD.

Out of scope (deliberate)

  • No further main()/_execute_screener decomposition — those are genuinely orchestration and stay.
  • No behavior changes beyond the declared rider; every moved line is otherwise verbatim, docstrings and comments included.
  • The TEST-007 render tests for the REF-002 modules are a sibling PR (test(TEST-007): render-path tests for fundamentals_panel + scan_view #98) off main — no stacking; the branches touch disjoint files.

This is ticket 2 of a 10-ticket second improvement wave (TEST-007 #98, REF-003, AI-006, IPO-006, TEST-006, PERF-002, DEPLOY-004, QUAL-006, QUAL-007, DOC-003), each shipped as its own PR off main.

Why the seams hold

  • main() calls show_status_panel / render_universe_table / _render_parameter_overrides / _apply_param_overrides through app module globals, so existing monkeypatches of app.<name> are unaffected.
  • The .clear() calls in refresh_universes_and_invalidate() go through the re-exported bindings; from ui.status_panel import _universe_mtime binds the same function object, so clearing through app empties the cache ui.status_panel reads. The extended re-export identity test asserts this for all nine moved names.
  • The only orchestration test that exercised a moved body directly (universe-table laziness) now patches ui.status_panel.st — consistent with how REF-001 repointed the page-renderer tests.

Gates (all green, local, Python 3.13)

Gate Result
pytest -q --cov=backend --cov=screeners --cov=ui --cov-fail-under=87 1,404 passed, 1 skipped; coverage 88.21%; both new modules 100%
pre_commit validate-config clean
compileall clean
ruff check clean
mypy (121 files) clean
bandit clean
pip_audit -r constraints.txt no known vulnerabilities

constraints.txt / pyproject.toml diff vs main: empty (as required).

Review

/code-review: Approve — verified the seven risk points (cache identity through re-exports, cache_summary cache-key change, laziness-test repointing, cache clears around real cached helpers, removed-import safety, bool-before-int widget dispatch, raising rerun fake). /security-review: no findings (verbatim code move; no new injection/traversal/auth surface; the param-merge loop that keeps arbitrary session-state keys out of screener params is now test-locked).

🤖 Generated with Claude Code

Third app.py slimming pass (after REF-001/REF-002). Moves the pre-run
system-status card and the sidebar parameter-override plumbing into
dedicated ui/ modules, verbatim except for one rider:

- ui/status_panel.py: show_status_panel, render_universe_table, and their
  30s @st.cache_data helpers (cache_summary, _universe_mtime,
  _cached_universe_status, _cached_all_universe_statuses).
- ui/parameter_controls.py: _param_state_key, _render_parameter_overrides,
  _apply_param_overrides.
- Rider: cache_summary's `cache_dir: Path = DAILY_CACHE_DIR` default bound
  the config path at import time; now `Path | None` resolved in the body so
  a repointed cache dir is honored per call (locked by a test that fails
  against the old signature).

app.py re-exports every moved helper, so `app.<name>` imports and the
monkeypatch seams in test_app_orchestration.py keep working; function
identity is preserved, so refresh_universes_and_invalidate() still clears
the same cache objects (asserted by new identity checks). The universe-table
laziness test now patches ui.status_panel per the house pattern ("patch the
module that actually reads st").

New render tests for both modules (100% coverage each; lesson from #97's
untested-extraction coverage dip). Docs: app-orchestration LLD updated.

Gates: 1,404 passed, coverage 88.21% (floor 87); pre-commit validate,
compileall, ruff, mypy (121 files), bandit, pip-audit all clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@DoRmAmMu1997 DoRmAmMu1997 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review (posted as COMMENT — the bot runs as the PR author and cannot APPROVE). Verdict: Approve.

Diff-level checks against the seams this extraction must not break:

  1. Verbatim movegit diff on the moved bodies confirms only the cache_summary signature/body rider differs; docstrings, comments, and widget-dispatch order (bool checked before int — bool is an int subclass) are byte-identical. The rider is pinned by test_cache_summary_default_resolves_current_daily_cache_dir, which fails against the old import-time-bound default.
  2. Re-export identity — nine new assertions in test_app_reexports_helpers_from_extracted_ui_modules prove app.<name> is ui.<module>.<name>. This matters doubly here: refresh_universes_and_invalidate() clears caches through the app bindings, which only works because they are the same function objects.
  3. Monkeypatch seamsmain() still calls the four moved renderers via app module globals, so the :870-871 patches in the orchestration suite work untouched. The single test that exercised a moved body directly (universe-table laziness) now patches ui.status_panel per the house pattern; no other test patched the moved names (verified by repo-wide grep).
  4. Import removals safepd, datetime, DAILY_CACHE_DIR, all_universe_statuses, universe_file_path, universe_status had no remaining app.py consumers; full suite + ruff + mypy (121 files) clean.
  5. st.cache_data hygiene in new tests — every test that runs a real cached helper (cache_summary, _universe_mtime, _cached_universe_status, _cached_all_universe_statuses) clears before and in finally, so no state leaks into other suites (same discipline as TEST-007).
  6. Layeringui/ imports backend only (rule §4); backend/ untouched; no ui module imports app.

Gates: 1,404 passed + 1 skipped, coverage 88.21% (floor 87), both new modules 100%; ruff/mypy/bandit/pip-audit/pre-commit/compileall clean; constraints/pyproject diff vs main empty. app.py: 1,127 → 822 lines.

Copy link
Copy Markdown
Owner Author

Codex review plan:

I found no actionable standalone code issue in REF-003. I will rerun the focused extraction tests and verify the status panel, parameter override/reset, universe details, and cache invalidation flows on desktop and mobile. I’ll post a no-findings verdict with the evidence; no branch change is planned unless verification uncovers a regression.

@DoRmAmMu1997
DoRmAmMu1997 merged commit ecf6813 into main Jul 11, 2026
3 checks passed
@DoRmAmMu1997
DoRmAmMu1997 deleted the refactor/ref-003-app-extraction branch July 11, 2026 13:28
@DoRmAmMu1997

Copy link
Copy Markdown
Owner Author

Completion verdict

Complete — no findings. This is a completion comment, not an approval.

No follow-up code changes were required. Verification covered 51 focused tests plus desktop and mobile browser QA for the status panel, parameter controls, universe handling, and cache invalidation. No actionable quality, behavior, or security findings remained.

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