74 lines
4.1 KiB
JavaScript
74 lines
4.1 KiB
JavaScript
/**
|
||
* 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: '○'
|
||
}
|
||
}
|
||
};
|