From 773c9337a124d05648d37e624c13b41cf766d510 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Tue, 10 Nov 2026 13:26:29 +0400 Subject: [PATCH] =?UTF-8?q?openspec:=20=D0=B0=D1=80=D1=85=D0=B8=D0=B2=20co?= =?UTF-8?q?rrections-api-stage-one=20(AURORA-1540,=20PR=20#208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change остался неархивированным после слияния #208; все задачи выполнены. Co-Authored-By: Claude Opus 5.5 --- .../.openspec.yaml | 0 .../design.md | 0 .../proposal.md | 0 .../specs/corrections-api/spec.md | 0 .../tasks.md | 0 openspec/specs/corrections-api/spec.md | 97 +++++++++++++++++++ 6 files changed, 97 insertions(+) rename openspec/changes/{corrections-api-stage-one => archive/2026-11-10-corrections-api-stage-one}/.openspec.yaml (100%) rename openspec/changes/{corrections-api-stage-one => archive/2026-11-10-corrections-api-stage-one}/design.md (100%) rename openspec/changes/{corrections-api-stage-one => archive/2026-11-10-corrections-api-stage-one}/proposal.md (100%) rename openspec/changes/{corrections-api-stage-one => archive/2026-11-10-corrections-api-stage-one}/specs/corrections-api/spec.md (100%) rename openspec/changes/{corrections-api-stage-one => archive/2026-11-10-corrections-api-stage-one}/tasks.md (100%) create mode 100644 openspec/specs/corrections-api/spec.md diff --git a/openspec/changes/corrections-api-stage-one/.openspec.yaml b/openspec/changes/archive/2026-11-10-corrections-api-stage-one/.openspec.yaml similarity index 100% rename from openspec/changes/corrections-api-stage-one/.openspec.yaml rename to openspec/changes/archive/2026-11-10-corrections-api-stage-one/.openspec.yaml diff --git a/openspec/changes/corrections-api-stage-one/design.md b/openspec/changes/archive/2026-11-10-corrections-api-stage-one/design.md similarity index 100% rename from openspec/changes/corrections-api-stage-one/design.md rename to openspec/changes/archive/2026-11-10-corrections-api-stage-one/design.md diff --git a/openspec/changes/corrections-api-stage-one/proposal.md b/openspec/changes/archive/2026-11-10-corrections-api-stage-one/proposal.md similarity index 100% rename from openspec/changes/corrections-api-stage-one/proposal.md rename to openspec/changes/archive/2026-11-10-corrections-api-stage-one/proposal.md diff --git a/openspec/changes/corrections-api-stage-one/specs/corrections-api/spec.md b/openspec/changes/archive/2026-11-10-corrections-api-stage-one/specs/corrections-api/spec.md similarity index 100% rename from openspec/changes/corrections-api-stage-one/specs/corrections-api/spec.md rename to openspec/changes/archive/2026-11-10-corrections-api-stage-one/specs/corrections-api/spec.md diff --git a/openspec/changes/corrections-api-stage-one/tasks.md b/openspec/changes/archive/2026-11-10-corrections-api-stage-one/tasks.md similarity index 100% rename from openspec/changes/corrections-api-stage-one/tasks.md rename to openspec/changes/archive/2026-11-10-corrections-api-stage-one/tasks.md diff --git a/openspec/specs/corrections-api/spec.md b/openspec/specs/corrections-api/spec.md new file mode 100644 index 0000000..44385ea --- /dev/null +++ b/openspec/specs/corrections-api/spec.md @@ -0,0 +1,97 @@ +# corrections-api Specification + +## Purpose +Предоставляет backend-контракт для просмотра, сохранения и экспорта корректировок агрегатов бухгалтерского баланса, вычисленных сервисом разнесения ОСВ. + +## Requirements + +### Requirement: Чтение таблицы корректировок +Система SHALL вызывать сервис разнесения AURORA-1751 через `CorrectionAggregateSource` и возвращать его агрегаты ББ с компаниями, статьями, счетами, позициями, сопоставленными парами, суммами, отклонением и сохранённой корректировкой. GET MUST NOT записывать вычисленное разнесение, пары или корректировки в БД. + +#### Scenario: Чтение доступной версии +- **WHEN** пользователь с правом просмотра запрашивает таблицу доступной версии +- **THEN** система возвращает вычисленные агрегаты, сопоставленные пары и оставшиеся позиции в стабильном порядке +- **THEN** в БД не создаются назначения или корректировки + +#### Scenario: Сопоставленная пара +- **WHEN** сервис AURORA-1751 возвращает элемент в `matched` или `with_discrepancy` +- **THEN** агрегат содержит `pairs` с обеими сторонами этого элемента +- **THEN** каждая сторона пары содержит относящиеся к ней идентификаторы строк ОСВ, счета и сумму +- **THEN** суммы и отклонение пары совпадают с результатом AURORA-1751 без повторного сопоставления в сервисе корректировок + +#### Scenario: Позиция без сопоставленной стороны +- **WHEN** ручная или односторонняя позиция агрегата не входит ни в одну вычисленную пару +- **THEN** она присутствует в соответствующей стороне агрегата без искусственно созданной встречной позиции + +### Requirement: Расчёт отклонения и элиминации +Система SHALL считать абсолютное отклонение и процент к меньшей положительной сумме без предварительного округления. При отклонении не более 5 % справочная сумма элиминации SHALL равняться меньшей сумме; остаток SHALL относиться к большей статье. + +#### Scenario: Отклонение не более пяти процентов +- **WHEN** меньшая сторона положительна и отклонение составляет ровно 5 % или меньше +- **THEN** сумма элиминации равна меньшей стороне +- **THEN** разница остаётся в большей статье + +#### Scenario: Отклонение больше пяти процентов +- **WHEN** отклонение больше 5 % +- **THEN** агрегат помечается как требующий корректировки + +#### Scenario: Нулевая меньшая сторона +- **WHEN** одна сторона равна нулю +- **THEN** процент отклонения равен `null` +- **THEN** агрегат считается односторонним + +### Requirement: Сохранение корректировки агрегата +Система SHALL атомарно заменять корневые и дочерние строки корректировки существующего агрегата. Комментарий после trim MUST быть непустым при каждом сохранении. Успешное сохранение SHALL устанавливать статус `APPLIED`. + +#### Scenario: Сохранение с комментарием +- **WHEN** аналитик сохраняет допустимые суммы и статьи обеих сторон с непустым комментарием +- **THEN** система полностью заменяет набор корректировки и возвращает `APPLIED` +- **THEN** создаётся аудит `CORRECTION_CREATE` или `CORRECTION_EDIT` + +#### Scenario: Пустой комментарий +- **WHEN** аналитик сохраняет корректировку с пустым или состоящим из пробелов комментарием +- **THEN** система возвращает `COMMENT_REQUIRED` +- **THEN** ни одна строка корректировки не изменяется + +#### Scenario: Ошибка одной дочерней строки +- **WHEN** одна из сумм или статей недопустима +- **THEN** весь запрос отклоняется без частичной записи + +### Requirement: Конкурентное и статусное ограничение +Система MUST разрешать изменение только владельцу активной блокировки редактируемой версии. Клиент SHALL передавать ожидаемую редакцию существующей корректировки. + +#### Scenario: Конфликт редакции +- **WHEN** ожидаемая редакция не совпадает с текущей +- **THEN** система возвращает `CORRECTION_VERSION_CONFLICT` без записи + +#### Scenario: Верифицированная версия +- **WHEN** пользователь пытается сохранить корректировку после верификации версии +- **THEN** система отклоняет изменение + +### Requirement: XLSX-экспорт корректировок +Система SHALL экспортировать таблицу одним листом XLSX. Строка агрегата SHALL сопровождаться следующими за ней раскрываемыми строками детализации; колонка правила у строки детализации SHALL быть пустой. Каждая сопоставленная пара SHALL занимать одну строку с одновременно заполненными колонками обеих компаний. + +#### Scenario: Экспорт ББ +- **WHEN** пользователь экспортирует таблицу корректировок +- **THEN** файл называется `Корректировки_<название ГК>_<год>_<квартал>.xlsx` +- **THEN** книга содержит один лист с агрегатами, детализацией и итогами в рублях +- **THEN** позиции сопоставленной пары не дублируются отдельными строками под той же парой +- **THEN** ручные и односторонние позиции выводятся отдельными строками +- **THEN** система создаёт событие аудита `EXPORT` + +### Requirement: Граница этапа +Система MUST NOT предоставлять в этом capability импорт XLSX, собственный алгоритм разнесения строк ОСВ, ручной перенос строк между правилами или операции изменения назначений. Вызов готового расчёта AURORA-1751 для чтения таблицы SHALL считаться интеграцией с источником, а не реализацией разнесения в capability корректировок. + +#### Scenario: Контракт этапа +- **WHEN** публикуется OpenAPI этапа корректировок +- **THEN** в нём отсутствуют операции импорта и назначения строк правилам + +### Requirement: Инвалидация корректировки при ручном назначении +После успешного ASSIGN/UNASSIGN система SHALL определять затронутые пары компаний непосредственно по `entry_ids` в +`osv_entry` и переводить все их `APPLIED`-корректировки в `DRAFT`. Суммы, статьи и комментарий SHALL сохраняться. +Операция MUST NOT выполнять полный расчёт `assignment_candidates`; статус `REVOKED` на этом этапе не устанавливается. + +#### Scenario: Изменено назначение строки пары компаний +- **WHEN** аналитик назначает строку правилу или снимает назначение +- **THEN** все `APPLIED`-корректировки этой пары компаний получают `DRAFT` +- **THEN** корректировки других пар и уже находящиеся в `DRAFT` не изменяются -- 2.47.2