# Phase 0 Research: User Profile Dashboard Filter

## Decision 1: Profile binding includes Superset account lookup by selected environment

**Decision**  
During account binding on profile page, user selects a Superset environment and the system requests account candidates from that environment (as requested by stakeholder, including compatibility with Superset users-list style such as `/users/?pageIndex=...&sortColumn=...&sortOrder=...`).

**Rationale**  
The new requirement explicitly asks for environment-based account querying during binding. This improves correctness and reduces manual typos in usernames.

**Alternatives considered**  
- **Manual username entry only**: rejected (does not satisfy requested behavior).  
- **Global account lookup without environment context**: rejected (incorrect in multi-environment setups).  
- **Browser direct call to Superset from frontend**: rejected (CORS/session fragility and credential exposure risks).

---

## Decision 2: Account lookup is executed via backend proxy, not direct frontend-to-Superset fetch

**Decision**  
Frontend calls internal API; backend queries selected Superset environment using existing server-side environment credentials/session flow and returns normalized account candidates.

**Rationale**  
Current backend already handles Superset auth/session (`security/login` + CSRF) through existing network client. Reusing that channel is safer and operationally stable.

**Alternatives considered**  
- **Frontend fetch with `credentials: include` directly to Superset**: rejected for cross-origin and cookie-domain uncertainty; also weak security boundary.  
- **Store Superset cookies/tokens in frontend state**: rejected as security anti-pattern.  
- **Separate external integration service**: rejected as unnecessary complexity for current scope.

---

## Decision 3: Preserve one global bound Superset username per app user

**Decision**  
Even with environment-based lookup for convenience, saved preference remains a single global Superset username per application user (already clarified), not per-environment mapping.

**Rationale**  
This preserves previously accepted scope and avoids expanding feature into multi-mapping profile management.

**Alternatives considered**  
- **Per-environment username mapping**: rejected (scope increase, additional UX complexity).  
- **Multiple candidate bindings at once**: rejected (not required and harder to validate).

---

## Decision 4: Use deterministic normalization and validation for bound username

**Decision**  
Apply consistent policy:

1. trim leading/trailing spaces,  
2. compare case-insensitively,  
3. block save when filter is enabled and username is empty,  
4. reject unsupported format (including spaces inside username),  
5. store normalized companion value for comparison.

**Rationale**  
Matches accepted clarifications and keeps filter behavior deterministic across inconsistent source formatting.

**Alternatives considered**  
- **Case-sensitive match**: rejected (contradicts accepted clarification).  
- **Frontend-only validation**: rejected (backend must remain source of truth).  
- **No format validation**: rejected (conflicts with spec acceptance criteria).

---

## Decision 5: Apply profile filter on backend dashboards listing path for pagination correctness

**Decision**  
Main dashboards list endpoint applies profile-filter logic server-side when requested by `/dashboards` page context. Matching rule is `owners OR modified_by` against normalized bound username.

**Rationale**  
Server-side filtering keeps `total`, `total_pages`, and page slices consistent. Frontend-only filtering after pagination would produce misleading counts.

**Alternatives considered**  
- **Frontend-only filtering**: rejected (breaks pagination semantics).  
- **Separate “my dashboards” endpoint**: rejected (unnecessary API fragmentation).  
- **Always-on server auto-filter for all dashboard endpoints**: rejected (clarified scope says only main list page auto-apply).

---

## Decision 6: Temporary “show all” override is page-scoped and non-persistent

**Decision**  
Dashboards page supports temporary clear of active profile filter without changing saved profile preference; re-entering page restores default behavior.

**Rationale**  
Directly satisfies FR-011/FR-012 semantics and avoids accidental preference mutation.

**Alternatives considered**  
- **Persist override as profile update**: rejected (not temporary).  
- **Global override across app routes**: rejected (scope leak and confusing UX).  
- **No override**: rejected (explicit requirement exists).

---

## Decision 7: Account lookup failure is non-blocking with manual fallback

**Decision**  
If environment account lookup fails or is unavailable, system shows warning and keeps manual username entry enabled; save remains possible.

**Rationale**  
UX reference requires guiding recovery and avoiding dead-end errors. Binding should not become impossible due to transient connectivity.

**Alternatives considered**  
- **Hard-block save on lookup failure**: rejected (poor resilience, unnecessary blocker).  
- **Silent failure**: rejected (bad transparency and operator confidence).  
- **Auto-disable filter on lookup failure**: rejected (unexpected side effects).

---

## Decision 8: Normalize account candidate payload from Superset into stable UI contract

**Decision**  
Backend maps environment-specific Superset response into canonical candidate shape:

- `username` (required),  
- `display_name` (preferred),  
- `email` (optional),  
- `environment_id` (echo context).

**Rationale**  
Superset deployments may differ in fields and endpoint format; normalized response shields frontend from version-specific payload drift.

**Alternatives considered**  
- **Expose raw Superset payload directly**: rejected (tight coupling and brittle UI).  
- **Single-string list only**: rejected (insufficient context for user choice).  
- **Environment-agnostic cache-only list**: rejected (staleness risk).

---

## Decision 9: Navigation and i18n must reflect new profile flow and lookup states

**Decision**  
Add profile entry in app navigation and introduce localized text for:

- environment selector label,  
- account lookup loading/empty/error states,  
- manual fallback hint,  
- active filter indicator and clear action.

**Rationale**  
Constitution requires i18n for all user-facing text and unified UX conventions.

**Alternatives considered**  
- **Hardcoded inline strings**: rejected (constitutional violation).  
- **Reuse unrelated settings labels**: rejected (ambiguous UX).  
- **No nav entry (deep-link only)**: rejected (discoverability issue).

---

## Decision 10: Testing strategy covers binding lookup + filtering + recovery independently

**Decision**  
Define independent checks for:

1. profile preference read/update ownership rules,  
2. account lookup by selected environment (success + failure fallback),  
3. dashboards `owners OR modified_by` filtering correctness,  
4. temporary override restore behavior,  
5. localized UX feedback states.

**Rationale**  
Supports constitution independent-testability and reduces regression ambiguity.

**Alternatives considered**  
- **Only e2e flow tests**: rejected (debugging becomes expensive).  
- **Only unit tests**: rejected (insufficient contract confidence).  
- **Manual QA only**: rejected (non-repeatable quality gate).

---

## UX Feasibility Check (Phase 0 -> Phase 1)

Architecture remains compatible with UX reference after requirement expansion:

- Profile page can represent additional **Lookup Loading** / **Lookup Error** states without breaking existing save states.
- Manual username fallback preserves uninterrupted happy-path completion.
- Dashboards page active filter badge + temporary clear remains intact with server-side filtering.

**Result**: No blocking UX/architecture conflict. Phase 1 design can proceed.

---

## Open Clarifications Status

All active clarifications are resolved, including the newly introduced one:

1. Global Superset username across environments — resolved.  
2. Include when `owners OR modified_by` — resolved.  
3. Case-insensitive + trim matching — resolved.  
4. Own-settings-only edit rule — resolved.  
5. Auto-apply only on main dashboards list page — resolved.  
6. During binding, query Superset accounts from selected environment — resolved.

No unresolved `NEEDS CLARIFICATION` markers remain.