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

24 KiB
Raw Blame History

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 и прочие правила

  • 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)

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

Порядок правок полей и раскладки — docs/plan-fields-audit-fixes.md, сами находки («что плохо», с датой аудита) — docs/tools-audit.md. Здесь — как это исправить; находка в аудите не отменяет задачу здесь.

  • Пересмотреть тесты - исправить всякие хрупкие, которые проверяют количество инструментов, точное совпадение текстов, поиск по 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 с паспортом, семейства с кириллицей)
  • поле ввода текста - сделать по умолчанию нормального размера, а не одну строку для svg - форматирование или подсветку синтаксиса??? для bin\hex - форматирование по колонкам??? для hex\bytes\rgba - пример в placeholder
  • сделать загрузку картинки исходника по 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 - пересчитывать второе поле, учитывать какое было изменено
  • обновить страницу kit или сделать storybook
  • Слаги инструментов (*-png) — развести id и адрес страницы. Инструменты работают с любым форматом, но называются crop-png, resize-png; имя в коде, пайплайнах и i18n должно быть crop, resize, а адрес и имя скачиваемого файла — прежними (/tools/crop-png → crop-png.png). Решение и его SEO-последствия: docs/plan-seo.md §0; текущее состояние (поля slug нет, роут — tools/[id]) — docs/architecture.md, раздел 3. Порядок работ: 1. добавить slug в ToolEntry + toolSlug() / getToolBySlug() в registry/index.ts, проверку уникальности slug в registry.test.ts; 2. перевести routes/tools/[id] → [slug] (entries(), load(), +page.svelte), ToolCard, крошку в +layout.svelte и имя файла download в SchemaToolView на toolSlug(tool); старые адреса продолжают работать, редиректы не нужны; 3. переименовать id волнами по группам реестра (convert, alpha, color, geometry, filters, analyze, generate, text); в каждой волне — registry/<group>.ts, ключи tools.* в en.ts/ru.ts, tool-icons.ts, захардкоженные id в тестах и e2e (smoke-i18n.test.ts, kit/+page.svelte); 4. docs/tools-map.md при этом не меняется: карта перечисляет id, а они остаются прежними как адреса. Обратной совместимости не делаем: формат пайплайна ещё не устоялся, старые экспорты и записи в localStorage после переименования просто перестают открываться — это осознанно, миграция усложнила бы код ради пары пользователей.
  • придумать процесс редактирования и настройки pipeline - drag-n-drop, удаление, добавление инструментов. переход один инструмент - pipeline без перезагрузки
  • 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 (S1–S4). Старт возможен — пока только domain-free часть S1. Полное содержание этапов не дублируется здесь, только идентификаторы.

  • переименование бренда + домен: чек-лист в локальном файле plan-domain.local.md (в git не входит, в клоне отсутствует; подробности и порядок — docs/plan-seo.md §6, R1/R2)
  • снять noindex со страниц инструментов, когда будут sitemap, canonical и контент (S1h; блокирует индексацию всего сайта) — docs/plan-seo.md §4
  • download с селектором формата PNG/JPG/WebP/BMP для всех инструментов (райз «Download» → S1f)
  • форматные страницы по конкурентным слагам (crop-jpeg, …) — только по вордстату с уникальным контентом; редиректы только для опечаток и переименований уже опубликованных страниц; клонов с canonical не делать (docs/plan-seo.md §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 (фазы 2–8). Здесь только треки, которых нет в roadmap.

  • PWA: manifest + service worker, оффлайн-режим, установка (после S1)
  • API: спайк серверного ядра (нативный Rust vs edge-wasm), ключи, free tier (после wasm-фаз 5–7)
  • Шрифты: лицензирование (F1–F4) и DOM-free рендер (F5–F6) — до фазы 8 (docs/plan-platform.md §4)

Качество production UI

Политика проверок — docs/quality-gates.md, e2e — docs/testing-strategy.md.

  • Component-тесты SchemaToolView/SchemaPreview требуют отдельного решения: node Vitest не имеет DOM/canvas, а e2e уже покрывает поведение.
  • Ошибка декодирования изображения из createImageBitmap пока показывается сырым сообщением браузера; нужен ToolError-маппер и i18n-ключ.

Идеи

Идеи 1–5 и 15 относятся к пайплайну (цепочкам шагов), которого в коде пока нет: это фаза 11 docs/roadmap.md. Идеи 6–14 — к существующим инструментам и UI. Оценки (S/M/L) — оценка труда, не приоритет.

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

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

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

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

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

  6. Конвертация формата — НЕ отдельный инструмент, а выбор в кнопке Download — оценка M/L. Решение и продуктовое обоснование: docs/plan-seo.md §0 и задача S1f; почему селектор не заменяет существующие convert-страницы — docs/plan-seo.md §5. Механическая часть уже есть: ToolEntry.output (OutputFormat: mime/ext/qualityParamId) и кодирование по нему в SchemaToolView.download() — docs/architecture.md, раздел 3. Что осталось сверх S1f:

    • экспорт с лимитом размера → закрывает отложенный reduce-to-size-png (целевой KB, бинарный поиск по k из квантования). Проработать вместе с достройкой download-флоу.
  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) — придумать и реализовать процесс показа маски результата. Контекст: удалённый UI-v1 умел показывать ч/б превью-маску «что будет вырезано» отдельным полем; при переходе на единый run(ctx) этого поля не осталось — executor и schema-превью зовут run() напрямую, маска не возвращается. Идея 1: дать каждому run возможность вернуть (или инструмент — объявить) runMask — ч/б изображение маски изменений либо иной подход (отдельное поле mask + функция маски, второй результат, overlay). Оценка — на усмотрение при проработке (S/M). Пока живём без неё. Идея 2: каждый run возвращает два изображения — для отображения (показывает маску или сам результат) и для передачи в следующий инструмент (всегда результат). Оценка — на усмотрение при проработке (S/M). Пока живём без неё. Первые кандидаты на маску: remove-color-from-png, remove-background-png.

  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, поэтому расхождение ловится на ревью.