# Контракт данных СуБаланс v2

Все тестовые файлы синтетические. Они проверяют функции приложения и не подтверждают пригодность модели для реального водопользования.

## Полный проект / ответ API

Структура показана в `api-contract.json`: `schema_version: 2`, `metadata`, `zones`, `scenario`, `periods`, `channels`, `history`, `history_source`, `trained`.

- `metadata`: название `title`, целый год `season`, описание источника `source_name`, `provenance` (`synthetic` или `user`), лимит `limit_m3`, дата учёта `as_of` (ГГГГ-ММ-ДД).
- `scenario`: `water` от −20 до 20 (%), `weather` от −10 до 20 (%), `saving` от 0 до 40 (добавленные п.п.), `rice` от 0 до 20 (снятые п.п.).
- `history_source`: `name` и `provenance`. Происхождение истории не определяется автоматически по имени файла.
- `trained`: сохранять ли состояние обучения; модель детерминированно переобучается из сохранённой истории при загрузке.

## CSV / XLSX

CSV — UTF-8, разделитель `;`, запятая или табуляция; заголовки обязательны. Для десятичной запятой используйте `;`. XLSX — один лист, числовые значения без формул. Файл до 2 МБ, до 200 зон, 2 400 строк периодов, 500 каналов, 10 000 строк истории. Дубликаты ключей и пропуски не подменяются нулём.

### Зоны

`id,name,area_ha,rice_ha,saving_ha,weather_index,planned_water_m3,latitude,longitude`

Площади — га; план — м³ за сезон; индекс безразмерный. Координаты WGS84 необязательны, но задаются парой. ID — латинские буквы, цифры, дефис, подчёркивание. Площади риса и технологий не превышают общую площадь. Для подробных культур используйте JSON или редактор.

`crops` — до 20 строк культуры: `type` (`rice`, `wheat`, `maize`, `alfalfa`, `cotton`, `other` или другой идентификатор), `area_ha`, `saving_ha`, `norm_m3_ha`, `stage_factor`, `soil_factor`, `saving_efficiency` (доля 0–0,9). Итоги площадей обязаны совпасть с зоной. Только `rice` считается рисом. Тестовые нормы не являются утверждёнными агронормами.

### Периоды

`period,zone_id,demand_m3,planned_m3,received_m3,remaining_m3,growth_factor`

Одна строка на месяц и зону. Месяц `ГГГГ-ММ` принадлежит году проекта. Все объёмы — м³ за этот месяц. `received_m3` — накопленная фактическая подача на дату `metadata.as_of`; `remaining_m3` — ожидаемый остаток до конца месяца. Это непересекающиеся части. Для завершённого месяца задайте остаток 0; для будущего месяца фактическую подачу 0. `demand_m3` — базовая потребность месяца до коэффициента фазы. Она не выводится из сезонной автоматически; ответственность за временное согласование на источнике.

### Каналы

`from,to,capacity_m3,loss_pct`

Направленная связь двух известных зон. Пропуск — м³ на входе в участок за выбранный месяц; потери — проценты 0–90. Один набор пропускных способностей повторно применяется к выбранным месяцам; изменяющиеся по месяцам ограничения пока следует моделировать отдельными сохранёнными сценариями. Параллельные одинаковые направления объединяйте в одну эквивалентную связь.

### История ML

`season,zone_id,area_ha,rice_ha,saving_ha,weather_index,demand_m3`

Одна запись на сезон и зону, одинаковая точка учёта. `demand_m3` — измеренная или экспертно восстановленная потребность, не просто полученная вода в условиях дефицита. Не менее трёх сезонов; старые сезоны ≥20 строк, предпоследний ≥10, последний ≥10. Исторические зоны не обязаны совпадать с текущими.

## Будущий внешний API

HTTPS GET должен вернуть полный JSON проекта, HTTP 200 и JSON-контент. Разрешите CORS для опубликованного сайта. Приложение отправляет запрос без cookies и без токена; не помещайте секреты в URL. Redirect запрещён, таймаут 15 секунд, ответ до 2 МБ. Для закрытого ведомственного источника нужен отдельный серверный адаптер с секретом и проверкой полномочий.

## Источники реализации

- [SheetJS 0.20.3: самостоятельная браузерная сборка](https://docs.sheetjs.com/docs/getting-started/installation/standalone/) — локальный разбор Excel.
- [Open-Meteo Forecast API](https://open-meteo.com/en/docs) — модельные температура, осадки и ET₀ по координатам на ближайшие 7 дней. Прогноз не преобразуется автоматически в сезонный индекс.
