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

@@ -11,6 +11,8 @@ Auto-generated from all feature plans. Last updated: 2025-12-19
- Filesystem (plugins, logs, backups), SQLite (optional, for job history if needed) (005-fix-ui-ws-validation) - Filesystem (plugins, logs, backups), SQLite (optional, for job history if needed) (005-fix-ui-ws-validation)
- Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS (007-migration-dashboard-grid) - Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS (007-migration-dashboard-grid)
- N/A (Superset API integration) (007-migration-dashboard-grid) - N/A (Superset API integration) (007-migration-dashboard-grid)
- Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS, Pydantic, Superset API (007-migration-dashboard-grid)
- N/A (Superset API integration - read-only for metadata) (007-migration-dashboard-grid)
- Python 3.9+ (Backend), Node.js 18+ (Frontend Build) (001-plugin-arch-svelte-ui) - Python 3.9+ (Backend), Node.js 18+ (Frontend Build) (001-plugin-arch-svelte-ui)
@@ -31,9 +33,9 @@ cd src; pytest; ruff check .
Python 3.9+ (Backend), Node.js 18+ (Frontend Build): Follow standard conventions Python 3.9+ (Backend), Node.js 18+ (Frontend Build): Follow standard conventions
## Recent Changes ## Recent Changes
- 007-migration-dashboard-grid: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS, Pydantic, Superset API
- 007-migration-dashboard-grid: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS - 007-migration-dashboard-grid: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS
- 007-migration-dashboard-grid: Added [if applicable, e.g., PostgreSQL, CoreData, files or N/A] - 007-migration-dashboard-grid: Added [if applicable, e.g., PostgreSQL, CoreData, files or N/A]
- 006-configurable-belief-logs: Added Python 3.9+ + FastAPI (Backend), Pydantic (Config), Svelte (Frontend)
<!-- MANUAL ADDITIONS START --> <!-- MANUAL ADDITIONS START -->

27
.kilocodemodes Normal file
View File

@@ -0,0 +1,27 @@
customModes:
- slug: tech-lead
name: Tech Lead
description: Architect for contracts and scaffolding
roleDefinition: >-
You are Kilo Code, acting as a Technical Lead and System Architect.
Your primary responsibility is to define the "Structure" and "Contracts" of the system before implementation, following the Semantic Code Generation Protocol.
You operate primarily on 'tasks-arch.md' task lists.
YOUR DUTIES:
1. Create new files and directory structures.
2. Define Modules, Classes, and Functions using `[DEF]` anchors.
3. Write clear Headers with `@PURPOSE`, `@LAYER`, `@RELATION`.
4. Define strict Contracts using `@PRE`, `@POST`, `@PARAM`, `@RETURN`.
5. Leave the implementation body empty or with a placeholder (e.g., `pass`, `return ...`).
YOU DO NOT WRITE BUSINESS LOGIC. Your output is the "Skeleton" and "Rules" that the Developer Agent will fill in.
whenToUse: >-
Use this mode during the "Architecture Phase" of a feature. Select this mode when you need to create new files, define API surfaces, or set up the project structure before coding begins.
groups:
- read
- edit
- command
- list_files
- search_files

View File

