8.3 KiB
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: includedirectly 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:
- trim leading/trailing spaces,
- compare case-insensitively,
- block save when filter is enabled and username is empty,
- reject unsupported format (including spaces inside username),
- 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:
- profile preference read/update ownership rules,
- account lookup by selected environment (success + failure fallback),
- dashboards
owners OR modified_byfiltering correctness, - temporary override restore behavior,
- 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:
- Global Superset username across environments — resolved.
- Include when
owners OR modified_by— resolved. - Case-insensitive + trim matching — resolved.
- Own-settings-only edit rule — resolved.
- Auto-apply only on main dashboards list page — resolved.
- During binding, query Superset accounts from selected environment — resolved.
No unresolved NEEDS CLARIFICATION markers remain.