# Quickstart: User Profile Dashboard Filter ## Purpose This quickstart describes how to validate the full feature flow: 1. bind Superset account on profile page with environment-based lookup, 2. save default "show only my dashboards" preference, 3. verify default filtering on `/dashboards`, 4. verify temporary override and restoration behavior. --- ## Prerequisites 1. App is running with backend + frontend in a reachable local environment. 2. At least one Superset environment is configured in settings. 3. Test user can authenticate into the app. 4. Selected Superset environment has reachable users endpoint and dashboard metadata containing `owners` and `modified_by`. 5. Test data includes at least: - one dashboard matching test user by `owners` or `modified_by`, - one dashboard not matching test user. --- ## Step 1 — Open Profile Page 1. Log in as test user. 2. Navigate to profile page (new navigation entry). Expected: - Profile form shows: - Superset environment selector, - account input (manual), - "Show only my dashboards by default" toggle, - Save/Cancel actions. - Existing saved values (if any) are preloaded. --- ## Step 2 — Environment-Based Account Lookup 1. Select a configured Superset environment. 2. Wait for account lookup request to complete. Expected (success path): - Account candidate list appears. - Candidate includes recognizable `username`/`display_name`. - User can pick account candidate to fill binding field. Expected (degraded path): - If lookup fails, inline warning appears: - "Cannot load Superset accounts for this environment right now. You can enter username manually." - Manual username input remains enabled. - Save remains available. --- ## Step 3 — Save Preference 1. Choose account candidate **or** manually enter valid username. 2. Enable `Show only my dashboards by default`. 3. Click Save. Expected: - Save enters loading state. - Success toast confirms persistence. - Reloading profile page shows the same saved values. Validation checks: - If username invalid (e.g., contains spaces), save is blocked with validation message. - If toggle enabled and username empty, save is blocked. --- ## Step 4 — Verify Default Filter on Dashboards Main Page 1. Navigate to `/dashboards`. 2. Ensure main list context applies profile default. Expected: - Active indicator (e.g., "My Dashboards Only") is visible. - Returned list includes dashboards where normalized username matches: - any `owners` entry **OR** - `modified_by`. - Non-matching dashboards are excluded. - Pagination totals reflect filtered results (no client-side mismatch). --- ## Step 5 — Verify Temporary Override 1. Click active filter indicator clear action ("show all"). 2. Observe list behavior. Expected: - All dashboards become visible for this page session/context. - Saved profile preference is **not** changed. - Indicator reflects override state. 3. Leave dashboards page and return to `/dashboards`. Expected: - Default profile filter is auto-applied again. - Indicator returns to active filtered state. --- ## Step 6 — Verify Recovery / Error UX ### 6A. Lookup Failure Recovery 1. Simulate Superset lookup failure (temporary env outage or invalid env). 2. Open profile page and select environment. Expected: - Non-blocking warning shown. - Manual username fallback remains possible. - Save succeeds with valid manual username. ### 6B. No Match Empty State 1. Save valid username that matches no dashboards. 2. Open `/dashboards`. Expected: - Friendly empty state message is displayed. - User can clear filter override to see all dashboards. --- ## Backend API Smoke Checklist ### Profile endpoints - `GET /api/profile/preferences` returns authenticated user's preference only. - `PATCH /api/profile/preferences` persists normalized username + toggle. - `GET /api/profile/superset-accounts?environment_id=` returns: - success payload with candidates, or - degraded payload with warning + empty list. ### Dashboards endpoint - `GET /api/dashboards?...&page_context=dashboards_main&apply_profile_default=true&override_show_all=false` returns filtered result + effective filter metadata. - Same call with `override_show_all=true` returns unfiltered list and marks effective filter as not applied. --- ## Acceptance Checklist (Operator) - [ ] Profile page visible and reachable from navigation. - [ ] Environment-based account lookup works for binding. - [ ] Lookup failure path allows manual entry (non-blocking). - [ ] Preference save persists across reload/session. - [ ] `/dashboards` applies default filter by `owners OR modified_by`. - [ ] Temporary clear shows all dashboards without changing saved preference. - [ ] Re-entering `/dashboards` restores default filtered behavior. - [ ] i18n texts are present for new profile/lookup/filter states (EN + RU). --- ## Troubleshooting Matrix | Category | Symptom | Likely Cause | Recovery | |---|---|---|---| | `lookup` | Account list does not load | Superset env unavailable or upstream endpoint issue | Show warning, use manual username, retry later | | `validation` | Save blocked unexpectedly | Invalid username format or empty username with toggle on | Correct username, re-save | | `filtering` | Unexpected dashboards included/excluded | Mismatch in normalization or actor fields | Confirm trim/case-insensitive compare and `owners OR modified_by` logic | | `override` | Temporary clear persists incorrectly | Override state leaking into saved preference | Verify override is page-scoped and non-persistent | --- ## Suggested Test Commands (Backend) Use project venv and `python3` as required. ```bash cd backend && .venv/bin/python3 -m pytest tests -k "profile or dashboards" -q ``` If adding dedicated route tests for this feature: ```bash cd backend && .venv/bin/python3 -m pytest src/api/routes/__tests__ -k "profile or dashboards" -q ``` --- ## Exit Criteria Feature is considered ready for implementation tasking when: 1. All acceptance checklist items above are reproducibly passable. 2. Contracts in [`contracts/modules.md`](./contracts/modules.md) and [`contracts/api.yaml`](./contracts/api.yaml) cover all required paths (happy + degraded + edge). 3. No unresolved clarification remains in [`research.md`](./research.md).