@@ -7,7 +7,8 @@ Changes:
Templates Status: Templates Status:
- .specify/templates/plan-template.md: ✅ Aligned. - .specify/templates/plan-template.md: ✅ Aligned.
- .specify/templates/spec-template.md: ✅ Aligned. - .specify/templates/spec-template.md: ✅ Aligned.
- .specify/templates/tasks-template.md: ✅ Aligned. - .specify/templates/tasks-arch-template.md: ✅ Aligned (New role-based split).
- .specify/templates/tasks-dev-template.md: ✅ Aligned (New role-based split).
--> -->
# Semantic Code Generation Constitution # Semantic Code Generation Constitution
@@ -68,11 +69,24 @@ Every `.svelte` file must start with a Component definition header (`[DEF:Compon
- `@INVARIANT`: Immutable UI/State rules. - `@INVARIANT`: Immutable UI/State rules.
## Generation Workflow ## Generation Workflow
The development process follows a strict sequence: The development process follows a strict sequence enforced by Agent Roles:
1. **Analyze Request**: Identify target module and graph position.
2. **Define Structure**: Generate `[DEF]` anchors and Contracts FIRST. ### 1. Architecture Phase (Mode: `tech-lead`)
3. **Implement Logic**: Write code satisfying Contracts. **Input**: `tasks-arch.md`
4. **Validate**: If logic conflicts with Contract -> Stop -> Report Error. **Responsibility**:
- Analyze request and graph position.
- Generate `[DEF]` anchors, Headers, and Contracts (`@PRE`, `@POST`).
- **Output**: Scaffolding files with no implementation logic.
### 2. Implementation Phase (Mode: `code`)
**Input**: `tasks-dev.md` + Scaffolding files
**Responsibility**:
- Read contracts defined by Architect.
- Write implementation code that strictly satisfies contracts.
- **Output**: Working code with passing tests.
### 3. Validation
If logic conflicts with Contract -> Stop -> Report Error.
## Governance ## Governance
This Constitution establishes the "Semantic Code Generation Protocol" as the supreme law of this repository. This Constitution establishes the "Semantic Code Generation Protocol" as the supreme law of this repository.

View File

@@ -9,8 +9,8 @@
# #
# OPTIONS: # OPTIONS:
# --json Output in JSON format # --json Output in JSON format
# --require-tasks Require tasks.md to exist (for implementation phase) # --require-tasks Require tasks-arch.md and tasks-dev.md to exist (for implementation phase)
# --include-tasks Include tasks.md in AVAILABLE_DOCS list # --include-tasks Include task files in AVAILABLE_DOCS list
# --paths-only Only output path variables (no validation) # --paths-only Only output path variables (no validation)
# --help, -h Show help message # --help, -h Show help message
# #
@@ -49,8 +49,8 @@ Consolidated prerequisite checking for Spec-Driven Development workflow.
OPTIONS: OPTIONS:
--json Output in JSON format --json Output in JSON format
--require-tasks Require tasks.md to exist (for implementation phase) --require-tasks Require tasks-arch.md and tasks-dev.md to exist (for implementation phase)
--include-tasks Include tasks.md in AVAILABLE_DOCS list --include-tasks Include task files in AVAILABLE_DOCS list
--paths-only Only output path variables (no prerequisite validation) --paths-only Only output path variables (no prerequisite validation)
--help, -h Show this help message --help, -h Show this help message
@@ -58,7 +58,7 @@ EXAMPLES:
# Check task prerequisites (plan.md required) # Check task prerequisites (plan.md required)
./check-prerequisites.sh --json ./check-prerequisites.sh --json
# Check implementation prerequisites (plan.md + tasks.md required) # Check implementation prerequisites (plan.md + task files required)
./check-prerequisites.sh --json --require-tasks --include-tasks ./check-prerequisites.sh --json --require-tasks --include-tasks
# Get feature paths only (no validation) # Get feature paths only (no validation)
@@ -86,15 +86,16 @@ check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
if $PATHS_ONLY; then if $PATHS_ONLY; then
if $JSON_MODE; then if $JSON_MODE; then
# Minimal JSON paths payload (no validation performed) # Minimal JSON paths payload (no validation performed)
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \ printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS_ARCH":"%s","TASKS_DEV":"%s"}\n' \
"$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS" "$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS_ARCH" "$TASKS_DEV"
else else
echo "REPO_ROOT: $REPO_ROOT" echo "REPO_ROOT: $REPO_ROOT"
echo "BRANCH: $CURRENT_BRANCH" echo "BRANCH: $CURRENT_BRANCH"
echo "FEATURE_DIR: $FEATURE_DIR" echo "FEATURE_DIR: $FEATURE_DIR"
echo "FEATURE_SPEC: $FEATURE_SPEC" echo "FEATURE_SPEC: $FEATURE_SPEC"
echo "IMPL_PLAN: $IMPL_PLAN" echo "IMPL_PLAN: $IMPL_PLAN"
echo "TASKS: $TASKS" echo "TASKS_ARCH: $TASKS_ARCH"
echo "TASKS_DEV: $TASKS_DEV"
fi fi
exit 0 exit 0
fi fi
@@ -112,11 +113,18 @@ if [[ ! -f "$IMPL_PLAN" ]]; then
exit 1 exit 1
fi fi
# Check for tasks.md if required # Check for task files if required
if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then if $REQUIRE_TASKS; then
echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2 if [[ ! -f "$TASKS_ARCH" ]]; then
echo "Run /speckit.tasks first to create the task list." >&2 echo "ERROR: tasks-arch.md not found in $FEATURE_DIR" >&2
exit 1 echo "Run /speckit.tasks first to create the task lists." >&2
exit 1
fi
if [[ ! -f "$TASKS_DEV" ]]; then
echo "ERROR: tasks-dev.md not found in $FEATURE_DIR" >&2
echo "Run /speckit.tasks first to create the task lists." >&2
exit 1
fi
fi fi
# Build list of available documents # Build list of available documents
@@ -133,9 +141,10 @@ fi
[[ -f "$QUICKSTART" ]] && docs+=("quickstart.md") [[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")
# Include tasks.md if requested and it exists # Include task files if requested and they exist
if $INCLUDE_TASKS && [[ -f "$TASKS" ]]; then if $INCLUDE_TASKS; then
docs+=("tasks.md") [[ -f "$TASKS_ARCH" ]] && docs+=("tasks-arch.md")
[[ -f "$TASKS_DEV" ]] && docs+=("tasks-dev.md")
fi fi
# Output results # Output results
@@ -161,6 +170,7 @@ else
check_file "$QUICKSTART" "quickstart.md" check_file "$QUICKSTART" "quickstart.md"
if $INCLUDE_TASKS; then if $INCLUDE_TASKS; then
check_file "$TASKS" "tasks.md" check_file "$TASKS_ARCH" "tasks-arch.md"
check_file "$TASKS_DEV" "tasks-dev.md"
fi fi
fi fi

View File

@@ -143,7 +143,9 @@ HAS_GIT='$has_git_repo'
FEATURE_DIR='$feature_dir' FEATURE_DIR='$feature_dir'
FEATURE_SPEC='$feature_dir/spec.md' FEATURE_SPEC='$feature_dir/spec.md'
IMPL_PLAN='$feature_dir/plan.md' IMPL_PLAN='$feature_dir/plan.md'
TASKS='$feature_dir/tasks.md' TASKS_ARCH='$feature_dir/tasks-arch.md'
TASKS_DEV='$feature_dir/tasks-dev.md'
TASKS='$feature_dir/tasks.md' # Deprecated
RESEARCH='$feature_dir/research.md' RESEARCH='$feature_dir/research.md'
DATA_MODEL='$feature_dir/data-model.md' DATA_MODEL='$feature_dir/data-model.md'
QUICKSTART='$feature_dir/quickstart.md' QUICKSTART='$feature_dir/quickstart.md'

View File

@@ -0,0 +1,35 @@
---
description: "Architecture task list template (Contracts & Scaffolding)"
---
# Architecture Tasks: [FEATURE NAME]
**Role**: Architect Agent
**Goal**: Define the "What" and "Why" (Contracts, Scaffolding, Models) before implementation.
**Input**: Design documents from `/specs/[###-feature-name]/`
**Output**: Files with `[DEF]` anchors, `@PRE`/`@POST` contracts, and `@RELATION` mappings. No business logic.
## Phase 1: Setup & Models
- [ ] A001 Create/Update data models in [path] with `[DEF]` and contracts
- [ ] A002 Define API route structure/contracts in [path]
- [ ] A003 Define shared utilities/interfaces
## Phase 2: User Story 1 - [Title]
- [ ] A004 [US1] Define contracts for [Component/Service] in [path]
- [ ] A005 [US1] Define contracts for [Endpoint] in [path]
- [ ] A006 [US1] Define contracts for [Frontend Component] in [path]
## Phase 3: User Story 2 - [Title]
- [ ] A007 [US2] Define contracts for [Component/Service] in [path]
- [ ] A008 [US2] Define contracts for [Endpoint] in [path]
## Handover Checklist
- [ ] All new files created with `[DEF]` anchors
- [ ] All functions/classes have `@PURPOSE`, `@PRE`, `@POST` tags
- [ ] No "naked code" (logic outside of anchors)
- [ ] `tasks-dev.md` is ready for the Developer Agent

View File

@@ -0,0 +1,35 @@
---
description: "Developer task list template (Implementation Logic)"
---
# Developer Tasks: [FEATURE NAME]
**Role**: Developer Agent
**Goal**: Implement the "How" (Logic, State, Error Handling) inside the defined contracts.
**Input**: `tasks-arch.md` (completed), Scaffolding files with `[DEF]` anchors.
**Output**: Working code that satisfies `@PRE`/`@POST` conditions.
## Phase 1: Setup & Models
- [ ] D001 Implement logic for [Model] in [path]
- [ ] D002 Implement logic for [API Route] in [path]
- [ ] D003 Implement shared utilities
## Phase 2: User Story 1 - [Title]
- [ ] D004 [US1] Implement logic for [Component/Service] in [path]
- [ ] D005 [US1] Implement logic for [Endpoint] in [path]
- [ ] D006 [US1] Implement logic for [Frontend Component] in [path]
- [ ] D007 [US1] Verify semantic compliance and belief state logging
## Phase 3: User Story 2 - [Title]
- [ ] D008 [US2] Implement logic for [Component/Service] in [path]
- [ ] D009 [US2] Implement logic for [Endpoint] in [path]
## Polish & Quality Assurance
- [ ] DXXX Verify all tests pass
- [ ] DXXX Check error handling and edge cases
- [ ] DXXX Ensure code style compliance

View File

@@ -1,263 +0,0 @@
---
description: "Task list template for feature implementation"
---
# Tasks: [FEATURE NAME]
**Input**: Design documents from `/specs/[###-feature-name]/`
**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/
**Tests**: The examples below include test tasks. Tests are OPTIONAL - only include them if explicitly requested in the feature specification.
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
## Path Conventions
- **Single project**: `src/`, `tests/` at repository root
- **Web app**: `backend/src/`, `frontend/src/`
- **Mobile**: `api/src/`, `ios/src/` or `android/src/`
- Paths shown below assume single project - adjust based on plan.md structure
<!--
============================================================================
IMPORTANT: The tasks below are SAMPLE TASKS for illustration purposes only.
The /speckit.tasks command MUST replace these with actual tasks based on:
- User stories from spec.md (with their priorities P1, P2, P3...)
- Feature requirements from plan.md
- Entities from data-model.md
- Endpoints from contracts/
Tasks MUST be organized by user story so each story can be:
- Implemented independently
- Tested independently
- Delivered as an MVP increment
DO NOT keep these sample tasks in the generated tasks.md file.
============================================================================
-->
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Project initialization and basic structure
- [ ] T001 Create project structure per implementation plan
- [ ] T002 Initialize [language] project with [framework] dependencies
- [ ] T003 [P] Configure linting and formatting tools
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
Examples of foundational tasks (adjust based on your project):
- [ ] T004 Setup database schema and migrations framework
- [ ] T005 [P] Implement authentication/authorization framework
- [ ] T006 [P] Setup API routing and middleware structure
- [ ] T007 Create base models/entities that all stories depend on
- [ ] T008 Configure error handling and logging infrastructure
- [ ] T009 Setup environment configuration management
**Checkpoint**: Foundation ready - user story implementation can now begin in parallel
---
## Phase 3: User Story 1 - [Title] (Priority: P1) 🎯 MVP
**Goal**: [Brief description of what this story delivers]
**Independent Test**: [How to verify this story works on its own]
### Tests for User Story 1 (OPTIONAL - only if tests requested) ⚠️
> **NOTE: Write these tests FIRST, ensure they FAIL before implementation**
- [ ] T010 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T011 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py
### Implementation for User Story 1
> **Protocol Note**: Follow Semantic Protocol. Define contracts (`[DEF]`, `@PRE`, `@POST`) BEFORE implementing logic.
- [ ] T012 [P] [US1] Define contracts/scaffolding for [Entity1] in src/models/[entity1].py
- [ ] T013 [P] [US1] Define contracts/scaffolding for [Entity2] in src/models/[entity2].py
- [ ] T014 [P] [US1] Implement logic for [Entity1] in src/models/[entity1].py
- [ ] T015 [P] [US1] Implement logic for [Entity2] in src/models/[entity2].py
- [ ] T016 [US1] Define contracts/scaffolding for [Service] in src/services/[service].py
- [ ] T017 [US1] Implement logic for [Service] in src/services/[service].py
- [ ] T018 [US1] Define contracts/scaffolding for [endpoint/feature] in src/[location]/[file].py
- [ ] T019 [US1] Implement logic for [endpoint/feature] in src/[location]/[file].py
- [ ] T020 [US1] Verify semantic compliance and belief state logging
**Checkpoint**: At this point, User Story 1 should be fully functional and testable independently
---
## Phase 4: User Story 2 - [Title] (Priority: P2)
**Goal**: [Brief description of what this story delivers]
**Independent Test**: [How to verify this story works on its own]
### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️
- [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py
### Implementation for User Story 2
- [ ] T021 [P] [US2] Define contracts/scaffolding for [Entity] in src/models/[entity].py
- [ ] T022 [P] [US2] Implement logic for [Entity] in src/models/[entity].py
- [ ] T023 [US2] Define contracts/scaffolding for [Service] in src/services/[service].py
- [ ] T024 [US2] Implement logic for [Service] in src/services/[service].py
- [ ] T025 [US2] Define contracts/scaffolding for [endpoint/feature] in src/[location]/[file].py
- [ ] T026 [US2] Implement logic for [endpoint/feature] in src/[location]/[file].py
- [ ] T027 [US2] Integrate with User Story 1 components (if needed)
**Checkpoint**: At this point, User Stories 1 AND 2 should both work independently
---
## Phase 5: User Story 3 - [Title] (Priority: P3)
**Goal**: [Brief description of what this story delivers]
**Independent Test**: [How to verify this story works on its own]
### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️
- [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py
### Implementation for User Story 3
- [ ] T028 [P] [US3] Define contracts/scaffolding for [Entity] in src/models/[entity].py
- [ ] T029 [P] [US3] Implement logic for [Entity] in src/models/[entity].py
- [ ] T030 [US3] Define contracts/scaffolding for [Service] in src/services/[service].py
- [ ] T031 [US3] Implement logic for [Service] in src/services/[service].py
- [ ] T032 [US3] Define contracts/scaffolding for [endpoint/feature] in src/[location]/[file].py
- [ ] T033 [US3] Implement logic for [endpoint/feature] in src/[location]/[file].py
**Checkpoint**: All user stories should now be independently functional
---
[Add more user story phases as needed, following the same pattern]
---
## Phase N: Polish & Cross-Cutting Concerns
**Purpose**: Improvements that affect multiple user stories
- [ ] TXXX [P] Documentation updates in docs/
- [ ] TXXX Code cleanup and refactoring
- [ ] TXXX Performance optimization across all stories
- [ ] TXXX [P] Additional unit tests (if requested) in tests/unit/
- [ ] TXXX Security hardening
- [ ] TXXX Run quickstart.md validation
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies - can start immediately
- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
- **User Stories (Phase 3+)**: All depend on Foundational phase completion
- User stories can then proceed in parallel (if staffed)
- Or sequentially in priority order (P1 → P2 → P3)
- **Polish (Final Phase)**: Depends on all desired user stories being complete
### User Story Dependencies
- **User Story 1 (P1)**: Can start after Foundational (Phase 2) - No dependencies on other stories
- **User Story 2 (P2)**: Can start after Foundational (Phase 2) - May integrate with US1 but should be independently testable
- **User Story 3 (P3)**: Can start after Foundational (Phase 2) - May integrate with US1/US2 but should be independently testable
### Within Each User Story
- Tests (if included) MUST be written and FAIL before implementation
- **Contracts First**: Define module structure and contracts (`[DEF]`, `@PRE`, `@POST`) before logic
- Models before services
- Services before endpoints
- Core implementation before integration
- Story complete before moving to next priority
### Parallel Opportunities
- All Setup tasks marked [P] can run in parallel
- All Foundational tasks marked [P] can run in parallel (within Phase 2)
- Once Foundational phase completes, all user stories can start in parallel (if team capacity allows)
- All tests for a user story marked [P] can run in parallel
- Models within a story marked [P] can run in parallel
- Different user stories can be worked on in parallel by different team members
---
## Parallel Example: User Story 1
```bash
# Launch all tests for User Story 1 together (if tests requested):
Task: "Contract test for [endpoint] in tests/contract/test_[name].py"
Task: "Integration test for [user journey] in tests/integration/test_[name].py"
# Launch all contracts for User Story 1 together:
Task: "Define contracts/scaffolding for [Entity1] in src/models/[entity1].py"
Task: "Define contracts/scaffolding for [Entity2] in src/models/[entity2].py"
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup
2. Complete Phase 2: Foundational (CRITICAL - blocks all stories)
3. Complete Phase 3: User Story 1
4. **STOP and VALIDATE**: Test User Story 1 independently
5. Deploy/demo if ready
### Incremental Delivery
1. Complete Setup + Foundational → Foundation ready
2. Add User Story 1 → Test independently → Deploy/Demo (MVP!)
3. Add User Story 2 → Test independently → Deploy/Demo
4. Add User Story 3 → Test independently → Deploy/Demo
5. Each story adds value without breaking previous stories
### Parallel Team Strategy
With multiple developers:
1. Team completes Setup + Foundational together
2. Once Foundational is done:
- Developer A: User Story 1
- Developer B: User Story 2
- Developer C: User Story 3
3. Stories complete and integrate independently
---
## Notes
- [P] tasks = different files, no dependencies
- [Story] label maps task to specific user story for traceability
- Each user story should be independently completable and testable
- Verify tests fail before implementing
- Commit after each task or logical group
- Stop at any checkpoint to validate story independently
- Avoid: vague tasks, same file conflicts, cross-story dependencies that break independence

View File

@@ -2,48 +2,57 @@
## Endpoints ## Endpoints
### GET /api/migration/dashboards ### 1. List Dashboards
**Method**: `GET`
**Path**: `/api/environments/{env_id}/dashboards`
**Purpose**: Fetch all dashboards from the specified environment for the grid.
Fetch a list of dashboards from the specified source environment. **Request Parameters**:
- `env_id` (path): The ID of the environment to fetch from.
**Request:** **Response**:
- **Headers**: - **200 OK**:
- `x-source-env-id`: `string` (UUID of the source environment configuration) ```json
[
{
"id": 123,
"title": "Sales Dashboard",
"last_modified": "2023-10-27T10:00:00Z",
"status": "published"
},
{
"id": 124,
"title": "Draft Metrics",
"last_modified": "2023-10-26T15:30:00Z",
"status": "draft"
}
]
```
- **404 Not Found**: Environment not found.
- **500 Internal Server Error**: Superset API error.
**Response:** ## Components (Frontend)
- **Status**: `200 OK`
- **Body**: `List[Dashboard]`
```json ### DashboardGrid
[ **Props**:
{ - `dashboards`: `DashboardMetadata[]` - List of dashboards to display.
"id": 101, - `selectedIds`: `number[]` - IDs of currently selected dashboards.
"title": "Sales Overview",
"changed_on": "2023-10-27T14:30:00Z",
"published": true,
"url": "/superset/dashboard/sales-overview/"
},
{
"id": 102,
"title": "Marketing Draft",
"changed_on": "2023-10-26T09:15:00Z",
"published": false,
"url": "/superset/dashboard/marketing-draft/"
}
]
```
**Errors:** **Events**:
- `400 Bad Request`: Missing environment ID header. - `selectionChanged`: Emitted when selection changes. Payload: `number[]` (new list of selected IDs).
- `404 Not Found`: Environment configuration not found.
- `502 Bad Gateway`: Error communicating with Superset.
## Python Definitions **State**:
- `filterText`: string - Current filter text.
- `currentPage`: number - Current page index (0-based).
- `pageSize`: number - Items per page (default 20).
- `sortColumn`: string - 'title' | 'last_modified' | 'status'.
- `sortDirection`: 'asc' | 'desc'.
```python ## Superset Client Extension
# [DEF:backend.src.api.routes.migration.get_dashboards:Function]
# @PURPOSE: Fetch dashboards from the specified source environment. ### `get_dashboards_summary`
# @PRE: Header 'x-source-env-id' must be a valid environment UUID. **Signature**: `def get_dashboards_summary(self) -> List[Dict]`
# @POST: Returns a list of Dashboard models with id, title, changed_on, and published status. **Purpose**: Fetches dashboard metadata optimized for the grid.
# @PARAM: source_env_id (str) - UUID of the source environment. **Implementation Detail**:
# @RETURN: List[DashboardModel] - Calls `GET /api/v1/dashboard/` with query params `q=(columns:!(id,dashboard_title,changed_on_utc,published))`.
- Maps response fields to `DashboardMetadata` schema.

View File

@@ -2,37 +2,24 @@
## Entities ## Entities
### Dashboard ### DashboardMetadata
Represents a Superset dashboard with extended metadata for migration selection. **Source**: Superset API (`/api/v1/dashboard/`)
**Purpose**: Represents a dashboard available for migration.
| Field | Type | Description | Source | | Field | Type | Description | Source Mapping |
|-------|------|-------------|--------| |-------|------|-------------|----------------|
| `id` | `int` | Unique identifier | Superset API | | `id` | Integer | Unique identifier | `id` |
| `title` | `string` | Display name of the dashboard | Superset API (`dashboard_title`) | | `title` | String | Display name of the dashboard | `dashboard_title` |
| `changed_on` | `datetime` | Last modification timestamp (UTC) | Superset API (`changed_on_utc`) | | `last_modified` | String (ISO 8601) | Timestamp of last modification | `changed_on_utc` |
| `published` | `boolean` | Publication status (True=Published, False=Draft) | Superset API | | `status` | Enum ('published', 'draft') | Publication status | `published` (boolean) -> 'published'/'draft' |
| `url` | `string` | Link to the dashboard (optional, for preview) | Superset API (`url`) |
## Value Objects
### DashboardSelection ### DashboardSelection
State of the user's selection in the grid. **Purpose**: Represents the user's selection of dashboards to migrate.
| Field | Type | Description | | Field | Type | Description |
|-------|------|-------------| |-------|------|-------------|
| `selected_ids` | `Set<int>` | IDs of selected dashboards | | `selected_ids` | List[Integer] | List of dashboard IDs selected for migration |
| `is_all_selected` | `boolean` | Helper for "Select All" logic (optional) | | `source_env_id` | String | ID of the source environment |
| `target_env_id` | String | ID of the target environment |
## Component State (Frontend)
### DashboardGrid
State managed within the Svelte component.
| State | Type | Description |
|-------|------|-------------|
| `dashboards` | `Array<Dashboard>` | Full list of fetched dashboards |
| `filtered_dashboards` | `Array<Dashboard>` | List after applying text filter |
| `paginated_dashboards` | `Array<Dashboard>` | Slice of filtered list for current view |
| `filter_text` | `string` | Current search query |
| `sort_by` | `string` | Column key to sort by (`title`, `changed_on`, `published`) |
| `sort_asc` | `boolean` | Sort direction |
| `page` | `int` | Current page number (0-indexed) |
| `page_size` | `int` | Items per page (default 20) |

View File

@@ -12,24 +12,25 @@
## Technical Context ## Technical Context
**Language/Version**: Python 3.9+ (Backend), Node.js 18+ (Frontend) **Language/Version**: Python 3.9+ (Backend), Node.js 18+ (Frontend)
**Primary Dependencies**: FastAPI, SvelteKit, Tailwind CSS **Primary Dependencies**: FastAPI, SvelteKit, Tailwind CSS, Pydantic, Superset API
**Storage**: N/A (Superset API integration) **Storage**: N/A (Superset API integration - read-only for metadata)
**Testing**: pytest (Backend), vitest (Frontend) **Testing**: pytest (Backend), vitest (Frontend - inferred)
**Target Platform**: Web Browser, Linux Server **Target Platform**: Linux server / Containerized
**Project Type**: Web application **Project Type**: web application (Backend + Frontend)
**Performance Goals**: Filtering < 200ms **Performance Goals**: Client-side filtering < 200ms for 100+ items
**Constraints**: Pagination for large datasets **Constraints**: Must handle large lists via pagination (Client-side). Spec says "Client-side (Fetch all, filter locally)" and "Pagination (e.g., 20 per page)". *RESOLVED: Fetch all, paginate locally.*
**Scale/Scope**: < 1000 dashboards typical **Scale/Scope**: ~100s of dashboards per environment.
## Constitution Check ## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- [x] **I. Causal Validity**: Contracts (`data-model.md`, `contracts/api.md`) defined before implementation. - [x] **Causal Validity**: Contracts (API/Data Model) defined before implementation.
- [x] **II. Immutability**: No core architecture changes. - [x] **Immutability**: Module headers (`[DEF]`) preserved/added.
- [x] **III. Semantic Format**: `[DEF]` syntax used in contracts. - [x] **Semantic Format**: All new code uses `[DEF]` anchors and metadata.
- [x] **IV. DbC**: Pre/Post conditions defined in contracts. - [x] **Fractal Complexity**: New components (Grid) kept modular; `SupersetClient` extensions are small methods.
- [x] **V. Belief State**: Logging standards acknowledged.
**Status**: PASSED
## Project Structure ## Project Structure
@@ -46,51 +47,33 @@ specs/[###-feature]/
``` ```
### Source Code (repository root) ### Source Code (repository root)
<!--
ACTION REQUIRED: Replace the placeholder tree below with the concrete layout
for this feature. Delete unused options and expand the chosen structure with
real paths (e.g., apps/admin, packages/something). The delivered plan must
not include Option labels.
-->
```text ```text
# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT)
src/
├── models/
├── services/
├── cli/
└── lib/
tests/
├── contract/
├── integration/
└── unit/
# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected)
backend/ backend/
├── src/ ├── src/
│ ├── models/ │ ├── api/
├── services/ │ └── routes/
└── api/ │ └── environments.py # Update to support dashboard fetching
│ ├── core/
│ │ └── superset_client.py # Update to fetch extended dashboard metadata
│ └── models/
│ └── dashboard.py # New model for Dashboard metadata
└── tests/ └── tests/
└── test_superset_client.py
frontend/ frontend/
├── src/ ├── src/
│ ├── components/ │ ├── components/
│ ├── pages/ │ ├── DashboardGrid.svelte # New component
│ └── services/ │ └── Pagination.svelte # New component (if not exists)
└── tests/ │ ├── routes/
│ │ └── migration/
# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) │ │ └── +page.svelte # Update to use DashboardGrid
api/ │ └── types/
└── [same as backend above] │ └── dashboard.ts # New type definitions
ios/ or android/
└── [platform-specific structure: feature modules, UI flows, platform tests]
``` ```
**Structure Decision**: [Document the selected structure and reference the real **Structure Decision**: Standard Web Application structure. Backend updates to `SupersetClient` and API routes to serve dashboard metadata. Frontend updates to include a new `DashboardGrid` component and integrate it into the migration flow.
directories captured above]
## Complexity Tracking ## Complexity Tracking

View File

@@ -1,23 +1,31 @@
# Quickstart: Migration Dashboard Grid # Quickstart: Migration Dashboard Grid
## Overview ## Prerequisites
The Migration Dashboard Grid allows users to select dashboards for migration using a rich interface with filtering, sorting, and status indicators. - Backend running (`uvicorn backend.src.app:app --reload`)
- Frontend running (`npm run dev`)
- Superset instance accessible and configured in `config.yaml`
## Usage ## Steps to Verify
1. **Navigate to Migration Page**: Go to the Migration section in the app. 1. **Navigate to Migration Page**:
2. **Select Source Environment**: Choose the Superset environment you want to migrate from. - Open browser to `http://localhost:5173/migration`
3. **View Dashboards**: The grid will automatically load the list of available dashboards. - Select a Source Environment from the dropdown.
- **Filter**: Type in the "Search dashboards..." box to filter by name.
- **Sort**: Click on column headers (Name, Last Modified, Status) to sort.
- **Paginate**: Use the "Next" and "Previous" buttons to navigate through pages.
4. **Select Dashboards**:
- Click individual checkboxes to select specific dashboards.
- Click the "Select All" checkbox in the header to select **all** dashboards matching the current filter (even those on other pages).
5. **Proceed**: Once selection is complete, click "Next" to configure mappings.
## Troubleshooting 2. **Verify Dashboard Grid**:
- The grid should appear below the environment selectors.
- It should list dashboards with columns: Title, Last Modified, Status.
- Status pills should be green (Published) or gray (Draft).
- **"No dashboards found"**: Ensure the source environment is correctly configured and accessible. 3. **Test Filtering**:
- **Slow loading**: If the environment has thousands of dashboards, the initial load might take a few seconds. - Type in the "Search dashboards..." input.
- **Status "Unknown"**: If the API fails to return publication status, it will default to a neutral state. - The list should filter instantly (client-side).
4. **Test Pagination**:
- If >20 dashboards, check pagination controls at the bottom.
- Navigate to next page.
5. **Test Selection**:
- Select a few dashboards.
- Change filter (hide selected).
- Clear filter -> Selection should persist.
- Click "Select All" -> Should select all matching current filter.

View File

@@ -1,66 +1,48 @@
# Research: Migration Dashboard Grid # 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**: ### 2. Superset API for Dashboard Metadata
- The `SupersetClient.get_dashboards` method in `superset_tool/client.py` already exists. **Context**: Need to fetch `title`, `changed_on`, `published`.
- It fetches the following columns by default: `["slug", "id", "changed_on_utc", "dashboard_title", "published"]`. **Research**:
- This covers all requirements: - Superset API endpoint: `/api/v1/dashboard/`
- Name -> `dashboard_title` - Standard response includes `result` array with `dashboard_title`, `changed_on_utc`, `published`.
- Last Modified -> `changed_on_utc` - **Decision**: Use `GET /api/v1/dashboard/` with `q` parameter to select specific columns to minimize payload.
- Status -> `published` - Columns: `id`, `dashboard_title`, `changed_on_utc`, `published`.
- Pagination is handled internally by `_fetch_all_pages`, so the client fetches *all* dashboards.
- **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**: ### Architecture
1. **Server-side pagination**: Fetch page by page. Good for huge datasets (>10k). - **Backend**:
2. **Client-side pagination**: Fetch all, filter/sort/paginate in browser. Good for typical datasets (<1k) and simplifies "Select All" logic. - `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**: ### UX/UI
- Spec explicitly requests "Client-side (Fetch all, filter locally)". - **Status Column**: Badge (Green for Published, Gray for Draft).
- 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). - **Selection**: Checkbox in first column.
- Existing `MappingTable.svelte` is too simple (no sorting/pagination). - **Pagination**: Simple "Prev 1 of 5 Next" controls at bottom.
- **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).

View File

@@ -13,6 +13,11 @@
- Q: How should the grid handle large lists of dashboards (e.g., >50)? → A: **Pagination** (e.g., 20 per page). - Q: How should the grid handle large lists of dashboards (e.g., >50)? → A: **Pagination** (e.g., 20 per page).
- Q: Does the "Select All" checkbox select only the currently visible page of dashboards, or all dashboards that match the current filter? → A: **All matching filter** (Selects all filtered results, not just the visible page). - Q: Does the "Select All" checkbox select only the currently visible page of dashboards, or all dashboards that match the current filter? → A: **All matching filter** (Selects all filtered results, not just the visible page).
- Q: What should happen if the user changes the filter while some items are already selected? → A: **Preserve selection** (Selected items remain selected even if hidden by new filter). - Q: What should happen if the user changes the filter while some items are already selected? → A: **Preserve selection** (Selected items remain selected even if hidden by new filter).
- Q: What should be the default sort order when the dashboard grid first loads? → A: **Last Modified Date (Newest first)**.
- Q: Should the grid include an "Owners" column to help distinguish dashboards with the same name? → A: **Yes, include Owners**.
- Q: How should the "Owners" column display multiple owners? → A: **Show first owner + count (e.g., "admin + 2") with tooltip**.
- Q: How should the "Status" (Draft/Published) be visually represented in the grid? → A: **Colored Badges/Chips**.
- Q: Should the grid include a "Preview" action (e.g., link to open the dashboard in Superset)? → A: **Yes, open in new tab**.
## User Scenarios & Testing *(mandatory)* ## User Scenarios & Testing *(mandatory)*
@@ -50,6 +55,7 @@ As a migration engineer, I want to select dashboards from a detailed grid view t
- Name (Dashboard Title) - Name (Dashboard Title)
- Last Modified (Date/Time) - Last Modified (Date/Time)
- Status (Published/Draft) - Status (Published/Draft)
- Owners (List of owner names)
- **FR-004**: The UI MUST provide a text filter input that filters the grid rows by Dashboard Name in real-time using client-side logic (fetching all dashboards once). - **FR-004**: The UI MUST provide a text filter input that filters the grid rows by Dashboard Name in real-time using client-side logic (fetching all dashboards once).
- **FR-005**: The grid MUST support multi-row selection to allow migrating batches of dashboards. - **FR-005**: The grid MUST support multi-row selection to allow migrating batches of dashboards.
- **FR-006**: The selection state MUST be passed to the migration execution logic when the user initiates the migration. - **FR-006**: The selection state MUST be passed to the migration execution logic when the user initiates the migration.
@@ -64,6 +70,7 @@ As a migration engineer, I want to select dashboards from a detailed grid view t
- `title`: Display name. - `title`: Display name.
- `changed_on`: Timestamp of last edit. - `changed_on`: Timestamp of last edit.
- `is_published`: Boolean status. - `is_published`: Boolean status.
- `owners`: List of owner objects/names.
## Success Criteria *(mandatory)* ## Success Criteria *(mandatory)*

View File

@@ -0,0 +1,29 @@
---
description: "Architecture tasks for Migration Plugin Dashboard Grid"
---
# Architecture Tasks: Migration Plugin Dashboard Grid
**Role**: Architect Agent
**Goal**: Define the "What" and "Why" (Contracts, Scaffolding, Models) before implementation.
## Phase 1: Setup & Models
- [ ] A001 Define contracts/scaffolding for migration route in backend/src/api/routes/migration.py
- [ ] A002 Define contracts/scaffolding for Dashboard model in backend/src/models/dashboard.py
## Phase 2: User Story 1 - Advanced Dashboard Selection
- [ ] A003 [US1] Define contracts/scaffolding for SupersetClient extensions in backend/src/core/superset_client.py
- [ ] A004 [US1] Define contracts/scaffolding for GET /api/migration/dashboards endpoint in backend/src/api/routes/migration.py
- [ ] A005 [US1] Define contracts/scaffolding for DashboardGrid component in frontend/src/components/DashboardGrid.svelte
- [ ] A006 [US1] Define contracts/scaffolding for migration page integration in frontend/src/routes/migration/+page.svelte
- [ ] A007 [US1] Define contracts/scaffolding for POST /api/migration/execute endpoint in backend/src/api/routes/migration.py
## Handover Checklist
- [ ] All new files created with `[DEF]` anchors
- [ ] All functions/classes have `@PURPOSE`, `@PRE`, `@POST` tags
- [ ] No "naked code" (logic outside of anchors)
- [ ] `tasks-dev.md` is ready for the Developer Agent

View File

@@ -0,0 +1,34 @@
---
description: "Developer tasks for Migration Plugin Dashboard Grid"
---
# Developer Tasks: Migration Plugin Dashboard Grid
**Role**: Developer Agent
**Goal**: Implement the "How" (Logic, State, Error Handling) inside the defined contracts.
## Phase 1: Setup & Models
- [ ] D001 Implement logic for migration route in backend/src/api/routes/migration.py
- [ ] D002 Register migration router in backend/src/app.py
- [ ] D003 Export migration router in backend/src/api/routes/__init__.py
- [ ] D004 Implement logic for Dashboard model in backend/src/models/dashboard.py
## Phase 2: User Story 1 - Advanced Dashboard Selection
- [ ] D005 [P] [US1] Implement logic for SupersetClient extensions in backend/src/core/superset_client.py
- [ ] D006 [US1] Implement logic for GET /api/migration/dashboards endpoint in backend/src/api/routes/migration.py
- [ ] D007 [US1] Implement structure and styles for DashboardGrid component in frontend/src/components/DashboardGrid.svelte
- [ ] D008 [US1] Implement data fetching and state management in frontend/src/components/DashboardGrid.svelte
- [ ] D009 [US1] Implement client-side filtering logic in frontend/src/components/DashboardGrid.svelte
- [ ] D010 [US1] Implement pagination logic in frontend/src/components/DashboardGrid.svelte
- [ ] D011 [US1] Implement selection logic (single and Select All) in frontend/src/components/DashboardGrid.svelte
- [ ] D012 [US1] Integrate DashboardGrid and connect selection to submission in frontend/src/routes/migration/+page.svelte
- [ ] D013 [US1] Implement logic for POST /api/migration/execute endpoint in backend/src/api/routes/migration.py
- [ ] D014 [US1] Verify semantic compliance and belief state logging
## Polish & Quality Assurance
- [ ] D015 Verify error handling and empty states in frontend/src/components/DashboardGrid.svelte
- [ ] D016 Ensure consistent styling with Tailwind CSS in frontend/src/components/DashboardGrid.svelte

View File

@@ -1,32 +0,0 @@
# Tasks: Migration Plugin Dashboard Grid
## Phase 1: Setup
- [ ] T001 Create migration route module in backend/src/api/routes/migration.py
- [ ] T002 Register migration router in backend/src/app.py
- [ ] T003 Export migration router in backend/src/api/routes/__init__.py
## Phase 2: Foundational
- [ ] T004 Create Dashboard model in backend/src/models/dashboard.py
## Phase 3: User Story 1 - Advanced Dashboard Selection
- [ ] T005 [P] [US1] Extend SupersetClient to fetch dashboards with metadata (handling missing fields) in backend/src/core/superset_client.py
- [ ] T006 [US1] Implement GET /api/migration/dashboards endpoint in backend/src/api/routes/migration.py
- [ ] T007 [P] [US1] Create DashboardGrid component structure in frontend/src/components/DashboardGrid.svelte
- [ ] T008 [US1] Implement data fetching and state management in frontend/src/components/DashboardGrid.svelte
- [ ] T009 [US1] Implement client-side filtering logic in frontend/src/components/DashboardGrid.svelte
- [ ] T010 [US1] Implement pagination logic in frontend/src/components/DashboardGrid.svelte
- [ ] T011 [US1] Implement selection logic (single and Select All) in frontend/src/components/DashboardGrid.svelte
- [ ] T012 [US1] Integrate DashboardGrid into migration page and connect selection to submission in frontend/src/routes/migration/+page.svelte
- [ ] T013 [US1] Implement POST /api/migration/execute endpoint to accept selected dashboard IDs in backend/src/api/routes/migration.py
## Phase 4: Polish
- [ ] T014 Verify error handling and empty states in frontend/src/components/DashboardGrid.svelte
- [ ] T015 Ensure consistent styling with Tailwind CSS in frontend/src/components/DashboardGrid.svelte
## Dependencies
- US1 depends on T004, T005, T006
## Implementation Strategy
- Implement backend support first (Models -> Client -> API)
- Implement frontend component with mock data then connect API
- Integrate into main page