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

261 lines
22 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.
# Backlog
> Статус: **active**. Продуктовые, UX- и инфраструктурные задачи. Здесь только
> **открытые** задачи: выполненные удаляются, а критичные для проекта факты из
> них переносятся в тематический документ (архитектура, quality gates, lint,
> e2e) по мере закрытия.
>
> «Что сознательно не вводим и почему» живёт в `docs/decisions.md`, архитектура
> — в `docs/architecture.md`. Raw-находки UX-аудита — `docs/tools-audit.md`, их
> разбивка на волны — `docs/plan-fields-audit-fixes.md`.
>
> Ids инструментов сверять с `web/src/lib/registry/`; полный список —
> `docs/tools-map.md`.
## lint и прочие правила
- [ ] расширить `i18n/no-hardcoded-user-text` на `web/src/routes/**`: сейчас
правило навешено только на `components/**` (без `/kit`), поэтому
захардкоженный текст в `routes/**` проходит молча (`web/eslint.config.js`,
`web/eslint-plugins/README.md`)
- [ ] `tseslint.config(...)` deprecated: сигнатура
`(...configs: InfiniteDepthConfigWithExtends[]): ConfigArray` помечена
устаревшей, нужен переход на `defineConfig` из `typescript-eslint` —
`web/eslint.config.js`.
- [ ] удалить мёртвые `tools.*.params` из root i18n после проверки потребителей;
до этого действует pattern-based policy-исключение
(`web/eslint-plugins/README.md`, раздел `dict-consistency`)
## Мелочи всякие
- [ ] Пересмотреть тесты - исправить всякие хрупкие, которые проверяют
количество инструментов, точное совпадение текстов, поиск по
`img[alt="Result image"]`, svelte классам и тому подобные
- [ ] нужен инструмент для удаления фона по выбранной точке - удалять внутри
выделенной области
- [ ] сделать конвертацию в смайлики\награды для твитча (6 размеров или выбор
какой размер и 2 сетки)
- [ ] неудобно настраивать ползунками, некоторые инструменты удобнее настроить
через drag-n-drop. звучит сложно, но надо придумать процесс
- [ ] можно ли в тестах получать i18n ключ вместо текста?
- [ ] убрать в тестах все нестандартные символы `→`, длинные тире и т.д.
- [ ] Пересмотреть прозрачность в инструментах - Create empty PNG - прозрачность
должны быть настраиваемой 0-100%, а не переключателем
- [ ] обдумать объединение пар `inputMode + source` и `resultKind + result` в
единую структуру, позволит упростить некоторые вещи - например
`sourceValue` \ `resultValue` в `SchemaPreview.svelte`
- [ ] Рассмотреть необходимость всех этих пропсов в `SchemaPreview.svelte` они
дублируют друг друга `ontextsource`, `onrendertext`, `oncopytext`,
`ondownloadtxt`, `ondownload`,
- [ ] Переделать внешний вид инструментов без настроек, например Remove alpha
channel PNG "remove-alpha-channel-png". Сейчас выглядит слишком пустым.
- [ ] Убрать описание формата в отображении исходник\результат - это должно быть
в кнопке Download
- [ ] Кнопка download должна сразу писать какой формат сейчас, быть с селектором
формата и подсвечивать предупреждение если формат не совместим (альфа
канал)
- [ ] Пересмотреть поля - Plate, Position, Font Style - сейчас второй label
- [ ] Font Style - обдумать выбор шрифта (google fonts???) как организовать
шрифты с кириллицей? сделать галочку "только с кириллицей"??? (решение о
наборе и лицензиях: `docs/plan-platform.md` §4 — только OFL/Apache с
паспортом, семейства с кириллицей)
- [ ] сделать загрузку картинки исходника по ctrl+v и drag-and-drop (dropzone)
- [ ] square-mask-png - проверить работу - параметры неверно считаются. width -
100, height - 100, x - 100, y - 100, обрезает 50% на 50% картинку
- [ ] прикрутить кастомный color picker, добавить прозрачность (range?)
- [ ] проверить настройки range slider на crop-png - слишком большие значения
- [ ] для range slider field - добавить поле для ввода цифр и кнопку сброса
значения
- [ ] для keep Aspect field - пересчитывать второе поле, учитывать какое было
изменено
- [ ] поле ввода текста - сделать по умолчанию нормального размера, а не одну
строку для svg - форматирование или подсветку синтаксиса??? для bin\hex -
форматирование по колонкам??? для hex\bytes\rgba - пример в placeholder
- [ ] обновить страницу kit или сделать storybook
- [ ] придумать процесс редактирования и настройки pipeline - drag-n-drop,
удаление, добавление инструментов. переход один инструмент - pipeline без
перезагрузки
- [ ] Слаги инструментов (`*-png`) — надо переименовть, они работают с любыми
изображениями. Надо сделать отдельный интерфейс маппинга инструмент ->
ссылка
- [ ] `CatalogToolbar`: фильтры используют сырой `<button>`, а не `ui/Button` —
единый контрол для всей библиотеки
(`web/src/lib/components/CatalogToolbar.svelte`).
- [ ] Вынести `ToneVariant`/варианты в общий модуль: `const`-объект с тонами
продублирован в `ui/Badge.svelte` и кнопках
(`web/src/lib/components/ui/Badge.svelte`).
- [ ] `PreviewTile`: canvas должен сам выбирать соотношение сторон в диапазоне
16:9…9:16 вместо фиксированного
(`web/src/lib/components/layout/PreviewTile.svelte`).
- [ ] `ThemeToggle`: свои анимации иконок и своя кнопка вместо `IconButton`
(`web/src/lib/components/ui/ThemeToggle.svelte`).
- [ ] Радиусы бордеров не совпадают с референсом: в `refs` радиусы были 0, а мы
взяли ненулевой `--radius-m` для всех бордеров. Проверить токен против
референсов; возможно он должен быть 0, а скругления оставить только там,
где они реально есть в дизайне.
- [ ] `Footer`: версию брать из `package.json`, а не писать `v0.1.0` вручную
(`web/src/lib/components/layout/Footer.svelte`).
## Переезд
- [ ] множественные числа (часть/части/частей; «N параметров», счётчики) —
`tPlural()` и формат `PluralForms`; детали и критерии — в этом backlog
## SEO/GEO
Общий план: `docs/plan-seo.md` (S0–S4). Переезд preview на реальные маршруты
выполнен; старт возможен — пока только domain-free часть S1.
- [ ] переименование бренда + домен: чек-лист в локальном плане
`docs/plan-domain.local.md` (вне git, имя домена в репо не публикуется;
план-seo §6, R1/R2)
- [ ] download с селектором формата PNG/JPG/WebP/BMP для всех инструментов (райз
№7 → S1f)
- [ ] форматные страницы (`crop-jpeg`, …) — только по вордстату с уникальным
контентом; редиректы только для опечаток; клонов с canonical не делать
(план §5)
- [ ] sitemap.xml из реестра + `Sitemap:` в robots.txt (S1b/S1c)
- [ ] Seo.svelte: canonical + OG-теги, per-tool OG-картинки (S1d/S1e)
- [ ] контент страницы инструмента: seo-блок в словарях, H1/how-to/FAQ/related
(S2)
- [ ] JSON-LD (SoftwareApplication/FAQPage/Breadcrumb) + llms.txt (S3)
- [ ] GSC + приватная аналитика (Plausible/Umami/CF), дистрибуция (S4)
## Платформа (API/PWA)
Общий план: `docs/plan-platform.md`; WASM-ядро и CLI уже в `docs/roadmap.md`
(фазы 3–8) — здесь только новые треки.
- [ ] PWA: manifest + service worker, оффлайн-режим, установка (после S1)
- [ ] API: спайк серверного ядра (нативный Rust vs edge-wasm), ключи, free tier
(после wasm-фаз 5–7)
## Качество production UI
Политика проверок — `docs/quality-gates.md`, e2e — `docs/testing-strategy.md`.
- [ ] Component-тесты `SchemaToolView`/`SchemaPreview` требуют отдельного
решения: node Vitest не имеет DOM/canvas, а e2e уже покрывает поведение.
- [ ] Ошибка декодирования изображения из `createImageBitmap` пока показывается
сырым сообщением браузера; нужен `ToolError`-маппер и i18n-ключ.
## Идеи
1. **Менять первый инструмент цепочки** — оценка M. Сейчас базовый инструмент
зафиксирован при открытии страницы; хочется заменить его на другой без
разборки цепочки: шаги и их параметры сохраняются, вход перечитывается.
Открытый вопрос: что делать с несовместимыми параметрами (text-source ↔
file).
2. **Сворачивать инструменты в chain** — оценка S. Тоггл сворачивания звена до
заголовка «Шаг n: название» (превью скрываются). Состояние свёрнутости
помнить в workspace-pipeline.
3. **Несколько цепочек: сохранение и загрузка** — оценка M. Именованные цепочки
в localStorage (список, создать/переименовать/удалить), быстрое переключение.
Формат экспортного JSON расширить опциональным полем имени, старые файлы
читаются как безымянные.
4. **Batch-обработка архивов выбранным chain** — оценка L. Вход — zip-архив
картинок (распаковка в браузере), прогон текущего или выбранного сохранённого
chain по каждому файлу, сборка результата обратно в zip для скачивания.
Зависит от идеи 3 (выбор цепочки) и от экспортного формата pipeline JSON;
прогресс и ошибки — пофайлово.
5. **Избранные инструменты (fav tools)** — оценка S/M. Тоггл-звёздочка на
карточках каталога, результатах поиска и в шапке страницы инструмента; список
id в localStorage. Избранное показывается отдельной секцией сверху каталога и
поднимается в выдаче поиска (бонус к popularity при скоринге).
6. **Конвертация формата — НЕ отдельный инструмент, а выбор в кнопке Download**
— оценка M/L. Инструменты `convert-png-to-jpg` / `convert-png-to-webp` (и др.
форматы) не должны жить как самостоятельные инструменты цепочки. Механическая
часть уже есть: `ToolEntry.output` (`OutputFormat`: mime/ext/qualityParamId)
и кодирование по нему в `SchemaToolView.download()` — `docs/architecture.md`,
раздел 3. Осталось (UX-райз «Download»):
- выбор формата/качества прямо в кнопке/диалоге Download для любого
результата (не отдельными конвертерами);
- экспорт с лимитом размера → закрывает отложенный `reduce-to-size-png`
(целевой KB, бинарный поиск по k из квантования). Проработать вместе с
достройкой download-флоу нового UI.
7. **`watermark-image-png` (водяной знак картинкой)** — оценка M. Нужна
overlay-механика: второй источник изображения (getOverlay/store), параметры
scale/opacity/position/margin/aspect. Решается вместе с вопросом, как второй
источник картинки вписывается в schema-driven preview (`SchemaToolView`).
8. **`png-info` (детальная информация о PNG)** — оценка M/L. Отдельный райз:
exif-теги, редактирование, структурированный вывод; нужен свой отдельный
случай в UI, не «ещё один text/verdict». Возможно нужна вообще отдельная
страница, несовместимая с другими инструментами: 1) она работает не с
изображением, а с метаданными из файла, 2) она не может быть частью цепочки,
т.к. результат не является изображением, 3) если надо изменить теги, никакого
форматирования и изменения в изображение вносить не надо, только в
метаинформацию.
9. **Region-инструменты** (censor/erase/pixelate-area/blur-area/sharpen-area/
reverse-area) — ждут UI выделения области на превью. Вне очереди.
10. **Мультифайловые инструменты-потребители** (gif-to-frames, separate-colors)
— механизм «результат = набор файлов» (1 → many) уже есть
(`docs/architecture.md`, раздел 7), первый потребитель —
`split-into-parts-png`. Остальные подключаются по мере нужды.
11. **Анимационные** (slow-reveal/fade/scrolling) — выход не PNG; отдельное
решение о формате.
12. **HARD-серия** (glitch, barcode, signature-extract, handwritten-digital).
13. **Контраст текста на акцентных кнопках — частично закрыт**. Тона
`--color-main`/`--color-accent` подняты под текущий порог `palette.test.ts`;
targeted-тест проходит. Light-тема всё ещё ниже AA 4.5 для обычного текста,
а `--color-danger` в light-теме на границе: после завершения редизайна
вернуть порог 4.5 и перепроверить оба токена.
14. **Отображение маски для инструментов (runMask/preview-mask)** — придумать и
реализовать процесс показа маски результата. **Контекст:** в старом
контракте поле `preview` у `remove-color`/`remove-background` показывало
быстрый ч/б превью-маску (`colorMask`/`backgroundMaskPreview`) того, что
будет вырезано. При миграции на единый `run(ctx)` поле убрано (шаг 8,
`web/src/lib/registry/alpha.ts`) — новый executor и schema-превью зовут
`run()` напрямую, маска пока не нужна. **Идея 1:** дать каждому `run`
возможность вернуть (или инструмент — объявить) `runMask` — ч/б изображение
маски изменений либо иной подход (отдельное поле `mask` + функция маски,
второй результат, overlay). Оценка — на усмотрение при проработке (S/M).
Пока живём без неё. **Идея 2:** каждый `run` возвращает два изображения —
для отображения (показывает маску или сам результат) и для передачи в
следующий инструмент (всегда результат). Оценка — на усмотрение при
проработке (S/M). Пока живём без неё.
15. **Набор файлов в пайплайне: 1 → many не должен быть терминальным** — оценка
L. **Сейчас** `execute` принимает один `source: PixelImage | undefined` и
возвращает один `ToolResult`, а `SchemaToolView` раскладывает вывод в
`result` / `fileResult` / `textResult` по `resultKind` — поэтому шаг с
`result: "files"` упирается в конец цепочки. **Направление:** следующий
инструмент применяется **ко всем картинкам** предыдущего результата
(fan-out), а many → 1 (вход = архив или несколько файлов) — обратная сторона
того же контракта. Терминальными остаются только результаты, которые не
картинка (text, verdict). Что обдумать:
- где проходит граница: один вызов `run(ctx)` на файл (имя части склеивается
в `FileResult.files`) или батч целиком на стороне исполнителя;
`executor/protocol.ts` `files` уже сериализуются, но при батче нужен
прогресс и отмена;
- частичные ошибки: один битый файл не должен ронять весь шаг — нужен
per-file отчёт, а не один `ToolError` на шаг;
- имена частей на каждом шаге и Download для набора (сейчас zip по
`tool.id`, `SchemaToolView.download()`);
- обратная сторона: распаковка zip в браузере, порядок файлов, поведение
many → 1 → many в одной цепочке. Зависит от идеи 10 (остальные потребители
1 → many) и идеи 4 (batch по архиву), `docs/roadmap.md` фаза 8
«batch-страница».
16. **Главная должна отличаться от каталога** — оценка S. Сейчас
`src/routes/+page.svelte` и `src/routes/list-tools/+page.svelte` побайтово
идентичны (совпадают script, шаблон и стили), при этом `/list-tools` —
рабочий маршрут: на него ссылается крошка в `+layout.svelte` и он открыт
e2e-сценариями `catalog.spec.ts`, `i18n.spec.ts`, `navigation.spec.ts`.
Замысел: главная — крупнее и с более простым поиском, без категорий; каталог
остаётся группировкой с фильтрами. Детектор дублирования разметки
сознательно не вводим — `docs/decisions.md`, раздел 1, поэтому расхождение
ловится на ревью.