# UnifiedSpread dev-21.5.0 Data Tools Foundation

This milestone adds the first practical Data Tools layer on top of the NativeGrid and FormulaEngine foundations.

## Implemented areas

- Advanced filter criteria foundation
  - non-blank / blank
  - text contains
  - number greater than
  - number between
  - value checklist remains available from the column filter menu
- Multi-column sort foundation
  - sorts by selected columns in order from left to right
  - preserves whole worksheet rows while reordering
- Data validation metadata
  - list validation
  - number-between validation
  - invalid-cell marker overlay
  - `.uspdx` persistence through sheet config
- Duplicate removal
  - selected range deduplication
  - first row is treated as header by default
  - duplicate rows are cleared from the selected range tail rather than deleting sheet rows
- Split text to columns
  - comma and tab commands
  - quoted CSV-like values are handled for comma split
- XLSX compatibility foundation
  - AutoFilter range import/export where SheetJS exposes it
  - validation metadata remains UnifiedSpread-native for now

## Design notes

Data validation is not implemented as a hard edit blocker. Spreadsheet users often paste imperfect data first and clean it later, so the model records validation rules and the renderer flags invalid cells visually. A later Host policy may turn these warnings into save-time errors.

Duplicate removal currently clears duplicate rows within the selected range instead of deleting physical rows. This avoids unexpected formula, freeze, filter, and object-layer shifts while the row-deletion dependency update engine is still being expanded.

## Commands

- `spread.data.sort.multi`
- `spread.data.filter.nonBlank`
- `spread.data.filter.blank`
- `spread.data.filter.textContains`
- `spread.data.filter.numberGreaterThan`
- `spread.data.filter.numberBetween`
- `spread.data.removeDuplicates`
- `spread.data.splitText.comma`
- `spread.data.splitText.tab`
- `spread.data.validation.list`
- `spread.data.validation.numberBetween`
- `spread.data.validation.clear`
