docs: session handoff 2026-09-22 20:40 (HEIC, images→PDF, white UI)

This commit is contained in:
treamz 2026-09-22 20:41:29 +03:00
parent c65b3f5006
commit 9ecdd88163
2 changed files with 79 additions and 0 deletions

View File

@ -4,6 +4,7 @@
с итогами, решениями, открытыми вопросами и инструкцией «как продолжить». Ведётся скиллом с итогами, решениями, открытыми вопросами и инструкцией «как продолжить». Ведётся скиллом
`/session-handoff`. `/session-handoff`.
- [2026-09-22 20:40 — HEIC, конструктор «Картинки → PDF», белые фоны UI](sessions/2026-09-22-2040.md)
- [2026-09-05 02:31 — ffmpeg/ghostscript в образ, водяной знак PDF, снятие лимитов админа](sessions/2026-09-05-0231.md) - [2026-09-05 02:31 — ffmpeg/ghostscript в образ, водяной знак PDF, снятие лимитов админа](sessions/2026-09-05-0231.md)
- [2026-07-24 23:48 — Аудит безопасности (19 фиксов) + снятие лимитов /compress, деплой на VPS](sessions/2026-07-24-2348.md) - [2026-07-24 23:48 — Аудит безопасности (19 фиксов) + снятие лимитов /compress, деплой на VPS](sessions/2026-07-24-2348.md)
- [2026-07-24 17:43 — Локальная копия, снятие лимитов /compress, скилл деплоя под VPS](sessions/2026-07-24-1743.md) - [2026-07-24 17:43 — Локальная копия, снятие лимитов /compress, скилл деплоя под VPS](sessions/2026-07-24-1743.md)

View File

