tech_lead / coder 2roles

This commit is contained in:
2025-12-27 08:02:59 +03:00
parent 07914c8728
commit 3d75a21127
17 changed files with 376 additions and 507 deletions

View File

@@ -1,66 +1,48 @@
# Research: Migration Dashboard Grid
## 1. Superset API Capabilities
## Unknowns & Clarifications
**Objective**: Verify how to fetch dashboard metadata (title, last modified, status).
### 1. Pagination vs Client-side Filtering
**Context**: The spec mentions "Client-side (Fetch all, filter locally)" (FR-004) but also "Pagination (e.g., 20 per page)" (FR-008).
**Resolution**:
- We will fetch ALL dashboard metadata from the Superset API in one go. The metadata (ID, Title, Status, Date) is lightweight. Even for 1000 dashboards, the payload is small (~100KB).
- **Client-side Pagination**: We will implement pagination purely on the frontend. This satisfies "Pagination" for UI performance/usability while keeping the "Fetch all" requirement for fast filtering.
- **Decision**: Fetch all, paginate locally.
- **Findings**:
- The `SupersetClient.get_dashboards` method in `superset_tool/client.py` already exists.
- It fetches the following columns by default: `["slug", "id", "changed_on_utc", "dashboard_title", "published"]`.
- This covers all requirements:
- Name -> `dashboard_title`
- Last Modified -> `changed_on_utc`
- Status -> `published`
- Pagination is handled internally by `_fetch_all_pages`, so the client fetches *all* dashboards.
### 2. Superset API for Dashboard Metadata
**Context**: Need to fetch `title`, `changed_on`, `published`.
**Research**:
- Superset API endpoint: `/api/v1/dashboard/`
- Standard response includes `result` array with `dashboard_title`, `changed_on_utc`, `published`.
- **Decision**: Use `GET /api/v1/dashboard/` with `q` parameter to select specific columns to minimize payload.
- Columns: `id`, `dashboard_title`, `changed_on_utc`, `published`.
- **Decision**: Use the existing `SupersetClient.get_dashboards` method. No changes needed to the core client.
### 3. Grid Component
**Context**: Need a grid with sorting, filtering, and selection.
**Options**:
- **Custom Svelte Table**: Lightweight, full control.
- **3rd Party Lib (e.g. svelte-headless-table)**: Powerful but maybe overkill.
- **Decision**: **Custom Svelte Component** (`DashboardGrid.svelte`).
- Why: Requirements are specific (Select All across pages, custom status pill, specific columns). A custom component using standard HTML table + Tailwind is simple and maintainable for this scope.
## 2. Frontend Grid Implementation
## Design Decisions
**Objective**: Choose a strategy for the grid component (filtering, sorting, pagination).
### Data Model
- **Dashboard**:
- `id`: string (or int, depends on Superset version, usually int for dashboards but we treat as ID)
- `title`: string
- `last_modified`: string (ISO date)
- `status`: 'published' | 'draft'
- **Options**:
1. **Server-side pagination**: Fetch page by page. Good for huge datasets (>10k).
2. **Client-side pagination**: Fetch all, filter/sort/paginate in browser. Good for typical datasets (<1k) and simplifies "Select All" logic.
### Architecture
- **Backend**:
- `SupersetClient.get_dashboards()`: Fetches list from Superset.
- `GET /api/environments/{id}/dashboards`: Proxy endpoint.
- **Frontend**:
- `DashboardGrid.svelte`: Handles display, sorting, pagination, and selection logic.
- `migration/+page.svelte`: Orchestrates fetching and passes data to Grid.
- **Findings**:
- Spec explicitly requests "Client-side (Fetch all, filter locally)".
- Spec requires "Select All" to select *all filtered results*, which is trivial with client-side state but complex with server-side pagination (requires tracking exclusion list or query parameters).
- Existing `MappingTable.svelte` is too simple (no sorting/pagination).
- **Decision**:
- Implement a new `DashboardGrid.svelte` component.
- **State Management**:
- `dashboards`: Array of all fetched dashboards.
- `filterText`: String for name filtering.
- `sortColumn`: 'title' | 'changed_on' | 'published'.
- `sortDirection`: 'asc' | 'desc'.
- `currentPage`: Integer.
- `pageSize`: Integer (default 20).
- `selectedIds`: Set/Array of selected dashboard IDs.
- **Logic**:
- `filteredDashboards`: Derived store/value based on `dashboards` + `filterText`.
- `sortedDashboards`: Derived from `filteredDashboards` + `sort` params.
- `paginatedDashboards`: Slice of `sortedDashboards` for current page.
- "Select All": Adds all IDs from `sortedDashboards` (not just `paginatedDashboards`) to `selectedIds`.
## 3. API Contract
**Objective**: Define the endpoint to serve dashboard data.
- **Current State**: Need to check if an endpoint exists that returns this data.
- **Requirement**: `GET /api/migration/dashboards` (or similar).
- **Response Structure**:
```json
[
{
"id": 123,
"title": "Sales Dashboard",
"changed_on": "2023-10-27T10:00:00Z",
"published": true
},
...
]
```
- **Decision**: Create or update a route in `backend/src/api/routes/migration.py` (or `mappings.py` if more appropriate, but `migration` seems better for source selection).
### UX/UI
- **Status Column**: Badge (Green for Published, Gray for Draft).
- **Selection**: Checkbox in first column.
- **Pagination**: Simple "Prev 1 of 5 Next" controls at bottom.