- GET /pdf/preview/:fileId — renders first page as PNG (72 DPI)
- GET /pdf/preview/:fileId/:page — specific page preview
- GET /pdf/thumbnails/:fileId — list of all page preview URLs
- File cards show actual PDF thumbnail instead of icon
- Cached previews (30 min cleanup)
- Fallback to PDF icon if preview fails
- Fix multer encoding: decode Latin-1 to UTF-8 for Cyrillic names
- Use pdf-lib instead of pdf-parse for page count (more reliable)
- ignoreEncryption flag for encrypted PDFs
- 15 API endpoints for PDF operations (pdf-lib, pdf-parse, Ghostscript)
- Frontend with 8 operation tabs
- Merge multiple PDFs, split by page ranges
- Rotate/delete/reorder pages
- Add watermark text, page numbers
- Compress via Ghostscript (screen/ebook/printer quality)
- PDF to PNG/JPG, Images to PDF
- Password protection, text extraction
- Added to sidebar, dashboard (Utils category), DB
- Parse time= from each stderr chunk (not accumulated buffer)
- Add -progress pipe:2 flag for frequent progress output
- Support both time= and out_time= formats
- Progress only increases (no jumps back)
- /convert now returns immediately, ffmpeg runs in background
- Client polls /progress every second for live progress %
- Progress endpoint returns downloadUrl/outputSize when done
- UI shows real-time percentage during conversion
- AdminJS at /admin with auth (admin role only)
- Manage: users, categories, tools, content blocks, settings
- DB tables: settings, categories, tools, content_blocks
- Users table: added role (user/admin) and is_blocked fields
- API: /api/settings, /api/tools, /api/content/:section
- Sidebar: admin link visible only for admin users
- Removed /logs from public routes (now in AdminJS)
- Video converter: fixed ffmpeg codecs for RPi5 (h264_v4l2m2m)
- Dependencies: sequelize, @adminjs/sequelize, mariadb