# Data Model: User Profile Dashboard Filter ## Overview This model defines persistent and transient entities needed to: 1. store per-user dashboard filter preferences, 2. support Superset account lookup by selected environment during profile binding, 3. apply deterministic dashboard filtering on the main dashboards list page. --- ## 1) UserDashboardPreference (persistent) **Purpose**: Stores the authenticated user’s saved profile settings for dashboard filtering. ### Fields - `preference_id` (string/uuid, required, unique) - `user_id` (string, required, unique, FK -> `users.id`) - `superset_username` (string, optional) - `superset_username_normalized` (string, optional) - `show_only_my_dashboards` (boolean, required, default `false`) - `created_at` (datetime, required) - `updated_at` (datetime, required) ### Validation Rules - `user_id` must be unique (one preference record per user). - If `show_only_my_dashboards = true`, `superset_username` must be non-empty and valid. - `superset_username_normalized` must be `trim(lower(superset_username))` when username exists. - A user can mutate only their own preference record. ### Lifecycle Notes - `unconfigured` -> `configured_disabled` (username optional, toggle off) - `configured_disabled` -> `configured_enabled` (valid username + toggle on) - `configured_enabled` -> `configured_disabled` (toggle off, username may be retained) --- ## 2) SupersetAccountLookupRequest (transient) **Purpose**: Represents a profile-page request to fetch account candidates from a selected Superset environment. ### Fields - `requester_user_id` (string, required) - `environment_id` (string, required) - `search` (string, optional) - `page_index` (integer, required, default `0`, min `0`) - `page_size` (integer, required, default `20`, min `1`, max `100`) - `sort_column` (enum, required, default `username`) Allowed: `username`, `first_name`, `last_name`, `email` - `sort_order` (enum, required, default `desc`) Allowed: `asc`, `desc` ### Validation Rules - `requester_user_id` must be authenticated user identity. - `environment_id` must exist in configured environments. - Pagination and sort values must respect allowed bounds/enums. ### Integration Note Backend may translate these fields into Superset-compatible query style (including `pageIndex`, `sortColumn`, `sortOrder`) when contacting selected environment. --- ## 3) SupersetAccountCandidate (transient) **Purpose**: Canonical account option returned to frontend from selected Superset environment. ### Fields - `environment_id` (string, required) - `username` (string, required) - `display_name` (string, optional) - `email` (string, optional) - `is_active` (boolean, optional) ### Validation Rules - `username` must be non-empty. - Candidate list should be deduplicated by normalized username per environment response. - Payload must remain stable even if upstream Superset shape differs. --- ## 4) DashboardActorProjection (derived, transient) **Purpose**: Normalized actor fields used for deterministic filter matching. ### Fields - `dashboard_id` (integer, required) - `owners_tokens` (array[string], required) - `modified_by_token` (string, optional) - `match_reason` (enum, required) Allowed: `owners`, `modified_by`, `none` ### Validation Rules - `owners_tokens` must contain trimmed unique non-empty tokens. - `modified_by_token` must be trimmed when present. - Matching uses case-insensitive compare against `superset_username_normalized`. --- ## 5) DashboardProfileFilterContext (transient) **Purpose**: Carries effective profile-filter state for dashboards list response. ### Fields - `user_id` (string, required) - `apply_profile_default` (boolean, required) - `override_show_all` (boolean, required) - `effective_filter_applied` (boolean, required) - `effective_username` (string, optional) - `source_page` (enum, required) Allowed: `dashboards_main`, `other` ### Validation Rules - Auto-apply is valid only when `source_page = dashboards_main`. - If `override_show_all = true`, `effective_filter_applied` must be `false`. - If preference toggle is disabled, `effective_filter_applied` must be `false`. --- ## 6) ProfileSaveResult (transient) **Purpose**: Normalized save response used by profile page UX feedback. ### Fields - `status` (enum, required) Allowed: `success`, `error` - `message` (string, optional) - `validation_errors` (array[string], optional) - `saved_preference` (`UserDashboardPreference`, optional) ### Validation Rules - `saved_preference` present only for successful save. - `validation_errors` present only for invalid input scenarios. --- ## Relationships 1. `User` 1 — 1 `UserDashboardPreference` 2. `Environment` 1 — N `SupersetAccountLookupRequest` (runtime) 3. `SupersetAccountLookupRequest` 1 — N `SupersetAccountCandidate` (runtime) 4. `UserDashboardPreference` + `DashboardActorProjection` -> filtered dashboard list projection 5. `DashboardProfileFilterContext` decorates dashboards response behavior/state --- ## State Model Highlights ### Profile Binding Flow `idle -> environment_selected -> lookup_loading -> lookup_loaded|lookup_failed -> save_loading -> save_success|save_error` ### Dashboards Filter Flow (main list page) `default_apply -> active_filtered -> temporary_show_all -> leave_page -> default_apply_restored` --- ## Data Consistency & Security Invariants - Preference mutations are always scoped to authenticated user identity. - Bound username normalization is deterministic and identical across save and match paths. - Temporary "show all" override does not mutate saved preference. - Account lookup errors never force data loss; manual username fallback remains available.