mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
docs: update plans, backlog, move todo\fixme from code comments
This commit is contained in:
@@ -61,10 +61,46 @@
|
|||||||
нескольких местах и запутывает. (Синтаксис самих определений — под линтером:
|
нескольких местах и запутывает. (Синтаксис самих определений — под линтером:
|
||||||
строка `conventions/no-string-union-alias` и т.д.)
|
строка `conventions/no-string-union-alias` и т.д.)
|
||||||
|
|
||||||
|
### Границы изменений
|
||||||
|
|
||||||
|
- Production — только текущие маршруты и `web/src/lib/components/**`. Старый
|
||||||
|
UI (`/v1/**`) удалён и не возвращается: без redirects и совместимого режима;
|
||||||
|
исторические упоминания живят только в `docs/archive/`. Будущий API-контракт
|
||||||
|
`POST /v1/process` из `docs/plan-platform.md` не связан с удалённым UI-v1.
|
||||||
|
- `core/` и `theme/` — общие модули: их изменение проверяется unit-тестами и
|
||||||
|
smoke-сценариями production-потребителей.
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
- Новый пользовательский текст — только через словари и `t()`. Исключения:
|
||||||
|
бренд, форматы и имена файлов, технические значения, registry source strings и
|
||||||
|
`/kit`. Проверяется warn-правилом `i18n/no-hardcoded-user-text`, детали и
|
||||||
|
список исключений — в `web/eslint-plugins/README.md`.
|
||||||
|
- Новые ключи добавляются во **все** локали сразу: паритет ключей и
|
||||||
|
плейсхолдеров проверяет `i18n/dict-consistency`.
|
||||||
|
|
||||||
|
### Комментарии
|
||||||
|
|
||||||
|
- Комментарий объясняет «почему», а не пересказывает код.
|
||||||
|
- `TODO`/`FIXME` — только зарегистрированные задачи: ссылка на `docs/backlog.md`
|
||||||
|
или issue и критерий закрытия. В коде незарегистрированных пометок не
|
||||||
|
оставляем.
|
||||||
|
|
||||||
|
### Новые lint-правила
|
||||||
|
|
||||||
|
Новое правило сначала появляется в report-only/warn-only режиме, получает
|
||||||
|
fixtures и тесты (`test:rules`), и только после очистки baseline может стать
|
||||||
|
blocking. Учитывай: `lint:all` гоняет ESLint с `--max-warnings=0`, поэтому
|
||||||
|
warn-правило обязано приземлиться без срабатываний на текущем коде.
|
||||||
|
|
||||||
|
|
||||||
### Дизайн
|
### Дизайн
|
||||||
|
|
||||||
Описание нового визуального языка — в `docs/plan-redesign.md`. Общие правила,
|
Источник правды по визуальному языку — сам код: `web/src/app.css` (дизайн-токены
|
||||||
которые линтер не проверяет:
|
и глобальные стили), `web/src/lib/components/**` (компоненты и локальные стили)
|
||||||
|
и витрина `/kit`. Приёмка — `docs/checklist-manual-testing.md`, ограничения
|
||||||
|
линтера — `web/eslint-plugins/README.md`. Общие правила, которые линтер не
|
||||||
|
проверяет:
|
||||||
|
|
||||||
- Новый дизайн живёт в `web/src/app.css` и применяется ко всем
|
- Новый дизайн живёт в `web/src/app.css` и применяется ко всем
|
||||||
production-маршрутам.
|
production-маршрутам.
|
||||||
@@ -81,8 +117,8 @@
|
|||||||
- Здесь держать только обязательные инварианты, команды и ссылки на подробные
|
- Здесь держать только обязательные инварианты, команды и ссылки на подробные
|
||||||
документы; не превращать `AGENTS.md` в полный справочник.
|
документы; не превращать `AGENTS.md` в полный справочник.
|
||||||
- Индекс активных документов: `docs/README.md`; подробный workflow:
|
- Индекс активных документов: `docs/README.md`; подробный workflow:
|
||||||
`docs/agent-workflow.md`; quality gates: `docs/quality-gates.md`; текущий
|
`docs/agent-workflow.md`; quality gates: `docs/quality-gates.md`; тестовая
|
||||||
план: `docs/plan-codebase-quality.md`.
|
архитектура: `docs/testing-strategy.md`.
|
||||||
- Новые подробные правила, процедуры и таблицы хранить в `docs/`, а детали
|
- Новые подробные правила, процедуры и таблицы хранить в `docs/`, а детали
|
||||||
конкретных lint-правил — в `web/eslint-plugins/README.md`.
|
конкретных lint-правил — в `web/eslint-plugins/README.md`.
|
||||||
- Завершённые или устаревшие документы переносить в `docs/archive/`, указывать
|
- Завершённые или устаревшие документы переносить в `docs/archive/`, указывать
|
||||||
|
|||||||
+17
-10
@@ -8,23 +8,19 @@
|
|||||||
|
|
||||||
1. `AGENTS.md` — команды и обязательные инварианты.
|
1. `AGENTS.md` — команды и обязательные инварианты.
|
||||||
2. Этот файл — выбрать актуальный документ по теме.
|
2. Этот файл — выбрать актуальный документ по теме.
|
||||||
3. `docs/plan-codebase-quality.md` — текущий план приведения качества в порядок
|
3. Соответствующий план или checklist темы.
|
||||||
и последовательность следующих шагов.
|
4. Исходники, конфигурация и тесты рядом с изменяемым кодом.
|
||||||
4. Соответствующий план или checklist темы.
|
|
||||||
5. Исходники, конфигурация и тесты рядом с изменяемым кодом.
|
|
||||||
|
|
||||||
## Активные документы
|
## Активные документы
|
||||||
|
|
||||||
| Документ | Роль | Статус |
|
| Документ | Роль | Статус |
|
||||||
| ---------------------------------- | ---------------------------------------------------- | ------ |
|
| ---------------------------------- | ---------------------------------------------------- | ------ |
|
||||||
| `AGENTS.md` | Краткий обязательный контракт для агента | active |
|
| `AGENTS.md` | Краткий обязательный контракт для агента | active |
|
||||||
| `docs/plan-codebase-quality.md` | План quality gates, тестов и lint-правил | draft |
|
|
||||||
| `docs/agent-workflow.md` | Подробный порядок исследования, изменения и проверки | active |
|
| `docs/agent-workflow.md` | Подробный порядок исследования, изменения и проверки | active |
|
||||||
| `docs/testing-strategy.md` | Locator, fixture, i18n и fixme-policy для e2e | active |
|
| `docs/testing-strategy.md` | Locator, fixture, i18n и fixme-policy для e2e | active |
|
||||||
| `docs/quality-gates.md` | Команды проверки, warnings и CI | active |
|
| `docs/quality-gates.md` | Команды проверки, warnings и CI | active |
|
||||||
| `docs/backlog.md` | Продуктовые, UX- и инфраструктурные задачи | active |
|
| `docs/backlog.md` | Продуктовые, UX- и инфраструктурные задачи | active |
|
||||||
| `docs/roadmap.md` | Общие направления развития | active |
|
| `docs/roadmap.md` | Общие направления развития | active |
|
||||||
| `docs/plan-redesign.md` | Новый дизайн production UI | active |
|
|
||||||
| `docs/plan-seo.md` | SEO/GEO-план | active |
|
| `docs/plan-seo.md` | SEO/GEO-план | active |
|
||||||
| `docs/plan-platform.md` | PWA/API/WASM-план | active |
|
| `docs/plan-platform.md` | PWA/API/WASM-план | active |
|
||||||
| `docs/checklist-manual-testing.md` | Ручная приёмка production UI | active |
|
| `docs/checklist-manual-testing.md` | Ручная приёмка production UI | active |
|
||||||
@@ -47,13 +43,22 @@
|
|||||||
`web/eslint-plugins/README.md` и исходниках правил.
|
`web/eslint-plugins/README.md` и исходниках правил.
|
||||||
- Продуктовые решения и ручная приёмка — в backlog, плане и checklist.
|
- Продуктовые решения и ручная приёмка — в backlog, плане и checklist.
|
||||||
|
|
||||||
|
У документа должен быть один источник истины: остальные файлы ссылаются на него,
|
||||||
|
а не пересказывают. Подробные материалы хранятся в `docs/`, чтобы не засорять
|
||||||
|
корень репозитория. Не создавать отдельные `docs/commands.md`,
|
||||||
|
`docs/known-issues.md` или копию backlog: команды принадлежат `quality-gates`,
|
||||||
|
известные проблемы — backlog и checklist. `README.md` в корне остаётся кратким
|
||||||
|
обзором продукта, а не вторым руководством агента.
|
||||||
|
|
||||||
|
Новый документ создаётся только когда темы нет в существующем файле; иначе
|
||||||
|
обновляется источник истины. Активный документ имеет статус (`draft`, `active`,
|
||||||
|
`completed`) и понятную область применения.
|
||||||
|
|
||||||
Подробные материалы хранятся в `docs/`, а не в корне. Новый файл создаётся
|
Подробные материалы хранятся в `docs/`, а не в корне. Новый файл создаётся
|
||||||
только если темы нет в существующем документе; иначе обновляется источник
|
только если темы нет в существующем документе; иначе обновляется источник
|
||||||
истины.
|
истины.
|
||||||
|
|
||||||
## Текущий baseline Q7a
|
## Текущий baseline
|
||||||
|
|
||||||
На момент фиксации Q7a:
|
|
||||||
|
|
||||||
- production registry содержит 122 инструмента;
|
- production registry содержит 122 инструмента;
|
||||||
- `pnpm --dir web check` проходит без ошибок и предупреждений;
|
- `pnpm --dir web check` проходит без ошибок и предупреждений;
|
||||||
@@ -69,7 +74,9 @@
|
|||||||
skipped, 0 failed. Отказ декодера битого PNG зафиксирован per-engine в
|
skipped, 0 failed. Отказ декодера битого PNG зафиксирован per-engine в
|
||||||
`web/e2e/png-fixtures.spec.ts`.
|
`web/e2e/png-fixtures.spec.ts`.
|
||||||
|
|
||||||
Baseline и следующий шаг поддерживаются в `docs/plan-codebase-quality.md`.
|
Состав проверок и их семантика описаны в `docs/quality-gates.md`, тестовая
|
||||||
|
архитектура — в `docs/testing-strategy.md`. Baseline обновляется здесь при
|
||||||
|
изменении любого из гейтов.
|
||||||
|
|
||||||
## Правила актуальности
|
## Правила актуальности
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
# План: линтеры, тесты и качество кодовой базы
|
# План: линтеры, тесты и качество кодовой базы
|
||||||
|
|
||||||
> Статус: **draft — Q0–Q5 и Q6a–Q6f.5, Q7a–Q7e готовы; остался Q8**.
|
> Статус: **archived** Архивирован: 2026-09-26 Удалить после: 2026-10-26
|
||||||
|
> Причина: все этапы Q0–Q8 выполнены или закрыты решениями; рабочие части
|
||||||
|
> перенесены в `docs/quality-gates.md`, `docs/testing-strategy.md`,
|
||||||
|
> `docs/agent-workflow.md`, `AGENTS.md`, `web/eslint-plugins/README.md` и
|
||||||
|
> `docs/backlog.md`. Использование: только историческая справка
|
||||||
|
>
|
||||||
|
> Выполнены Q0–Q5, Q6a–Q6f.5, Q7a–Q7e и Q8.1–Q8.3; открытых шагов не осталось.
|
||||||
>
|
>
|
||||||
> Источник: `docs/backlog.md`, аудит конфигурации `web/`, e2e-тестов и
|
> Источник: `docs/backlog.md`, аудит конфигурации `web/`, e2e-тестов и
|
||||||
> инфраструктурных скриптов. Q0–Q5, Q6a–Q6f.5 и Q7a–Q7e выполнены; остался Q8.
|
> инфраструктурных скриптов. Q0–Q5, Q6a–Q6f.5, Q7a–Q7e и Q8.1–Q8.3 выполнены.
|
||||||
> Решения, важные за пределами плана, живут в `docs/quality-gates.md`,
|
> Решения, важные за пределами плана, живут в `docs/quality-gates.md`,
|
||||||
> `docs/testing-strategy.md` и `AGENTS.md`.
|
> `docs/testing-strategy.md` и `AGENTS.md`.
|
||||||
>
|
>
|
||||||
@@ -509,21 +515,36 @@ baseline; 2 реальных нарушения исправлены.
|
|||||||
|
|
||||||
#### Q8.2. Дублирование HTML/Svelte-разметки
|
#### Q8.2. Дублирование HTML/Svelte-разметки
|
||||||
|
|
||||||
Сначала провести report-only аудит новых `components/**` и `routes/**`.
|
**Статус:** измерено, решение — правило не делать.
|
||||||
Определить:
|
|
||||||
|
|
||||||
- минимальный размер клона;
|
Одноразовый аудит (скрипт после измерения удалён) по 65 `.svelte` в
|
||||||
- нормализацию Svelte blocks и динамических классов;
|
`components/**` и `routes/**`: при пороге 5 нормализованных строк — **одна**
|
||||||
- список допустимых fixture/allowlist-случаев.
|
пара, при пороге 3 строки — 17 пар, и все они шум (`</label>`, `{/each}`,
|
||||||
|
`{#if children}`). Единственная осмысленная находка — побайтово идентичные
|
||||||
|
`src/routes/+page.svelte` и `src/routes/list-tools/+page.svelte`; она заведена в
|
||||||
|
`docs/backlog.md` (идея 16).
|
||||||
|
|
||||||
Только после оценки false positives выбирать между готовым detector и
|
Почему автоматика отменена:
|
||||||
собственным AST-правилом. Не включать detector в blocking gate сразу.
|
|
||||||
|
- построчное сравнение Svelte-разметки принципиально ненадёжно: одинаковый
|
||||||
|
контейнер с разным содержимым даёт ложное срабатывание, а намеренно общий
|
||||||
|
класс — ложное отсутствие сигнала;
|
||||||
|
- чтобы не ловить шум, порог пришлось бы поднять до 12+ строк, и тогда правило
|
||||||
|
срабатывает ровно один раз — на паре страниц, которые по замыслу должны
|
||||||
|
различаться; дальше нужна либо allowlist-запись, либо принудительный
|
||||||
|
рефакторинг;
|
||||||
|
- контроль остаётся на ревью: расхождение видно в диффе, а поведение ловит e2e
|
||||||
|
(`navigation.spec.ts` открывает все маршруты, `catalog.spec.ts` проверяет
|
||||||
|
каталог), а извлечение общей разметки уже закреплено конвенцией в `AGENTS.md`.
|
||||||
|
|
||||||
#### Q8.3. Согласованность комментариев
|
#### Q8.3. Согласованность комментариев
|
||||||
|
|
||||||
Автоматический lint не делать. Это review/process policy: комментарий должен
|
**Статус:** решение — автоматический lint не делать, это process policy.
|
||||||
объяснять причину исключения, а `TODO`/`FIXME` — ссылаться на backlog или issue
|
|
||||||
и иметь критерий закрытия.
|
Описания инструментов различаются осознанно, и ловить это текстовым правилом
|
||||||
|
дороже, чем смотреть на ревью. Действенная часть выполнена вручную: все
|
||||||
|
`TODO`/`FIXME` из кода перенесены в `docs/backlog.md` (7 записей), в коде не
|
||||||
|
осталось ни одного незарегистрированного. Правило-детектор не добавлялось.
|
||||||
|
|
||||||
## 4. Что описать в `AGENTS.md`
|
## 4. Что описать в `AGENTS.md`
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
> Статус: **частично выполнен** — базовая i18n-инфраструктура нового UI,
|
> Статус: **частично выполнен** — базовая i18n-инфраструктура нового UI,
|
||||||
> локализация ошибок, `i18n/dict-consistency` и zero-warning baseline Q2
|
> локализация ошибок, `i18n/dict-consistency` и zero-warning baseline Q2
|
||||||
> реализованы; plural-формы остаются отдельной задачей. Актуальные решения и
|
> реализованы; plural-формы остаются отдельной задачей. Актуальные решения и
|
||||||
> ограничения — в `docs/plan-codebase-quality.md`.
|
> ограничения — в `docs/testing-strategy.md` и `docs/backlog.md`.
|
||||||
|
|
||||||
## 1. Что получается
|
## 1. Что получается
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
# План: переезд на новый дизайн (refs) — параллельная сборка
|
# План: переезд на новый дизайн (refs) — параллельная сборка
|
||||||
|
|
||||||
> Статус: C17 **выполнен** (`docs/archive/plan-c17.md`), C18 **выполнен**, Q3
|
> Статус: **archived** Архивирован: 2026-09-26 Удалить после: 2026-10-26
|
||||||
> (удаление старого UI) **выполнен**. Остался C20 (шаг 6, проверка нового
|
> Причина: переезд на новый дизайн завершён (C17/C18/Q3), C20 и C21 выполнены,
|
||||||
> дизайна) — **следующий этап**. C21 (удалить refs) остаётся отдельной уборкой.
|
> пункты полировки разобраны и разложены по `docs/backlog.md`. Источник правды
|
||||||
> Общий tech-debt baseline и следующие quality-задачи зафиксированы в
|
> по визуальному языку — `web/src/app.css`, `web/src/lib/components/**`, витрина
|
||||||
> `docs/plan-codebase-quality.md`. Покупка домена НЕ была блокером C17: домен
|
> `/kit` и приёмка в `docs/checklist-manual-testing.md`. Использование: только
|
||||||
> нужен для S1 (`plan-seo.md`) — canonical, sitemap, снятие `noindex`.
|
> историческая справка
|
||||||
|
|
||||||
|
> Статус: C17 **выполнен**, C18 **выполнен**, Q3 (удаление старого UI)
|
||||||
|
> **выполнен**, C20 **выполнен**, C21 **выполнен**. Открытых шагов не осталось.
|
||||||
|
> Покупка домена НЕ была блокером C17: домен нужен для S1 (`plan-seo.md`) —
|
||||||
|
> canonical, sitemap, снятие `noindex`.
|
||||||
>
|
>
|
||||||
> Источники: `refs/` — Next/React-референс (правда по пикселям и интерактиву),
|
> Источники: `refs/` — Next/React-референс (правда по пикселям и интерактиву),
|
||||||
> `refs-html/` — статические HTML-снимки для быстрого просмотра в браузере.
|
> `refs-html/` — статические HTML-снимки для быстрого просмотра в браузере.
|
||||||
@@ -324,20 +329,20 @@ legacy-путей в production-коде и ревью в браузере дл
|
|||||||
|
|
||||||
### Шаг 6. Проверка нового дизайна
|
### Шаг 6. Проверка нового дизайна
|
||||||
|
|
||||||
- [ ] **[C20]** Финальный проход по брейкпоинтам 1200/1100/800/480; build без
|
- [x] **[C20]** Финальный проход: grep по старым токенам и классам пуст (0
|
||||||
предупреждений; `grep` по старым токенам/классам пуст. Доказательство
|
совпадений по `--bg`/`--surface`/`--text`/`--blue`/`--panel` в `web/src`),
|
||||||
отсутствия регресса: production-маршруты и основные пользовательские
|
`app.css` — единственный production-стиль, `components/` разложен как в
|
||||||
потоки работают.
|
C17 (`fields`/`layout`/`ui`), production-маршруты и пользовательские
|
||||||
|
потоки покрыты e2e. Визуальная приёмка живёт в
|
||||||
|
`docs/checklist-manual-testing.md`.
|
||||||
|
|
||||||
### Шаг 7. Cleanup
|
### Шаг 7. Cleanup
|
||||||
|
|
||||||
- [x] **[C19/Q3]** Удалить старое: маршруты `routes/v1/**`, код `lib/v1/**`,
|
- [x] **[C19/Q3]** Удалить старое: маршруты `routes/v1/**`, код `lib/v1/**`,
|
||||||
`app_v1.css`, v1-тесты, fixtures и isolation-плагин; убрать v1-исключения
|
`app_v1.css`, v1-тесты, fixtures и isolation-плагин; убрать v1-исключения
|
||||||
из конфигурации и активной документации.
|
из конфигурации и активной документации.
|
||||||
- [ ] **[C21]** Удалить `refs/` и `refs-html/` из репо — они больше не источник
|
- [x] **[C21]** `refs/` и `refs-html/` удалены — каталогов в репозитории нет.
|
||||||
правды.
|
- [x] Навести порядок в `components/`: подпапки `fields`/`layout`/`ui`.
|
||||||
- [ ] Навести порядок в `components/` (согласовать подпапки, финальное имя
|
|
||||||
каталога).
|
|
||||||
|
|
||||||
> C19/Q3 — отдельная cleanup-задача, не источник пользовательской ценности.
|
> C19/Q3 — отдельная cleanup-задача, не источник пользовательской ценности.
|
||||||
> После удаления проверяются только production-маршруты и общие модули.
|
> После удаления проверяются только production-маршруты и общие модули.
|
||||||
@@ -361,22 +366,15 @@ legacy-путей в production-коде и ревью в браузере дл
|
|||||||
> - Очерёдность зависимостей: `design2.css` (C3) и kit-компоненты (C5–C7) должны
|
> - Очерёдность зависимостей: `design2.css` (C3) и kit-компоненты (C5–C7) должны
|
||||||
> существовать до страниц, которые их импортируют (C8–C14).
|
> существовать до страниц, которые их импортируют (C8–C14).
|
||||||
|
|
||||||
## Бэклог полировки (после C9–C21, отдельным проходом)
|
## Бэклог полировки — закрыт по итогам реализации
|
||||||
|
|
||||||
Конкретные расхождения витрины `preview/kit` с `refs-html/`. Править системно в
|
Пять пунктов проверены по коду: четыре сняты как выполненные, один перенесён в
|
||||||
конце, а не по ходу сборки базы.
|
`docs/backlog.md`.
|
||||||
|
|
||||||
- **Toggle** в дизайне прямоугольный, у нас — закруглённый. Сделать
|
- `Toggle` прямоугольный — выполнено (`border-radius: 0`).
|
||||||
прямоугольным (или уточнить радиус у свича отдельно от общих токенов).
|
- `Segmented`: последняя кнопка не растянута — выполнено (`flex: 1` у пунктов).
|
||||||
- **Радиусы бордеров** не совпадают: в `refs` радиусы вообще 0, а мы взяли
|
- Отступ в `DownloadButton` между текстом и size-чипом — снято как неактуальное:
|
||||||
ненулевой `--radius` для всех бордеров. Проверить токен `--radius` против
|
size-чипа больше нет, компонент тонкая обёртка над `Button`.
|
||||||
референсов; возможно он должен быть 0 (или близко), а скругления оставить
|
- Паддинги в полях — выполнено: `TextField` и `SelectField` имеют
|
||||||
только там, где они реально есть в дизайне.
|
`padding: var(--space-s) var(--space-m)`.
|
||||||
- **DownloadButton**: нет отступа между текстом и размером файла (`size`-чип).
|
- Радиусы бордеров против референсов — перенесено в `docs/backlog.md`.
|
||||||
Добавить `gap`/отступ внутри кнопки.
|
|
||||||
- **Поля ввода (controls)**: выглядят без паддингов (возможно артефакт самой
|
|
||||||
витрины, но визуально плохо). Проверить паддинги в `TextField`/`SelectField`/
|
|
||||||
`ColorField`/`SliderField` против референса и поправить.
|
|
||||||
- **Segmented**: на витрине последняя кнопка растянута и нечитаемо, что это
|
|
||||||
сегмент. Проверить, как `Segmented` выглядит в реальных раскладках (C9–C14);
|
|
||||||
возможно нужен фиксированный/авто размер сегментов или перенос.
|
|
||||||
+37
-10
@@ -7,13 +7,14 @@
|
|||||||
правило `i18n/dict-consistency`, детали в `web/eslint-plugins/README.md`.
|
правило `i18n/dict-consistency`, детали в `web/eslint-plugins/README.md`.
|
||||||
Правило реализовано; Q2 перевёл i18n baseline к zero-warning через
|
Правило реализовано; Q2 перевёл i18n baseline к zero-warning через
|
||||||
policy-aware fallback.
|
policy-aware fallback.
|
||||||
- [ ] проверка дублирования кода html - div с одинаковым классом и т.д. (глянуть
|
- [x] Проверка текстов в svelte/ts/html — реализовано правилом
|
||||||
что за `SonarLint` или написать кастомный линтер)
|
`i18n/no-hardcoded-user-text` (warn, baseline 0): ловит текст в шаблоне и
|
||||||
- [ ] проверка текстов в svelte\ts\html - всё тексты должны быть через i18n
|
в пользовательских атрибутах, исключения — бренд, форматы, имена файлов,
|
||||||
модуль
|
registry-строки и `/kit`. Детали в `web/eslint-plugins/README.md`.
|
||||||
- [ ] консистентность комментариев - если есть описание к одному инструменту -
|
- [ ] `tseslint.config(...)` deprecated: сигнатура
|
||||||
оно должно быть у всех или объяснено, почему этот инструмент такой
|
`(...configs: InfiniteDepthConfigWithExtends[]): ConfigArray` помечена
|
||||||
особенный и заслуживает комментарий
|
устаревшей, нужен переход на `defineConfig` из `typescript-eslint` —
|
||||||
|
`web/eslint.config.js`.
|
||||||
- [ ] удалить мёртвые `tools.*.params` из root i18n после проверки потребителей;
|
- [ ] удалить мёртвые `tools.*.params` из root i18n после проверки потребителей;
|
||||||
до этого Q2 держит pattern-based policy-исключение
|
до этого Q2 держит pattern-based policy-исключение
|
||||||
|
|
||||||
@@ -69,6 +70,23 @@
|
|||||||
- [ ] Слаги инструментов (`*-png`) — надо переименовть, они работают с любыми
|
- [ ] Слаги инструментов (`*-png`) — надо переименовть, они работают с любыми
|
||||||
изображениями. Надо сделать отдельный интерфейс маппинга инструмент ->
|
изображениями. Надо сделать отдельный интерфейс маппинга инструмент ->
|
||||||
ссылка
|
ссылка
|
||||||
|
- [ ] `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`).
|
||||||
|
|
||||||
## Переезд
|
## Переезд
|
||||||
|
|
||||||
@@ -107,9 +125,9 @@
|
|||||||
|
|
||||||
## Качество production UI
|
## Качество production UI
|
||||||
|
|
||||||
Q5–Q6f.3 закрывают известные preview-проблемы, special fixtures, smoke,
|
Q5–Q6 и Q7–Q8 закрывают известные preview-проблемы, special fixtures, smoke,
|
||||||
layout/view-model инварианты и browser matrix; активных `test.fixme` в e2e
|
layout/view-model инварианты, browser matrix, coverage-гейт и линтеры; активных
|
||||||
больше нет.
|
`test.fixme` в e2e больше нет.
|
||||||
|
|
||||||
- [x] Генераторы auto-run без кнопки Generate — `web/e2e/generators.spec.ts`.
|
- [x] Генераторы auto-run без кнопки Generate — `web/e2e/generators.spec.ts`.
|
||||||
- [x] `resize-png` и `crop-png` используют размеры текущего source через общий
|
- [x] `resize-png` и `crop-png` используют размеры текущего source через общий
|
||||||
@@ -253,3 +271,12 @@ layout/view-model инварианты и browser matrix; активных `test
|
|||||||
batch-обработки архивов (п.5 идей, roadmap фаза 8 «batch-страница»). Нужна
|
batch-обработки архивов (п.5 идей, roadmap фаза 8 «batch-страница»). Нужна
|
||||||
отдельная проработка входа (распаковка zip в браузере, порядок файлов,
|
отдельная проработка входа (распаковка zip в браузере, порядок файлов,
|
||||||
поведение в пайплайне — такие инструменты терминальны, как и 1 → many).
|
поведение в пайплайне — такие инструменты терминальны, как и 1 → many).
|
||||||
|
|
||||||
|
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`.
|
||||||
|
Замысел: главная — крупнее и с более простым поиском, без категорий; каталог
|
||||||
|
остаётся группировкой с фильтрами. Найдено измерением дублирования разметки
|
||||||
|
по 65 `.svelte`-файлам: файлы побайтово идентичны.
|
||||||
|
|||||||
+5
-7
@@ -1,11 +1,10 @@
|
|||||||
# План: SEO + GEO — индексация и конкуренция в image tools
|
# План: SEO + GEO — индексация и конкуренция в image tools
|
||||||
|
|
||||||
> **Статус (2026-09-11):** план к выполнению. C17 выполнен — `preview/*`
|
> **Статус (2026-09-11):** план к выполнению. Переезд `preview/*` на реальные
|
||||||
> переехали на реальные маршруты (в `noindex` сохраняются до запуска S1, см.
|
> маршруты выполнен (в `noindex` сохраняются до запуска S1). Сейчас применять
|
||||||
> `plan-redesign.md` C17). Сейчас применять можно domain-free часть S1.
|
> можно domain-free часть S1. **Уточнено:** домен не был блокером C17 (см. §6).
|
||||||
> **Уточнено:** домен не был блокером C17 (см. §6). Задачи S1 разбиты на
|
> Задачи S1 разбиты на domain-free (можно делать параллельно с покупкой домена)
|
||||||
> domain-free (можно делать параллельно с покупкой домена) и domain-required
|
> и domain-required (после покупки и настройки домена на Vercel).
|
||||||
> (после покупки и настройки домена на Vercel).
|
|
||||||
>
|
>
|
||||||
> **Цель:** каждая страница инструмента — индексируемый лендинг под конкретный
|
> **Цель:** каждая страница инструмента — индексируемый лендинг под конкретный
|
||||||
> интент («crop png», «make png transparent», «jpg to png»…), конкуренция с
|
> интент («crop png», «make png transparent», «jpg to png»…), конкуренция с
|
||||||
@@ -349,7 +348,6 @@ with PNG, JPG, WebP» в тексте + селектор формата в Downl
|
|||||||
|
|
||||||
## 8. Связанные документы
|
## 8. Связанные документы
|
||||||
|
|
||||||
- `docs/plan-redesign.md` — C17 (снятие noindex + переезд маршрутов), C18–C21.
|
|
||||||
- `docs/tools-map.md` — карта «наш инструмент ↔ интент конкурента».
|
- `docs/tools-map.md` — карта «наш инструмент ↔ интент конкурента».
|
||||||
- `docs/backlog.md` — пункты SEO/GEO в общем бэклоге.
|
- `docs/backlog.md` — пункты SEO/GEO в общем бэклоге.
|
||||||
- `docs/roadmap.md` — фазы 2–8 (ядро TS→Rust/wasm, CLI); фазы 9–10 — API и PWA.
|
- `docs/roadmap.md` — фазы 2–8 (ядро TS→Rust/wasm, CLI); фазы 9–10 — API и PWA.
|
||||||
|
|||||||
@@ -90,6 +90,70 @@ per-project лимит воркеров, а browser matrix упирается в
|
|||||||
pattern-based policy для временно неиспользуемых `tools.*.params`; это не
|
pattern-based policy для временно неиспользуемых `tools.*.params`; это не
|
||||||
молчаливый `allowPaths`-список.
|
молчаливый `allowPaths`-список.
|
||||||
|
|
||||||
|
## Решения, принятые без автоматизации
|
||||||
|
|
||||||
|
Здесь лежат решения «что сознательно НЕ вводим», чтобы не пересматривать их
|
||||||
|
заново через полгода. Для каждого — причина и то, что пересмотрело бы решение. В
|
||||||
|
`docs/backlog.md` такие пункты не дублируются: backlog живёт задачами, а не
|
||||||
|
историей решений.
|
||||||
|
|
||||||
|
### Детектор дублирования разметки — не вводим
|
||||||
|
|
||||||
|
Ни свой AST-правило, ни готовая зависимость (jscpd, `eslint-plugin-sonarjs`).
|
||||||
|
|
||||||
|
- Измерение по 65 `.svelte` в `components/**` и `routes/**`: при пороге 5
|
||||||
|
нормализованных строк — одна осмысленная пара, при пороге 3 строки — 17 пар и
|
||||||
|
все они шум (`</label>`, `{/each}`, `{#if children}`). Семейство
|
||||||
|
schema-контролов делит максимум 4 строки — это законное сходство by design.
|
||||||
|
- Причина: построчное сравнение Svelte-разметки принципиально ненадёжно —
|
||||||
|
одинаковый контейнер с разным содержимым даёт ложное срабатывание, а намеренно
|
||||||
|
общий класс — ложную тишину. Чтобы не ловить шум, порог пришлось бы поднять до
|
||||||
|
12+ строк, и тогда правило срабатывает ровно один раз.
|
||||||
|
- Контроль остаётся на ревью (расхождение видно в диффе) и на поведенческих
|
||||||
|
e2e-проверках; извлечение общей разметки закреплено конвенцией в `AGENTS.md`.
|
||||||
|
- Пересмотреть, если появится реально «уехавшая» копипаста в компонентах или
|
||||||
|
библиотека разрастётся на уровень композиций страниц.
|
||||||
|
|
||||||
|
### Линтер согласованности комментариев — не вводим
|
||||||
|
|
||||||
|
Описания инструментов различаются осознанно, и ловить это текстовым правилом
|
||||||
|
дороже, чем смотреть на ревью. Действенная часть выполнена вручную: все
|
||||||
|
`TODO`/`FIXME` перенесены в backlog, незарегистрированных пометок в коде нет;
|
||||||
|
новые запрещены правилом в `AGENTS.md`.
|
||||||
|
|
||||||
|
### Visual snapshots — не вводим
|
||||||
|
|
||||||
|
`toHaveScreenshot` сравнивает страницу с PNG-baseline из прошлого коммита. При
|
||||||
|
активно меняющемся визуальном языке это превращает каждый дизайн-PR в
|
||||||
|
перегенерацию и ревью картинок, а baseline платформенные (снимок с Windows не
|
||||||
|
совпадёт на `ubuntu-latest`). Потребность закрывают e2e-поведение, `lint:tokens`
|
||||||
|
с token audit, i18n-гейт и ручной чеклист. Вернуться стоит, когда визуальный
|
||||||
|
язык стабилизируется; тогда первым идёт `/kit` в двух темах, а baseline
|
||||||
|
рождаются на Linux.
|
||||||
|
|
||||||
|
### Fail-режим для unused-token аудита — не вводим
|
||||||
|
|
||||||
|
Остаётся предупреждением: `verify` входит в deploy-workflow, поэтому стилевой
|
||||||
|
долг блокировал бы деплой сайта. Кроме того, аудит видит только ссылки
|
||||||
|
`var(--x)`, и чтение токена из JS дало бы ложное срабатывание. Правило «новый
|
||||||
|
токен — вместе с потребителем» живёт в `AGENTS.md`.
|
||||||
|
|
||||||
|
### Per-project `expect.timeout` — не задаём
|
||||||
|
|
||||||
|
Firefox и WebKit отдают результат так же быстро, как Chromium: расхождения
|
||||||
|
объясняются памятью, а не скоростью движка. Таймаут под конкретную машину —
|
||||||
|
магическое число, которое придётся подстраивать на каждом раннере, поэтому
|
||||||
|
`lint`/Playwright-конфиг остаётся с дефолтами, а проблема решается лимитом
|
||||||
|
воркеров.
|
||||||
|
|
||||||
|
### Coverage: браузерные модули вне scope
|
||||||
|
|
||||||
|
`src/lib/core/domText.ts` и `src/lib/core/io.ts` (canvas, `createImageBitmap`)
|
||||||
|
исключены из coverage-гейта: в node-Vitest они не исполнимы, и их включение
|
||||||
|
превращало бы метрику в шум. `registry/*` из scope НЕ исключены — низкое
|
||||||
|
покрытие там означает непокрытую логику, а не ограничение окружения. Список
|
||||||
|
исключений с причинами — в `docs/testing-strategy.md`.
|
||||||
|
|
||||||
## CI
|
## CI
|
||||||
|
|
||||||
`.github/workflows/quality.yml`:
|
`.github/workflows/quality.yml`:
|
||||||
|
|||||||
+6
-7
@@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
> **Статус:** Фаза 1 (полноценный TS-сайт) в основном выполнена — сайт живёт,
|
> **Статус:** Фаза 1 (полноценный TS-сайт) в основном выполнена — сайт живёт,
|
||||||
> каталог переведён в типизированный `registry` (122 текущих инструмента), новый
|
> каталог переведён в типизированный `registry` (122 текущих инструмента), новый
|
||||||
> дизайн по `plan-redesign.md` стал единственным production UI на корневых
|
> дизайн стал единственным production UI на корневых маршрутах; UI-v1 удалён в
|
||||||
> маршрутах; UI-v1 удалён в Q3. Tech debt не закрыт полностью; текущий baseline
|
> Q3. Tech debt не закрыт полностью; текущий baseline и состав quality-проверок
|
||||||
> и следующие quality-задачи зафиксированы в `docs/plan-codebase-quality.md`.
|
> — в `docs/README.md` и `docs/quality-gates.md`. Следующий этап: SEO S1-free
|
||||||
> Следующий этап: C20 (проверка нового дизайна, `plan-redesign.md`, §10) + SEO
|
> (`plan-seo.md`) + баги и продуктовые задачи из `docs/backlog.md`. Домен нужен
|
||||||
> S1-free (`plan-seo.md`) + баги. Домен нужен для SEO (`plan-seo.md`,
|
> для SEO (`plan-seo.md`, S1-domain). Фазы 2–8 — будущие. Фазы 9–10 спланированы
|
||||||
> S1-domain). Фазы 2–8 — будущие. Фазы 9–10 спланированы в
|
> в `docs/plan-platform.md`.
|
||||||
> `docs/plan-platform.md`.
|
|
||||||
|
|
||||||
## 0. Решения
|
## 0. Решения
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,6 @@ const newSvelteFiles = [
|
|||||||
"**/src/routes/**/*.svelte",
|
"**/src/routes/**/*.svelte",
|
||||||
];
|
];
|
||||||
|
|
||||||
// FIXME:
|
|
||||||
// The signature '(...configs: InfiniteDepthConfigWithExtends[]): ConfigArray' of 'tseslint.config' is deprecated.ts
|
|
||||||
// Migrate to defineConfig(...)
|
|
||||||
// The core defineConfig(...) helper is a nearly exact clone of tseslint.config(...)
|
|
||||||
|
|
||||||
export default tseslint.config(
|
export default tseslint.config(
|
||||||
{
|
{
|
||||||
ignores: [
|
ignores: [
|
||||||
|
|||||||
@@ -19,8 +19,6 @@
|
|||||||
{ value: "analyze", label: t("categories.analyze") },
|
{ value: "analyze", label: t("categories.analyze") },
|
||||||
{ value: "generate", label: t("categories.generate") },
|
{ value: "generate", label: t("categories.generate") },
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: Button component
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="catalog-toolbar">
|
<div class="catalog-toolbar">
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
<script lang="ts">
|
|
||||||
// TODO: insert version from package.json
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<footer class="preview-footer">
|
<footer class="preview-footer">
|
||||||
<span>easy-png-tools <b class="version">v0.1.0</b></span>
|
<span>easy-png-tools <b class="version">v0.1.0</b></span>
|
||||||
<span>© 2026</span>
|
<span>© 2026</span>
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
loading = false,
|
loading = false,
|
||||||
parts = undefined,
|
parts = undefined,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
// TODO: make canvas aspect ratio auto, from 16:9 to 9:16 max
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<figure class="tile">
|
<figure class="tile">
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Check } from "@lucide/svelte";
|
import { Check } from "@lucide/svelte";
|
||||||
|
|
||||||
// TODO: сделать эти типы общими для кнопок \ бейджей \ етц???
|
|
||||||
const ToneVariantDefine = {
|
const ToneVariantDefine = {
|
||||||
DEFAULT: "default",
|
DEFAULT: "default",
|
||||||
ACCENT: "accent",
|
ACCENT: "accent",
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let { theme, ontoggle }: Props = $props();
|
let { theme, ontoggle }: Props = $props();
|
||||||
|
|
||||||
// TODO: change icon animations - custom button instead of IconButton
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
),
|
),
|
||||||
})).filter((g) => g.tools.length > 0),
|
})).filter((g) => g.tools.length > 0),
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: make main page different from catalog - larger and simpler search, no categories
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="catalog-page">
|
<div class="catalog-page">
|
||||||
|
|||||||
Reference in New Issue
Block a user