diff --git a/.kilocode/workflows/speckit.implement.md b/.kilocode/workflows/speckit.implement.md
index d2e2a47..1ad3e41 100644
--- a/.kilocode/workflows/speckit.implement.md
+++ b/.kilocode/workflows/speckit.implement.md
@@ -117,7 +117,8 @@ You **MUST** consider the user input before proceeding (if not empty).
- **Validation checkpoints**: Verify each phase completion before proceeding
7. Implementation execution rules:
- - **Strict Adherence**: Apply `semantic_protocol.md` rules - every file must start with [DEF] header, include @TIER, and define contracts
+ - **Strict Adherence**: Apply `semantic_protocol.md` rules - every file must start with [DEF] header, include @TIER, and define contracts.
+ - **CRITICAL Contracts**: If a task description contains a contract summary (e.g., `CRITICAL: PRE: ..., POST: ...`), these constraints are **MANDATORY** and must be strictly implemented in the code using guards/assertions (if applicable per protocol).
- **Setup first**: Initialize project structure, dependencies, configuration
- **Tests before code**: If you need to write tests for contracts, entities, and integration scenarios
- **Core development**: Implement models, services, CLI commands, endpoints
diff --git a/.kilocode/workflows/speckit.tasks.md b/.kilocode/workflows/speckit.tasks.md
index a59deca..fa98caa 100644
--- a/.kilocode/workflows/speckit.tasks.md
+++ b/.kilocode/workflows/speckit.tasks.md
@@ -119,7 +119,10 @@ Every task MUST strictly follow this format:
- If tests requested: Tests specific to that story
- Mark story dependencies (most stories should be independent)
-2. **From Contracts**:
+2. **From Contracts (CRITICAL TIER)**:
+ - Identify components marked as `@TIER: CRITICAL` in `contracts/modules.md`.
+ - For these components, **MUST** append the summary of `@PRE`, `@POST`, and `@UX_STATE` contracts directly to the task description.
+ - Example: `- [ ] T005 [P] [US1] Implement Auth (CRITICAL: PRE: token exists, POST: returns User) in src/auth.py`
- Map each contract/endpoint → to the user story it serves
- If tests requested: Each contract → contract test task [P] before implementation in that story's phase
diff --git a/specs/019-superset-ux-redesign/contracts/modules.md b/specs/019-superset-ux-redesign/contracts/modules.md
new file mode 100644
index 0000000..3607368
--- /dev/null
+++ b/specs/019-superset-ux-redesign/contracts/modules.md
@@ -0,0 +1,612 @@
+# Module Contracts: Superset-Style UX Redesign
+
+**Feature**: 019-superset-ux-redesign
+**Date**: 2026-02-10
+**Semantic Protocol Version**: GRACE-Poly (UX Edition)
+
+---
+
+## Overview
+
+This document defines module-level contracts following the Semantic Protocol. Each module is annotated with `[DEF]` anchors, `@TIER` classification, and full Design-by-Contract (`@PRE`, `@POST`, `@UX_STATE`) specifications.
+
+---
+
+## Frontend Modules
+
+### 1. SidebarStore
+
+```javascript
+// [DEF:SidebarStore:Store]
+// @TIER: STANDARD
+// @SEMANTICS: navigation, state-management, persistence
+// @PURPOSE: Manage sidebar visibility, active navigation state, and mobile overlay behavior
+// @LAYER: UI
+// @RELATION: DEPENDS_ON -> localStorage
+// @RELATION: BINDS_TO -> +layout.svelte
+// @INVARIANT: isExpanded state is always synced with localStorage key 'sidebar_state'
+
+// @UX_STATE: Idle -> Sidebar visible with current category highlighted
+// @UX_STATE: Collapsed -> Icons-only mode, tooltips on hover
+// @UX_STATE: MobileOverlay -> Full-screen overlay with backdrop, close on outside click
+// @UX_STATE: Toggling -> CSS transition animation (200ms ease-in-out)
+
+// @PRE: localStorage is available and accessible
+// @PRE: defaultValue has valid shape { isExpanded: boolean, activeCategory: string, activeItem: string, isMobileOpen: boolean }
+
+// @POST: Store always emits valid SidebarState shape
+// @POST: localStorage 'sidebar_state' is updated on every state change
+// @POST: isMobileOpen is reset to false when screen size changes to desktop (>=768px)
+
+// @SIDE_EFFECT: Writes to localStorage
+// @SIDE_EFFECT: Triggers CSS transitions via class binding
+
+export const sidebarStore = persistentStore('sidebar_state', {
+ isExpanded: true,
+ activeCategory: 'dashboards',
+ activeItem: '/dashboards',
+ isMobileOpen: false
+});
+
+export function toggleSidebar() { /* ... */ }
+export function setActiveCategory(category) { /* ... */ }
+export function setActiveItem(path) { /* ... */ }
+export function openMobileSidebar() { /* ... */ }
+export function closeMobileSidebar() { /* ... */ }
+// [/DEF:SidebarStore]
+```
+
+---
+
+### 2. TaskDrawerStore
+
+```javascript
+// [DEF:TaskDrawerStore:Store]
+// @TIER: CRITICAL
+// @SEMANTICS: task-management, resource-mapping, real-time, drawer-state
+// @PURPOSE: Manage Task Drawer visibility, active task tracking, and resource-to-task associations
+// @LAYER: UI
+// @RELATION: DEPENDS_ON -> WebSocket connection
+// @RELATION: DEPENDS_ON -> task:status events
+// @RELATION: DEPENDS_ON -> task:log events
+// @RELATION: BINDS_TO -> TaskDrawer.svelte
+// @INVARIANT: resourceTaskMap always contains valid task associations
+// @INVARIANT: When isOpen is false, activeTaskId may still reference a running task
+
+// @UX_STATE: Closed -> Drawer hidden, Activity indicator shows active count
+// @UX_STATE: Open-Loading -> Drawer visible, loading spinner for logs
+// @UX_STATE: Open-Streaming -> Drawer visible, real-time log stream
+// @UX_STATE: Open-InputRequired -> Interactive form rendered in drawer (PasswordPrompt, etc.)
+// @UX_STATE: Open-Completed -> Task finished, success/error status displayed
+
+// @UX_FEEDBACK: Toast notification when task completes while drawer is closed
+// @UX_FEEDBACK: Activity indicator badge pulses when new tasks start
+// @UX_RECOVERY: If WebSocket disconnects, show "Reconnecting..." with retry button
+
+// @PRE: WebSocket connection is established before subscribing to task events
+// @PRE: taskId passed to openDrawerForTask() is a valid UUID string
+// @PRE: resourceId in updateResourceTask() matches pattern {type}:{uuid}
+
+// @POST: After openDrawerForTask(taskId): isOpen === true && activeTaskId === taskId
+// @POST: After closeDrawer(): isOpen === false, activeTaskId unchanged
+// @POST: resourceTaskMap is updated when task:status events are received
+// @POST: When task status changes to SUCCESS|ERROR, entry remains in map for 5 minutes then auto-cleanup
+
+// @SIDE_EFFECT: Subscribes to WebSocket events
+// @SIDE_EFFECT: May trigger browser notification for task completion
+
+export const taskDrawerStore = writable({
+ isOpen: false,
+ activeTaskId: null,
+ resourceTaskMap: {} // { resourceId: { taskId, status, startedAt } }
+});
+
+export function openDrawerForTask(taskId) { /* ... */ }
+export function closeDrawer() { /* ... */ }
+export function updateResourceTask(resourceId, taskId, status) { /* ... */ }
+export function clearCompletedTasks() { /* ... */ }
+// [/DEF:TaskDrawerStore]
+```
+
+---
+
+### 3. ActivityStore
+
+```javascript
+// [DEF:ActivityStore:Store]
+// @TIER: STANDARD
+// @SEMANTICS: activity-indicator, derived-state, task-count
+// @PURPOSE: Provide reactive count of active tasks for the navbar Activity indicator
+// @LAYER: UI
+// @RELATION: DEPENDS_ON -> TaskDrawerStore
+// @RELATION: BINDS_TO -> TopNavbar.svelte
+// @INVARIANT: activeCount is always >= 0
+// @INVARIANT: activeCount equals count of RUNNING tasks in resourceTaskMap
+
+// @UX_STATE: Idle -> Badge hidden or shows "0"
+// @UX_STATE: Active-N -> Badge shows count N with pulse animation
+// @UX_STATE: Active-Many -> Badge shows "9+" when count exceeds 9
+
+// @PRE: TaskDrawerStore is initialized and emitting values
+
+// @POST: activeCount reflects exact count of tasks with status === 'RUNNING'
+// @POST: recentTasks contains last 5 tasks sorted by startedAt desc
+
+export const activityStore = derived(
+ taskDrawerStore,
+ ($drawer) => {
+ const tasks = Object.values($drawer.resourceTaskMap);
+ const activeCount = tasks.filter(t => t.status === 'RUNNING').length;
+ const recentTasks = tasks
+ .sort((a, b) => new Date(b.startedAt) - new Date(a.startedAt))
+ .slice(0, 5);
+ return { activeCount, recentTasks };
+ }
+);
+// [/DEF:ActivityStore]
+```
+
+---
+
+### 4. Sidebar Component
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+### 5. TopNavbar Component
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+### 6. TaskDrawer Component
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+### 7. DashboardHub Component
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+### 8. DatasetHub Component
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+### 9. Breadcrumbs Component
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+## Backend Modules
+
+### 10. Dashboards API
+
+```python
+# [DEF:DashboardsAPI:Module]
+# @TIER: CRITICAL
+# @SEMANTICS: rest-api, resource-fetching, git-integration
+# @PURPOSE: API endpoints for Dashboard Hub - list dashboards with metadata
+# @LAYER: Domain
+# @RELATION: DEPENDS_ON -> superset_client
+# @RELATION: DEPENDS_ON -> git_service
+# @RELATION: DEPENDS_ON -> task_manager
+# @RELATION: CALLS -> Superset API /api/v1/dashboard/
+
+# @PRE: env_id parameter is valid UUID of existing environment
+# @PRE: User has permission to read dashboards from specified environment
+
+# @POST: Response includes all dashboards accessible in environment
+# @POST: Each dashboard has git_status with branch and sync_status
+# @POST: Each dashboard has last_task with most recent task status
+# @POST: Search parameter filters by title and slug (case-insensitive)
+
+# Endpoint: GET /api/dashboards
+# Query: env_id (required), search (optional)
+# Response: { dashboards: [...] }
+
+# Endpoint: POST /api/dashboards/migrate
+# Body: { source_env_id, target_env_id, dashboard_ids, db_mappings }
+# Response: { task_id }
+
+# Endpoint: POST /api/dashboards/backup
+# Body: { env_id, dashboard_ids, schedule (optional cron) }
+# Response: { task_id }
+# [/DEF:DashboardsAPI]
+```
+
+---
+
+### 11. Datasets API
+
+```python
+# [DEF:DatasetsAPI:Module]
+# @TIER: CRITICAL
+# @SEMANTICS: rest-api, dataset-metadata, column-mapping
+# @PURPOSE: API endpoints for Dataset Hub - list datasets with mapping info
+# @LAYER: Domain
+# @RELATION: DEPENDS_ON -> superset_client
+# @RELATION: DEPENDS_ON -> mapping_service
+# @RELATION: DEPENDS_ON -> task_manager
+# @RELATION: CALLS -> Superset API /api/v1/dataset/
+
+# @PRE: env_id parameter is valid UUID of existing environment
+# @PRE: User has permission to read datasets from specified environment
+
+# @POST: Response includes all datasets accessible in environment
+# @POST: Each dataset has mapped_fields count (mapped/total)
+# @POST: Each dataset has extracted SQL table names
+# @POST: Search filters by table_name, schema, and extracted table names
+
+# Endpoint: GET /api/datasets
+# Query: env_id (required), search (optional)
+# Response: { datasets: [...] }
+
+# Endpoint: POST /api/datasets/map-columns
+# Body: { env_id, dataset_ids, source_type, connection_id or file }
+# Response: { task_id }
+
+# Endpoint: POST /api/datasets/generate-docs
+# Body: { env_id, dataset_ids, llm_provider, options }
+# Response: { task_id }
+# [/DEF:DatasetsAPI]
+```
+
+---
+
+### 12. Activity API
+
+```python
+# [DEF:ActivityAPI:Module]
+# @TIER: STANDARD
+# @SEMANTICS: rest-api, activity-summary, task-metrics
+# @PURPOSE: Provide activity summary for navbar indicator
+# @LAYER: Domain
+# @RELATION: DEPENDS_ON -> task_manager
+# @RELATION: CALLS -> task_manager.get_active_tasks()
+
+# @PRE: User is authenticated
+
+# @POST: Returns count of RUNNING tasks
+# @POST: Returns last 5 tasks sorted by started_at desc
+# @POST: Tasks include resource_name and resource_type for display
+
+# Endpoint: GET /api/activity
+# Response: { active_count: number, recent_tasks: [...] }
+# [/DEF:ActivityAPI]
+```
+
+---
+
+### 13. ResourceService
+
+```python
+# [DEF:ResourceService:Class]
+# @TIER: STANDARD
+# @SEMANTICS: service-layer, shared-logic, resource-fetching
+# @PURPOSE: Shared logic for fetching resources from Superset with caching
+# @LAYER: Domain
+# @RELATION: DEPENDS_ON -> superset_client
+# @RELATION: DEPENDS_ON -> ConfigManager
+# @INVARIANT: All methods accept env_id and resolve via ConfigManager
+
+# @PRE: env_id corresponds to valid Environment configuration
+# @PRE: ConfigManager returns valid Superset connection params
+
+# @POST: Returns normalized resource data structure
+# @POST: Handles connection errors gracefully with meaningful messages
+# @POST: Caches results for 30 seconds to reduce API load
+
+class ResourceService:
+ async def fetch_dashboards(env_id: str, search: str = None) -> list[Dashboard]: ...
+ async def fetch_datasets(env_id: str, search: str = None) -> list[Dataset]: ...
+ async def get_git_status(env_id: str, resource_id: str) -> GitStatus: ...
+ async def get_last_task(resource_type: str, resource_id: str) -> TaskSummary: ...
+# [/DEF:ResourceService]
+```
+
+---
+
+## Contract Compliance Matrix
+
+| Module | TIER | @PRE/@POST | @UX_STATE | @RELATION | Status |
+|--------|------|------------|-----------|-----------|--------|
+| SidebarStore | STANDARD | ✅ | ✅ | ✅ | Ready |
+| TaskDrawerStore | CRITICAL | ✅ | ✅ | ✅ | Ready |
+| ActivityStore | STANDARD | ✅ | ✅ | ✅ | Ready |
+| Sidebar | CRITICAL | ✅ | ✅ | ✅ | Ready |
+| TopNavbar | CRITICAL | ✅ | ✅ | ✅ | Ready |
+| TaskDrawer | CRITICAL | ✅ | ✅ | ✅ | Ready |
+| DashboardHub | CRITICAL | ✅ | ✅ | ✅ | Ready |
+| DatasetHub | CRITICAL | ✅ | ✅ | ✅ | Ready |
+| Breadcrumbs | STANDARD | ✅ | ✅ | ✅ | Ready |
+| DashboardsAPI | CRITICAL | ✅ | N/A | ✅ | Ready |
+| DatasetsAPI | CRITICAL | ✅ | N/A | ✅ | Ready |
+| ActivityAPI | STANDARD | ✅ | N/A | ✅ | Ready |
+| ResourceService | STANDARD | ✅ | N/A | ✅ | Ready |
+
+---
+
+## UX State Mapping to Components
+
+| UX State (from ux_reference.md) | Component | @UX_STATE Tag |
+|----------------------------------|-----------|---------------|
+| Sidebar Expanded | Sidebar | Idle-Expanded |
+| Sidebar Collapsed | Sidebar | Idle-Collapsed |
+| Mobile Overlay | Sidebar | Mobile-Open |
+| Task Drawer Closed | TaskDrawer | Closed |
+| Task Drawer Streaming | TaskDrawer | Open-Streaming |
+| Task Drawer Input Required | TaskDrawer | Open-InputRequired |
+| Activity Badge Active | TopNavbar | Activity-Pulse |
+| Dashboard Grid Loading | DashboardHub | Loading |
+| Dashboard Grid Empty | DashboardHub | Empty-NoData |
+| Bulk Selection Active | DashboardHub | Selecting |
+| Migration Modal Open | DashboardHub | BulkAction-Modal |
+| Dataset Grid Loading | DatasetHub | Loading |
+| Dataset Detail View | DatasetHub | Detail-View |
+
+---
+
+## Design-by-Contract Enforcement
+
+### Critical Modules (Full Contracts Required)
+
+All CRITICAL tier modules MUST have:
+- Complete `@PRE` conditions for all public functions
+- Complete `@POST` conditions guaranteeing output
+- All `@UX_STATE` transitions documented
+- `@UX_FEEDBACK` and `@UX_RECOVERY` where applicable
+- `@RELATION` tags for all dependencies
+
+### Standard Modules (Basic Contracts Required)
+
+All STANDARD tier modules MUST have:
+- `@PURPOSE` declaration
+- Key `@PRE` and `@POST` for main operations
+- Primary `@UX_STATE` states
+- `@RELATION` tags for major dependencies
+
+---
+
+## Constitution Compliance
+
+| Principle | Compliance | Notes |
+|-----------|------------|-------|
+| I. Semantic Protocol | ✅ | All modules use [DEF] anchors and proper tagging |
+| II. Everything is a Plugin | ✅ | Dashboard/Dataset hubs dispatch to existing plugins |
+| III. Unified Frontend | ✅ | Uses requestApi, i18n, and component library |
+| IV. Security & Access Control | ✅ | Permission checks in @PRE conditions |
+| V. Independent Testability | ✅ | Each hub has defined independent test scenarios |
+| VI. Asynchronous Execution | ✅ | All bulk operations return task_id, use TaskManager |
diff --git a/specs/019-superset-ux-redesign/plan.md b/specs/019-superset-ux-redesign/plan.md
index 1d1327f..357c48b 100644
--- a/specs/019-superset-ux-redesign/plan.md
+++ b/specs/019-superset-ux-redesign/plan.md
@@ -50,10 +50,11 @@ specs/019-superset-ux-redesign/
├── data-model.md # Phase 1 output
├── quickstart.md # Phase 1 output
├── contracts/ # Phase 1 output
-│ └── api.md # API contracts
+│ ├── api.md # API contracts
+│ └── modules.md # Module contracts (Semantic Protocol)
├── checklists/
│ └── requirements.md # Spec quality checklist
-└── tasks.md # Phase 2 output (NOT created yet)
+└── tasks.md # Phase 2 output
```
### Source Code (repository root)
@@ -98,6 +99,27 @@ frontend/
**Structure Decision**: Web application structure with new `layout/` and `hubs/` component directories. The Sidebar and TaskDrawer live in the root `+layout.svelte` for global availability.
+## Contract References
+
+All implementation MUST follow the Design-by-Contract specifications in [`contracts/modules.md`](./contracts/modules.md):
+
+| Component/Module | Contract Location | TIER |
+|------------------|-------------------|------|
+| SidebarStore | [DEF:SidebarStore:Store](./contracts/modules.md#1-sidebarstore) | STANDARD |
+| TaskDrawerStore | [DEF:TaskDrawerStore:Store](./contracts/modules.md#2-taskdrawerstore) | CRITICAL |
+| ActivityStore | [DEF:ActivityStore:Store](./contracts/modules.md#3-activitystore) | STANDARD |
+| Sidebar | [DEF:Sidebar:Component](./contracts/modules.md#4-sidebar-component) | CRITICAL |
+| TopNavbar | [DEF:TopNavbar:Component](./contracts/modules.md#5-topnavbar-component) | CRITICAL |
+| TaskDrawer | [DEF:TaskDrawer:Component](./contracts/modules.md#6-taskdrawer-component) | CRITICAL |
+| DashboardHub | [DEF:DashboardHub:Component](./contracts/modules.md#7-dashboardhub-component) | CRITICAL |
+| DatasetHub | [DEF:DatasetHub:Component](./contracts/modules.md#8-datasethub-component) | CRITICAL |
+| DashboardsAPI | [DEF:DashboardsAPI:Module](./contracts/modules.md#10-dashboards-api) | CRITICAL |
+| DatasetsAPI | [DEF:DatasetsAPI:Module](./contracts/modules.md#11-datasets-api) | CRITICAL |
+
+### UX State Contract Mapping
+
+All UI states defined in [`ux_reference.md`](./ux_reference.md) are mapped to `@UX_STATE` tags in module contracts. See [UX State Mapping table](./contracts/modules.md#ux-state-mapping-to-components) for complete mapping.
+
## Complexity Tracking
> No Constitution violations. All changes use existing patterns.
diff --git a/specs/019-superset-ux-redesign/tasks.md b/specs/019-superset-ux-redesign/tasks.md
index 7d79028..39249ef 100644
--- a/specs/019-superset-ux-redesign/tasks.md
+++ b/specs/019-superset-ux-redesign/tasks.md
@@ -12,22 +12,49 @@
- **[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
+- **Contract Reference**: Each task links to [contracts/modules.md](./contracts/modules.md) for Design-by-Contract specifications
## Path Conventions
- **Web app**: `backend/src/`, `frontend/src/`
+## Contract References
+
+All implementation tasks MUST follow the Design-by-Contract specifications:
+
+| Component | Contract | TIER |
+|-----------|----------|------|
+| `sidebar.js` | [DEF:SidebarStore:Store](./contracts/modules.md#1-sidebarstore) | STANDARD |
+| `taskDrawer.js` | [DEF:TaskDrawerStore:Store](./contracts/modules.md#2-taskdrawerstore) | CRITICAL |
+| `activity.js` | [DEF:ActivityStore:Store](./contracts/modules.md#3-activitystore) | STANDARD |
+| `Sidebar.svelte` | [DEF:Sidebar:Component](./contracts/modules.md#4-sidebar-component) | CRITICAL |
+| `TopNavbar.svelte` | [DEF:TopNavbar:Component](./contracts/modules.md#5-topnavbar-component) | CRITICAL |
+| `TaskDrawer.svelte` | [DEF:TaskDrawer:Component](./contracts/modules.md#6-taskdrawer-component) | CRITICAL |
+| `Breadcrumbs.svelte` | [DEF:Breadcrumbs:Component](./contracts/modules.md#9-breadcrumbs-component) | STANDARD |
+| `DashboardHub` | [DEF:DashboardHub:Component](./contracts/modules.md#7-dashboardhub-component) | CRITICAL |
+| `DatasetHub` | [DEF:DatasetHub:Component](./contracts/modules.md#8-datasethub-component) | CRITICAL |
+| `dashboards.py` | [DEF:DashboardsAPI:Module](./contracts/modules.md#10-dashboards-api) | CRITICAL |
+| `datasets.py` | [DEF:DatasetsAPI:Module](./contracts/modules.md#11-datasets-api) | CRITICAL |
+| `resource_service.py` | [DEF:ResourceService:Class](./contracts/modules.md#13-resourceservice) | STANDARD |
+
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Create new directory structure and stores for layout state
+**Contract Requirements**:
+- All stores MUST implement `@PRE` and `@POST` conditions from [contracts/modules.md](./contracts/modules.md)
+- CRITICAL tier modules (TaskDrawerStore) require full UX state documentation
+
- [x] T001 Create `frontend/src/lib/components/layout/` directory for shared layout components
- [x] T002 Create `frontend/src/lib/components/hubs/` directory for resource hub pages
-- [x] T003 [P] Create `frontend/src/lib/stores/sidebar.js` with persistentStore pattern for sidebar state
-- [x] T004 [P] Create `frontend/src/lib/stores/taskDrawer.js` with resourceTaskMap store
-- [x] T005 [P] Create `frontend/src/lib/stores/activity.js` as derived store from taskDrawer
+- [x] T003 [P] Create `frontend/src/lib/stores/sidebar.js` with persistentStore pattern for sidebar state
+ _Contract: [DEF:SidebarStore:Store](./contracts/modules.md#1-sidebarstore)_
+- [x] T004 [P] Create `frontend/src/lib/stores/taskDrawer.js` with resourceTaskMap store
+ _Contract: [DEF:TaskDrawerStore:Store](./contracts/modules.md#2-taskdrawerstore) - CRITICAL: Must implement all @UX_STATE transitions_
+- [x] T005 [P] Create `frontend/src/lib/stores/activity.js` as derived store from taskDrawer
+ _Contract: [DEF:ActivityStore:Store](./contracts/modules.md#3-activitystore)_
---
@@ -37,9 +64,16 @@
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
-- [x] T006 Create `frontend/src/lib/components/layout/Sidebar.svelte` with categories: DASHBOARDS, DATASETS, STORAGE, ADMIN
-- [x] T007 Create `frontend/src/lib/components/layout/TopNavbar.svelte` with Logo, Search placeholder, Activity indicator, User menu
-- [x] T008 Create `frontend/src/lib/components/layout/Breadcrumbs.svelte` for page hierarchy navigation
+**Contract Requirements**:
+- All CRITICAL tier components MUST implement full `@UX_STATE` specifications
+- Components MUST follow `@PRE` conditions for props and `@POST` for event handling
+
+- [x] T006 Create `frontend/src/lib/components/layout/Sidebar.svelte` with categories: DASHBOARDS, DATASETS, STORAGE, ADMIN
+ _Contract: [DEF:Sidebar:Component](./contracts/modules.md#4-sidebar-component) - CRITICAL: Implement all @UX_STATE transitions (Expanded/Collapsed/Mobile)_
+- [x] T007 Create `frontend/src/lib/components/layout/TopNavbar.svelte` with Logo, Search placeholder, Activity indicator, User menu
+ _Contract: [DEF:TopNavbar:Component](./contracts/modules.md#5-topnavbar-component) - CRITICAL: Activity badge must pulse on new tasks_
+- [x] T008 Create `frontend/src/lib/components/layout/Breadcrumbs.svelte` for page hierarchy navigation
+ _Contract: [DEF:Breadcrumbs:Component](./contracts/modules.md#9-breadcrumbs-component) - Handle truncation for >3 levels_
- [x] T009 Update `frontend/src/routes/+layout.svelte` to include Sidebar, TopNavbar, and main content area
- [x] T010 Add i18n keys for navigation labels in `frontend/src/lib/i18n/translations/en.json`
- [x] T011 Add i18n keys for navigation labels in `frontend/src/lib/i18n/translations/ru.json`
@@ -75,12 +109,20 @@
### Implementation for User Story 2
-- [x] T018 [US2] Create `frontend/src/lib/components/layout/TaskDrawer.svelte` as slide-out panel from right
+**Contract Requirements**:
+- TaskDrawer MUST implement all `@UX_STATE` transitions from [DEF:TaskDrawerStore:Store](./contracts/modules.md#2-taskdrawerstore)
+- MUST handle `@UX_RECOVERY` for WebSocket disconnections
+
+- [x] T018 [US2] Create `frontend/src/lib/components/layout/TaskDrawer.svelte` as slide-out panel from right
+ _Contract: [DEF:TaskDrawer:Component](./contracts/modules.md#6-taskdrawer-component) - CRITICAL: Implement Closed → Open-Loading → Open-Streaming → Open-InputRequired states_
- [x] T019 [US2] Integrate existing `TaskLogViewer` component inside Task Drawer
- [x] T020 [US2] Implement Activity indicator badge in TopNavbar showing `activeCount` from store
-- [x] T021 [US2] Connect Task Drawer to WebSocket for real-time log streaming
-- [x] T022 [US2] Implement interactive area in drawer for `PasswordPrompt` and other inputs
-- [x] T023 [US2] Add close button that allows task to continue running in background
+- [x] T021 [US2] Connect Task Drawer to WebSocket for real-time log streaming
+ _Contract: @RELATION: DEPENDS_ON -> WebSocket connection_
+- [x] T022 [US2] Implement interactive area in drawer for `PasswordPrompt` and other inputs
+ _Contract: @UX_STATE: Open-InputRequired_
+- [x] T023 [US2] Add close button that allows task to continue running in background
+ _Contract: @POST: Closing drawer does NOT cancel running task_
- [x] T024 [US2] Implement drawer open trigger from Activity indicator click
- [x] T025 [US2] Verify implementation matches ux_reference.md (Task Drawer mockup)
@@ -114,29 +156,52 @@
### Backend for User Story 3
-- [x] T031 [P] [US3] Create `backend/src/api/routes/dashboards.py` with GET /api/dashboards endpoint
-- [x] T032 [P] [US3] Create `backend/src/services/resource_service.py` for shared resource fetching logic
+**Contract Requirements**:
+- All endpoints MUST follow `@PRE` and `@POST` conditions from [DEF:DashboardsAPI:Module](./contracts/modules.md#10-dashboards-api)
+- MUST use `ConfigManager` via dependency injection (Constitution Principle II)
+
+- [x] T031 [P] [US3] Create `backend/src/api/routes/dashboards.py` with GET /api/dashboards endpoint
+ _Contract: [DEF:DashboardsAPI:Module](./contracts/modules.md#10-dashboards-api) - CRITICAL_
+- [x] T032 [P] [US3] Create `backend/src/services/resource_service.py` for shared resource fetching logic
+ _Contract: [DEF:ResourceService:Class](./contracts/modules.md#13-resourceservice)_
- [x] T033 [US3] Implement dashboard list fetching with Git status and last task status
-- [ ] T034 [US3] Add pagination support to GET /api/dashboards endpoint (page, page_size parameters)
-- [ ] T035 [US3] Implement bulk migration endpoint POST /api/dashboards/migrate with target environment and dashboard IDs
-- [ ] T036 [US3] Implement bulk backup endpoint POST /api/dashboards/backup with optional cron schedule
+- [ ] T034 [US3] Add pagination support to GET /api/dashboards endpoint (page, page_size parameters)
+ _Contract: @POST: Response includes pagination metadata_
+- [ ] T035 [US3] Implement bulk migration endpoint POST /api/dashboards/migrate with target environment and dashboard IDs
+ _Contract: @PRE: User has permission plugin:migration:execute_
+- [ ] T036 [US3] Implement bulk backup endpoint POST /api/dashboards/backup with optional cron schedule
+ _Contract: @PRE: User has permission plugin:backup:execute_
- [ ] T037 [US3] Add database mappings retrieval from MappingService for migration modal
### Frontend for User Story 3
-- [x] T038 [US3] Create `frontend/src/routes/dashboards/+page.svelte` as Dashboard Hub
+**Contract Requirements**:
+- MUST implement all `@UX_STATE` transitions from [DEF:DashboardHub:Component](./contracts/modules.md#7-dashboardhub-component)
+- MUST preserve selection across pagination (`@INVARIANT: Selected dashboards persist across pagination`)
+
+- [x] T038 [US3] Create `frontend/src/routes/dashboards/+page.svelte` as Dashboard Hub
+ _Contract: [DEF:DashboardHub:Component](./contracts/modules.md#7-dashboardhub-component) - CRITICAL_
- [x] T039 [US3] Implement environment selector dropdown at top of Dashboard Hub
-- [x] T040 [US3] Create dashboard grid with checkboxes, columns: Title, Slug, Git Status, Last Task, Actions
-- [ ] T041 [US3] Implement "Select All" and "Select Visible" buttons in toolbar
-- [ ] T042 [US3] Add real-time search input that filters dashboard list
-- [ ] T043 [US3] Implement pagination controls with page numbers and "Rows per page" dropdown
-- [ ] T044 [US3] Create floating bulk action panel at bottom: "[✓ N selected] [Migrate] [Backup]"
-- [ ] T045 [US3] Implement Bulk Migration modal with target environment, database mappings, and selected dashboards list
+- [x] T040 [US3] Create dashboard grid with checkboxes, columns: Title, Slug, Git Status, Last Task, Actions
+ _Contract: @UX_STATE: Idle-Grid, @UX_FEEDBACK: Git status color-coded icons_
+- [ ] T041 [US3] Implement "Select All" and "Select Visible" buttons in toolbar
+ _Contract: @UX_STATE: Selecting_
+- [ ] T042 [US3] Add real-time search input that filters dashboard list
+ _Contract: @POST: Search filters results in real-time (debounced 300ms)_
+- [ ] T043 [US3] Implement pagination controls with page numbers and "Rows per page" dropdown
+ _Contract: @INVARIANT: Selection persists across pagination_
+- [ ] T044 [US3] Create floating bulk action panel at bottom: "[✓ N selected] [Migrate] [Backup]"
+ _Contract: @UX_FEEDBACK: Floating panel slides up from bottom_
+- [ ] T045 [US3] Implement Bulk Migration modal with target environment, database mappings, and selected dashboards list
+ _Contract: @UX_STATE: BulkAction-Modal_
- [ ] T046 [US3] Implement Bulk Backup modal with one-time/scheduled options and cron expression
- [x] T047 [US3] Implement individual Actions menu with Migrate, Backup, Git Operations options
-- [x] T048 [US3] Connect Actions menu to existing plugin triggers (Migration, Backup, Git)
-- [x] T049 [US3] Implement status badge click to open Task Drawer with correct task
-- [x] T050 [US3] Add empty state when no environments configured or no dashboards found
+- [x] T048 [US3] Connect Actions menu to existing plugin triggers (Migration, Backup, Git)
+ _Contract: @RELATION: DISPATCHES -> MigrationPlugin, BackupPlugin_
+- [x] T049 [US3] Implement status badge click to open Task Drawer with correct task
+ _Contract: @POST: Clicking status badge opens TaskDrawer with that task_
+- [x] T050 [US3] Add empty state when no environments configured or no dashboards found
+ _Contract: @UX_STATE: Empty-NoEnv, Empty-NoData_
- [ ] T051 [US3] Verify implementation matches ux_reference.md (Dashboard Hub Grid mockup)
**Checkpoint**: Dashboard Hub fully functional with bulk operations
@@ -151,25 +216,46 @@
### Backend for User Story 4
-- [x] T052 [P] [US4] Create `backend/src/api/routes/datasets.py` with GET /api/datasets endpoint
-- [x] T053 [US4] Implement dataset list fetching with mapped fields count and SQL table extraction
+**Contract Requirements**:
+- All endpoints MUST follow `@PRE` and `@POST` conditions from [DEF:DatasetsAPI:Module](./contracts/modules.md#11-datasets-api)
+- MUST calculate `mapped_fields` as (mapped_columns / total_columns) * 100
+
+- [x] T052 [P] [US4] Create `backend/src/api/routes/datasets.py` with GET /api/datasets endpoint
+ _Contract: [DEF:DatasetsAPI:Module](./contracts/modules.md#11-datasets-api) - CRITICAL_
+- [x] T053 [US4] Implement dataset list fetching with mapped fields count and SQL table extraction
+ _Contract: @INVARIANT: Mapped % is calculated as (mapped_columns / total_columns) * 100_
- [ ] T054 [US4] Add pagination support to GET /api/datasets endpoint (page, page_size parameters)
-- [ ] T055 [US4] Implement bulk column mapping endpoint POST /api/datasets/map-columns with source selection
-- [ ] T056 [US4] Implement bulk documentation generation endpoint POST /api/datasets/generate-docs
+- [ ] T055 [US4] Implement bulk column mapping endpoint POST /api/datasets/map-columns with source selection
+ _Contract: @PRE: User has permission plugin:mapper:execute_
+- [ ] T056 [US4] Implement bulk documentation generation endpoint POST /api/datasets/generate-docs
+ _Contract: @PRE: User has permission plugin:llm_analysis:execute_
- [ ] T057 [US4] Add dataset-to-dashboard relationship retrieval for linked dashboards display
### Frontend for User Story 4
-- [x] T058 [US4] Create `frontend/src/routes/datasets/+page.svelte` as Dataset Hub
-- [x] T059 [US4] Implement dataset grid with checkboxes, columns: Name, Database, Schema, Tables, Columns, Mapped %, Updated By, Actions
-- [ ] T060 [US4] Implement "Select All" and "Select Visible" buttons in toolbar
-- [ ] T061 [US4] Add real-time search input that filters dataset list by name, schema, or table names
+**Contract Requirements**:
+- MUST implement all `@UX_STATE` transitions from [DEF:DatasetHub:Component](./contracts/modules.md#8-datasethub-component)
+- MUST display Mapped % with progress bar as specified in `@UX_FEEDBACK`
+
+- [x] T058 [US4] Create `frontend/src/routes/datasets/+page.svelte` as Dataset Hub
+ _Contract: [DEF:DatasetHub:Component](./contracts/modules.md#8-datasethub-component) - CRITICAL_
+- [x] T059 [US4] Implement dataset grid with checkboxes, columns: Name, Database, Schema, Tables, Columns, Mapped %, Updated By, Actions
+ _Contract: @UX_FEEDBACK: Mapped % column shows progress bar + percentage text_
+- [ ] T060 [US4] Implement "Select All" and "Select Visible" buttons in toolbar
+ _Contract: @UX_STATE: Selecting_
+- [ ] T061 [US4] Add real-time search input that filters dataset list by name, schema, or table names
+ _Contract: @POST: Search filters by name, schema, and table names_
- [ ] T062 [US4] Implement pagination controls with page numbers and "Rows per page" dropdown
-- [ ] T063 [US4] Create floating bulk action panel at bottom: "[✓ N selected] [Map Columns] [Generate Docs] [Validate]"
-- [ ] T064 [US4] Implement Column Mapping modal with PostgreSQL comments/XLSX source selection and preview
-- [ ] T065 [US4] Implement Documentation Generation modal with LLM provider selection and options
-- [ ] T066 [US4] Create dataset detail view showing SQL tables, column counts, mapping percentages, and linked dashboards
-- [x] T067 [US4] Add empty state when no datasets found
+- [ ] T063 [US4] Create floating bulk action panel at bottom: "[✓ N selected] [Map Columns] [Generate Docs] [Validate]"
+ _Contract: @UX_STATE: Selecting, @UX_FEEDBACK: Floating panel slides up_
+- [ ] T064 [US4] Implement Column Mapping modal with PostgreSQL comments/XLSX source selection and preview
+ _Contract: @POST: Map Columns modal shows source selection (PostgreSQL or XLSX)_
+- [ ] T065 [US4] Implement Documentation Generation modal with LLM provider selection and options
+ _Contract: @POST: Generate Docs modal shows LLM provider selection_
+- [ ] T066 [US4] Create dataset detail view showing SQL tables, column counts, mapping percentages, and linked dashboards
+ _Contract: @UX_STATE: Detail-View, @POST: Clicking dataset name opens detail view_
+- [x] T067 [US4] Add empty state when no datasets found
+ _Contract: @UX_STATE: Empty-NoData_
- [ ] T068 [US4] Verify implementation matches ux_reference.md (Dataset Hub Grid mockup)
**Checkpoint**: Dataset Hub fully functional with bulk operations
@@ -204,11 +290,19 @@
**Purpose**: Improvements that affect multiple user stories
-- [x] T057 [P] Add breadcrumb navigation to all new pages
-- [x] T058 [P] Implement breadcrumb truncation for deep paths (>3 levels)
+**Contract Requirements**:
+- Breadcrumbs MUST follow [DEF:Breadcrumbs:Component](./contracts/modules.md#9-breadcrumbs-component) specification
+- Error handling MUST implement `@UX_RECOVERY` patterns from component contracts
+
+- [x] T057 [P] Add breadcrumb navigation to all new pages
+ _Contract: [DEF:Breadcrumbs:Component](./contracts/modules.md#9-breadcrumbs-component)_
+- [x] T058 [P] Implement breadcrumb truncation for deep paths (>3 levels)
+ _Contract: @POST: Deep paths (>3 levels) truncate middle segments_
- [x] T059 Remove old card-based dashboard grid if no longer needed
-- [x] T060 [P] Add skeleton loaders for resource hub grids
-- [x] T061 [P] Add error banners for environment connection failures
+- [x] T060 [P] Add skeleton loaders for resource hub grids
+ _Contract: @UX_STATE: Loading -> Skeleton loaders in grid rows_
+- [x] T061 [P] Add error banners for environment connection failures
+ _Contract: @UX_RECOVERY: Failed environment connection shows error banner with retry_
- [x] T062 Run quickstart.md validation for all user stories
- [x] T063 Final UX review against ux_reference.md