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)
- 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)
- 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)
@@ -31,9 +33,9 @@ cd src; pytest; ruff check .
Python 3.9+ (Backend), Node.js 18+ (Frontend Build): Follow standard conventions
## 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 [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 -->

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:
- .specify/templates/plan-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
@@ -68,11 +69,24 @@ Every `.svelte` file must start with a Component definition header (`[DEF:Compon
- `@INVARIANT`: Immutable UI/State rules.
## Generation Workflow
The development process follows a strict sequence:
1. **Analyze Request**: Identify target module and graph position.
2. **Define Structure**: Generate `[DEF]` anchors and Contracts FIRST.
3. **Implement Logic**: Write code satisfying Contracts.
4. **Validate**: If logic conflicts with Contract -> Stop -> Report Error.
The development process follows a strict sequence enforced by Agent Roles:
### 1. Architecture Phase (Mode: `tech-lead`)
**Input**: `tasks-arch.md`
**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
This Constitution establishes the "Semantic Code Generation Protocol" as the supreme law of this repository.

View File

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

View File

@@ -143,7 +143,9 @@ HAS_GIT='$has_git_repo'
FEATURE_DIR='$feature_dir'
FEATURE_SPEC='$feature_dir/spec.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'
DATA_MODEL='$feature_dir/data-model.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
### 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:**
- **Headers**:
- `x-source-env-id`: `string` (UUID of the source environment configuration)
**Response**:
- **200 OK**:
```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:**
- **Status**: `200 OK`
- **Body**: `List[Dashboard]`
## Components (Frontend)
```json
[
{
"id": 101,
"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/"
}
]
```
### DashboardGrid
**Props**:
- `dashboards`: `DashboardMetadata[]` - List of dashboards to display.
- `selectedIds`: `number[]` - IDs of currently selected dashboards.
**Errors:**
- `400 Bad Request`: Missing environment ID header.
- `404 Not Found`: Environment configuration not found.
- `502 Bad Gateway`: Error communicating with Superset.
**Events**:
- `selectionChanged`: Emitted when selection changes. Payload: `number[]` (new list of selected IDs).
## 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
# [DEF:backend.src.api.routes.migration.get_dashboards:Function]
# @PURPOSE: Fetch dashboards from the specified source environment.
# @PRE: Header 'x-source-env-id' must be a valid environment UUID.
# @POST: Returns a list of Dashboard models with id, title, changed_on, and published status.
# @PARAM: source_env_id (str) - UUID of the source environment.
# @RETURN: List[DashboardModel]
## Superset Client Extension
### `get_dashboards_summary`
**Signature**: `def get_dashboards_summary(self) -> List[Dict]`
**Purpose**: Fetches dashboard metadata optimized for the grid.
**Implementation Detail**:
- 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
### Dashboard
Represents a Superset dashboard with extended metadata for migration selection.
### DashboardMetadata
**Source**: Superset API (`/api/v1/dashboard/`)
**Purpose**: Represents a dashboard available for migration.
| Field | Type | Description | Source |
|-------|------|-------------|--------|
| `id` | `int` | Unique identifier | Superset API |
| `title` | `string` | Display name of the dashboard | Superset API (`dashboard_title`) |
| `changed_on` | `datetime` | Last modification timestamp (UTC) | Superset API (`changed_on_utc`) |
| `published` | `boolean` | Publication status (True=Published, False=Draft) | Superset API |
| `url` | `string` | Link to the dashboard (optional, for preview) | Superset API (`url`) |
| Field | Type | Description | Source Mapping |
|-------|------|-------------|----------------|
| `id` | Integer | Unique identifier | `id` |
| `title` | String | Display name of the dashboard | `dashboard_title` |
| `last_modified` | String (ISO 8601) | Timestamp of last modification | `changed_on_utc` |
| `status` | Enum ('published', 'draft') | Publication status | `published` (boolean) -> 'published'/'draft' |
## Value Objects
### DashboardSelection
State of the user's selection in the grid.
**Purpose**: Represents the user's selection of dashboards to migrate.
| Field | Type | Description |
|-------|------|-------------|
| `selected_ids` | `Set<int>` | IDs of selected dashboards |
| `is_all_selected` | `boolean` | Helper for "Select All" logic (optional) |
## 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) |
| `selected_ids` | List[Integer] | List of dashboard IDs selected for migration |
| `source_env_id` | String | ID of the source environment |
| `target_env_id` | String | ID of the target environment |

View File

@@ -12,24 +12,25 @@
## Technical Context
**Language/Version**: Python 3.9+ (Backend), Node.js 18+ (Frontend)
**Primary Dependencies**: FastAPI, SvelteKit, Tailwind CSS
**Storage**: N/A (Superset API integration)
**Testing**: pytest (Backend), vitest (Frontend)
**Target Platform**: Web Browser, Linux Server
**Project Type**: Web application
**Performance Goals**: Filtering < 200ms
**Constraints**: Pagination for large datasets
**Scale/Scope**: < 1000 dashboards typical
**Primary Dependencies**: FastAPI, SvelteKit, Tailwind CSS, Pydantic, Superset API
**Storage**: N/A (Superset API integration - read-only for metadata)
**Testing**: pytest (Backend), vitest (Frontend - inferred)
**Target Platform**: Linux server / Containerized
**Project Type**: web application (Backend + Frontend)
**Performance Goals**: Client-side filtering < 200ms for 100+ items
**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**: ~100s of dashboards per environment.
## Constitution Check
*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] **II. Immutability**: No core architecture changes.
- [x] **III. Semantic Format**: `[DEF]` syntax used in contracts.
- [x] **IV. DbC**: Pre/Post conditions defined in contracts.
- [x] **V. Belief State**: Logging standards acknowledged.
- [x] **Causal Validity**: Contracts (API/Data Model) defined before implementation.
- [x] **Immutability**: Module headers (`[DEF]`) preserved/added.
- [x] **Semantic Format**: All new code uses `[DEF]` anchors and metadata.
- [x] **Fractal Complexity**: New components (Grid) kept modular; `SupersetClient` extensions are small methods.
**Status**: PASSED
## Project Structure
@@ -46,51 +47,33 @@ specs/[###-feature]/
```
### 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
# [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/
├── src/
│ ├── models/
├── services/
└── api/
│ ├── api/
│ └── routes/
│ └── 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/
└── test_superset_client.py
frontend/
├── src/
│ ├── components/
│ ├── pages/
│ └── services/
└── tests/
# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected)
api/
└── [same as backend above]
ios/ or android/
└── [platform-specific structure: feature modules, UI flows, platform tests]
│ ├── DashboardGrid.svelte # New component
│ └── Pagination.svelte # New component (if not exists)
│ ├── routes/
│ │ └── migration/
│ │ └── +page.svelte # Update to use DashboardGrid
│ └── types/
│ └── dashboard.ts # New type definitions
```
**Structure Decision**: [Document the selected structure and reference the real
directories captured above]
**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.
## Complexity Tracking

View File

@@ -1,23 +1,31 @@
# Quickstart: Migration Dashboard Grid
## Overview
The Migration Dashboard Grid allows users to select dashboards for migration using a rich interface with filtering, sorting, and status indicators.
## Prerequisites
- 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.
2. **Select Source Environment**: Choose the Superset environment you want to migrate from.
3. **View Dashboards**: The grid will automatically load the list of available dashboards.
- **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.
1. **Navigate to Migration Page**:
- Open browser to `http://localhost:5173/migration`
- Select a Source Environment from the dropdown.
## 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.
- **Slow loading**: If the environment has thousands of dashboards, the initial load might take a few seconds.
- **Status "Unknown"**: If the API fails to return publication status, it will default to a neutral state.
3. **Test Filtering**:
- Type in the "Search dashboards..." input.
- 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
## 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.

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: 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 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)*
@@ -50,6 +55,7 @@ As a migration engineer, I want to select dashboards from a detailed grid view t
- Name (Dashboard Title)
- Last Modified (Date/Time)
- 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-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.
@@ -64,6 +70,7 @@ As a migration engineer, I want to select dashboards from a detailed grid view t
- `title`: Display name.
- `changed_on`: Timestamp of last edit.
- `is_published`: Boolean status.
- `owners`: List of owner objects/names.
## 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