mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
288 lines
24 KiB
Markdown
288 lines
24 KiB
Markdown
# 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, поэтому расхождение
|
||
ловится на ревью.
|