feat(export): Markdown + JSON download of §22 report — slice of #959 #1089

Merged
bot-backend merged 1 commit from feat/forecast-export-md-959 into main 2026-06-06 18:39:52 +00:00
Collaborator

Что

Слайс EPIC #959 (экспорт): Markdown + JSON-download §22-отчёта. PDF/XLSX уже были — это самые дешёвые no-dep форматы. (DOCX/pptx/Telegram — отдельно, требуют новых зависимостей + devops.)

Относится к #959 (НЕ закрывает — остаются DOCX/pptx/Telegram/презентация).

Содержимое

  • exporters/report_md.pyrender_report_markdown(report): чистый, без новых зависимостей, переиспользует str-хелперы из report_pdf.py (DRY: _normalize/_fmt/_level_ru/...). Рендерит 8 секций §13-отчёта в читаемый MD (exec_summary, market_now, future_market по горизонтам, сценарии, product_tz, scoring, confidence-drivers, meta + advisory-дисклеймер). Graceful на тонком/пустом отчёте, GFM-safe экранирование таблиц.
  • GET /{cad}/forecast/export?format=md|json — читает последний §22-ран (latest_run_for schema 1.0); md → text/markdown attachment, json → download-вариант. Нет рана → 404 (не 500/202). Невалидный format → 422 до БД.

Качество

  • code-reviewer: APPROVE — graceful (empty/None/garbage), GFM-экранирование, DRY-импорт верный (report_pdf._fmt→str), route не коллизит, no new deps, psycopg v3 чисто. 18 новых тестов (961 passed), ruff clean.
  • Минор (non-blocking): имя файла санитайзит только : — как в 2 существующих export-эндпоинтах (precedent), за auth. Кросс-эндпоинт хардненинг — опц. follow-up.

Тест-план (post-deploy)

GET /api/v1/parcels/66:41:0702048:27/forecast/export?format=md → 200 text/markdown, читаемый отчёт; ?format=json → download; участок без прогноза → 404.

## Что Слайс EPIC **#959** (экспорт): **Markdown + JSON-download** §22-отчёта. PDF/XLSX уже были — это самые дешёвые no-dep форматы. (DOCX/pptx/Telegram — отдельно, требуют новых зависимостей + devops.) Относится к #959 (НЕ закрывает — остаются DOCX/pptx/Telegram/презентация). ## Содержимое - `exporters/report_md.py` — `render_report_markdown(report)`: чистый, без новых зависимостей, переиспользует str-хелперы из `report_pdf.py` (DRY: `_normalize`/`_fmt`/`_level_ru`/...). Рендерит 8 секций §13-отчёта в читаемый MD (exec_summary, market_now, future_market по горизонтам, сценарии, product_tz, scoring, confidence-drivers, meta + advisory-дисклеймер). Graceful на тонком/пустом отчёте, GFM-safe экранирование таблиц. - `GET /{cad}/forecast/export?format=md|json` — читает последний §22-ран (`latest_run_for` schema 1.0); md → `text/markdown` attachment, json → download-вариант. Нет рана → 404 (не 500/202). Невалидный format → 422 до БД. ## Качество - `code-reviewer`: ✅ APPROVE — graceful (empty/None/garbage), GFM-экранирование, DRY-импорт верный (`report_pdf._fmt`→str), route не коллизит, no new deps, psycopg v3 чисто. 18 новых тестов (961 passed), ruff clean. - Минор (non-blocking): имя файла санитайзит только `:` — как в 2 существующих export-эндпоинтах (precedent), за auth. Кросс-эндпоинт хардненинг — опц. follow-up. ## Тест-план (post-deploy) `GET /api/v1/parcels/66:41:0702048:27/forecast/export?format=md` → 200 text/markdown, читаемый отчёт; `?format=json` → download; участок без прогноза → 404.
bot-backend added the
scope/backend
GG-форсайт
site-finder
labels 2026-06-06 18:39:49 +00:00
bot-backend added 1 commit 2026-06-06 18:39:49 +00:00
feat(export): Markdown + JSON download of §22 forecast report (#959)
All checks were successful
CI / changes (push) Successful in 6s
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Successful in 6m9s
CI / backend-tests (push) Successful in 5m58s
9ca8c9bf26
render_report_markdown (pure, no new runtime deps) reuses report_pdf's str
helpers (DRY), + GET /{cad_num}/forecast/export?format=md|json. No forecast run
→ 404; graceful on thin/empty reports; GFM-safe table escaping. PDF/XLSX already
existed; this adds the cheapest no-dep formats. Part of EPIC #959.
bot-backend merged commit 25f7052084 into main 2026-06-06 18:39:52 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1089
No description provided.