Backend: - Add MetricItem, StatsCounts, ColumnDescriptionUpdate, MetricDescriptionUpdate DTOs - Add metric_count to DatasetItem and DatasetDetailResponse - Add server-side filtering via ?filter=unmapped|mapped|linked|all - Add PUT endpoints for column/metric description inline-edit - Add HTML stripping validation (max 2000 chars, plain text) - Add WebSocket dataset.updated event on task completion - RBAC: plugin:migration:WRITE for mutations, READ for reads - 14 pytest tests (stats, filter, metrics, inline-edit, validation, 502/503) Frontend: - Rewrite +page.svelte as split-view orchestrator (387 lines) - StatsBar.svelte — 4 metric tiles with aria-pressed, server-side filter dispatch - DatasetList.svelte — card grid with progress bars, checkboxes, search - DatasetPreview.svelte — presentational detail panel (container fetches) - ColumnsTable.svelte — inline-edit with type chips, bold/italic fallback - MetricsTable.svelte — inline-edit with expression hints - 52 vitest tests across 7 test files - i18n: 11 EN + 11 RU keys (with_mapping/с_маппингом) Spec: - 15 issues resolved (semantic label, filtering, endpoints, conflict, metric_count, RBAC, ID types, ports, i18n, validation, a11y, propagation, resize, perf, ownership) Status: 14/14 backend tests pass, 52/52 frontend tests pass, build succeeds Risk: Low — T051 browser validation pending (non-blocking)
73 lines
4.6 KiB
Markdown
73 lines
4.6 KiB
Markdown
# Requirements Checklist: Dataset Lifecycle Workspace
|
||
|
||
**Purpose**: Validate completeness of functional and non-functional requirements for the Dataset Lifecycle Workspace feature.
|
||
**Created**: 2026-05-19
|
||
**Feature**: [spec.md](../spec.md)
|
||
|
||
## Functional Coverage
|
||
|
||
- [ ] CHK001 Stats Bar renders 4 metrics (Все, Без маппинга, С маппингом, С дашбордами) in page header
|
||
- [ ] CHK002 Each Stats Bar metric is clickable and filters the dataset list accordingly
|
||
- [ ] CHK003 Active filter is visually highlighted; clicking again resets filter
|
||
- [ ] CHK004 Split-view layout renders with 40% left panel and 60% right panel on desktop
|
||
- [ ] CHK005 Right panel shows placeholder "Выберите датасет" when no dataset is selected
|
||
- [ ] CHK006 Mobile layout (< 768px) uses full-width list with slide-over for detail panel
|
||
- [ ] CHK007 Dataset cards display: table_name, schema, column_count, metric_count, progress bar, quick action buttons
|
||
- [ ] CHK008 Progress bar shows color-coded fill: green (100%), yellow (≥50%), blue (<50%)
|
||
- [ ] CHK009 Right panel header shows: table_name, schema, column_count, metric_count, linked_dashboard_count, created_on
|
||
- [ ] CHK010 Right panel has "Columns" section with table (column_name, verbose_name, type, description, ✏️ inline edit)
|
||
- [ ] CHK011 Right panel has "Metrics" section with table (metric_name, expression, verbose_name, description, ✏️ inline edit)
|
||
- [ ] CHK012 verbose_name displayed in bold; fallback to column_name/metric_name in italic when absent
|
||
- [ ] CHK013 Missing description shows "✏️ Добавить описание" / "✏️ Add description" action prompt
|
||
- [ ] CHK014 Metric without description shows expression as hint below the name
|
||
- [ ] CHK015 Inline edit opens textarea with "Save"/"Cancel" buttons
|
||
- [ ] CHK016 Existing description is pre-filled in inline edit textarea
|
||
- [ ] CHK017 Save column description sends `PUT /api/datasets/{id}/columns/{col_id}/description`
|
||
- [ ] CHK017a Save metric description sends `PUT /api/datasets/{id}/metrics/{metric_id}/description`
|
||
- [ ] CHK018 Save success shows toast and closes textarea
|
||
- [ ] CHK019 Save failure shows error message and keeps textarea open
|
||
- [ ] CHK020 Cards have checkboxes; selecting 2+ shows floating bulk action bar
|
||
- [ ] CHK021 Bulk Map Columns modal reused from existing implementation
|
||
- [ ] CHK022 Bulk Generate Docs modal reused from existing implementation
|
||
- [ ] CHK023 Deselecting all hides the bulk action bar
|
||
|
||
## Backend API Coverage
|
||
|
||
- [ ] CHK024 DatasetDetailResponse includes `metrics: list[MetricItem]` field
|
||
- [ ] CHK025 DatasetDetailResponse includes `metric_count: int` field
|
||
- [ ] CHK026 MetricItem Pydantic DTO has fields: id, metric_name, expression, verbose_name, description, metric_type
|
||
- [ ] CHK027 SupersetClient.get_dataset_detail extracts metrics from Superset API response
|
||
- [ ] CHK028 API correctly handles datasets with zero metrics (empty list, count 0)
|
||
|
||
## i18n Coverage
|
||
|
||
- [ ] CHK029 New EN keys: all, without_mapping, with_mapping, linked_to_dashboards, metrics, metric_count, no_selection, save_description, add_description
|
||
- [ ] CHK030 New RU keys: все, без_маппинга, с_маппингом, связаны_с_дашбордами, метрики, метрик, выберите_датасет, сохранить_описание, добавить_описание
|
||
- [ ] CHK031 Breadcrumb for /datasets reads "Датасеты" (RU) / "Datasets" (EN)
|
||
|
||
## Cross-Cutting Concerns
|
||
|
||
- [ ] CHK032 Stats Bar values correctly update when switching environment
|
||
- [ ] CHK033 Existing pagination works with filtered dataset list
|
||
- [ ] CHK034 Search input filters work alongside Stats Bar active filter
|
||
- [ ] CHK035 Loading states for Stats Bar, card list, and detail panel
|
||
- [ ] CHK036 Error states with retry for list, detail, and inline save failures
|
||
- [ ] CHK037 No breaking changes to existing API endpoints (backward compatible)
|
||
- [ ] CHK038 No regression in existing bulk map/generate docs workflows
|
||
- [ ] CHK039 Responsive behavior at breakpoints: 1280px, 1024px, 768px, 480px
|
||
|
||
## Out of Scope (Negative Checklist)
|
||
|
||
- [ ] CHK040 Drag-and-drop колонок NOT implemented
|
||
- [ ] CHK041 CSV export NOT implemented
|
||
- [ ] CHK042 Side-by-side сравнение датасетов NOT implemented
|
||
- [ ] CHK043 Тёмная тема NOT implemented
|
||
- [ ] CHK044 Scheduled автоматический маппинг NOT implemented
|
||
|
||
## Notes
|
||
|
||
- Check items off as completed: `[x]`
|
||
- Add comments or findings inline
|
||
- Link to relevant tasks from tasks.md after decomposition
|
||
- Items CHK040-CHK044 serve as scope boundaries to prevent creep
|