tech_lead / coder 2roles
This commit is contained in:
@@ -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
27
.kilocodemodes
Normal 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
|
||||||
@@ -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.
|
||||||
|
|||||||
@@ -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,12 +113,19 @@ 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
|
||||||
|
echo "Run /speckit.tasks first to create the task lists." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
# Build list of available documents
|
||||||
docs=()
|
docs=()
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
35
.specify/templates/tasks-arch-template.md
Normal file
35
.specify/templates/tasks-arch-template.md
Normal 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
|
||||||
35
.specify/templates/tasks-dev-template.md
Normal file
35
.specify/templates/tasks-dev-template.md
Normal 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
|
||||||
@@ -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
|
|
||||||
@@ -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:**
|
|
||||||
- **Headers**:
|
|
||||||
- `x-source-env-id`: `string` (UUID of the source environment configuration)
|
|
||||||
|
|
||||||
**Response:**
|
|
||||||
- **Status**: `200 OK`
|
|
||||||
- **Body**: `List[Dashboard]`
|
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
- **200 OK**:
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id": 101,
|
"id": 123,
|
||||||
"title": "Sales Overview",
|
"title": "Sales Dashboard",
|
||||||
"changed_on": "2023-10-27T14:30:00Z",
|
"last_modified": "2023-10-27T10:00:00Z",
|
||||||
"published": true,
|
"status": "published"
|
||||||
"url": "/superset/dashboard/sales-overview/"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 102,
|
"id": 124,
|
||||||
"title": "Marketing Draft",
|
"title": "Draft Metrics",
|
||||||
"changed_on": "2023-10-26T09:15:00Z",
|
"last_modified": "2023-10-26T15:30:00Z",
|
||||||
"published": false,
|
"status": "draft"
|
||||||
"url": "/superset/dashboard/marketing-draft/"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
- **404 Not Found**: Environment not found.
|
||||||
|
- **500 Internal Server Error**: Superset API error.
|
||||||
|
|
||||||
**Errors:**
|
## Components (Frontend)
|
||||||
- `400 Bad Request`: Missing environment ID header.
|
|
||||||
- `404 Not Found`: Environment configuration not found.
|
|
||||||
- `502 Bad Gateway`: Error communicating with Superset.
|
|
||||||
|
|
||||||
## Python Definitions
|
### DashboardGrid
|
||||||
|
**Props**:
|
||||||
|
- `dashboards`: `DashboardMetadata[]` - List of dashboards to display.
|
||||||
|
- `selectedIds`: `number[]` - IDs of currently selected dashboards.
|
||||||
|
|
||||||
```python
|
**Events**:
|
||||||
# [DEF:backend.src.api.routes.migration.get_dashboards:Function]
|
- `selectionChanged`: Emitted when selection changes. Payload: `number[]` (new list of selected IDs).
|
||||||
# @PURPOSE: Fetch dashboards from the specified source environment.
|
|
||||||
# @PRE: Header 'x-source-env-id' must be a valid environment UUID.
|
**State**:
|
||||||
# @POST: Returns a list of Dashboard models with id, title, changed_on, and published status.
|
- `filterText`: string - Current filter text.
|
||||||
# @PARAM: source_env_id (str) - UUID of the source environment.
|
- `currentPage`: number - Current page index (0-based).
|
||||||
# @RETURN: List[DashboardModel]
|
- `pageSize`: number - Items per page (default 20).
|
||||||
|
- `sortColumn`: string - 'title' | 'last_modified' | 'status'.
|
||||||
|
- `sortDirection`: 'asc' | 'desc'.
|
||||||
|
|
||||||
|
## 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.
|
||||||
@@ -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) |
|
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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).
|
|
||||||
|
|||||||
@@ -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)*
|
||||||
|
|
||||||
|
|||||||
29
specs/007-migration-dashboard-grid/tasks-arch.md
Normal file
29
specs/007-migration-dashboard-grid/tasks-arch.md
Normal 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
|
||||||
34
specs/007-migration-dashboard-grid/tasks-dev.md
Normal file
34
specs/007-migration-dashboard-grid/tasks-dev.md
Normal 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
|
||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user