Files
contracts-flask/site/static/state.js
T

74 lines
4.1 KiB
JavaScript
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.
/**
* state.js — Центральное состояние приложения.
*
* ПАТТЕРН (из decoupling-final-plan.md, Фаза 0):
* action → мутация state → render(state)
*
* ПРАВИЛА:
* 1. ВСЕ состояния приложения — только здесь, в объекте state.
* 2. DOM — проекция state, никто не читает данные из DOM.
* Если что-то нужно узнать — смотри в state, а не в element.innerHTML.
* 3. Мутировал любое поле state → обязан вызвать render(state).
* Никаких прямых манипуляций DOM в обход render().
* 4. В любой момент console.log(state) показывает ВСЁ состояние приложения.
*
* СТРУКТУРА (Фаза 0 — минимальная, будет расширяться в Фазах 1-4):
*
* state.files — бывший fileQueue, массив загруженных файлов.
* Каждый элемент: { name, size, lastModified, file, doc_id,
* uploaded, parsed, parseInfo, supp_id, supp_type, status, zip_source }
*
* state.contractId — бывший contractId, ID контракта в БД.
* Приходит с бэкенда после первого успешного upload.
* null пока не загружен ни один файл.
*
* state.batchId — бывший batchId, уникальный ID сессии (UUID).
* Используется для привязки всех файлов сессии при классификации.
* Генерируется один раз при загрузке страницы.
*
* state.groups — бывший window._groupsData.
* Массив групп после классификации. Каждая группа:
* { contract_number, counterparty, documents[], unresolved? }
* null если классификация ещё не запускалась.
*
* state._activeCompare — бывшие _activeCompareES и _activeCompareTimer.
* Управляет ОДНИМ активным SSE-сравнением.
* Правило: только одно сравнение одновременно — все кнопки блокируются.
* { es: EventSource|null, timer: intervalId|null }
*
* state.ui — UI-состояние, не связанное с данными.
* ui.steps: { upload, classify, groups, compare }
* Каждый шаг: '○' (не начат) | '⏳' (в процессе) | '✓' (завершён)
* В Фазе 4 будет renderStepper(state).
*/
var state = {
// ── Файлы (бывший fileQueue) ──────────────────────────────
files: [],
// ── Контракт (бывший contractId) ──────────────────────────
contractId: null,
// ── Сессия (бывший batchId) ───────────────────────────────
// crypto.randomUUID() — браузерный API, поддержка 92%+ (Chrome 92+, FF 95+, Safari 15.4+)
batchId: crypto.randomUUID(),
// ── Группы (бывший window._groupsData) ────────────────────
groups: null,
// ── Активное сравнение ────────────────────────────────────
_activeCompare: {
es: null, // EventSource (SSE-соединение с /process-v2)
timer: null // setInterval ID для индикатора времени
},
// ── UI-состояние ──────────────────────────────────────────
ui: {
steps: {
upload: '○',
classify: '○',
groups: '○',
compare: '○'
}
}
};