Files
ss-tools/specs/024-user-dashboard-filter/plan.md
2026-03-04 19:42:17 +03:00

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:

  1. select a Superset environment and lookup account candidates for binding,
  2. save one global Apache Superset username (shared across all environments), and
  3. 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 owners OR modified_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 existing requestApi/fetchApi wrappers.

  • 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:

  1. Preference persistence location and shape
    Evaluate safest persistence approach compatible with current auth/session model and existing DB lifecycle.

  2. Filtering locus and pagination correctness
    Decide where to apply “my dashboards” filtering so pagination/total counts stay deterministic.

  3. Username normalization/validation policy
    Formalize trim + case-insensitive matching and input validation boundaries.

  4. Temporary override semantics
    Ensure override is page-scoped and does not mutate saved preference.

  5. UX-state compatibility check
    Verify the plan preserves loading/success/error UX states defined in ux_reference.md.

Output: fully resolved research.md with no unresolved clarifications.

Phase 1 — Design & Contracts Plan

  1. 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.

  2. Data model extraction
    Define entities and relationships in data-model.md for profile preferences and dashboard filter context.

  3. Semantic contracts
    Define/verify module contracts in contracts/modules.md, including CRITICAL test tags and UX state mappings where required.

  4. API contract generation
    Produce backend/frontend synchronization contract in contracts/api.yaml.

  5. Operational usage flow
    Document end-to-end setup and verification in quickstart.md.

  6. 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 /dashboards with 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