- handle document paste: images become the entry photo when none is set,
otherwise they land in "Файлы проекта" along with any other pasted files
- take file names from the clipboard, replace generic ones (image.png, blob)
with "Вставка <date>.<ext>"; derive extension from MIME when missing
- validate client-side like the server: 10 files, 10 MB per file, 30 MB total,
reject blocked extensions (*.html, *.js, *.svg, ...)
- share the limit logic between the picker and paste, send the photo under its
real name so pasted PNG/JPEG keep their extension
- add Ctrl+V hints to the photo and files cards (hidden on touch devices)
Формирование и скачивание бэкапа разделены: POST /api/backup собирает архив
на диске и возвращает временную ссылку, GET /api/backup/:token отдаёт его
через res.download (Content-Length, Accept-Ranges, 206 при докачке).
- больше нет fs.readFileSync всего архива и res.send буфера (~550 МБ RAM -> ~60 МБ)
- GET /api/backup сохранён для совместимости, тоже потоковый
- gzip level 1 (архив из JPEG почти не сжимается), чистка /tmp/wido-backups по TTL 30 мин
- settings.html/js: нативное скачивание браузером с прогрессом и докачкой,
понятные ошибки вместо «Ошибка сети при формировании бэкапа»
- DB: add photo_jobs.applied column (init + migration + ensure)
- Worker: generate preview only (after_path), no longer mutates entry
- New POST /api/entries/:id/photo/jobs/:jobId/apply — apply done job
result to entry (backs up current photo, marks applied)
- New POST /api/entries/:id/photo/jobs/:jobId/reject — discard result,
delete temp file, mark rejected
- saveEnhance: apply AI result directly when sliders are at defaults
- Photo history: '✓ Применить' action for unapplied done AI jobs;
'rejected' status label
- sweepOrphanedUploads keeps done-not-applied preview files
- Fix runAiEnhance missing return/closing brace from previous commit
- Remove duplicate code fragments in worker.js
- Add renderPhotoPending() to show pending/processing jobs in worker dashboard
- New pending queue table in worker.html photo section
- Replace in-memory photoAiJobs Map with DB-backed photo_jobs table
- Background photo worker (worker.js) with retry, backoff, stale reset
- Handles both AI (Real-ESRGAN) and server-side (sharp) enhancement
- Controlled via photo_worker_enabled setting
- Photo job history in enhance modal with before/after thumbnails + rollback
- Worker dashboard: photo jobs section with status counts, recent table,
compare slider for before/after, rollback from worker UI
- New endpoints: /api/photo-jobs/status|wake|enabled|requeue-failed,
/api/entries/:id/photo/jobs (history), .../rollback
- swapEntryPhotoFiles logs every mutation to photo_jobs table
- Side-by-side before/after comparison with draggable divider
- Zoom (scroll wheel) and pan when zoomed in, double-click to reset
- Sliders moved to sidebar panel, responsive layout
- Original/Result badges on the comparison view
- Helper functions: setEnhanceClip, showEnhanceResult, applyEnhanceTransform
- Modal no longer auto-closes after Real-ESRGAN completes; result loads into
canvas so user can review, adjust sliders, and choose to apply or discard
- Backend skips swapEntryPhotoFiles until user confirms via Применить
- New DELETE /api/entries/:id/photo/enhance-ai/preview for temp file cleanup
- photo-ai Dockerfile: patch basicsr via find+sed instead of import (avoids
torchvision.functional_tensor import crash)
- webcam capture resolution/quality configurable in admin settings (defaults 640x480 / 0.92)
- enhance photo modal in journal: original vs preview with sliders (brightness, contrast, saturation, sharpen) and auto-levels button
- new endpoint PUT /api/entries/:id/photo/enhance replaces photo, cleans old file and thumb
- sharper HEIC conversion (0.92) and webp thumbnails (85)
- worker: fail explicitly on empty AI response
- renderStudentReport: детский учебный дизайн (крупные скругления, sticky-навигация, секции-карточки)
- журнал занятий в две колонки (одна на мобильных)
- единая галерея фото и видео: листание кнопками/стрелками, счётчик
- воспроизведение видео прямо в лайтбоксе
- кнопка закрытия ✕, закрытие по фону и Esc
- модалка экспорта отчёта ученика (период и выбор содержимого)