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

24 KiB
Raw Blame History

Backlog

lint и прочие правила

  • Кросс-языковой линтер словарей (warn-only: паритет ключей, пустые значения, совпадение {placeholder}-переменных между всеми локалями) — правило i18n/dict-consistency, детали в web/eslint-plugins/README.md. Правило реализовано; Q2 перевёл i18n baseline к zero-warning через policy-aware fallback.
  • Проверка текстов в svelte/ts/html — реализовано правилом i18n/no-hardcoded-user-text (warn, baseline 0): ловит текст в шаблоне и в пользовательских атрибутах, исключения — бренд, форматы, имена файлов, registry-строки и /kit. Детали в web/eslint-plugins/README.md.
  • tseslint.config(...) deprecated: сигнатура (...configs: InfiniteDepthConfigWithExtends[]): ConfigArray помечена устаревшей, нужен переход на defineConfig из typescript-eslint — web/eslint.config.js.
  • удалить мёртвые tools.*.params из root i18n после проверки потребителей; до этого Q2 держит pattern-based policy-исключение

Мелочи всякие

  • Пересмотреть тесты - исправить всякие хрупкие, которые проверяют количество инструментов, точное совпадение текстов, поиск по 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).

Переезд

  • добавить i18n в preview
  • множественные числа (часть/части/частей; «N параметров», счётчики) — tPlural() и формат PluralForms; детали и критерии — в этом backlog

SEO/GEO

Общий план: docs/plan-seo.md (S0–S4). C17 выполнен; старт возможен — пока только 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

Q5–Q6 и Q7–Q8 закрывают известные preview-проблемы, special fixtures, smoke, layout/view-model инварианты, browser matrix, coverage-гейт и линтеры; активных test.fixme в e2e больше нет.

  • Генераторы auto-run без кнопки Generate — web/e2e/generators.spec.ts.
  • resize-png и crop-png используют размеры текущего source через общий source-aware schema resolver — web/e2e/pipeline.spec.ts.
  • Reset сохраняет source/text, восстанавливает defaults и запускает deferred auto-run — web/e2e/pipeline.spec.ts.
  • Ошибки хранят i18n key/vars и переводятся при выводе; изменение языка обновляет alert — web/e2e/i18n.spec.ts.
  • Malformed/special PNG fixtures: CRC, truncated, palette и 16-bit проходят через upload без краша — web/e2e/png-fixtures.spec.ts.
  • Registry-wide smoke покрывает все 122 инструмента по input/result-типу — web/e2e/tools-smoke.spec.ts, generators.spec.ts, text-and-verdicts.spec.ts.
  • Layout-группировка вынесена в resolveLayoutGroups и покрыта unit-тестами; SchemaFields.svelte использует общий seam.
  • SchemaPreview view-model вынесена в buildSchemaPreviewModel и покрыта unit-тестами для всех input/result-типов.
  • Browser matrix: полный Chromium, Firefox/WebKit для browser-critical спецификаций и mobile Chromium 390×844 — web/playwright.config.ts.
  • Расхождение декодеров зафиксировано как ожидаемое поведение: Firefox и WebKit декодируют truncated-no-iend и idat-cut, а WebKit ещё и crc-bad-idat. Таблица движков живёт в web/e2e/png-fixtures.spec.ts, продукт не ужесточается, и любая выгрузка битого файла обязана давать alert, а не падение или «пустой» результат.
  • Component-тесты SchemaToolView/SchemaPreview требуют отдельного решения: node Vitest не имеет DOM/canvas, а e2e уже покрывает поведение.
  • Ошибка декодирования изображения из createImageBitmap пока показывается сырым сообщением браузера; нужен ToolError-маппер и i18n-ключ. Это продуктовая задача, не Q6d.

