# Dashboard Functional UX Stabilization

Use this reference when the user asks to stabilize the Streamlit Finance dashboard from a user-experience perspective rather than adding new features.

## User-facing acceptance rules

- One clear navigation only. Do not leave Streamlit's automatic multipage sidebar visible alongside a custom JARVIS navigation.
- User Mode must stay small and task-oriented: Command Center, Portfolio, Crypto, Wallets, Equities/ETFs, Reports. Hide unfinished pages such as Watchlist or review/admin modules unless they are truly functional.
- Admin/Review/Debug pages should be separate and visually secondary: Ledger, Audit, Alerts, Data Quality, Import Wizard, Settings, Manage pages, Manual Review Queue, Watchlist if unfinished.
- No fake buttons. Every visible button must either execute a real action, navigate/prefill a real flow, or be disabled with a clear explanation.
- Default is Read-only Mode. Schreibende Aktionen remain disabled until session-based Edit Mode is explicitly enabled with a clear warning that writes go to the runtime DB and are audit-logged.
- User Mode must not expose `_asset_id`, `_wallet_id`, provider internals, raw IDs, debug columns, or import boilerplate notes. Keep those in Admin/Debug.
- Alerts should resolve entity labels to instrument/coin/wallet names and tickers/symbols rather than showing raw IDs.
- Dashboard render must not call market/provider APIs. Price refresh/report generation are explicit click actions only and must read/write runtime paths outside Git.

## Streamlit navigation pattern

If custom routing is used, keep executable Streamlit page modules out of `dashboard/pages/` to avoid automatic multipage navigation. A robust pattern is:

- `dashboard/views/page_*.py` contains real page modules.
- `dashboard/pages/__init__.py` is compatibility-only and imports/re-exports views if needed.
- `dashboard/main.py` imports `PAGES` from the compatibility package or directly from `views` and renders a single sidebar radio/navigation.
- Delete/avoid numeric top-level stubs such as `00_command_center.py`; they appear as ugly auto-pages.

## Button/action pattern

Centralize button behavior in a small dashboard action helper:

- `edit_mode_enabled(st)` reads `st.session_state['jarvis_edit_mode']` defensively.
- `action_button(container, label, edit_required=True, disabled_reason=...)` applies read-only disabling and a consistent help message.
- `open_crypto_manage(st, action, asset_id=None, wallet_id=None)` stores selected context in session state (`crypto_manage_prefill_*`) and points users to the Manage page instead of rendering inert text links.

Read-only exceptions may include pure navigation or audit/history display, but all mutations require Edit Mode and a confirmation/review step.

## Testing pattern

Add stabilization tests that use fake Streamlit objects and monkeypatch providers:

- User navigation contains no auto-page labels or unfinished User Mode pages.
- `dashboard/pages/` contains no executable numeric auto-page modules.
- User Mode tables do not include raw technical IDs or import/debug notes.
- Coin/wallet selectboxes store selected asset/wallet IDs in session state but do so defensively for test fakes.
- Detail views render real `st.button` actions, not text action lists.
- Action buttons are disabled in Read-only Mode and enabled in Edit Mode.
- Manage actions prefill selected coin/wallet context.
- Adjustment/transfer flows write audited events and do not silently mutate holdings.
- Report buttons create runtime reports only on click.
- Price-update buttons call provider services only on click; normal render should pass even if provider methods are patched to fail.
- Allocation rows and charts are sorted by value descending unless the user changes sort order.
- Alert cards resolve entity labels to human-readable names/tickers.
- Watchlist is either functional or absent from User Mode.

## Verification sequence

1. Run targeted stabilization tests during implementation.
2. Run `python -m compileall -q src tests`.
3. Run the full test suite.
4. Remove generated caches (`rm -rf .pytest_cache **/__pycache__` or equivalent) after tests, because pytest recreates `.pytest_cache`.
5. Run Git-safety after cache cleanup and before staging/commit/push.

## Pitfalls

- Treating a button that only writes text like `Details · Bestand hinzufügen · Korrigieren` as a real action. It is not; use actual Streamlit controls.
- Showing write actions while the sidebar says Read-only without disabling them. This reads as broken UX.
- Building new pages while the user asked for stabilization. First remove empty pages, duplicate navigation and dead controls.
- Allowing API refreshes from page render to satisfy a dashboard status display. This violates the local-cache/no-live-render rule.
- Running Git-safety immediately after pytest without deleting `.pytest_cache`; this causes avoidable runtime-cache findings even when the source changes are safe.
