Files
easy-png-tools2/docs/roadmap.md
T

195 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# План развития: easy-png-tools
> **Статус (2026-09):** Фаза 1 (полноценный TS-сайт) в основном выполнена — сайт
> живёт, каталог переведён в типизированный `registry`, новый дизайн стал
> единственным production UI на корневых маршрутах, UI-v1 удалён. Tech debt не
> закрыт полностью; состав quality-проверок — `docs/quality-gates.md`,
> архитектура кода — `docs/architecture.md`, список инструментов —
> `docs/tools-map.md`. Текущий фокус: SEO S1-free (`docs/plan-seo.md`) +
> продуктовые задачи из `docs/backlog.md`. Домен нужен для SEO (`plan-seo.md`,
> S1-domain). Фазы 2–8 — будущие; фазы 9–10 спланированы в
> `docs/plan-platform.md`.
>
> **Нумерация фаз этого документа не совпадает с волнами разработки** (`Q*`/`C*`
> в других документах) и не используется как идентификатор задач: ссылаться на
> фазу, а не на номер волны.
## 0. Решения
- **Набор утилит для изображений, всё в браузере** (SvelteKit +
`adapter-static`), данные не покидают машину.
- **Первый и главный приоритет — полностью рабочий сайт**: максимум простых
инструментов, UX/UI, пайплайны (несколько инструментов подряд), описания
инструментов.
- **Никакого wasm/Rust на этом этапе.** TS-реализация на canvas + `ImageData` —
эталон алгоритмов, из которого позже генерируются эталонные файлы для проверки
Rust-порта. Rust-ядро, WASM и CLI — отдельные фазы позже, когда сайт живёт.
- **Пайплайн = JSON-список шагов** `{tool, params}`. Формат закладывается сейчас
и потом станет общим для браузера, wasm и CLI.
- **Реестр инструментов** (`web/src/lib/registry/`: id, title, description,
category, schema, `run`) — источник истины: из него генерируются страницы,
формы, пайплайны. Позже — общий формат для Rust-парсера.
- Валидация будущего Rust-порта — эталонные файлы, сгенерированные из
TS-реализации. Сравнение: **бит-в-бит** для чистых пиксельных операций,
**perceptual diff** для canvas-зависимых.
- **Единая точка исполнения инструментов.** Страницы вызывают операции только
через `web/src/lib/executor/` — нигде напрямую `tool.run`. Контракт уже
асинхронный, поэтому:
- когда появятся тяжёлые MEDIUM-операции (свёртки, квантование), внутренности
исполнителя переезжают в Web Worker — воркер импортирует тот же чистый core
как TS-фолбэк, алгоритмы не дублируются, вызывающий код не меняется;
- в WASM-фазе тот же воркер принимает wasm-модуль и диспетчеризует по `toolId`
— свитч A/B из фазы 5 сводится к замене реализации внутри исполнителя;
- до появления MEDIUM-операций воркер не вводится: EASY-операции быстры и не
блокируют UI.
## 1. Где что лежит
Актуальная карта модулей, поток данных и рецепт добавления инструмента —
`docs/architecture.md`. Список реализованных инструментов — `docs/tools-map.md`,
открытые продуктовые задачи — `docs/backlog.md`.
## 2. Фазы
### Фаза 1 — Полноценный TS-сайт (единственный приоритет)
**Цель: сайт, которым можно пользоваться.** Без wasm, без Rust, без
clamp-семантики (в TS это делает `Uint8ClampedArray` сам).
1.1 **Каркас и UX/UI.** SvelteKit + static adapter, дизайн-система (цвета,
типографика, компоненты), общий лейаут, шапка с навигацией по категориям.
1.2 **Ядро.** Операции над `ImageData` (загрузка/декодирование файла,
кодирование и скачивание, библиотека операций
color/alpha/geometry/format/text/analyze). Всё без DOM-зависимостей внутри
`core`.
1.3 **Реестр инструментов.** Одна запись =
`{ id, title, description, category, schema, run }`. Универсальный рендерер:
страница инструмента и форма параметров строятся из записи реестра
автоматически; маршруты-утилиты генерируются из реестра на билде. Новый
инструмент = новая запись + функция `run` (рецепт — `docs/architecture.md` §8).
1.4 **Пайплайн-workspace**: загрузил изображение → список шагов (инструмент +
его параметры) → последовательное применение с превью каждого шага → скачивание
финального результата. Добавление/удаление шагов. Сохранение пайплайнов в
localStorage, экспорт/импорт JSON.
1.5 **Массовая реализация EASY-инструментов** по категориям:
- конвертация форматов (png/jpg/webp/bmp/base64/gif) и текстовые представления;
- прозрачность и альфа-канал;
- цвет: замена, тон, каналы, оттенки серого, инверсии;
- геометрия и холст: resize, crop, rotate, flip, border, padding, background;
- текст и простые эффекты: watermark, add-text, рамки, шум, pixelate;
- анализ: размеры, палитра, проверки, просмотр. Приоритет — ширина, не глубина:
как можно больше простых инструментов.
1.6 **Полировка.** Описания и подсказки для всех инструментов, состояния
загрузки/ошибок, доступность, пустые состояния.
**Checkpoint:** загрузил PNG → применил пайплайн из N шагов → сохранил и вернул
пайплайн → скачал результат. Все инструменты 1.5 работают на сайте. Ни одного
wasm.
### Фаза 2 — Тестовые PNG и генератор эталонов
- Фикстурные входы: градиенты/паттерны/шум + пара «настоящих» PNG.
- Правило: сравниваем **распакованные пиксели**, не байты файла.
- **Checkpoint:** в `tests/reference/<op>/` лежат `input-*.png` +
`expected-*.png`.
### Фаза 3 — Эталонные файлы и UI-регресс
> UI-регресс на Playwright уже существует и закрывает фазу 3 частично
> (`web/e2e/`, browser matrix). Недостающая часть фазы — именно эталоны.
- Скрипт генерации эталонов: грузит страницу, гоняет TS-реализацию, сохраняет
`expected-*.png`.
- **Checkpoint:** регресс-тесты падают при изменении выхода эталона.
### Фаза 4 — Rust-ядро
- Порт 1:1 чистых операций (первым делом те, что покрыты эталонными файлами) с
`PixelImage` ↔ TS `ImageData`.
- `clamp_to_u8` с семантикой `ToUint8Clamp` (round-half-to-even, ≥255 → 255) +
юнит-тесты на краях.
- `cargo test` читает эталонные файлы напрямую, **без браузера**.
- **Checkpoint:** `cargo test` зелёный на всех эталонных файлах.
### Фаза 5 — WASM на сайте
- Спайк WASM + Vite (проверить интеграцию) → wasm-bindgen-биндинги.
- Свитч A/B: TS-реализация заменяется на wasm-вызов.
- Playwright-проверка: wasm-результат == эталон.
- **Checkpoint:** сайт работает через WASM; A/B TS vs WASM идентично.
### Фаза 6 — Rust-CLI
- CLI: обход папки, `--pipeline pipeline.json`, запись результатов.
- Воспроизведение эталонов из консоли.
- **Checkpoint:** CLI выдаёт те же пиксели, что сохранены в эталонных файлах.
### Фаза 7 — Сквозная проверка идентичности
- Матрица: **эталонные файлы (из TS) ↔ Rust-native ↔ Rust-wasm**, одна команда
`harness compare`.
- **Checkpoint:** сходимость по всем покрытым операциям во всех трёх рантаймах.
### Фаза 8 — Масштабирование и продвинутое
- Порт оставшихся EASY → MEDIUM (свёртки, морфология, квантование; кодеки через
крейт `image`).
- Canvas-зависимые операции (текст, градиенты, штампы, `ctx.filter`): остаются в
TS с perceptual-классом либо реимплементация в Rust. Для текста выбран курс на
реимплементацию в Rust (рендер без DOM + шрифты OFL с лицензионными
паспортами) — `docs/plan-platform.md`, §4.
- batch-страница: дроп папки → wasm по всем файлам → zip. localStorage-пресеты
(тот же JSON, что у CLI).
- HARD: compress/optimize через oxipng/zopfli (в Rust — нативно).
### Фаза 9 — API (монетизация) — см. `docs/plan-platform.md`
Серверная обёртка над тем же ядром (нативный Rust или wasm на edge — решает
спайк), ключи и free tier, платные лимиты, индексируемая документация `/api`.
Чек-лист и решения — `docs/plan-platform.md`, §1.
### Фаза 10 — PWA — см. `docs/plan-platform.md`
Manifest + service worker, оффлайн-режим («работает без сети — файлы не покидают
устройство»), установка как приложение. Wasm-фаз не требует, идёт после S1 из
`plan-seo.md`. Чек-лист — `docs/plan-platform.md`, §2.
## 3. Правила сравнения (для фаз 4–7)
| Класс операции | Критерий |
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| Чистые пиксельные: цвет, альфа, порог, свёртки, морфология, квантование | **бит-в-бит** |
| Canvas-растеризация: текст, градиенты, антиалиасинг, `drawImage`, `ctx.filter` | **perceptual diff** (допуск: % изменившихся пикселей / цветовое расстояние) |
| PNG-декод | бит-в-бит (lossless) |
| JPEG-декод | perceptual (разные декодеры дают лёгкий дрейф) |
| Кодирование | сравниваем декодированные пиксели, не байты файла |
| compress/optimize | своя метрика: размер + визуальная дельта |
## 4. Риски и контрмеры
- **Реестр разрастается, страницы дублируются** — один универсальный рендерер
страниц/форм из записей реестра; инструмент = данные + `run`.
- **Семантика пайплайна** — зафиксирована: каждый шаг применяется к результату
предыдущего; единый тип `PixelImage` на всём пути; схема параметров на шаге.
- **Canvas-операции не бит-в-бит** — класс perceptual закладывается на Фазе 2–3,
а не в конце.
- **WASM + Vite** — спайк на Фазе 5 до массовой интеграции (риск отложен
сознательно: сайт уже живёт на TS).
- **Расползание реестра при будущем Rust-порте** — схема параметров в JSON, её
можно парсить и из Rust.
- **Разные декодеры PNG** — фикстурные PNG генерировать самим, чтобы не тащить
чужие артефакты.
## 5. Команды верификации
Текущие команды и матрица «изменение → проверки» — `docs/quality-gates.md`
(`pnpm verify` — быстрый gate текущего этапа). Для будущих фаз добавляются
`cargo test` (Rust-ядро против эталонных файлов, фаза 4+) и
`harness compare tests/reference` (сквозная сверка native + wasm, фаза 7).