From e9dc67b2e951e406ee0b0524e4f187ec9132c6ca Mon Sep 17 00:00:00 2001 From: PotapovaA Date: Wed, 21 Oct 2026 18:40:05 +0300 Subject: [PATCH] =?UTF-8?q?refactor(matrix):=20=D0=B2=D1=8B=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=BE=D0=BA=20=D0=B8=D0=B7=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=82=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B5=D1=81=D0=B5=D1=82?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- api/src/repositories/consolidations.py | 21 ------ api/src/schemas/consolidations.py | 2 - api/src/services/intercompany_matrix.py | 63 +--------------- api/tests/test_api_intercompany_matrix.py | 3 - api/tests/test_correction_repository.py | 34 --------- api/tests/test_intercompany_matrix.py | 75 ------------------- api/tests/test_intercompany_matrix_export.py | 8 -- .../intercompany-matrix-presets/design.md | 2 +- .../intercompany-matrix-presets/proposal.md | 9 +-- .../specs/consolidated-osv/spec.md | 20 ----- .../intercompany-matrix-presets/tasks.md | 5 +- 12 files changed, 10 insertions(+), 234 deletions(-) delete mode 100644 api/tests/test_correction_repository.py diff --git a/README.md b/README.md index a449cdd..4626427 100644 --- a/README.md +++ b/README.md @@ -872,7 +872,7 @@ API: список счетов `GET /directories/accounts`, правила ве `GET …/intercompany-matrix/all` и `POST …/manual`, их XLSX-выгрузки, статичная таблица `GET …/intercompany-matrix/result-table`. Режим PRESET (счета и показатель из правила элиминации): `GET …/intercompany-matrix/preset/{rule_id}`, его выгрузка `…/preset/{rule_id}/export` и строки сводной ОСВ без пары -`…/preset/{rule_id}/unpaired-osv`; в ячейке `correction_ids_debit/credit` (применённые корректировки правила). +`…/preset/{rule_id}/unpaired-osv`. `GET …/elimination-rules` отдаёт объект `{version_no, is_version_fixed, rules}` (у правила есть `id`): при незаданной версии правил — открытые правила (`valid_to IS NULL`). Ошибки PRESET: 422 `RULE_REQUIRED`, `INVALID_RULE`, `ACCOUNTS_REQUIRED`; правило недействительное для версии или несуществующее — 404. В шапке xlsx — строка «Показатель», diff --git a/api/src/repositories/consolidations.py b/api/src/repositories/consolidations.py index 4afee3e..ac7cdd9 100644 --- a/api/src/repositories/consolidations.py +++ b/api/src/repositories/consolidations.py @@ -31,7 +31,6 @@ from src.models.directories import CompanyGroup, LegalEntity, LegalEntityAlias, from src.models.enums import ( ConsolidationApproach, ConsolidationStatus, - CorrectionStatus, DocumentStatus, DocumentType, FileStatus, @@ -41,7 +40,6 @@ from src.models.enums import ( RelatedGroupKind, ) from src.models.files import Document, StoredFile -from src.models.kfo import Correction from src.models.osv import OsvEntry from src.repositories.directories import LIKE_ESCAPE, escape_like @@ -565,22 +563,3 @@ async def current_related_groups( for entity_id, group in await session.execute(stmt): groups[entity_id][group.kind] = group return dict(groups) - - -async def correction_for_version_consolidation( - session: AsyncSession, version_id: uuid.UUID, rule_id: uuid.UUID -) -> list[Correction]: - """Применённые корректировки правила для версии консолидации.""" - if not version_id or not rule_id: - return [] - - stmt = ( - select(Correction) - .where( - Correction.consolidation_version_id == version_id, - Correction.rule_id == rule_id, - Correction.status == CorrectionStatus.APPLIED, - ) - .order_by(Correction.id) - ) - return list((await session.scalars(stmt)).all()) diff --git a/api/src/schemas/consolidations.py b/api/src/schemas/consolidations.py index 809ba09..00435a7 100644 --- a/api/src/schemas/consolidations.py +++ b/api/src/schemas/consolidations.py @@ -367,8 +367,6 @@ class IntercompanyMatrixCellOut(BaseModel): ) osv_entry_ids_debit: list[uuid.UUID] osv_entry_ids_credit: list[uuid.UUID] - correction_ids_debit: list[uuid.UUID] = Field(default_factory=list) - correction_ids_credit: list[uuid.UUID] = Field(default_factory=list) @field_validator("amount_a", "amount_b", "variance_amount", "variance_percent") @classmethod diff --git a/api/src/services/intercompany_matrix.py b/api/src/services/intercompany_matrix.py index 9ea6d82..c77fe55 100644 --- a/api/src/services/intercompany_matrix.py +++ b/api/src/services/intercompany_matrix.py @@ -17,7 +17,6 @@ from src.models.accounting import ChartOfAccount, EliminationRule from src.models.consolidation import Consolidation, ConsolidationVersion from src.models.directories import CompanyGroup from src.models.enums import AccountKind, PeriodQuarter -from src.repositories import consolidations as consolidation_repo from src.repositories import directories as directory_repo from src.repositories import elimination_rules as elimination_rules_repo from src.schemas.consolidations import ( @@ -407,63 +406,6 @@ class IntercompanyMatrixService: unmatched = get_unpaired_rows(result.rows, result.matrix) return UnpairedOsvOut(items=[row_out(row) for row in unmatched], total=len(unmatched)) - async def _apply_corrections( - self, matrix: IntercompanyMatrixOut, version_id: uuid.UUID, rule_id: uuid.UUID - ) -> IntercompanyMatrixOut: - """Исключение суммы применённых корректировок из сторон пары пресета.""" - corrections = await consolidation_repo.correction_for_version_consolidation( - self._session, version_id=version_id, rule_id=rule_id - ) - if not corrections: - return matrix - - debit_by_pair: dict[tuple[uuid.UUID, uuid.UUID], Decimal] = defaultdict(lambda: ZERO) - credit_by_pair: dict[tuple[uuid.UUID, uuid.UUID], Decimal] = defaultdict(lambda: ZERO) - debit_ids_by_pair: dict[tuple[uuid.UUID, uuid.UUID], set[uuid.UUID]] = defaultdict(set) - credit_ids_by_pair: dict[tuple[uuid.UUID, uuid.UUID], set[uuid.UUID]] = defaultdict(set) - for correction in corrections: - owner, counterparty = correction.legal_entity_id, correction.counterparty_id - if owner is None or counterparty is None: - continue - pair = (owner, counterparty) - if correction.debit_adjustment is not None: - debit_by_pair[pair] += correction.debit_adjustment - debit_ids_by_pair[pair].add(correction.id) - if correction.credit_adjustment is not None: - credit_by_pair[pair] += correction.credit_adjustment - credit_ids_by_pair[pair].add(correction.id) - - cells = [] - for cell in matrix.cells: - debit_pair = (cell.company_a_id, cell.company_b_id) - credit_pair = (cell.company_b_id, cell.company_a_id) - amount_a = cell.amount_a - debit_by_pair.get(debit_pair, ZERO) - amount_b = cell.amount_b - credit_by_pair.get(credit_pair, ZERO) - debit_ids = list(debit_ids_by_pair.get(debit_pair, ())) - credit_ids = list(credit_ids_by_pair.get(credit_pair, ())) - if not debit_ids and not credit_ids: - cells.append(cell) - continue - variance_amount = abs(amount_a - amount_b) - base = min(amount_a, amount_b) - variance_percent = None if base == ZERO else variance_amount / base * 100 - cells.append( - IntercompanyMatrixCellOut.model_validate( - { - **cell.model_dump(), - "amount_a": amount_a, - "amount_b": amount_b, - "correction_ids_debit": debit_ids, - "correction_ids_credit": credit_ids, - "variance_amount": variance_amount, - "variance_percent": variance_percent, - "exceeds_threshold": variance_percent is not None - and variance_percent > VARIANCE_THRESHOLD_PERCENT, - } - ) - ) - return IntercompanyMatrixOut(companies=matrix.companies, cells=cells) - async def _resolve_preset_selection( self, rule_id: uuid.UUID | None, @@ -514,7 +456,6 @@ class IntercompanyMatrixService: rows = osv_result.consolidated.rows accounts = await directory_repo.list_accounts(self._session) by_id, children = _make_account_tree(accounts) - rule: EliminationRule | None = None if mode == "ALL": if debit_account_ids or credit_account_ids: raise DomainValidationError("ACCOUNTS_NOT_ALLOWED", "Для режима ALL не нужно указывать счета") @@ -528,12 +469,10 @@ class IntercompanyMatrixService: credit = _select_accounts(credit_account_ids, (), "K", by_id, children) selection = MatrixSelection(debit, credit, "closing") elif mode == "PRESET": - selection, rule = await self._resolve_preset_selection(rule_id, osv_result.version, by_id, children) + selection, _ = await self._resolve_preset_selection(rule_id, osv_result.version, by_id, children) else: raise DomainValidationError("INVALID_MODE", "Неизвестный режим выбора счетов") matrix = self._calculate(rows, osv_result.members, selection) - if rule is not None: - matrix = await self._apply_corrections(matrix, version_id, rule.id) return MatrixBuildResult( matrix=matrix, version=osv_result.version, diff --git a/api/tests/test_api_intercompany_matrix.py b/api/tests/test_api_intercompany_matrix.py index abecf82..0f49a82 100644 --- a/api/tests/test_api_intercompany_matrix.py +++ b/api/tests/test_api_intercompany_matrix.py @@ -133,8 +133,6 @@ async def test_no_osv_for_selected_accounts(auth_client: AuthClientFactory, seed assert { "osv_entry_ids_debit", "osv_entry_ids_credit", - "correction_ids_debit", - "correction_ids_credit", "exceeds_threshold", } <= cell.keys() assert {"entry_osv_ids_debit", "entry_osv_ids_credit", "is_more_5_percent"}.isdisjoint(cell) @@ -142,7 +140,6 @@ async def test_no_osv_for_selected_accounts(auth_client: AuthClientFactory, seed assert cell["variance_percent"] is None assert cell["one_sided"] is False assert cell["osv_entry_ids_debit"] == cell["osv_entry_ids_credit"] == [] - assert cell["correction_ids_debit"] == cell["correction_ids_credit"] == [] assert cell["skipped_osv_entry_count"] == 0 diff --git a/api/tests/test_correction_repository.py b/api/tests/test_correction_repository.py deleted file mode 100644 index 916cf61..0000000 --- a/api/tests/test_correction_repository.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Запрос корректировок к строкам ОСВ версии консолидации.""" - -import uuid -from types import SimpleNamespace -from unittest.mock import AsyncMock - -from sqlalchemy.dialects import postgresql - -from src.repositories.consolidations import correction_for_version_consolidation - - -async def test_correction_query_returns_all_applied_records_without_matching_osv() -> None: - session = AsyncMock() - corrections = [object(), object()] - session.scalars.return_value = SimpleNamespace(all=lambda: corrections) - version_id, rule_id = uuid.uuid4(), uuid.uuid4() - - assert await correction_for_version_consolidation(session, version_id, rule_id) == corrections - - stmt = session.scalars.await_args.args[0] - sql = str(stmt.compile(dialect=postgresql.dialect())) - assert "FROM dkb.correction" in sql - assert "osv_entry" not in sql - assert "correction.consolidation_version_id" in sql - assert "correction.rule_id" in sql - assert "correction.status" in sql - - -async def test_correction_query_requires_version_and_rule() -> None: - session = AsyncMock() - - assert await correction_for_version_consolidation(session, None, uuid.uuid4()) == [] - assert await correction_for_version_consolidation(session, uuid.uuid4(), None) == [] - session.scalars.assert_not_awaited() diff --git a/api/tests/test_intercompany_matrix.py b/api/tests/test_intercompany_matrix.py index 236465f..b9e91b1 100644 --- a/api/tests/test_intercompany_matrix.py +++ b/api/tests/test_intercompany_matrix.py @@ -82,7 +82,6 @@ def test_routes_are_separate_and_matrix_expands_manual_accounts() -> None: ] assert result.cells[0].amount_a == Decimal("100") assert result.cells[0].amount_b == Decimal("90") - assert result.cells[0].correction_ids_debit == result.cells[0].correction_ids_credit == [] assert result.cells[0].variance_percent == Decimal("11.11") assert isinstance(result, IntercompanyMatrixOut) response = result @@ -143,7 +142,6 @@ async def test_preset_applies_exclusions_to_its_own_side_and_rule_measure(monkey monkeypatch.setattr( matrix.elimination_rules_repo, "rule_with_account", AsyncMock(return_value=(rule, rule_accounts)) ) - monkeypatch.setattr(matrix.consolidation_repo, "correction_for_version_consolidation", AsyncMock(return_value=[])) session = SimpleNamespace(execute=AsyncMock(return_value=SimpleNamespace(scalar_one=lambda: "ГК"))) service = matrix.IntercompanyMatrixService(session, None, osv_service) captured = [] @@ -164,79 +162,6 @@ async def test_preset_applies_exclusions_to_its_own_side_and_rule_measure(monkey assert info.measure == "turnover" -async def test_preset_corrections_exclude_amounts_without_changing_osv(monkeypatch: pytest.MonkeyPatch) -> None: - company_a, company_b = uuid.uuid4(), uuid.uuid4() - debit_account, credit_account = uuid.uuid4(), uuid.uuid4() - debit_row = _row(company_a, company_b, debit_account, debit="1500") - credit_row = _row(company_b, company_a, credit_account, credit="1500") - debit_row.entry_ids = (uuid.uuid4(),) - credit_row.entry_ids = (uuid.uuid4(),) - companies = [ - IntercompanyMatrixCompanyOut(id=company_a, name="Компания А"), - IntercompanyMatrixCompanyOut(id=company_b, name="Компания Б"), - ] - original = matrix.calculate_matrix( - [debit_row, credit_row], - companies, - matrix.MatrixSelection(frozenset({debit_account}), frozenset({credit_account}), "closing"), - ) - debit_correction_id, credit_correction_id, child_correction_id = uuid.uuid4(), uuid.uuid4(), uuid.uuid4() - corrections = [ - SimpleNamespace( - id=debit_correction_id, - legal_entity_id=company_a, - counterparty_id=company_b, - debit_adjustment=Decimal("1000"), - credit_adjustment=None, - ), - SimpleNamespace( - id=credit_correction_id, - legal_entity_id=company_b, - counterparty_id=company_a, - debit_adjustment=None, - credit_adjustment=Decimal("500"), - ), - SimpleNamespace( - id=child_correction_id, - legal_entity_id=company_b, - counterparty_id=company_a, - debit_adjustment=None, - credit_adjustment=Decimal("500"), - ), - ] - monkeypatch.setattr( - matrix.consolidation_repo, "correction_for_version_consolidation", AsyncMock(return_value=corrections) - ) - - adjusted = await matrix.IntercompanyMatrixService(object(), None, object())._apply_corrections( - original, uuid.uuid4(), uuid.uuid4() - ) - - assert adjusted.cells[0].amount_a == Decimal("500") - assert adjusted.cells[0].amount_b == Decimal("500") - assert adjusted.cells[0].variance_amount == Decimal("0") - assert adjusted.cells[0].osv_entry_ids_debit == [debit_row.entry_ids[0]] - assert adjusted.cells[0].osv_entry_ids_credit == [credit_row.entry_ids[0]] - assert adjusted.cells[0].correction_ids_debit == [debit_correction_id] - assert set(adjusted.cells[0].correction_ids_credit) == {credit_correction_id, child_correction_id} - assert adjusted.cells[0].model_dump(mode="json")["correction_ids_debit"] == [str(debit_correction_id)] - assert original.cells[0].correction_ids_debit == original.cells[0].correction_ids_credit == [] - assert original.cells[0].amount_a == Decimal("1500") - assert original.cells[0].amount_b == Decimal("1500") - assert credit_row.closing_credit == Decimal("1500") - - -async def test_preset_without_corrections_keeps_matrix(monkeypatch: pytest.MonkeyPatch) -> None: - original = matrix.IntercompanyMatrixOut(companies=[], cells=[]) - monkeypatch.setattr(matrix.consolidation_repo, "correction_for_version_consolidation", AsyncMock(return_value=[])) - - adjusted = await matrix.IntercompanyMatrixService(object(), None, object())._apply_corrections( - original, uuid.uuid4(), uuid.uuid4() - ) - - assert adjusted is original - - def test_one_sided_reflects_osv_sources_even_when_amount_is_zero() -> None: company_a, company_b = uuid.uuid4(), uuid.uuid4() debit_account, credit_account = uuid.uuid4(), uuid.uuid4() diff --git a/api/tests/test_intercompany_matrix_export.py b/api/tests/test_intercompany_matrix_export.py index 1f7761d..1b78373 100644 --- a/api/tests/test_intercompany_matrix_export.py +++ b/api/tests/test_intercompany_matrix_export.py @@ -134,14 +134,6 @@ def test_matrix_export_has_three_rows_per_debit_company_and_highlights_threshold for offset in range(4) ) - debit_correction_id = UUID("796d1add-eaed-4802-8c79-8b3cdae2cca1") - credit_correction_id = UUID("55555555-5555-5555-5555-555555555555") - matrix.cells[0].correction_ids_debit = [debit_correction_id] - matrix.cells[0].correction_ids_credit = [credit_correction_id] - preset_sheet = load_workbook(BytesIO(build_matrix_workbook(matrix, _info(mode="PRESET")))).active - assert preset_sheet is not None - assert preset_sheet["D12"].comment is None - assert preset_sheet["D13"].comment is None async def test_export_routes_use_matrix_calculation() -> None: diff --git a/openspec/changes/intercompany-matrix-presets/design.md b/openspec/changes/intercompany-matrix-presets/design.md index 764a0e3..8858ffb 100644 --- a/openspec/changes/intercompany-matrix-presets/design.md +++ b/openspec/changes/intercompany-matrix-presets/design.md @@ -37,7 +37,7 @@ change не входит. Шахматка — чистая функция от 3. **Корректировки из шахматки убираются** (решение 4 выше и `correction_ids_*` в ячейке). Причины: корректировки в ядре никто не создаёт (спринт корректировок), семантика ключа `(rule, A, B)` относительно ячейки (A, B) / (B, A) не утверждена, счета корректировки и `parent_correction_id` не учитывались; §6 описывает шахматку как суммы первички. - Код сохранён в ветке `wip/shahmatka-corrections-unpaired` (`0e95f95`) и возвращается после решения по аналитике + Код корректировок выделен в ветку `AURORA-1747` и возвращается после решения по аналитике AURORA-1643 «Учитывание корректировок в шахматке». 4. **Ручка `…/preset/{rule_id}/unpaired-osv` убирается** (решение 5 выше). Причины: «без пары» по наличию строк (дефект AURORA-1651), ложные срабатывания при пересечении счетов сторон (76 в правиле № 6), нет ячейки и стороны diff --git a/openspec/changes/intercompany-matrix-presets/proposal.md b/openspec/changes/intercompany-matrix-presets/proposal.md index cb59d0e..1e58dee 100644 --- a/openspec/changes/intercompany-matrix-presets/proposal.md +++ b/openspec/changes/intercompany-matrix-presets/proposal.md @@ -1,7 +1,7 @@ ## Why Шахматка ВГО (ТЗ §6) считалась только по всем счетам (ALL) или по счетам, выбранным вручную (MANUAL). Аналитику нужен -режим «пресет»: счета и показатель берутся из правила элиминации (Прил. 3), с учётом применённых корректировок и со +режим «пресет»: счета и показатель берутся из правила элиминации (Прил. 3) и со списком строк сводной ОСВ без пары. Реализация — PR RSHB/arm-core#141 (ветка `add-preset-shahmatka`, автор — Потапова). Требования оформлены как дельты этого change'а при ревью (решение владельца 21.10.2026); спорное поведение вынесено в `design.md`, `## Known issues`, и в спеке не закреплено как окончательное. @@ -10,8 +10,7 @@ - Режим PRESET шахматки: `GET …/intercompany-matrix/preset/{rule_id}`, выгрузка `…/preset/{rule_id}/export`, список строк без пары `…/preset/{rule_id}/unpaired-osv`. -- Показатель пресета (`closing` / `turnover`) берётся из правила; в ячейке появляются `correction_ids_debit/credit`, - суммы уменьшаются на применённые корректировки правила. +- Показатель пресета (`closing` / `turnover`) берётся из правила. - `GET …/elimination-rules` возвращает объект `{version_no, is_version_fixed, rules}` вместо массива; у правила есть `id`. Для версии без зафиксированного `elimination_rules_version` отдаются открытые правила (`valid_to IS NULL`). - xlsx: для PRESET имя файла с `_preset-`, в шапке строка «Показатель»; audit `EXPORT` пишет `mode` @@ -24,11 +23,11 @@ ### Modified Capabilities - `consolidations-api`: ответ правил элиминации версии. -- `consolidated-osv`: режим PRESET шахматки, корректировки, строки без пары, xlsx пресета. +- `consolidated-osv`: режим PRESET шахматки, строки без пары, xlsx пресета. - `audit-trail`: аудит экспорта шахматки (режим PRESET). ## Impact Только `arm-core` (API, сервисы, схемы), таблицы и DBML не меняются. Ломающее изменение контракта -`GET …/elimination-rules` (массив → объект); поле `as_of` в ответ не входит. Потребителей старого формата в этом репозитории не проверялось — проверить при слиянии. Non-goals: фиксация версии правил, расчёт «актуальных» правил на отчётную дату, создание корректировок, +`GET …/elimination-rules` (массив → объект); поле `as_of` в ответ не входит. Потребителей старого формата в этом репозитории не проверялось — проверить при слиянии. Non-goals: фиксация версии правил, расчёт «актуальных» правил на отчётную дату, создание и применение корректировок, исправление `one_sided` (AURORA-1651). diff --git a/openspec/changes/intercompany-matrix-presets/specs/consolidated-osv/spec.md b/openspec/changes/intercompany-matrix-presets/specs/consolidated-osv/spec.md index 4e986b8..e168e46 100644 --- a/openspec/changes/intercompany-matrix-presets/specs/consolidated-osv/spec.md +++ b/openspec/changes/intercompany-matrix-presets/specs/consolidated-osv/spec.md @@ -28,26 +28,6 @@ - **WHEN** `rule_id` не существует - **THEN** 404 -### Requirement: Корректировки в шахматке пресета -В режиме PRESET расчёт SHALL учитывать корректировки `correction` со статусом `APPLIED`, у которых -`consolidation_version_id` равен версии, а `rule_id` — правилу пресета. Корректировка с `legal_entity_id = A` и -`counterparty_id = B` SHALL уменьшать `amount_a` ячейки `(A, B)` на `debit_adjustment` и `amount_b` ячейки `(B, A)` на -`credit_adjustment`. Затронутые ячейки SHALL получать пересчитанные `variance_amount`, `variance_percent`, -`exceeds_threshold` и ID корректировок в `correction_ids_debit`/`correction_ids_credit`; у остальных ячеек эти массивы -пусты (поля есть в ответе всех режимов). Корректировки без `legal_entity_id` или `counterparty_id` SHALL игнорироваться. - -#### Scenario: Корректировка по дебету -- **WHEN** есть применённая корректировка правила `(A, B)` с `debit_adjustment = 10` -- **THEN** у ячейки `(A, B)` `amount_a` меньше на 10, расхождение пересчитано, `correction_ids_debit` содержит её ID - -#### Scenario: Корректировка по кредиту -- **WHEN** есть применённая корректировка правила `(A, B)` с `credit_adjustment = 5` -- **THEN** у ячейки `(B, A)` `amount_b` меньше на 5, `correction_ids_credit` содержит её ID - -#### Scenario: Корректировка чужого правила или не применённая -- **WHEN** корректировка относится к другому правилу либо имеет статус не `APPLIED` -- **THEN** суммы ячеек не меняются, `correction_ids_*` пусты - ### Requirement: Строки сводной ОСВ без пары по пресету `GET /api/v1/consolidations/versions/{version_id}/intercompany-matrix/preset/{rule_id}/unpaired-osv` (`CONSOLIDATION_VIEW`, policy) SHALL возвращать `{items, total}`: все строки сводной ОСВ версии, чьи записи ОСВ diff --git a/openspec/changes/intercompany-matrix-presets/tasks.md b/openspec/changes/intercompany-matrix-presets/tasks.md index 53dca62..e2bd75c 100644 --- a/openspec/changes/intercompany-matrix-presets/tasks.md +++ b/openspec/changes/intercompany-matrix-presets/tasks.md @@ -5,8 +5,9 @@ ## 2. Доработки по решениям владельца 2026-10-21 (автор) -- [ ] 2.1 Отдельным коммитом убрать учёт корректировок (`_apply_corrections`, `correction_for_version_consolidation`, - `correction_ids_*`) и ручку `unpaired-osv` (`get_unpaired_rows`, `UnpairedOsvOut`, маршрут) вместе с тестами; +- [x] 2.1 Отдельным коммитом убрать учёт корректировок (`_apply_corrections`, `correction_for_version_consolidation`, + `correction_ids_*`) вместе с тестами; код выделен в `AURORA-1747`. +- [ ] 2.1a Убрать ручку `unpaired-osv` (`get_unpaired_rows`, `UnpairedOsvOut`, маршрут) вместе с тестами; код сохранён в `wip/shahmatka-corrections-unpaired`. - [ ] 2.2 PRESET — только правила `statement_type = balance`; правило ОФР — 422 `INVALID_RULE`, тест. - [ ] 2.3 Несколько открытых `version_no` — одна версия (max) или явная ошибка, тест.