docs: обновлён NEXT_SESSION.md — итоговое состояние на 09.06.2026
This commit is contained in:
+54
-155
@@ -1,168 +1,67 @@
|
|||||||
# BRIEFING: DairyTrends Report Generator — состояние на 08.06.2026
|
# DairyTrends Report Generator — состояние на 09.06.2026
|
||||||
|
|
||||||
## Что сделано
|
## Репозитории
|
||||||
|
- **Генератор**: https://git.zeroday.su/admin/dairy-report-generator → `/var/www/dairy-report-generator/`
|
||||||
|
- **Next.js приложение**: https://git.zeroday.su/admin/dairynews-nextjs → `/var/www/dairynews/`
|
||||||
|
- **Сервер**: dev2 (77.222.43.248)
|
||||||
|
|
||||||
### Репозиторий
|
## Что сделано и работает
|
||||||
`https://git.zeroday.su/admin/dairy-report-generator` — основной проект генератора.
|
|
||||||
|
|
||||||
Живёт на dev сервере: `/var/www/dairy-report-generator/`
|
### 5 графиков (SVG → sharp → PNG → DOCX)
|
||||||
|
|
||||||
### Структура проекта
|
| Файл | Описание | Статус |
|
||||||
```
|
|------|----------|--------|
|
||||||
src/
|
| chart1.js | Линейный: цена + себестоимость + 3 сценария + барчарт маржи | ✅ |
|
||||||
data/palette.js — DT-палитра (синхронизирована с DESIGN_DAIRYTRENDS.md)
|
| chart2.js | Две панели: горизонт. бары (красный=переработчик, серый=производитель) + верт. бары объёма | ✅ |
|
||||||
charts/chart1.js — Главный график: цена + себестоимость + 3 сценария + маржа
|
| chart3.js | Горизонт. бары EBITDA, цвет по группе (А=красный, Б=серый, В=красный приглушённый) | ✅ |
|
||||||
charts/chart5.js — Сгруппированные бары сценариев маржинальности
|
| chart4.js | Две панели, серые бары + красный highlight; режим independentScales для регионов | ✅ |
|
||||||
generators/document.js — Сборка DOCX: header, footer, KPI, callout, tables, images
|
| chart5.js | Группированные бары сценариев, зелёный/красный/серый | ✅ |
|
||||||
index.js — Entry point: generateReport(config) → Buffer
|
|
||||||
examples/
|
|
||||||
russia.js — Полный рабочий пример для РФ
|
|
||||||
```
|
|
||||||
|
|
||||||
### Что работает
|
### Документ (document.js)
|
||||||
- `node examples/russia.js` → генерирует `/tmp/DT_Russia_Example.docx` (44KB), validation PASSED
|
- Обложка: хедер DT, 4 KPI-блока, callout "Главный вывод"
|
||||||
- Графики рендерятся через SVG → sharp → PNG и встраиваются в DOCX
|
- Раздел 1: Ключевые выводы
|
||||||
- Дизайн: черный хедер DT/DAIRY TRENDS, красные заголовки разделов, callout-блоки с красной полосой, KPI-блок на обложке
|
- Раздел 2: Введение
|
||||||
- Изображения корректно встраиваются (баг с EMU был исправлен — ImageRun принимает пиксели напрямую)
|
- Раздел 3: Методика + Таблица 1 (допущения)
|
||||||
|
- Раздел 4: Ретроспектива + **Таблица 2** (кварталы 2024/2025/2026) + Рисунок 1
|
||||||
|
- Раздел 5: Анализ предприятий (5.1 лидеры + Рис.2, 5.2 кластеры + Рис.3, callout разрыв, Рис.4)
|
||||||
|
- Раздел 6: Прогноз + Рис.5 + **Таблица 3** (3 сценария × 3 квартала + Пр-во тыс.т)
|
||||||
|
- Раздел 7: Рекомендации (3 аудитории)
|
||||||
|
|
||||||
### Что ещё НЕ сделано (следующий шаг)
|
### Данные
|
||||||
1. **chart2** — горизонтальные бары лидеров (переработчики/производители)
|
- **127 недель РФ** + **413 по 8 ФО** с 2024-01-01 по сегодня
|
||||||
2. **chart3** — EBITDA margin по группам A/B/C
|
- Источник: dn MySQL `region_index` → Prisma `DairyIndex`
|
||||||
3. **chart4** — сравнение регионов (два вертикальных барчарта рядом)
|
- Автосинхронизация: cron пн 06:00 → `scripts/sync-region-index.js`
|
||||||
4. **Страница в админке** `/admin/dairytrends/reports/` в new.dairy-news.ru с:
|
- `BITRIX_MYSQL_URL=mysql://dt_reader:DT_reader_2026!@188.127.243.10:3306/dn_ru`
|
||||||
- Вкладка 1: **Отчёты** — выбор субъекта (регион/хозяйство/компания) + кнопка генерации + скачивание
|
|
||||||
- Вкладка 2: **Картинки через AI** — генерация изображений через Anthropic API
|
|
||||||
5. **API endpoint** `/api/admin/dairytrends/reports/generate` — принимает конфиг, возвращает DOCX
|
|
||||||
6. **Данные из БД** — для региональных отчётов тянуть из dn MySQL (`region_index`), для ФО из Prisma `DairyIndex`
|
|
||||||
7. **МЗЫ-режим** — отдельная схема данных для хозяйства (надой, поголовье, себестоимость, закупочная цена)
|
|
||||||
|
|
||||||
## Как запустить пример
|
### Дизайн
|
||||||
|
- Единый серо-красный стиль chart4 (серые соседи + красный выбранный субъект)
|
||||||
|
- Падеж субъекта в текстах: предложный "в Северо-Западном" (через FO_PREP)
|
||||||
|
- Динамические пороги кластеризации (фикс/квантильный fallback)
|
||||||
|
|
||||||
|
### Генерация картинок
|
||||||
|
- Страница `/admin/content/images`
|
||||||
|
- gpt-image-2 через aiguoguo199, баланс = лимит − потрачено
|
||||||
|
- Таймаут nginx 300s (был 504)
|
||||||
|
|
||||||
|
## Что нужно сделать (backlog)
|
||||||
|
|
||||||
|
1. **Региональный отчёт (не ФО)** — для конкретной области типа Вологды нужны данные надоя (model RegionalIndicator или внешний источник). Сейчас chart4 умеет independentScales=true, но данные надоя в БД нет.
|
||||||
|
2. **МЗЫ-отчёт** — для хозяйства Агромилк/МЗЫ: надой, поголовье, собственная цена. Нужна своя схема.
|
||||||
|
3. **Данные 2025 год в Таблице 2** — некоторые кварталы показывают прочерки, т.к. БД заполнена только с dec 2025 для РФ (ФО с 2024). Можно добрать из dn региональных данных.
|
||||||
|
|
||||||
|
## Smoke-тест
|
||||||
```bash
|
```bash
|
||||||
cd /var/www/dairy-report-generator
|
cd /var/www/dairynews
|
||||||
node examples/russia.js
|
bash scripts/smoke-report.sh rf # РФ
|
||||||
# → /tmp/DT_Russia_Example.docx
|
bash scripts/smoke-report.sh fo:СКФО # Северо-Кавказский
|
||||||
|
bash scripts/smoke-report.sh fo:СЗФО # Северо-Западный
|
||||||
|
bash scripts/smoke-report.sh fo:ПФО # Приволжский
|
||||||
```
|
```
|
||||||
|
|
||||||
## 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)
|
|
||||||
```
|
```
|
||||||
|
/var/www/dairynews/src/lib/dairytrends-report-config.ts ← данные, тексты, таблицы
|
||||||
## Ключевые технические детали
|
/var/www/dairy-report-generator/src/charts/chart1-5.js ← SVG-генераторы
|
||||||
|
/var/www/dairy-report-generator/src/generators/document.js ← сборка DOCX
|
||||||
### Баг с изображениями (ИСПРАВЛЕН)
|
/var/www/dairynews/scripts/sync-region-index.js ← cron-синхронизация
|
||||||
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`
|
|
||||||
|
|
||||||
Нужно добавить карточку "Отчёты" в этот файл и создать саму страницу.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user