Files
easy-png-tools2/docs/plan-platform.md
T
2026-10-04 07:18:50 +05:00

13 KiB
Raw Blame History

План: платформа — общее ядро, API и PWA

Статус: active. Этот план добавляет к docs/roadmap.md то, чего там нет: API (фаза 9, возможная монетизация) и PWA (фаза 10, оффлайн + установка), плюс шрифты (раздел 4 — частично относится к фазе 8, поэтому решения фазы 8 здесь дублируются). WASM-ядро, эталоны и CLI — фазы 2–8 docs/roadmap.md, они здесь не пересказываются. Оба трека стартуют после wasm-фаз; PWA не ждёт API и может идти раньше.

0. Решения

  • Одно ядро — три потребителя. Rust-крейт core/ (roadmap фаза 4) даёт: wasm-пакет для сайта (фаза 5), нативный CLI (фаза 6), серверный слой API (фаза 9). Единый контракт — JSON-пайплайн {id, params} (заложен в roadmap §0 и совпадает с Page.steps, реализуется в фазе 11); эталонные файлы и harness (фазы 2, 3, 7) гарантируют одинаковый результат во всех рантаймах.
  • API — нативный Rust на сервере, не wasm. В браузере wasm нужен ради доставки и песочницы; на сервере крейт линкуется напрямую — быстрее и проще. Исключение — edge-воркеры (см. спайк ниже): там исполняется тот же wasm-артефакт фазы 5.
  • PWA не трогает SEO-схему. Сайт остаётся полностью prerendered-статикой; service worker добавляет оффлайн-слой поверх и не отвечает за HTML ботовам.
  • Монетизация не ломает позиционирование. Браузерные инструменты — бесплатные, картинка обрабатывается в браузере и никуда не отправляется. Счётчик посещений GA4 этому не противоречит (границы — docs/plan-seo.md §0). API — отдельный продукт для автоматизации/бизнеса. Файлы в API обрабатываются в памяти: без хранения и логирования содержимого.

1. Фаза 9 — API (после фаз 5–7)

  • [A1] Спайк сервера: (а) axum/actix + нативный core/ на VPS против (б) wasm-артефакт фазы 5 на edge (CF Workers). Сравнить: стоимость, лимиты памяти/времени на больших картинках, сложность деплоя и rate-limiting. Решение записать в §0 этого файла.
  • [A2] Контракт: POST /v1/process — multipart (image) + JSON-пайплайн → изображение/архив; лимиты размера, коды ошибок; OpenAPI-спека.
  • [A3] Ключи и лимиты: Bearer-ключи, free tier (N запросов/мес), rate limiting по ключу; самостоятельная выдача/ротация ключей в кабинете — позже.
  • [A4] Биллинг: Stripe/LemonSqueezy (merchant of record), 2–3 тира по запросам/размеру файла. Только после стабильного free tier.
  • [A5] Документация как лендинг: /api — индексируемая страница (туториал, примеры curl/JS), OpenAPI, ссылка из llms.txt. Dev-аудитория — источник бэклинков (docs/plan-seo.md, S4c).
  • Гейт: один и тот же пайплайн даёт пиксельно идентичный результат в браузере, CLI и API (harness фазы 7 расширяется третьим рантаймом).

2. Фаза 10 — PWA (после S1)

  • [P1] Манифест: имя (бренд после R1 из plan-seo §6), иконки 192/512 + maskable, theme-color из дизайн-токенов, display: standalone.
  • [P2] Service worker (SvelteKit src/service-worker.ts): precache app-shell; immutable-ассеты (build-hash) — cache-first; навигация по инструментам — stale-while-revalidate; offline-fallback страница. Спайком оценить вес полного precache: страницы маленькие, тяжёлое тащить по требованию.
  • [P3] Оффлайн-UX: индикатор «offline — работаете локально», своя кнопка установки (на beforeinstallprompt), стратегия обновления версии (prompt vs skipWaiting — решить на спайке).
  • [P4] SEO-безопасность: SW не перехватывает запросы ботов и не меняет HTML-ответы; canonical/prerendered-страницы не затрагиваются. Проверка: Lighthouse PWA + SEO зелёные после внедрения.
  • Гейт: каталог и топ-инструменты полностью работают в airplane-mode; повторный визит без сети открывается мгновенно.

3. Порядок и связи

  • WASM-ядро, эталоны, CLI — docs/roadmap.md фазы 2–8; пайплайн как продуктовая фича — фаза 11 того же документа.
  • PWA — после S1 plan-seo.md; API — после фаз 5–7.
  • Синергия с дистрибуцией: «works offline, installable» и публичный API — аргументы для Product Hunt / alternative.to / GitHub (docs/plan-seo.md, S4c) и для GEO-текстов (llms.txt, описания категорий).

