SSE streaming added unnecessary complexity and latency due to
buffering issues across Node.js event loop, Nginx proxy, and
Docker layers. Reverted to a simple synchronous request/response
for PDF conversion. Kept extractLlmErrorMessage for user-friendly
LLM errors, lazy-loaded pdf-parse, and extended Nginx timeout.
- Move import modal visibility into ImportContext so the Layout
progress pill can reopen the result dialog after the modal was closed.
- Raise LLM progress cap from 85% to 98% and drop the intermediate
-import 88%- SSE event to eliminate the visual stall after LLM finishes.
- Detect LLM context-length errors (n_keep >= n_ctx) and surface a
clear message instead of generic -Временная ошибка конвертации-.
Replace the synchronous PDF import with Server-Sent Events streaming
between the backend (LLM) and the browser. The user can now close the
import modal and continue working while the conversion runs — a fixed
progress bar in the Layout shows real-time stage and percentage.
pdf-parse@2.4.5 pulls in @napi-rs/canvas (native Skia binary) which
crashes on import in Alpine containers. Moved to lazy require() so the
app starts normally and pdf-parse loads only when PDF conversion is
actually requested.
- Lazy-load pdf-parse in pdfToStatement to avoid startup crash
- Add libc6-compat, fontconfig, freetype to Alpine runner stage
- Increase npm fetch timeouts in both Dockerfiles for slow networks
- Add connectionTimeoutMillis to pg Pool for faster failure detection
- Accept only PDF and JSON files in import modal and API
- Convert PDF statements to JSON 1.0 via LLM (OpenAI-compatible)
- Use multipart/form-data for file upload (multer, 15 MB limit)
- Add LLM_API_KEY and LLM_API_BASE_URL for configurable LLM endpoint
- Update ImportModal to validate type and send FormData
- Add postFormData to API client for file upload