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

271 lines
26 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**. Открытые задачи. Подробные планы, разбор решений и сырые
> находки — `docs/plan-seo.md`, `docs/plan-platform.md`,
> `docs/plan-fields-audit-fixes.md`, `docs/tools-audit.md`, `docs/decisions.md`.
>
> Все пункты — чекбоксы; нумерация «Идея N» в тексте сквозная по документу и
> сохраняется ради перекрёстных ссылок («идея 4 зависит от идеи 3»). Оценки
> (S/M/L) — оценка труда, не приоритет.
## Pipeline
- [ ] названия инструментов — в pipeline инструмент называется «обрезать png»,
но он работает с любыми картинками, наверное надо убрать; в заголовке
страницы — возможно, надо указать все форматы (связано с SEO)
- [ ] кнопка «добавить инструмент» в pipeline — обдумать селектор с нормальным
поиском, фильтром возможных инструментов и т.д.
- [ ] **Идея 1. Заменить инструмент шага без удаления** — оценка M. В заголовке
карточки шага кнопка «поменять инструмент»: заменяет инструмент на месте
(любой шаг, не только первый), остальные шаги и их параметры сохраняются,
вход перечитывается. Открытый вопрос: что делать с несовместимыми входами
(text-source ↔ file).
- [ ] **Идея 2. Сворачивать инструменты в chain** — оценка S. Тоггл сворачивания
звена до заголовка «Шаг n: название» (превью скрываются). Состояние
свёрнутости помнить в workspace-pipeline.
- [ ] **Идея 3. Несколько цепочек: сохранение и загрузка** — оценка M.
Именованные цепочки в localStorage (список, создать/переименовать/
удалить), быстрое переключение. Формат экспортного JSON расширить
опциональным полем имени; обратной совместимости со старыми выгрузками не
делаем — формат не устоялся: он появится вместе с фазой 11
`docs/roadmap.md` и до её старта может измениться. Плюс отдельная страница
со списком всех цепочек: удалить, переименовать, добавить новую,
«использовать» (переход на страницу инструмента с этой цепочкой). На
странице — упрощённый вид: только список инструментов цепочки, без
реального выполнения и параметров.
- [ ] **Идея 4. Batch-обработка архивов выбранным chain** — оценка L. Вход —
zip-архив картинок (распаковка в браузере), прогон текущего или выбранного
сохранённого chain по каждому файлу, сборка результата обратно в zip для
скачивания. Зависит от идеи 3 (выбор цепочки) и от экспортного формата
pipeline JSON; прогресс и ошибки — пофайлово.
- [ ] **Идея 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 по `page.slug`,
`SchemaToolView.download()`); - обратная сторона: распаковка zip в
браузере, порядок файлов, поведение many → 1 → many в одной цепочке.
Зависит от идеи 10 (остальные потребители 1 → many) и идеи 4 (batch по
архиву), `docs/roadmap.md` фаза 8 «batch-страница».
- [ ] **Идея 17. Промежуточные результаты шагов + выравнивание рядов** — оценка
M. Два режима просмотра цепочки: - **без выравнивания (по умолчанию):** в
панели просмотра цепочка изображений по 2 в колонку «исходник → результат
1 → результат 2 → … → конечный результат»; - **с выравниванием (галочка
«выровнять инструменты и просмотр»):** у каждого инструмента показаны его
исходник и результат построчно «параметры — исходник — результат»;
промежуточные картинки при этом осознанно дублируются на экране —
результат шага является исходником следующего.
## Инструменты
- [ ] qr code to text, text to qr code
- [ ] bar code to text, text to bar code
- [ ] split-into-parts-png — режим «по размеру тайла»: указываешь размер тайла
(16×16, 32×32…, список `SIZE_PRESETS`), инструмент сам считает сетку —
сценарий «режу спрайтшит, знаю размер тайла, не знаю сетку» (новый режим:
схема + core, из задачи C3)
- [ ] нужен инструмент для удаления фона по выбранной точке - удалять внутри
выделенной области
- [ ] сделать конвертацию в смайлики\награды для твитча (6 размеров или выбор
какой размер - 112\56\28px или 72\36\18)
- [ ] сделать несколько проходное сжатие png для получения необходимого размера
файлов, посмотреть реализацию в
[twitch-emote-resizer](https://github.com/tma02/twitch-emote-resizer)
- [ ] Пересмотреть прозрачность в инструментах - Create empty PNG - прозрачность
должны быть настраиваемой 0-100%, а не переключателем
- [ ] Font Style - обдумать выбор шрифта (google fonts???) как организовать
шрифты с кириллицей? сделать галочку "только с кириллицей"??? (решение о
наборе и лицензиях: `docs/plan-platform.md` §4 — только OFL/Apache с
паспортом, семейства с кириллицей)
- [ ] проверить настройки range slider на crop-png - слишком большие значения
- [ ] Свести convert-страницы (`convert-png-to-jpg`, `convert-png-to-webp`,
`png-to-bmp`) на один инструмент `convert` — зависит от S1f
(`docs/plan-seo.md` §4). Мешает не только `quality` (он живёт в схеме
инструмента), а сама модель: `output` с mime/ext — свойство `Tool`, а
`PageStep` умеет только `{ id, params? }`, поэтому страницы на общий `id`
получат одинаковый формат вывода. Нужно научить шаг переопределять формат
вывода
- [ ] **Идея 6. Конвертация формата — НЕ отдельный инструмент, а выбор в кнопке
Download** — оценка M/L. Решение и продуктовое обоснование:
`docs/plan-seo.md` §0 и задача **S1f**; почему селектор не заменяет
существующие convert-страницы — `docs/plan-seo.md` §5. Механическая часть
уже есть: `Tool.output` (`OutputFormat`: mime/ext/qualityParamId) и
кодирование по нему в `SchemaToolView.download()` —
`docs/architecture.md`, раздел 3. Что осталось сверх S1f: - экспорт с
лимитом размера → «сжатие до целевого КБ»: для lossy это quality в
селекторе формата, для PNG — бинарный поиск по k из квантования. Нужна ли
отдельная страница под этот интент — открытый вопрос с вордстатом, имя не
выбрано (`docs/plan-seo.md` §5). Проработать вместе с достройкой
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).
- [ ] **Идея 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`.
## UI и качество
- [ ] мёртвый i18n-ключ `noParams` («нет параметров — результат готов»): его
ничем не читают. Либо показывать подсказку для инструментов с пустой
схемой (FA-E1), либо удалить ключ из обеих локалей
- [ ] неудобно настраивать ползунками, некоторые инструменты удобнее настроить
через drag-n-drop. звучит сложно, но надо придумать процесс
- [ ] просмотр картинки в оригинальном размере, и возможно с зумом отдельных
областей, чтобы просмотреть мелкие артефакты, выбор разных подложек -
черная\белая\цветные\серая для проверки прозрачных картинок
- [ ] при клике на картинку-исходник предложить загрузитрь другой файл (возможно
сделать кнопку, которая появляется при ховере на картинке)
- [ ] обдумать объединение пар `inputMode + source` и `resultKind + result` в
единую структуру, позволит упростить некоторые вещи - например
`sourceValue` \ `resultValue` в `SchemaPreview.svelte`
- [ ] Рассмотреть необходимость всех этих пропсов в `SchemaPreview.svelte` они
дублируют друг друга `ontextsource`, `onrendertext`, `oncopytext`,
`ondownloadtxt`, `ondownload`,
- [ ] Переделать внешний вид инструментов без настроек, например Remove alpha
channel PNG "remove-alpha-channel-png". Сейчас выглядит слишком пустым.
- [ ] Пересмотреть поля - Plate, Position, Font Style - сейчас второй label
- [ ] поле ввода текста - сделать по умолчанию нормального размера, а не одну
строку для svg - форматирование или подсветку синтаксиса??? для bin\hex -
форматирование по колонкам??? для hex\bytes\rgba - пример в placeholder
- [ ] прикрутить кастомный color picker, добавить прозрачность (range?)
- [ ] обновить страницу kit или сделать storybook
- [ ] `PreviewTile`: высота плитки задана только `min-height: clamp(...)`,
поэтому она не следует за пропорциями результата — широкий результат
уезжает в узкую полосу, а высокий упирается в `max-height: 100vh`. Нужно,
чтобы соотношение сторон выбиралось по результату в диапазоне 16:9…9:16
(`web/src/lib/components/schema/PreviewTile.svelte`).
- [ ] Радиусы бордеров: `--radius-m` ненулевой и применён ко всем бордерам
(`app.css`, `SchemaToolView.svelte`). Решить, где скругления реально есть
в дизайне, а где должен быть 0
- [ ] Component-тесты `SchemaToolView`/`SchemaPreview` требуют отдельного
решения: node Vitest не имеет DOM/canvas, а e2e уже покрывает поведение.
- [ ] Ошибка декодирования изображения из `createImageBitmap` пока показывается
сырым сообщением браузера; нужен `ToolError`-маппер и i18n-ключ.
- [ ] **Идея 5. Избранные инструменты (fav tools)** — оценка S/M.
Тоггл-звёздочка на карточках каталога, результатах поиска и в шапке
страницы инструмента; список slug в localStorage. Избранное показывается
отдельной секцией сверху каталога и поднимается в выдаче поиска (бонус к
popularity при скоринге).
- [ ] **Идея 13. Контраст текста на акцентных кнопках — частично закрыт**. Тона
`--color-main`/`--color-accent` подняты под текущий порог
`palette.test.ts`; targeted-тест проходит. Light-тема всё ещё ниже AA 4.5
для обычного текста, а `--color-danger` в light-теме на границе: после
завершения редизайна вернуть порог 4.5 и перепроверить оба токена.
- [ ] **Идея 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, поэтому расхождение
ловится на ревью.
## Тесты и lint
- [ ] `tseslint.config(...)` deprecated: сигнатура
`(...configs: InfiniteDepthConfigWithExtends[]): ConfigArray` помечена
устаревшей, нужен переход на `defineConfig` из `eslint/config` (ESLint
core, а не `typescript-eslint`) — `web/eslint.config.js`.
- [ ] удалить мёртвые `tools.*.params` из root i18n после проверки потребителей;
до этого действует pattern-based policy-исключение
(`web/eslint-plugins/README.md`, раздел `dict-consistency`)
- [ ] e2e: `i18n.spec.ts` и `text-and-verdicts.spec.ts` дублируют локаторы из
`helpers/page.ts` вместо вызова — правило «спека зовёт helpers»
(`docs/testing-strategy.md`, раздел 5)
- [ ] e2e webkit: случайные падения по таймауту 5с (элемент не появляется),
каждый прогон падают разные тесты — webkit под Windows слишком медленный.
Рассмотреть увеличение timeout/expectTimeout для webkit-проекта в
`playwright.config.ts`. После фикса перепроверить `tool-flows.spec.ts`
«chain: remove step» — на webkit удаление шага не успевает за 5с (на
остальных движках стабильно)
- [ ] Пересмотреть тесты — убрать точные совпадения текстов и любые селекторы,
привязанные к разметке или svelte-классам (сейчас остались:
`tool-flows.spec.ts`, `schema-tool-strings.test.ts`)
- [ ] можно ли в тестах получать i18n ключ вместо текста? можно ли написать lint
правило такое (запретить toContain без i18n)
- [ ] убрать в тестах все нестандартные символы `→`, длинные тире, русский язык
и т.д., сделать lint правило
- [ ] комментарии на английском, lint правило
- [ ] уменьшить количество и многословность комментариев (lint правило?)
## SEO/GEO
- [ ] переименование бренда + домен: чек-лист в локальном файле
`plan-domain.local.md` (в git не входит, в клоне отсутствует; подробности
и порядок — `docs/plan-seo.md` §6, R1/R2)
- [ ] снять `noindex` со страниц инструментов, когда будут sitemap, canonical и
контент (S1h; блокирует индексацию всего сайта) — `docs/plan-seo.md` §4
- [ ] форматные страницы по конкурентным слагам (`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-блок в словарях, how-to/FAQ/related (S2)
- [ ] JSON-LD (SoftwareApplication/FAQPage/Breadcrumb) + llms.txt (S3)
- [ ] дистрибуция: закрепить репо, alternative.to, Product Hunt, Reddit/HN (S4c)
- [ ] GSC: подключить домен, отправить sitemap, мониторинг индексации (S4a)
- [ ] GA4: cookieless-конфигурация, отключить рекламные audiences и signals,
`anonymize_ip` — сейчас в `web/src/routes/+layout.svelte` голый
`gtag('config')` (S4b)
## Платформа (API/PWA)
- [ ] 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)
## Переезд
- [ ] множественные числа (часть/части/частей; «N параметров», счётчики) —
функция `tPlural(path, n)` и форма `PluralForms` (обязательное `other`,
опциональные `one`/`few`/`many`); первые потребители — `part`/`parts` в
подписи результата и счётчики параметров. **Критерий приёмки:** у ключа с
plurals есть все формы, для которых нужен перевод, `other` никогда не
пустой, число подставляется в текст без склейки