docs: large update docs

This commit is contained in:
2026-09-25 14:20:44 +05:00
parent c187619933
commit acf9f19f1b
13 changed files with 379 additions and 82 deletions
+74
View File
@@ -0,0 +1,74 @@
# Документация проекта
> Статус: **active**. Это индекс документов и карта источников истины для
> разработчиков и агентов. Подробные правила находятся в самих документах, а
> обязательный краткий контракт — в `AGENTS.md`.
## Порядок чтения
1. `AGENTS.md` — команды, обязательные инварианты и границы old/new.
2. Этот файл — выбрать актуальный документ по теме.
3. `docs/plan-codebase-quality.md` — текущий план приведения качества в порядок
и последовательность следующих шагов.
4. Соответствующий план или checklist темы.
5. Исходники, конфигурация и тесты рядом с изменяемым кодом.
## Активные документы
| Документ | Роль | Статус |
| ---------------------------------- | ---------------------------------------------------- | ------ |
| `AGENTS.md` | Краткий обязательный контракт для агента | active |
| `docs/plan-codebase-quality.md` | План quality gates, тестов и lint-правил | draft |
| `docs/agent-workflow.md` | Подробный порядок исследования, изменения и проверки | active |
| `docs/backlog.md` | Продуктовые, UX- и инфраструктурные задачи | active |
| `docs/roadmap.md` | Общие направления развития | active |
| `docs/plan-redesign.md` | Новый дизайн и границы `/v1` | active |
| `docs/plan-preview-i18n.md` | План i18n нового UI | active |
| `docs/plan-seo.md` | SEO/GEO-план | active |
| `docs/plan-platform.md` | PWA/API/WASM-план | active |
| `docs/checklist-manual-testing.md` | Ручная приёмка preview | active |
| `docs/tools-map.md` | Живая карта инструментов | active |
| `web/eslint-plugins/README.md` | Детали custom lint rules и token policy | active |
| `docs/archive/README.md` | Правила архивирования и удаления старых документов | active |
`docs/archive/` содержит временную историческую справку и не является текущим
источником критериев приёмки. Для старых документов действует срок хранения 30
дней; после него их удаляют, а при необходимости достают из git history.
## Где хранить новую информацию
- Поведение, которое агент обязан соблюдать сразу, — кратко в `AGENTS.md`.
- Точные команды, параметры скриптов и критерии качества — в
`docs/quality-gates.md` после Q1 или в README соответствующей подсистемы.
- Архитектура, потоки данных и границы модулей — в отдельном architecture-плане
или документе, не дублируя существующие планы.
- Реализация lint-правил, fixtures и технические детали ESLint — в
`web/eslint-plugins/README.md` и исходниках правил.
- Продуктовые решения и ручная приёмка — в backlog, плане и checklist.
Подробные материалы хранятся в `docs/`, а не в корне. Новый файл создаётся
только если темы нет в существующем документе; иначе обновляется источник
истины.
## Текущий baseline Q0
На момент фиксации Q0:
- registry нового UI содержит 122 инструмента;
- `pnpm --dir web check` проходит без ошибок и предупреждений;
- `pnpm --dir web lint:all` завершается с 0 errors, но с 188 warnings
`i18n/dict-consistency` и 4 unused design tokens;
- unit/e2e результаты считать актуальными только после отдельного прогона;
исторические числа в `docs/archive/` не являются baseline.
Baseline и следующий шаг поддерживаются в `docs/plan-codebase-quality.md`.
## Правила актуальности
- У активного документа есть статус: `draft`, `active`, `completed` или
`archived`.
- Ссылки на конкретный файл или команду проверяются при изменении источника
истины.
- Архивный документ не возвращается в live-критерии без явной сверки.
- После каждого шага плана агент останавливается, показывает изменённые файлы,
проверки и нерешённые решения, и ждёт ревью.
+103
View File
@@ -0,0 +1,103 @@
# Workflow для агентов
> Статус: **active**. Подробная процедура работы с репозиторием; краткие
> обязательные правила остаются в `AGENTS.md`. Этот документ не заменяет source
> of truth конкретной подсистемы.
## 1. Подготовка к задаче
1. Прочитать `AGENTS.md` и `docs/README.md`.
2. Найти релевантный активный план, backlog или checklist.
3. Проверить `git status`: не перезаписывать чужие незакоммиченные изменения.
4. Найти существующие типы, константы, helpers и тестовые паттерны до создания
нового определения.
5. Определить границу изменения:
- новый UI — `web/src/routes/**` и `web/src/lib/components/**`;
- legacy — `web/src/routes/v1/**` и `web/src/lib/v1/**`;
- shared — `web/src/lib/core/**` и `web/src/lib/theme.svelte.ts`.
Изменение shared-кода требует проверки обеих веток. Смешивание old/new нельзя
обходить относительными импортами или исключениями линтера.
## 2. Порядок изменения
- Сначала исправляются тесты или контракт, который фиксирует неверное поведение,
затем production-код — если это не отдельная продуктовая задача.
- Один PR решает одну проблему и не объединяет lint, i18n, UI и архитектурный
рефакторинг без необходимости.
- Изменения держатся небольшими и атомарными, примерно до 500 строк или меньше.
- Не добавлять комментарии, которые пересказывают код. Комментарий объясняет
причину решения или фиксирует неочевидный инвариант.
- Не коммитить изменения автоматически: коммит делает разработчик после ревью.
## 3. Проверки
Команды и их область применения перечислены в `AGENTS.md`; после Q1 их точная
матрица будет поддерживаться в `docs/quality-gates.md`.
| Изменение | Минимальная проверка |
| ------------------------------------------------------- | ------------------------------------------------------ |
| Только Markdown | `pnpm check:docs` |
| TypeScript/Svelte | `pnpm --dir web check`, `pnpm --dir web test` |
| Lint-конфиг или custom rule | `pnpm --dir web test:rules`, `pnpm --dir web lint:all` |
| Маршрут, загрузка, результат, download, тема или локаль | `pnpm --dir web test:e2e` |
| Перед релизом | полный quality gate из плана Q1 |
`lint:all` может завершиться успешно при warnings. Это не означает чистый
baseline: нужно отдельно показать число errors, warnings и token warnings.
E2E запускается отдельно от быстрых проверок, потому что поднимает build и
статический сервер. Для UI-изменений сначала выбирается минимальный
пользовательский поток, затем при необходимости расширяется smoke.
## 4. Работа с тестами
- Поведенческий тест проверяет пользовательский контракт, а не текущую
реализацию.
- Сначала предпочитать `role`, `aria-*`, label, stable id или href.
- `data-testid` использовать только там, где семантического locator нет.
- Не фиксировать абсолютное число инструментов, если проверка не связана с этим
инвариантом.
- Точные переводы проверять в словарях и i18n helpers; в e2e проверять поведение
и отдельный locale smoke.
- `test.fixme` допускается только для зарегистрированной проблемы или явного
тестового долга, с ссылкой на backlog или checklist. После исправления тест и
его issue обновляются вместе.
- Новые fixtures должны быть воспроизводимыми и не требовать ручного создания
больших бинарных файлов.
## 5. Документация
Источник истины выбирается по теме:
- обязательное поведение агента — `AGENTS.md`;
- индекс и карта документов — `docs/README.md`;
- качество и точные команды — `docs/quality-gates.md` после Q1;
- тестовая архитектура — `docs/testing-strategy.md` после Q3;
- lint implementation — `web/eslint-plugins/README.md`;
- продуктовые решения — backlog и активные планы.
Не дублировать длинные объяснения в нескольких файлах. Если правило требует
пояснения, в `AGENTS.md` оставить короткую понятную формулировку и ссылку на
подробный документ.
### Архивирование завершённых документов
- Если план или исследование больше не является рабочим источником, перенести
файл в `docs/archive/`.
- В начало файла добавить `Статус`, `Архивирован`, `Удалить после` и причину.
- Архив хранить 30 дней для быстрой справки; после срока удалить после проверки
ссылок. Если решение понадобится снова, использовать git history.
- Не переносить активный план в архив только потому, что он пока не начат.
## 6. Протокол ревью между шагами
После каждого шага плана агент:
1. останавливается и не начинает следующий Q-этап;
2. перечисляет изменённые файлы и принятые решения;
3. указывает выполненные проверки и их фактический результат;
4. отдельно перечисляет warnings, fixme, долги и вопросы;
5. ждёт подтверждения на продолжение.
Следующий шаг начинается только после ревью текущего изменения.
+52
View File
@@ -0,0 +1,52 @@
# Архив документов
> Статус: **active**. Здесь хранятся завершённые, отменённые и явно устаревшие
> документы как временная историческая справка.
## Назначение
Архив помогает быстро посмотреть, какое решение принималось раньше и почему. Он
не является источником текущих требований, критериев приёмки или команды. Для
актуальных правил используются `AGENTS.md`, `docs/README.md` и активные планы.
Если решение снова понадобится, его можно восстановить из git history или
создать новый активный документ.
## Обязательные метаданные
При переносе документа в архив добавить в начало:
```text
> Статус: archived
> Архивирован: YYYY-MM-DD
> Удалить после: YYYY-MM-DD
> Причина: краткое объяснение, почему документ больше не активен
> Использование: только историческая справка
```
Дата `Удалить после` — дата архивирования плюс 30 дней. Старые файлы, созданные
до введения политики, могут не иметь этих дат; они также считаются архивными и
не являются активными требованиями. При следующем касании их можно удалить или
привести к шаблону.
## Порядок архивирования
1. Убедиться, что документ действительно завершён, отменён или заменён более
актуальным источником.
2. Добавить обязательные метаданные.
3. Переместить файл в `docs/archive/`.
4. Проверить ссылки из backlog, планов, checklist и `docs/README.md`.
5. Не менять архивный документ под новые требования.
## Удаление
Через 30 дней после архивирования:
- проверить, что документ не нужен для текущей работы;
- найти и удалить оставшиеся ссылки на него из активных документов;
- удалить файл из `docs/archive/`;
- при необходимости отметить удаление в истории изменений.
До истечения срока архивный файл не превращается обратно в live-документ: если
он снова актуален, создаётся новый документ или возвращается версия из git
истории с новым статусом и датами.
@@ -1,5 +1,9 @@
# Анализ: набор PNG-утилит для браузера
> Статус: archived Архивирован: 2026-09-25 Удалить после: 2026-10-25 Причина:
> ранний исследовательский разбор, не являющийся текущим планом Использование:
> только историческая справка
Проект: **easy-png-tools** — набор PNG-утилит, работающий полностью в браузере.
Вдохновлён идеей онлайн-сервисов «все PNG-операции в одном месте»: никаких
загрузок на сервер, всё считается локально. Стек: **SvelteKit +
@@ -1,5 +1,9 @@
# Хранить данные для сортировки по популярности инструментов
> Статус: archived Архивирован: 2026-09-25 Удалить после: 2026-10-25 Причина:
> ранний исследовательский вариант, не являющийся текущим планом Использование:
> только историческая справка
Идея выложить на Vercel и использовать Vercel KV (на базе Upstash Redis) — это
отличный, рабочий и очень быстрый в реализации вариант. Для 150 инструментов
объем данных будет крошечным, но здесь есть пара критически важных нюансов по
+33 -25
View File
@@ -5,7 +5,8 @@
- [x] Кросс-языковой линтер словарей (warn-only: паритет ключей, пустые
значения, совпадение `{placeholder}`-переменных между всеми локалями) —
правило `i18n/dict-consistency`, детали в §Фаза 8
`docs/plan-preview-i18n.md`
`docs/plan-preview-i18n.md`. Правило реализовано; доведение baseline до
zero-warning вынесено в Q2 `docs/plan-codebase-quality.md`.
- [ ] проверка дублирования кода html - div с одинаковым классом и т.д. (глянуть
что за `SonarLint` или написать кастомный линтер)
- [ ] проверка текстов в svelte\ts\html - всё тексты должны быть через i18n
@@ -109,29 +110,36 @@
Зарегистрированы при написании e2e (`web/e2e/`, `pnpm --dir web test:e2e`) и
ручного чек-листа — см. `docs/checklist-manual-testing.md` (раздел G). Каждый
зафиксирован как `test.fixme`. После фикса бага: убрать соответствующий
`test.fixme` и отметить пункт G в чек-листе как пройденный.
пункт связан с соответствующим `test.fixme` или отдельным тестовым долгом. После
фикса: убрать `test.fixme` и отметить пункт G в чек-листе как пройденный.
1. **Генераторы без кнопки «Generate»** — все 21 инструмент категории GENERATE
открываются, но в UI нет кнопки Generate и полей схемы (только RU/EN/Reset);
результат через UI недостижим. В `SchemaToolView.svelte` `isGenerator`
определяется как `tool.generate && !tool.run`, кнопка рисуется только если
`ongenerate` прокинут, а для генераторов с дефолтным `input: "file"` — нет.
Ожидание: поля схемы + кнопка «Generate», результат-картинка по дефолтам.
Fixme: `web/e2e/generators.spec.ts`. Кнопки и не должно быть, все процессы
должны запускаться автоматически
1. **Генераторы без автоматического результата** — все 21 инструмент категории
GENERATE открываются, но в UI нет полей схемы и результата; доступны только
RU/EN/Reset. В `SchemaToolView.svelte` уже есть auto-run через debounce,
поэтому отдельная кнопка Generate не требуется. Ожидание: поля схемы,
автоматический запуск по дефолтам и результат-картинка. Fixme:
`web/e2e/generators.spec.ts`. Кнопка Generate не добавляется без отдельного
UX-решения.
2. **resize-png с дефолтами падает** — схема по умолчанию `size: 0×0` +
`keepAspect: true` → при загрузке ЛЮБОГО PNG сразу `errors.resizeSize`
(alert), результата нет. `registry-new/geometry.ts`. Ожидание: осмысленный
дефолт-размер (например, исходный) либо кнопка, а не авто-ошибка.
(alert), результата нет. `web/src/lib/registry/geometry.ts`. Ожидание:
осмысленный дефолт-размер (например, исходный) либо отдельный режим ввода, а
не авто-ошибка.
3. **crop-png с дефолтами падает** — аналогично: `width: 0, height: 0` → сразу
`errors.cropSize`. `registry-new/geometry.ts`. Ожидание: базовый кроп по
умолчанию либо внятное предзаполнение.
`errors.cropSize`. `web/src/lib/registry/geometry.ts`. Ожидание: базовый кроп
по умолчанию либо внятное предзаполнение.
4. **Сырые ключи ошибок в UI** — alert на tool-странице показывает сырой ключ
i18n (`errors.resizeSize`), а не сообщение из `en.ts` / `ru.ts` (там
`resizeSize: "Width and/or height must be positive"`). Проверяется на
resize-png / crop-png. Ожидание: человекочитаемое сообщение на текущем языке.
Fixme: `web/e2e/known-issues.spec.ts` (тест «error message localized»).
5. **Theme storage key в e2e устарел** — production использует ключ `theme`, а
`web/e2e/navigation.spec.ts:30-48` проверяет `easy-png-tools:theme`.
Ожидание: исправить тест на фактический контракт и снять `test.fixme`.
6. **Reset и auto-run требуют решения** — `pipeline.spec.ts:55-63` ожидает
очистку результата, но текущий `SchemaToolView.svelte:162-173` может сразу
перезапустить обработку. Нужно определить семантику Reset, затем исправить
тест и снять `test.fixme`.
## Идеи
@@ -168,7 +176,7 @@
**Download**: юзер скачивает результат в нужном формате (mime/ext/quality), а
pipeline при этом не усложняется лишним звеном. **Сделано (2026-09):**
механическая часть реализована в preview — `ToolEntry.output`
(`OutputFormat`: mime/ext/qualityParamId) в `registry-new/types.ts`;
(`OutputFormat`: mime/ext/qualityParamId) в `web/src/lib/registry/types.ts`;
`SchemaToolView.download()` кодирует по `output` (jpg/webp/bmp уже настроены;
`png-to-bmp` переведён сюда же). **Осталось (UX-райз «Download»):**
- выбор формата/качества прямо в кнопке/диалоге Download для любого
@@ -221,15 +229,15 @@
контракте поле `preview` у `remove-color`/`remove-background` показывало
быстрый ч/б превью-маску (`colorMask`/`backgroundMaskPreview`) того, что
будет вырезано. При миграции на единый `run(ctx)` поле убрано (шаг 8,
`registry-new/alpha.ts`) — новый executor и schema-превью зовут `run()`
напрямую, маска пока не нужна. **Идея 1:** дать каждому `run` возможность
вернуть (или инструмент — объявить) `runMask` — ч/б изображение маски
изменений либо иной подход (отдельное поле `mask` + функция маски, второй
результат, overlay). Оценка — на усмотрение при проработке (S/M). Пока живём
без неё. **Идея 2:** каждый `run` возвращает два изображения - для
отображения (показывает маску или сам результат), и для передачи в следующий
инструмент (всегда результат. Оценка — на усмотрение при проработке (S/M).
Пока живём без неё.
`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`,
+21
View File
@@ -96,6 +96,27 @@
корректный (не «кракозябры»).
- [ ] remove-background на сложной полупрозрачности — края не «звенят».
## G. Известные баги preview
> Список синхронизирован с `docs/backlog.md`. Каждый пункт связан с
> зарегистрированной проблемой или соответствующим `test.fixme`; после
> исправления отметить его здесь и убрать `test.fixme` в том же изменении.
- [ ] **Генераторы:** открыть инструмент категории GENERATE, проверить поля
схемы, автоматический запуск по дефолтам и появление результата; кнопка
Generate не требуется. `docs/backlog.md`, `web/e2e/generators.spec.ts`.
- [ ] **resize-png:** загрузить изображение и получить результат без alert.
`docs/backlog.md`, `web/e2e/known-issues.spec.ts`.
- [ ] **crop-png:** загрузить изображение и получить осмысленный результат без
alert. `docs/backlog.md`, `web/e2e/known-issues.spec.ts`.
- [ ] **Локализация ошибок:** получить человекочитаемое сообщение на текущем
языке вместо сырого i18n-ключа. `docs/backlog.md`, `web/e2e/i18n.spec.ts`.
- [ ] **Theme persistence:** переключить тему и проверить сохранение в ключе
`theme`. `docs/backlog.md`, `web/e2e/navigation.spec.ts`.
- [ ] **Reset/auto-run:** проверить выбранную семантику Reset и автоматический
перезапуск после изменения параметров. `docs/backlog.md`,
`web/e2e/pipeline.spec.ts`.
## Как долго
- Полный прогон: ~40 минут (все разделы, включая мегапиксели и 4К) в двух
+17 -1
View File
@@ -50,7 +50,7 @@
### Q0. Зафиксировать baseline и синхронизировать документацию
**Оценка:** S. **Зависимости:** нет.
**Статус:** готов к ревью. **Оценка:** S. **Зависимости:** нет.
- Проверить фактические команды и зафиксировать их в quality-gate документации.
- Вынести расширенный workflow агента в `docs/agent-workflow.md`, оставив в
@@ -64,6 +64,8 @@
`docs/checklist-manual-testing.md`.
- Убрать устаревшее утверждение про hardcoded debt в `kit` из `AGENTS.md`, если
оно больше не соответствует коду.
- Перенести явно устаревшие `docs/analysis.md` и `docs/sorting-backend.md` в
`docs/archive/`, добавить даты архивирования и удаления через 30 дней.
- Создать `docs/README.md` как индекс активных документов и карту источников
истины; подробные правила не дублировать в корневых файлах.
@@ -296,6 +298,19 @@ Blanket-запрет всех string literals не использовать.
текущие критерии приёмки без отдельной сверки с кодом. Новый документ создаётся
только когда темы нет в существующем файле; иначе обновляется существующий.
### Архивирование и срок хранения
Завершённые, отменённые или явно устаревшие документы переносятся в
`docs/archive/`, а не остаются в корне `docs/` как рабочие планы. При переносе
добавляются дата архивирования, дата удаления и причина. Архивный документ —
временная справка для быстрого просмотра прошлых решений, но не источник текущих
требований.
Срок хранения после архивирования — 30 дней. После этой даты документ можно
удалить после проверки ссылок; если он снова нужен, его восстанавливают из git
history или пересоздают как новый активный документ. Подробная процедура и
шаблон метаданных находятся в `docs/archive/README.md`.
### Какие документы подготовить
| Документ | Назначение | Когда создавать/обновлять |
@@ -306,6 +321,7 @@ Blanket-запрет всех string literals не использовать.
| `docs/testing-strategy.md` | Слои тестов, locator policy, i18n assertions, fixtures, `test.fixme` и правила e2e | Q3; при изменении тестовой архитектуры |
| `docs/architecture-overview.md` | Карта `core`, registry, executor, нового UI и `/v1`, shared-модули и зависимости | Q4 или перед крупным рефакторингом; не дублировать существующие планы |
| `web/eslint-plugins/README.md` | Детали custom lint rules, token policy и fixtures | Уже существует; менять только вместе с правилами |
| `docs/archive/README.md` | Политика временного архива, даты и удаления через 30 дней | Q0; обновлять при изменении архивной политики |
Не создавать отдельные `docs/commands.md`, `docs/known-issues.md` или копию
backlog: команды принадлежат `quality-gates`, известные проблемы — backlog и
+7 -6
View File
@@ -1,15 +1,16 @@
# План: i18n в preview (новый UI)
> Статус: готов к реализации (вопросы §5 решены). Соответствует беклог-задаче
> «добавить i18n в preview» (`docs/backlog.md`). Реализация не начата.
> Статус: **частично выполнен** — базовая i18n-инфраструктура нового UI,
> локализация ошибок и `i18n/dict-consistency` уже реализованы; zero-warning
> baseline и plural-формы остаются Q2. Актуальные решения и ограничения — в
> `docs/plan-codebase-quality.md`.
## 1. Что получается
Новый UI (`web/src/routes/**` кроме `v1`, `web/src/lib/components/**` кроме
`v1`) переходит на существующий модуль `lib/i18n`: переключатель RU/EN в шапке
работает по-настоящему, все строки локализованы, ошибки уже локализуются.
Инфраструктура i18n уже есть и проверена (v1-ветка) — задача в том, чтобы
подключить к ней preview и закрыть пробелы словарей.
`v1`) использует модуль `lib/i18n`: переключатель RU/EN в шапке работает по
локали, строки и ошибки локализованы. Остаточные задачи — довести паритет
словарей до zero-warning и спроектировать plural-формы.
До начала локализации **v1 изолируется**: у v1 появляется полная замороженная
копия `lib/i18n` → `lib/v1/i18n`, у нового UI — своя независимая ветка
+5 -4
View File
@@ -4,10 +4,11 @@
> Остались C20 (шаг 6, проверка нового дизайна) — **следующий этап**. C19/C21
> (шаг 7, удаление старого) — **отложены**, нет ценности. Они больше не
> привязаны к «верности против рефа»: `docs/archive/plan-design-fix.md` закрыт,
> аудит против рефа прекращён. Tech debt закрыт
> (`docs/archive/plan-tech-debt.md`). Backlog №14 (переезд старых файлов в
> `old/`) — **выполнено**. Покупка домена НЕ была блокером C17: домен нужен для
> S1 (`plan-seo.md`) — canonical, sitemap, снятие `noindex`.
> аудит против рефа прекращён. Общий tech-debt baseline зафиксирован в
> `docs/plan-codebase-quality.md`; legacy cleanup остаётся отложенным. Backlog
> №14 (переезд старых файлов в `old/`) — **выполнено**. Покупка домена НЕ была
> блокером C17: домен нужен для S1 (`plan-seo.md`) — canonical, sitemap, снятие
> `noindex`.
>
> Источники: `refs/` — Next/React-референс (правда по пикселям и интерактиву),
> `refs-html/` — статические HTML-снимки для быстрого просмотра в браузере.
+25 -26
View File
@@ -50,11 +50,10 @@
клиенте (localStorage) — для SEO не учитываем.
- **Прод-домен без `BASE_PATH`.** Сборка с базой (GitHub Pages `/repo/`) ломает
абсолютные URL, canonical и «корневость» страниц. Свой домен + корень.
- **URL-схема инструментов:** короткие плоские адреса. После C17 вынести
страницы инструментов в корень: `/crop-png` (как у конкурента), каталог —
`/tools`. Переезд `/preview/tools/[id]` → `/[id]` сделать **одновременно с
C17** (в одном атомарном коммите): после индексации переименование URL = 301 и
потеря позиций.
- **URL-схема инструментов:** короткие плоские адреса. После C17 страницы
инструментов находятся в корне на `/tools/[id]`, каталог — на `/list-tools`;
текущую схему не менять без отдельного SEO-плана: после индексации
переименование URL означает 301 и потерю позиций.
- **Без GA и рекламных скриптов:** аналитика — self-hosted Plausible/Umami или
Cloudflare Web Analytics. «No tracking» — часть позиционирования, её нельзя
подрывать собственными скриптами.
@@ -68,10 +67,10 @@
- SvelteKit + `adapter-static`, `prerender = true` на весь сайт
(`web/src/routes/+layout.ts`) — весь контент в статичном HTML, ботам не нужен
JS. Это главный технический козырь.
- 121 инструмент в `registry-new` с «SEO-шными» id (`crop-png`,
- 122 инструмента в `web/src/lib/registry` с «SEO-шными» id (`crop-png`,
`add-border-png`, …) — URL уже повторяют паттерн конкурента.
- Уникальные `<title>` + `<meta description>` на страницах инструментов старой
ветки; механика переносится на новую при C17.
- На корневых страницах инструментов есть базовые `<title>` и `robots`; полный
SEO-слой (canonical, OG, content и JSON-LD) остаётся S1/S2.
- Каталог со ссылками на все инструменты (внутренняя перелинковка) и карта
инструментов против конкурента: `docs/tools-map.md` (у них 311, из них 107 —
нишевые клоны-серии Logo*/Icon*/Stamp* поверх обычных операций).
@@ -79,17 +78,17 @@
Чего нет (пробелы закрываются этапами ниже):
| Пробел | Где сейчас | Этап |
| ----------------------------------------------------- | ----------------------------------- | ------ |
| `sitemap.xml` | нет | S1 |
| `robots.txt` без `Sitemap:` | allow-all (`web/static/robots.txt`) | S1 |
| `rel=canonical` | нет | S1 |
| OG/Twitter-теги, OG-картинки | нет | S1 |
| `noindex, nofollow` на страницах инструментов preview | `preview/tools/[id]/+page.svelte` | S1/C17 |
| Контент страницы (H1-текст, how-to, FAQ, related) | только title/description | S2 |
| JSON-LD (SoftwareApplication, FAQPage, Breadcrumb) | нет | S3 |
| `llms.txt`, хабы категорий с текстом | нет | S3 |
| GSC + приватная аналитика | нет | S4 |
| Пробел | Где сейчас | Этап |
| ----------------------------------------------------- | ---------------------------------------- | ---- |
| `sitemap.xml` | нет | S1 |
| `robots.txt` без `Sitemap:` | allow-all (`web/static/robots.txt`) | S1 |
| `rel=canonical` | нет | S1 |
| OG/Twitter-теги, OG-картинки | нет | S1 |
| `noindex, nofollow` на страницах инструментов preview | `web/src/routes/tools/[id]/+page.svelte` | S1 |
| Контент страницы (H1-текст, how-to, FAQ, related) | только title/description | S2 |
| JSON-LD (SoftwareApplication, FAQPage, Breadcrumb) | нет | S3 |
| `llms.txt`, хабы категорий с текстом | нет | S3 |
| GSC + приватная аналитика | нет | S4 |
## 2. Конкурент (onlinepngtools.com)
@@ -111,7 +110,7 @@
## 3. Стратегия
1. **Не лобовая, а ядро интентов.** 80% объёма поиска приносят ~30–50 запросов.
Покрытие инструментов у нас почти полное (121); приоритет — контент и
Покрытие инструментов у нас почти полное (122); приоритет — контент и
качество страниц ядра, затем хвосты.
2. **Страница = лендинг, а не «пустая коробка».** Шаблон контента: H1 → 1–2
абзаца «что делает» → как использовать (шаги) → параметры → FAQ (3–5 вопросов
@@ -163,10 +162,10 @@
(`tools/[id]/+page.svelte`) — делается одновременно с S1d (canonical)
чтобы Google сразу проиндексировал с правильным доменом.
- [ ] **[S1b]** Скрипт `web/scripts/gen-sitemap.mjs`: генерирует `sitemap.xml` в
`build/` из `TOOLS` реестра (`registry-new`) + статических страниц. Вызов
из `pnpm build` после `vite build` (adapter-static пишет в `build/`,
дописываем файл там же). Origin — из env (`PUBLIC_SITE_ORIGIN`), учёт
опционального `BASE_PATH`.
`build/` из `TOOLS` реестра (`web/src/lib/registry`) + статических
страниц. Вызов из `pnpm build` после `vite build` (adapter-static пишет в
`build/`, дописываем файл там же). Origin — из env (`PUBLIC_SITE_ORIGIN`),
учёт опционального `BASE_PATH`.
- [ ] **[S1c]** `robots.txt`: `Sitemap:` + закрыть служебные маршруты (`/kit` до
C19; после — вернуть минимальный allow-all).
- [ ] **[S1d]** Компонент `Seo.svelte` (kit): canonical (абсолютный URL по
@@ -183,7 +182,7 @@
- [ ] **[S2a]** Схема данных: `seo`-блок per-tool (`longDescription`,
`howTo: string[]`, `faq: {q, a}[]`) — в i18n-словарях (ru/en), не в коде
реестра. Черновики — генерацией из схемы параметров инструмента, вычитка
вручную пачками по категориям (самый трудоёмкий этап: ~121 × 2 локали; RU
вручную пачками по категориям (самый трудоёмкий этап: ~122 × 2 локали; RU
— отложить до решения о `/ru/`).
- [ ] **[S2b]** Компонент контента страницы инструмента (kit): H1, lead, how-to
(`ol`), описание параметров (из схемы), FAQ, related tools (перелинковка
@@ -239,7 +238,7 @@
## 5. Приоритизация инструментов (первая волна контента)
Источник — `docs/tools-map.md` (121 реализовано; у конкурента 311, из них 107 —
Источник — `docs/tools-map.md` (122 реализовано; у конкурента 311, из них 107 —
клоны-серии). Первая волна — топ-интенты, где конкуренты ранжируются, а у нас
уже есть инструмент и он не хуже:
+8 -7
View File
@@ -1,13 +1,14 @@
# План разработки: easy-png-tools
> **Статус:** Фаза 1 (полноценный TS-сайт) в основном выполнена — сайт живёт,
> каталог переведён в типизированный `registry` (121/125), новый дизайн по
> `plan-redesign.md` стал основным на корневых маршрутах (C17/C18 выполнены),
> старый UI — на `/v1/*` (удаление отложено, ценности не даёт — C19 в бэклоге).
> Tech debt закрыт. Следующий этап: C20 (проверка нового дизайна,
> `plan-redesign.md`, §10) + SEO S1-free (`plan-seo.md`) + баги. Домен нужен для
> SEO (`plan-seo.md`, S1-domain). Фазы 2–8 — будущие. Фазы 9–10 спланированы в
> `docs/plan-platform.md`.
> каталог переведён в типизированный `registry` (122 текущих инструмента), новый
> дизайн по `plan-redesign.md` стал основным на корневых маршрутах (C17/C18
> выполнены), старый UI — на `/v1/*` (удаление отложено, ценности не даёт — C19
> в бэклоге). Tech debt не закрыт полностью; текущий baseline и следующие
> quality-задачи зафиксированы в `docs/plan-codebase-quality.md`. Следующий
> этап: C20 (проверка нового дизайна, `plan-redesign.md`, §10) + SEO S1-free
> (`plan-seo.md`) + баги. Домен нужен для SEO (`plan-seo.md`, S1-domain). Фазы
> 2–8 — будущие. Фазы 9–10 спланированы в `docs/plan-platform.md`.
## 0. Решения