All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 54s
Корень жалоб «дизайн не премиум»/«бары самодельные» — не в WeasyPrint, а в execution gap: CSS объявлял font-family DejaVu Serif/Sans, но ни один @font-face не embedded — документ всегда рендерился на системном fallback-шрифте. Price-range bar был буквально <div> с фиксированной 64%/14% заливкой, никак не связанной с реальными числами диапазона. Подтверждено 4 параллельными прототипами (ReportLab/Typst/Playwright/ улучшенный WeasyPrint) на одном и том же образце: WeasyPrint с честным шрифтом и настоящим графиком визуально не уступает более дорогим альтернативам (Chromium, Typst) при нулевом новом риске в Docker. Изменения: - PT Sans (400/700) + PT Serif (700, только для заголовков секций) — base64 @font-face из локальных .ttf (app/services/exporters/fonts/, OFL-лицензия ParaType), embedded один раз при импорте модуля. - Обязательный WeasyPrint FontConfiguration() — без него @font-face молча игнорируется и рендер откатывается на DejaVu (реальный баг, найденный и исправленный в процессе). - _price_range_bar (декоративный div) → _price_range_chart_svg — matplotlib (Agg backend, объектный Figure() API, не pyplot — потокобезопасно для конкурентных PDF-запросов в FastAPI threadpool) bullet-chart на реальном диапазоне значений, embedded как SVG data URI. - url_fetcher теперь передаётся в HTML() и CSS() конструкторы, а не в write_pdf() — в WeasyPrint 69 write_pdf(url_fetcher=...) молча игнорируется, из-за чего SSRF-guard фактически не применялся к CSS-ресурсам (@font-face src). Побочная находка при верификации, не связанная с шрифтами/графиком напрямую, но тот же вызов кода.
332 KiB
332 KiB