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

275 lines
24 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`.
## 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`)
## Мелочи всякие
- [ ] split-into-parts-png - увеличить максимальные значения, плохо работает для
нарезки ассетов
- [ ] crop, resize (но скорее всего все инструменты) - при загрузке нового
изображения сбрасывает размеры, настроенные пользователем
- [ ] split-into-parts-png, resize (может еще какие-то) - возможность указывать
размеры из заранее одобренного списка размеров - 16х16, 32х32, 64х64 как
минимум, может еще какие-то размеры добавить, единый список из предыдущей
задачи - (для инди разработчиков, стандартные тайлы часто делаются)
- [ ] e2e: `i18n.spec.ts` и `text-and-verdicts.spec.ts` дублируют локаторы из
`helpers/page.ts` вместо вызова — правило «спека зовёт helpers»
(`docs/testing-strategy.md`, раздел 5)
- [ ] мёртвый i18n-ключ `noParams` («нет параметров — результат готов»): его
ничем не читают. Либо показывать подсказку для инструментов с пустой
схемой (FA-E1), либо удалить ключ из обеих локалей
- [ ] Пересмотреть тесты — убрать точные совпадения текстов и любые селекторы,
привязанные к разметке или svelte-классам (сейчас остались:
`tool-flows.spec.ts`, `schema-tool-strings.test.ts`)
- [ ] нужен инструмент для удаления фона по выбранной точке - удалять внутри
выделенной области
- [ ] сделать конвертацию в смайлики\награды для твитча (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)
- [ ] прикрутить кастомный color picker, добавить прозрачность (range?)
- [ ] проверить настройки range slider на crop-png - слишком большие значения
- [ ] для range slider field - добавить поле для ввода цифр и кнопку сброса
значения
- [ ] для keep Aspect field - пересчитывать второе поле, учитывать какое было
изменено
- [ ] обновить страницу kit или сделать storybook
- [ ] Свести 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`
получат одинаковый формат вывода. Нужно научить шаг переопределять формат
вывода
- [ ] придумать процесс редактирования и настройки pipeline - drag-n-drop,
удаление, добавление инструментов. переход один инструмент - pipeline без
перезагрузки
- [ ] `CatalogToolbar`: фильтры используют сырой `<button>`, а не `ui/Button` —
единый контрол для всей библиотеки
(`web/src/lib/components/CatalogToolbar.svelte`).
- [ ] `SchemaTextResult` вердикт-бейдж рисует руками: свои классы
`badge`/`badge-tone--{tone}` и свой CSS в `<style>` вместо
`ui/Badge.svelte` — тон и разметка бейджа живут в двух местах
(`web/src/lib/components/schema/SchemaTextResult.svelte`).
- [ ] `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
## Переезд
- [ ] множественные числа (часть/части/частей; «N параметров», счётчики) —
функция `tPlural(path, n)` и форма `PluralForms` (обязательное `other`,
опциональные `one`/`few`/`many`); первые потребители — `part`/`parts` в
подписи результата и счётчики параметров. **Критерий приёмки:** у ключа с
plurals есть все формы, для которых нужен перевод, `other` никогда не
пустой, число подставляется в текст без склейки
## SEO/GEO
- [ ] переименование бренда + домен: чек-лист в локальном файле
`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-блок в словарях, 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)
## Качество production UI
- [ ] `/` и `/list-tools` выходят без `<title>`: `svelte:head` есть только на
странице инструмента, а готовые ключи `home.defaultTitle`,
`catalog.pageTitle`, `catalog.metaDescription` не читает ни один компонент
(S1d)
- [ ] Component-тесты `SchemaToolView`/`SchemaPreview` требуют отдельного
решения: node Vitest не имеет DOM/canvas, а e2e уже покрывает поведение.
- [ ] Ошибка декодирования изображения из `createImageBitmap` пока показывается
сырым сообщением браузера; нужен `ToolError`-маппер и i18n-ключ.
## Идеи
Идеи 1–5 и 15 — про пайплайн (фаза 11 `docs/roadmap.md`). Идеи 6–14 и 16 — про
существующие инструменты и UI. Оценки (S/M/L) — оценка труда, не приоритет.
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;
прогресс и ошибки — пофайлово.
5. **Избранные инструменты (fav tools)** — оценка S/M. Тоггл-звёздочка на
карточках каталога, результатах поиска и в шапке страницы инструмента; список
slug в localStorage. Избранное показывается отдельной секцией сверху каталога
и поднимается в выдаче поиска (бонус к popularity при скоринге).
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).
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 по
`page.slug`, `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, поэтому расхождение
ловится на ревью.