@ -0,0 +1,78 @@
# 2026-09-22 20:40 — HEIC, конструктор «Картинки → PDF», белые фоны UI
**Сделано:**
- **HEIC в /compress.** Раньше `.HEIC` проходил фильтр, но падал «Ошибка при сжатии»: prebuilt
libvips в sharp декодирует только AV1-HEIF (AVIF), а не HEVC. Добавлен `heic-decode`
(libheif на WASM, без нативных зависимостей), общий хелпер `lib/image.js`.
В режиме «Оригинал» HEIC/BMP → JPEG с расширением `.jpg`; формат источника берётся из
`sharp.metadata()`, а не из MIME браузера.
- **Конструктор «Картинки → PDF» в /pdf** (старая вкладка была нерабочей: фронт слал поле `files`,
бэкенд ждал `images`, и попасть туда можно было только после загрузки PDF):
форматы JPG/PNG/WebP/HEIC/AVIF/TIFF/GIF/BMP; drag&drop-порядок, стрелки, сортировка
(имя с natural-order/дата/размер), реверс, поворот по одной и всех, повтор страниц, удаление;
размер листа (по картинке/A4/A3/A5/Letter), ориентация, поля, качество, имя файла;
прогресс загрузки через XHR. Вход — кнопкой на шаге загрузки или броском одних картинок
в основную зону. Превью HEIC/TIFF — серверные миниатюры (`POST /pdf/thumb`).
- **Попутные фиксы /pdf:** потерянная обёртка `<div id="panel-watermark">` — из-за лишнего `</div>`
`stepConfig` закрывался рано, «Выполнить» и панели торчали на шаге загрузки; `pdfIcon` был
недоступен из inline-`onerror` (вынесен в `window`); SVG больше не принимается.
- **Белый фон (`--surface-800`)** у зон drag&drop, неактивных табов, кнопок-опций и карточек на
страницах compress, pdf, video, converter, formatter, sanitizer, parser. Активные табы —
светло-голубая заливка поверх белого (`linear-gradient(...), var(--surface-800)`).
- **Всё на проде** (VPS 195.140.146.84, контейнер `wadevelop`), прод-файлы байт-в-байт = `HEAD`.
`heic-decode@2.1.0` установлен в контейнере (`npm install` в `/app`, node_modules на томе).
- **Git:** два коммита запушены в Gitea (rpi4): `dabc26d` — незакоммиченная работа сессии
2026-09-05 (owner-реестр, лимиты, crash-guard ffmpeg/gs, водяной знак); `c65b3f5` — эта сессия.
**Изменённые / созданные файлы:**
- [lib/image.js](../../lib/image.js) — **новый**: `isHeic()` (по ftyp-бренду + расширению), `openImage()`
(HEIC через heic-decode → raw в sharp; непрозрачная альфа отбрасывается, иначе всё уходит в PNG)
- [routes/compress.js](../../routes/compress.js) — `openImage()`, общий `encodeImage()` вместо двух копий
if-цепочек, `sourceFormatOf(metadata)`
- [routes/pdf.js](../../routes/pdf.js) — новый `/fromImages` (опции в JSON-поле `options`, страницы
`[{f, r}]`, повторы встраиваются один раз, нетронутые JPEG/PNG — байт-в-байт), `/thumb`
(свой лимитер 300/мин, стоит ДО общего `router.use(limiter)`), `saveResult(..., displayName)` +
`owner.displayName` в скачивании, сообщение о лимите файлов, фильтр без SVG
- [public/pdf.html](../../public/pdf.html) — блок `#stepImages` (CSS `.ip-*`, JS `ip*`), панель
водяного знака, белые фоны
- [public/compress.html](../../public/compress.html) — `accept` с `.heic`, превью без битой картинки,
белые summary/список
- [public/video.html](../../public/video.html), [converter](../../public/converter.html),
[formatter](../../public/formatter.html), [sanitizer](../../public/sanitizer.html),
[parser](../../public/parser.html) — белые фоны
- [package.json](../../package.json) — `heic-decode`
**Решения:**
- HEIC декодируем через `heic-decode` (WASM), а не пересобираем sharp/libvips с libde265:
не нужен свой libvips в образе, работает на `node:20-slim`.
- Страницы PDF в режиме «По картинке»: 1 px = 1 pt (как было), длинная сторона ≤ 5080 pt.
- Миниатюры HEIC/TIFF делает сервер: браузеры, кроме Safari, их не рисуют.
- Табы `httpclient` (внутри белой панели), `regex` (уже белые), `md` (подчёркнутые) не трогали;
редакторы (`svgeditor`, `editor`) — полноэкранные холсты, не трогали.
**Открытые вопросы / следующие шаги:**
- [ ] Тёмная тема после смены фонов на `--surface-800` визуально не проверена (эмуляция в
headless не сработала) — глянуть руками.
- [ ] В самом браузере под учёткой прод-страницы не открывались (они за авторизацией) —
проверено сквозными запросами внутри контейнера и headless-тестом локальной копии.
- [ ] Серверные бэкапы этой сессии можно удалить, когда всё устоится:
`find /opt/sites/www/wadevelop.ru -name '*.bak-20260922-*'`.
- [ ] Идея: смешанная сборка «PDF + картинки» в одном документе (сейчас конструктор — только картинки).
**Как продолжить (для чистой сессии):**
- Контекст: [CLAUDE.md](../../CLAUDE.md), скилл `/deploy-wadevelop`. Перед правкой сверяй md5 файла
с VPS: `python3 C:/Users/tream/.claude/ssh_cmd.py root@195.140.146.84 "md5sum /opt/sites/www/wadevelop.ru/<file>"`.
- ⚠️ Грабли Windows: Python в текстовом режиме пишет CRLF — править файлы через `open(p,'rb'/'wb')`
или Edit-инструментом, иначе диф раздувается и хэши с продом расходятся (в репо — LF).
- ⚠️ Заливка через `ssh_cmd.run` + base64 в аргументе упирается в «Argument list too long» на
больших файлах (pdf.html ~100 КБ) — лить чанками по ~60 КБ; `ssh_cmd.run` вызывает `sys.exit`,
поэтому на несколько файлов — отдельный вызов на каждый (или ловить `SystemExit`).
- Локальный стенд без MySQL: мини-express с фейковой сессией
(`app.use((q,r,n)=>{q.session={user:{id:1}};n()})` + `app.use('/pdf', require('./routes/pdf.js'))`
+ `express.static('public')`), UI — headless Chrome через `puppeteer-core`
(`executablePath: 'C:/Program Files/Google/Chrome/Application/chrome.exe'`).
- Проверка на проде без логина: временный express-стенд внутри контейнера
(`docker exec -w /app wadevelop node -e "..."` на порту 3998).
**Ссылки:** https://wadevelop.ru/compress · https://wadevelop.ru/pdf · Gitea
`http://192.168.31.200:3002/treamz/wa-dev-tools`