141 lines
13 KiB
Markdown
141 lines
13 KiB
Markdown
# System Analysis
|
||
|
||
## Requirement Coverage
|
||
|
||
| Requirement / Scenario | Flow | Contract / Semantics |
|
||
| --- | --- | --- |
|
||
| Последний результат обхода… — Сбой после частичного обновления | `hourly-attempt-terminal-barrier.mmd` | Outcome derivation, terminal barrier |
|
||
| Последний результат обхода… — Сбой до первого обновления | `hourly-attempt-terminal-barrier.mmd` | Outcome derivation |
|
||
| Последний результат обхода… — Частичный успех | `hourly-attempt-terminal-barrier.mmd` | Step results preserved |
|
||
| Каждая попытка обхода достигает итога в ограниченное время — Шаг не завершается | `hourly-bounded-wait.mmd` | Bounded wait per required step |
|
||
| Каждая попытка обхода достигает итога в ограниченное время — Наблюдение не ждёт без ограничения | `hourly-bounded-wait.mmd` | Bounded terminal outcome |
|
||
| Восстановление после сбоя сохранения… — Потерянное закрытие попытки | `hourly-recovery.mmd` | Recovery of lost settle |
|
||
| Восстановление после сбоя сохранения… — Перезапуск процесса | `hourly-recovery.mmd` | Recovery of abandoned attempt |
|
||
| Устаревшая публикация… — Поздняя публикация после появления преемника | `hourly-recovery.mmd` | Successor fencing |
|
||
| Устаревшая публикация… — Поздняя публикация до фиксации итога | `hourly-bounded-wait.mmd` | Late publication counts before outcome is recorded |
|
||
|
||
## Systems and Responsibilities
|
||
|
||
- **Hourly walk coordinator** (backend): резервирует попытку часового обхода для
|
||
текущего подключения, запускает обязательные шаги, ждёт их терминального
|
||
результата с ограничением, выводит итог попытки и закрывает её.
|
||
- **Durable attempt status** (SQLite): единственная durable-запись попытки
|
||
(состояние, диагностическая причина, результаты шагов) и источник итога для
|
||
наблюдения и восстановления.
|
||
- **Child step owners**: шаги membership, Portfolio, операций и будущих событий
|
||
публикуют свой полный результат в durable-хранилище и обозначают свой
|
||
терминальный результат; финализатор шага обязан фиксировать результат даже
|
||
при ошибке.
|
||
- **T-Bank и публичные источники**: внешние данные; начатые обращения не
|
||
отменяются по внутреннему ограничению ожидания.
|
||
- **Resource GET observer**: читает сохранённые данные и `meta` с состоянием
|
||
последней попытки; наблюдение не запускает обход.
|
||
|
||
## Interaction Flows
|
||
|
||
- `sequences/hourly-attempt-terminal-barrier.mmd` — попытка, шаги, terminal
|
||
barrier и вывод итога из фактических результатов шагов.
|
||
- `sequences/hourly-bounded-wait.mmd` — ограничение ожидания шага, закрытие
|
||
попытки по его истечении и учёт позднего результата до появления преемника.
|
||
- `sequences/hourly-recovery.mmd` — восстановление после сбоя сохранения и
|
||
после перезапуска процесса, отклонение устаревшей публикации.
|
||
|
||
## Contracts
|
||
|
||
- Новых и изменённых межсистемных HTTP/event contracts нет. Публичный словарь
|
||
состояний последней попытки (`выполнение`, `полный успех`, `частичный успех`,
|
||
`неуспех`) и форма `{ data, meta }` не меняются.
|
||
- Машинно-читаемый target contract в `system-analysis/contracts/` не создаётся:
|
||
изменения ограничены уточнением значений внутри существующих полей.
|
||
- Диагностическое поле причины остаётся открытым строковым полем; значения
|
||
причин прерывания (`INTERRUPTED` — ошибка, сбой сохранения, остановка
|
||
процесса; `DEADLINE` — истечение ограничения ожидания шага) дополняют
|
||
существующие коды ошибок шагов и не требуют изменения формы ответа.
|
||
- Compatibility check до закрытия change: backend-generated OpenAPI остаётся
|
||
семантически совместимым с текущим контрактом (ожидаются только дополнительные
|
||
значения открытого строкового поля диагностики).
|
||
|
||
## Data and State Semantics
|
||
|
||
- **Попытка**: `running` → терминальный итог (`succeeded` | `partial` | `failed`).
|
||
Попытка, не завершившая обязательный шаг, не может получить `succeeded`.
|
||
- **Terminal barrier**: итог попытки выводится только после того, как каждый
|
||
обязательный шаг достиг терминального результата либо учтён как истёкший по
|
||
ограничению ожидания. Итог не вычисляется по неполному списку шагов.
|
||
- **Вывод итога**: `succeeded` — только когда все обязательные шаги успешны и
|
||
координатор сам зафиксировал закрытие попытки; `partial` — успешны некоторые
|
||
шаги; `failed` — не успешен ни один. Успешные результаты шагов сохраняются
|
||
независимо от итога.
|
||
- **Причина прерывания**: попытка, закрытая до нормального завершения всех
|
||
шагов, сохраняет причину прерывания в диагностическом поле и не превышает
|
||
`partial`.
|
||
- **Internal coordinator decisions** `first`, `not-due`, `running`, `restart`,
|
||
`partial`: внутренние метки решения о запуске и проверки итога после terminal
|
||
barrier; в HTTP contract не входят и публично не наблюдаемы.
|
||
- **Шаги**: каждый шаг владеет своей durable-строкой результата; строка шага
|
||
устаревшей попытки помечается устаревшей относительно преемника.
|
||
|
||
## Error and Recovery Semantics
|
||
|
||
- **Сбой шага** (внешняя ошибка T-Bank): шаг фиксирует терминальный неуспех со
|
||
своим кодом ошибки; остальные шаги продолжаются; итог — `partial` или `failed`.
|
||
- **Сбой сохранения** (завершение шага, публикация результата, закрытие
|
||
попытки): ошибка не подавляется молча в durable-состоянии; попытка, оставшаяся
|
||
`running`, закрывается восстановлением по фактическим результатам шагов.
|
||
- **Остановка процесса**: начатая попытка остаётся `running` в SQLite;
|
||
следующий запуск процесса закрывает её как прерванную (`partial` или `failed`
|
||
с сохранёнными результатами шагов) и не создаёт перекрывающийся обход.
|
||
- **Ограничение ожидания**: истечение ограничивает только ожидание шага; уже
|
||
начатое обращение к T-Bank не отменяется. Его поздний результат сохраняется и
|
||
учитывается при выводе итога своей попытки, если итог ещё не зафиксирован, и
|
||
отклоняется как устаревший после появления преемника.
|
||
- **Повтор**: неуспешная попытка не повторяется ранее следующего часового срока,
|
||
отсчитанного от начала этой попытки; восстановление не сокращает и не
|
||
продлевает этот срок.
|
||
- **Overlapping**: следующая попытка не резервируется, пока предыдущая не
|
||
терминальна; восстановление обязано сначала закрыть предыдущую.
|
||
|
||
## Observability Semantics
|
||
|
||
- Наблюдаемый итог попытки и безопасный перечень проблемных счетов/разделов —
|
||
существующее обязательство; значения итога не расширяются.
|
||
- Семантические коды причин: `INTERRUPTED` — попытка прервана до нормального
|
||
завершения (ошибка, сбой сохранения, остановка процесса); `DEADLINE` — шаг не
|
||
завершился в ограничение ожидания. Коды сохраняются в диагностическом поле
|
||
попытки и/или шага и дополняют коды ошибок шагов без изменения формы `meta`.
|
||
- SDK/exporter/logger — вне границ этого изменения; используется существующий
|
||
структурный лог backend.
|
||
|
||
## Security and NFR at System Boundaries
|
||
|
||
- Граница наблюдения попытки остаётся границей текущего подключения: результат
|
||
прежней границы не раскрывается (существующее обязательство).
|
||
- Ограниченное время достижения итога попытки — наблюдаемое обязательство
|
||
надёжности: ожидание шага и ожидание наблюдателя ограничены.
|
||
- Новых trust boundaries, authn/authz требований нет.
|
||
|
||
## Compatibility / Migration
|
||
|
||
- Схема данных и HTTP contract не меняются; миграция не требуется.
|
||
- Уже застрявшие строки попыток в состоянии выполнения закрываются первым
|
||
проходом восстановления по правилам этого изменения: итог из фактических
|
||
результатов шагов, причина прерывания, без полного успеха. Это ожидаемое
|
||
разовое приведение legacy-состояния к диагностируемому виду.
|
||
- Совместимость с одно-процессной топологией сохраняется; межпроцессный lease
|
||
не требуется.
|
||
|
||
## Durable Documentation Candidates
|
||
|
||
- `docs/integrations/tbank.md` (раздел «Состояние и ошибки»): итог часовой
|
||
попытки, причины прерывания и правило ограниченного ожидания как часть
|
||
наблюдаемого состояния интеграции.
|
||
- `docs/architecture/containers.md` (раздел «Сохранение и восстановление
|
||
данных»): восстановление попытки после сбоя сохранения и после перезапуска
|
||
процесса как durable-свойство системы.
|
||
- Итоговое решение о переносе принимает `docs-impact`.
|
||
|
||
## Open Questions
|
||
|
||
- Нет блокирующих вопросов. Частота проявления механизма в production остаётся
|
||
не установленной и не влияет на contract.
|