4. Шрифты: лицензирование и DOM-free рендер текста

Текст — один из canvas-зависимых классов, которые roadmap (фаза 8) держит в TS (перечень — там же); для текста выбран курс на реимплементацию, остальные классы не переносятся. Для CLI/API текст всё равно придётся рендерить в Rust, поэтому решение: перевести text-инструменты в ядро (в браузере canvas-рендер остаётся TS-фолбэком для A/B). Два вопроса — легальность шрифтов в дистрибутиве и рендер без DOM.

Когда начинать: блока F1–F4 нет — они не привязаны к фазе roadmap, но F5/F6 без них бессмысленны (нечего рендерить). Реализуется всё это в фазе 8, поэтому лицензирование стоит закрыть до неё, а не после.

Лицензирование (решить до выбора шрифтов, backlog «Font Style»)

  • [F1] В набор — только лицензии, допускающие коммерческое использование и встраивание в продукт (сайт + PWA + CLI + API): база — SIL OFL 1.1 (можно редистрибутировать и использовать коммерчески; нельзя продавать сами шрифты; требование — сохранять лицензию и имена при редистрибуции) и Apache 2.0 (Roboto, Open Sans, часть Noto).
  • [F2] Запрещённые категории: «free for personal use», shareware, шрифты без явной лицензии, MS core fonts (лицензия привязана к поставке с Windows-ПО). Отдельно проверять: бесплатность «для веба на одном домене» ≠ право класть TTF в дистрибутив CLI/API — у OFL/Apache таких ограничений нет, у прочих «free»-лицензий бывают.
  • [F3] Паспорт шрифта в core/fonts/<name>/ (или эквивалент): файл(ы), LICENSE, источник, версия, хеш; новый гейт «у каждого файла шрифта есть паспорт» — его ещё нет, проектируется здесь и добавляется в pnpm verify по правилам docs/quality-gates.md (решение о fail-режиме — docs/decisions.md). Браузер грузит шрифты из бандла, не из ОС и не с fonts.googleapis.com-CDN (сторонний запрос = утечка IP пользователя, лишняя зависимость от чужой инфраструктуры), — одинаковый результат у всех пользователей и во всех рантаймах.
  • [F4] Кириллица: приоритет семействам с полным покрытием — Liberation Sans, PT Sans/PT Serif, Noto Sans, Inter, Roboto (OFL/Apache), DejaVu Sans (пермиссивная лицензия Bitstream Vera: редистрибуция и коммерческое использование разрешены) — закрывает и backlog-вопрос про «только с кириллицей».
  • Стартовый набор (все OFL/Apache, с кириллицей; состав не догма — расширяется по запросам, каждый проходит паспорт F3). Сейчас в бандле сайта лежат @fontsource/ibm-plex-sans и @fontsource/ibm-plex-mono (тоже OFL) — в наборе ниже их нет, и при введении паспорта F3 их судьбу нужно решить явно: оставить или заменить.
    • базовый sans: Inter (дефолт add-text), PT Sans / Golos Text (профессиональная русская типографика), Noto Sans (фолбэк покрытия);
    • serif: PT Serif, Lora, Playfair Display (display);
    • mono: JetBrains Mono (дефолт), Roboto Mono;
    • display/акцент: Oswald (узкий), Rubik (округлый), Comfortaa, Caveat (рукописный), Amatic SC (маркерный);
    • кириллицу проверить по файлу при добавлении: Bebas Neue, Pacifico (добавлялась поздними версиями). Источник файлов — только Google Fonts / Fontsource (версионированные пакеты под паспорт F3); случайные «free font»-сайты — нет. Вес: woff2-сабсеты latin+cyr лениво в браузере, TTF в CLI (~2–4 МБ суммарно), в wasm не зашивать — грузить из статики по требованию.

Рендер без DOM (спайк — фаза 5–6, реализация — фаза 8)

  • [F5] Спайк стека: растеризация глифов (ab_glyph/rusttype) + шейпинг (swash/harfrust; для латиницы/кириллицы сложный шейпинг не критичен, сложные письменности — осознанно не в первой версии) → отрисовка в наш Image. Эталон — canvas-рендер TS (perceptual-класс по roadmap §3): совпадать обязаны позиция/выравнивание/переносы, пиксели будут отличаться хинтингом/антиалиасингом.
  • [F6] Единый текстовый API для TS-core и Rust-core: параметры текста — из JSON-схемы инструмента, шрифт — id из реестра шрифтов (не системное имя), метрики базовой линии считать в ядре, а не через canvas measureText (иначе TS и Rust разъедутся).
  • Гейт: один и тот же текстовый шаг пайплайна даёт в браузере (wasm), CLI и API визуально идентичный результат; в дистрибутиве нет ни одного файла шрифта без паспорта лицензии.