Files
dairy-report-generator/NEXT_SESSION.md
T

169 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BRIEFING: DairyTrends Report Generator — состояние на 08.06.2026
## Что сделано
### Репозиторий
`https://git.zeroday.su/admin/dairy-report-generator` — основной проект генератора.
Живёт на dev сервере: `/var/www/dairy-report-generator/`
### Структура проекта
```
src/
data/palette.js — DT-палитра (синхронизирована с DESIGN_DAIRYTRENDS.md)
charts/chart1.js — Главный график: цена + себестоимость + 3 сценария + маржа
charts/chart5.js — Сгруппированные бары сценариев маржинальности
generators/document.js — Сборка DOCX: header, footer, KPI, callout, tables, images
index.js — Entry point: generateReport(config) → Buffer
examples/
russia.js — Полный рабочий пример для РФ
```
### Что работает
- `node examples/russia.js` → генерирует `/tmp/DT_Russia_Example.docx` (44KB), validation PASSED
- Графики рендерятся через SVG → sharp → PNG и встраиваются в DOCX
- Дизайн: черный хедер DT/DAIRY TRENDS, красные заголовки разделов, callout-блоки с красной полосой, KPI-блок на обложке
- Изображения корректно встраиваются (баг с EMU был исправлен — ImageRun принимает пиксели напрямую)
### Что ещё НЕ сделано (следующий шаг)
1. **chart2** — горизонтальные бары лидеров (переработчики/производители)
2. **chart3** — EBITDA margin по группам A/B/C
3. **chart4** — сравнение регионов (два вертикальных барчарта рядом)
4. **Страница в админке** `/admin/dairytrends/reports/` в new.dairy-news.ru с:
- Вкладка 1: **Отчёты** — выбор субъекта (регион/хозяйство/компания) + кнопка генерации + скачивание
- Вкладка 2: **Картинки через AI** — генерация изображений через Anthropic API
5. **API endpoint** `/api/admin/dairytrends/reports/generate` — принимает конфиг, возвращает DOCX
6. **Данные из БД** — для региональных отчётов тянуть из dn MySQL (`region_index`), для ФО из Prisma `DairyIndex`
7. **МЗЫ-режим** — отдельная схема данных для хозяйства (надой, поголовье, себестоимость, закупочная цена)
## Как запустить пример
```bash
cd /var/www/dairy-report-generator
node examples/russia.js
# → /tmp/DT_Russia_Example.docx
```
## API генератора
```javascript
const { generateReport } = require('/var/www/dairy-report-generator/src')
const buf = await generateReport({
subject: {
name: 'Вологодской области', // в родительном падеже для заголовков
shortName: 'Вологда',
type: 'region', // 'region' | 'farm' | 'company'
},
period: {
historicalFrom: '2024-01-01',
historicalTo: '2026-05-31',
forecastTo: '2026-12-31',
},
data: {
prices: [{ date: 'YYYY-MM-DD', price: Number }], // фактическая цена
costs: [{ date: 'YYYY-MM-DD', cost: Number }], // себестоимость
scenarios: {
base: [{ date, price }],
opt: [{ date, price }],
pess: [{ date, price }],
},
marginBars: [{ label, value, isForecast }], // для нижней панели chart1
scenarioMargins: [{ label, opt, base, pess }], // для chart5
kpi: [{ value, label }], // 4 блока на обложке
scenarioAssumptions: [{ name, price, costGrowth, rationale }],
retrospective: { columns: [{label,width}], rows: [[...]] },
forecastTable: { columns: [{label,width}], rows: [[...]] },
},
text: {
mainConclusion: '...',
conclusions: ['...'],
intro: ['...'],
methodology: ['...'],
retrospectiveSummary: '...',
forecastSummary: '...',
risks: ['...'],
recommendations: {
'Для руководителей хозяйств': ['...'],
'Для менеджеров по продажам': ['...'],
'Для инвесторов': ['...'],
},
},
})
fs.writeFileSync('report.docx', buf)
```
## Ключевые технические детали
### Баг с изображениями (ИСПРАВЛЕН)
ImageRun в docx-js принимает размеры в **пикселях**, НЕ в EMU.
```javascript
// ПРАВИЛЬНО:
new ImageRun({ data: buf, transformation: { width: 650, height: 400 }, type: 'png' })
// НЕПРАВИЛЬНО было: width: Math.round(wEmu/9144) → давало 0 или 1px
```
### Рендер SVG → PNG
```javascript
const sharp = require('sharp')
const buf = await sharp(Buffer.from(svgString)).png({ quality: 95 }).toBuffer()
```
LibreOffice при конвертации в PDF НЕ рендерит canvas-based изображения, но PNG через sharp работает корректно в Word.
### Размеры страницы (A4)
```javascript
const PAGE_W = 11906 // DXA
const MARGIN = 1020 // ~1.8cm
const CONTENT_W = 9866 // = PAGE_W - MARGIN*2
```
## Стек new.dairy-news.ru (куда интегрировать)
- Next.js 16.2.6, React 19.2.4, TypeScript
- Prisma (PostgreSQL), Tailwind CSS
- Порт 3030, nginx proxy
- Путь: `/var/www/dairynews/`
- Существующие разделы админки DT: `/admin/dairytrends/{indices,regions,ratings}/`
- Роли для доступа: `ADMIN`, `EDITOR_STATS`, `ANALYST_ADMIN`
- Образец страницы: `src/app/admin/dairytrends/page.tsx` — карточки с иконками ti-*
## Данные для отчётов
### Региональные цены (23 региона)
БД: dn сервер (188.127.243.10), MySQL, база `dn_ru`
```sql
SELECT region_name, date, price FROM region_index
WHERE region_slug = 'vologodskaya-oblast'
ORDER BY date
```
### ФО-агрегаты
БД: dev сервер, PostgreSQL через Prisma
```javascript
await prisma.dairyIndex.findMany({
where: { type: 'DAIRY_INDEX_RU', regionCode: { not: null } },
orderBy: { date: 'asc' }
})
```
8 ФО: ЦФО, СЗФО, ЮФО, СКФО, ПФО, УФО, СФО, ДВФО. Итого 349 записей.
### МЗЫ (Мяксинский завод / Агромилк)
Данных в БД пока нет — нужно завести вручную или импортировать из Буренки/FarmAI.
Схема: `{ date, milk_kg, cows, price_per_kg, cost_per_kg, revenue, expenses }`
## Следующие задачи для нового чата
1. **Дописать chart2, chart3, chart4** в `/var/www/dairy-report-generator/src/charts/`
2. **Создать страницу** `src/app/admin/dairytrends/reports/page.tsx` в new.dairy-news.ru
3. **API роут** `src/app/api/admin/dairytrends/reports/generate/route.ts`
4. **Подключить генератор** как local dependency или скопировать src напрямую в dairynews
5. **Вкладка "Картинки через AI"** — форма с промптом, регионом, типом → Anthropic API → показ + скачивание
## Пример страницы для начала работы
Образец существующей страницы для повторения стиля:
`/var/www/dairynews/src/app/admin/dairytrends/page.tsx`
Нужно добавить карточку "Отчёты" в этот файл и создать саму страницу.