Идеи

  1. Менять первый инструмент цепочки — оценка M. Сейчас базовый инструмент зафиксирован при открытии страницы; хочется заменить его на другой без разборки цепочки: шаги и их параметры сохраняются, вход перечитывается. Открытый вопрос: что делать с несовместимыми параметрами (text-source ↔ file).

  2. Сворачивать инструменты в chain — оценка S. Тоггл сворачивания звена до заголовка «Шаг n: название» (превью скрываются). Состояние свёрнутости помнить в workspace-pipeline.

  3. Несколько цепочек: сохранение и загрузка — оценка M. Именованные цепочки в localStorage (список, создать/переименовать/удалить), быстрое переключение. Формат экспортного JSON расширить опциональным полем имени, старые файлы читаются как безымянные.

  4. Batch-обработка архивов выбранным chain — оценка L. Вход — zip-архив картинок (распаковка в браузере), прогон текущего или выбранного сохранённого chain по каждому файлу, сборка результата обратно в zip для скачивания. Зависит от п.4 (выбор цепочки) и от экспортного формата pipeline JSON; прогресс и ошибки — пофайлово.

  5. Избранные инструменты (fav tools) — оценка S/M. Тоггл-звёздочка на карточках каталога, результатах поиска и в шапке страницы инструмента; список id в localStorage. Избранное показывается отдельной секцией сверху каталога и поднимается в выдаче поиска (бонус к popularity при скоринге).

  6. Конвертация формата — НЕ отдельный инструмент, а выбор в кнопке Download — оценка M/L. Инструменты convert-png-to-jpg / convert-png-to-webp (и др. форматы) не должны жить как самостоятельные инструменты цепочки. Вместо этого — бесшовное внедрение выбора формата/качества прямо в кнопку/диалог Download: юзер скачивает результат в нужном формате (mime/ext/quality), а pipeline при этом не усложняется лишним звеном. Сделано (2026-09): механическая часть реализована в preview — ToolEntry.output (OutputFormat: mime/ext/qualityParamId) в web/src/lib/registry/types.ts; SchemaToolView.download() кодирует по output (jpg/webp/bmp уже настроены; png-to-bmp переведён сюда же). Q6c покрывает этот фиксированный контракт unit/E2E-проверками; переключатель форматов и quality остаётся отдельным UX-райзом. Осталось (UX-райз «Download»):

    • выбор формата/качества прямо в кнопке/диалоге Download для любого результата (не отдельными конвертерами);
    • экспорт с лимитом размера → закрывает отложенный reduce-to-size-png (целевой KB, бинарный поиск по k из квантования). Проработать вместе с достройкой download-флоу нового UI.
  7. watermark-image-png (водяной знак картинкой) — оценка M. Отложен из миграции (archive/plan-migrate-remaining.md). Нужна 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 выделения области на превью. Из archive/plan-gap-waves.md («вне очереди»).

  10. Мультифайловые инструменты-потребители (gif-to-frames, separate-colors) — механизм «результат = набор файлов» (1 → many) реализован: FileResult + result: "files" + скачивание zip-архивом + грид-превью частей. Первый потребитель — split-into-parts-png. Остальные подключаются по мере нужды.

  11. Анимационные (slow-reveal/fade/scrolling) — выход не PNG; отдельное решение о формате. Из archive/plan-gap-waves.md.

  12. HARD-серия (glitch, barcode, signature-extract, handwritten-digital). Из archive/plan-gap-waves.md.

  13. Контраст текста на акцентных кнопках — частично закрыт. Для dark-темы --color-main/--color-accent подняты до tone 56, чтобы пройти текущий порог palette.test.ts 4.0; targeted-тест проходит. Light-тема сохраняет контраст ~4.1–4.3, что ниже AA 4.5 для обычного текста, поэтому после завершения редизайна нужно повторно поднять тона и вернуть порог 4.5. Также проверить --color-danger (dark, тон 55): текст на нём 4.93 — ок, но light-danger tone 48 = 4.25 на границе.

  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 и many → 1 — абстракция результата «набор файлов» оформлена и работает: тип FileResult, result: "files" в реестре, сериализация через executor, скачивание zip-архивом, грид-превью частей. Реализовано на первом потребителе split-into-parts-png (2026-09, docs/archive/plan-split-into-parts.md). Q6b закрывает контракт ZIP/download: unit-тесты web/src/lib/zip.test.ts и browser-сценарий web/e2e/pipeline.spec.ts проверяют имена частей и содержимое архива. 1 → many: подключение остальных потребителей (gif-to-frames, separate-colors) при необходимости; формат/качество файлов внутри zip — отложено до UX-райза «Download» (п.7). many → 1 (вход = архив/несколько картинок → единый результат): не реализовано. Зависит от batch-обработки архивов (п.5 идей, roadmap фаза 8 «batch-страница»). Нужна отдельная проработка входа (распаковка zip в браузере, порядок файлов, поведение в пайплайне — такие инструменты терминальны, как и 1 → many).

  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. Замысел: главная — крупнее и с более простым поиском, без категорий; каталог остаётся группировкой с фильтрами. Найдено измерением дублирования разметки по 65 .svelte-файлам: файлы побайтово идентичны.