11 KiB
Implementation Plan: User Profile Dashboard Filter
Branch: 024-user-dashboard-filter | Date: 2026-03-04 | Spec: spec.md
Input: Feature specification from /specs/024-user-dashboard-filter/spec.md
Summary
Add a dedicated user profile page where an authenticated user can:
- select a Superset environment and lookup account candidates for binding,
- save one global Apache Superset username (shared across all environments), and
- save a default preference to show only dashboards related to that username.
The dashboard list page (/dashboards) applies this preference by default using the clarified rule:
- include dashboard when username matches
ownersORmodified_by; - normalize with trim + case-insensitive comparison.
Account lookup failures are degraded-but-usable (manual username entry remains available). The user can temporarily clear the filter from the dashboards page; preference remains saved and is applied again on next page visit.
Technical Context
Language/Version: Python 3.9+ (backend), Node.js 18+ + SvelteKit (frontend)
Primary Dependencies: FastAPI, SQLAlchemy, Pydantic, existing auth stack (get_current_user), existing dashboards route/service, Svelte runes ($state, $derived, $effect), Tailwind CSS, frontend api wrapper
Storage: Existing auth database (AUTH_DATABASE_URL) with a dedicated per-user preference entity
Testing: pytest for backend routes/services, frontend integration/UX tests (existing JS/Svelte test stack)
Target Platform: Linux-hosted backend API + browser SPA frontend
Project Type: Web application (backend + frontend monorepo)
Performance Goals:
- Profile preferences read/save should complete in normal interactive latency (target p95 <= 300ms server-side in internal network).
- Dashboard list should reflect active default filter within one normal page reload cycle (target <= 2s for typical environments up to ~2k dashboards).
Constraints: - Default filter auto-apply is allowed only on the main dashboards list page (
/dashboards). - Username is required when default filter is enabled.
- Username validation rejects whitespace-containing values and unsupported symbols.
- Matching must be case-insensitive and trim surrounding spaces on both saved username and dashboard actor fields.
- User may edit only own profile filter settings (self-service only, no cross-user edit API).
- Profile binding must support account lookup from selected Superset environment.
- Account lookup failure must be non-blocking and preserve manual username fallback. Scale/Scope:
- 1 new backend profile API surface (read/update own settings + account lookup by selected environment).
- 1 new persistence model for user dashboard filter preferences.
- 1 Superset lookup adapter/proxy path for account candidate retrieval and normalization.
- 1 update to dashboards listing API query contract for deterministic “my dashboards” filtering.
- 1 new frontend profile page and 1 dashboards-page enhancement for active-filter indicator + temporary override.
- Localized copy updates (
en,ru) and focused test additions.
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
-
I. Semantic Protocol Compliance: PASS
New/updated modules will define[DEF]headers,@TIER, contracts, and proper closings. CRITICAL modules will include required testing tags and UX-state contracts. -
II. Modular Plugin Architecture: PASS
Feature is implemented via existing modular API/service/model architecture and centralized dependencies; no hardcoded environment/config bypasses are introduced. -
III. Unified Frontend Experience: PASS
UI work stays within SvelteKit + Tailwind conventions, all user-facing strings go through i18n locale files, API calls use existingrequestApi/fetchApiwrappers. -
IV. Security & RBAC: PASS
Profile preferences API is self-scoped through authenticated identity (get_current_user), preventing cross-user updates. No permission escalation path is introduced. -
V. Independent Testability: PASS
Spec already defines independently testable user stories; design artifacts preserve isolated verification for profile save, default filtering, and temporary override behavior. -
VI. Asynchronous Execution: PASS
Feature introduces no long-running operations; existing async API patterns remain unchanged and compliant.
Gate Result (pre-research): PASS
Project Structure
Documentation (this feature)
specs/024-user-dashboard-filter/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ ├── modules.md
│ └── api.yaml
└── tasks.md
Source Code (repository root)
backend/
├── src/
│ ├── api/
│ │ └── routes/
│ │ ├── dashboards.py # update: default my-dashboards filtering inputs
│ │ └── profile.py # new: own profile preference endpoints
│ ├── models/
│ │ └── profile.py # new: user dashboard preference persistence entity
│ ├── schemas/
│ │ └── profile.py # new: request/response schemas for profile prefs
│ └── services/
│ └── profile_service.py # new: preference read/write + validation orchestration
└── tests/
└── ... # new/updated route + service tests
frontend/
└── src/
├── lib/
│ ├── api.js # update: profile preference methods and dashboard query params
│ ├── i18n/
│ │ └── locales/
│ │ ├── en.json # update: profile/filter labels and errors
│ │ └── ru.json # update: profile/filter labels and errors
│ └── components/layout/
│ └── Sidebar.svelte # update: navigation link to profile page
└── routes/
├── profile/
│ └── +page.svelte # new: profile preferences page
└── dashboards/
└── +page.svelte # update: apply/override default my-dashboards filter
Structure Decision: Use existing web-application layout (backend + frontend) and add a focused profile subdomain (model/service/schema/route + frontend page), while extending current dashboards flow without introducing a new standalone subsystem.
Phase 0 — Outline & Research Plan
Research focus areas:
-
Preference persistence location and shape
Evaluate safest persistence approach compatible with current auth/session model and existing DB lifecycle. -
Filtering locus and pagination correctness
Decide where to apply “my dashboards” filtering so pagination/total counts stay deterministic. -
Username normalization/validation policy
Formalize trim + case-insensitive matching and input validation boundaries. -
Temporary override semantics
Ensure override is page-scoped and does not mutate saved preference. -
UX-state compatibility check
Verify the plan preserves loading/success/error UX states defined inux_reference.md.
Output: fully resolved research.md with no unresolved clarifications.
Phase 1 — Design & Contracts Plan
-
Validate design against UX reference
Map profile save states and dashboards filter indicator/empty-state flows to explicit contracts.
If architecture prevents these UX states, stop and raise risk before implementation. -
Data model extraction
Define entities and relationships indata-model.mdfor profile preferences and dashboard filter context. -
Semantic contracts
Define/verify module contracts incontracts/modules.md, including CRITICAL test tags and UX state mappings where required. -
API contract generation
Produce backend/frontend synchronization contract incontracts/api.yaml. -
Operational usage flow
Document end-to-end setup and verification inquickstart.md. -
Agent context update Run agent context refresh script and capture result in planning output trace.
Agent Context Update Record
- Command:
.specify/scripts/bash/update-agent-context.sh kilocode - Result: success (exit code 0)
- Updated file:
.kilocode/rules/specify-rules.md - Added context entries:
- Language: Python 3.9+ (backend), Node.js 18+ + SvelteKit (frontend)
- Framework: FastAPI, SQLAlchemy, Pydantic, auth stack, dashboards route/service, Svelte runes, Tailwind, frontend api wrapper
- Database: existing auth DB with dedicated per-user preference entity
Phase 2 — Task Planning Approach
At /speckit.tasks, work will be decomposed into independent stories:
- US1 (P1): Profile page with environment-based account lookup and saving Superset username + default toggle.
- US2 (P1): Default “my dashboards” filtering on
/dashboardswith owners OR modified_by matching. - US3 (P2): Temporary filter override on dashboards page + restore-on-return behavior.
- US4 (P2): Validation, UX feedback, and degraded lookup fallback handling (invalid username/save failure/lookup failure/empty state).
- US5 (P3): Localization and test coverage updates.
Each story will include independent acceptance tests and explicit completion evidence.
Post-Design Constitution Re-Check
(Performed after generating research.md, data-model.md, contracts/modules.md, contracts/api.yaml, and quickstart.md.)
-
I. Semantic Protocol Compliance: PASS
Planned modules include explicit semantic contract envelopes and tiering in design artifacts. -
II. Modular Plugin Architecture: PASS
Design stays inside existing modular backend/frontend boundaries; no config hardcoding patterns required. -
III. Unified Frontend Experience: PASS
UX implementation relies on Tailwind + i18n + shared API wrappers, consistent with repository standards. -
IV. Security & RBAC: PASS
Self-service only profile preference operations; no cross-user mutation paths exposed by contract. -
V. Independent Testability: PASS
Contract and quickstart include independent checks for save, auto-filter, override, and recovery flows. -
VI. Asynchronous Execution: PASS
No new long-running jobs introduced; existing async API model remains intact.
Gate Result (post-design): PASS
Complexity Tracking
Fill ONLY if Constitution Check has violations that must be justified
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| None at planning stage | N/A | N/A |