Меню


[I128-2832] Политики bidirectional sync и conflict resolution в модуле API


НАЧАЛО >> Оглавление >> Общее описание >> История изменений >> Что нового в проекте I128 >> Версия 2026.3 >> [I128-2832] Политики bidirectional sync и conflict resolution в модуле API📄 Скачать в DOCX


Тип Версия Статус Приоритет Исполнитель
⚙️ Новые возможности 2026.3 🔘 Завершено Средний Ilya Mikhaylenko

Компоненты: ИРБИС 128. Модуль API - API ИРБИС 64/128

Завершено: 07.09.2026 08:53

  1. Цель

Нужно расширить существующий модуль API так, чтобы он стал владельцем общего contract для bidirectional sync и conflict resolution внешних интеграций ИРБИС 128.

Интеграционный профиль должен уметь не только сопоставить внешний объект с внутренней записью, но и объяснимо определить, можно ли применить входящее или исходящее изменение, какой источник является авторитетным, какие поля конфликтуют, какое действие предлагает policy и почему изменение отклонено, отложено или передано доменному модулю на применение.

  1. Контекст

В модуле API должен существовать реестр APIContract, IntegrationAdapterProfile, mapping profile и ExternalId. Этот срез добавляет следующий слой: SyncPolicy и ConflictPolicy для профилей, в которых допускается обмен в обе стороны или нужно безопасно сравнивать внутреннее и внешнее состояние.

Задача не должна превращать API в универсальный runtime синхронизации или в частный adapter конкретной внешней системы. API владеет contract, политиками, dryrun, explainable diff и стандартным результатом принятия решения. События, delivery, retry и очередь остаются в EventBus и Queue. Фактическое изменение внутренней записи выполняет доменный модульвладелец объекта.

  1. Что Нужно Сделать

Нужно реализовать модель SyncPolicy в модуле API. Политика должна быть связана с IntegrationAdapterProfile, object type, direction, APIContract version, mapping profile и набором поддерживаемых операций: create, update, transition, link, unlink, attach, detach, comment или другой published operation, если она объявлена доменным модулем через API contract.

SyncPolicy должна описывать direction обмена: inbound, outbound или bidirectional. Для bidirectionalпрофиля должны быть явно заданы sourceof-truth policy, conflict policy, allowed operations, idempotency requirements, trace requirements, handling stale data, retry eligibility и правила, когда операция только диагностируется, а когда может быть передана на применение.

Нужно реализовать модель ConflictPolicy. Она должна поддерживать варианты internal wins, external wins, last writer wins только при явном разрешении, manual resolution, fieldlevel merge, reject with explanation и create review task или workflowсобытие через доменный модуль. Политика должна задаваться не глобально на весь API, а на уровне adapter profile, object type, operation и при необходимости field group.

Нужно определить безопасное поведение по умолчанию: если policy не задана, conflict resolution должен возвращать reject with explanation. Неявное перезаписывание внутреннего или внешнего состояния запрещено.

Нужно реализовать explainable diff для sync dry-run. Результат должен показывать внешний payload после mapping, найденный internal object, matched ExternalId, текущий внутренний snapshot, предлагаемые изменения, затронутые fields, workflow status/transition changes, users/organisations resolution, detected conflicts, выбранное policy decision, required permissions, warnings и errors.

Field-level conflict classes должны быть стандартизированы. Минимальный набор: no conflict, external stale, internal stale, concurrent update, missing external id, duplicate external id, mapping missing, mapping incompatible, field unavailable, field permission denied, value validation failed, workflow transition unavailable, user resolver ambiguous, object deleted, object archived, protected field, attachment conflict и unsupported operation.

Нужно реализовать dryrun sync без применения изменений. Dryrun должен принимать external payload или outbound request context, adapter profile, object type, operation, external id или internal record reference, idempotency key и trace id. Результат dryrun не должен сохранять запись, создавать или менять ExternalId, выполнять workflowпереходы, запускать post-functions, публиковать события, ставить Queue jobs или отправлять внешние запросы.

Нужно описать стандартный SyncPlan. SyncPlan должен быть машинно-читаемым и включать normalized payload, object reference, external id decision, field changes, workflow action request, participant resolution, conflict list, selected ConflictPolicy branch, proposed domain operation, idempotency decision, trace id, security decision summary и safe diagnostic details.

Нужно описать стандартный SyncApplyRequest и SyncApplyResult для передачи результата доменному модулю. API может построить SyncPlan и проверить policy, но применение изменений должно делегироваться доменному модулю, который владеет записью и бизнесправилами. Доменный модуль должен вернуть applied, rejected, validation failed, conflict remains, queued, retryable failed или nonretryable failed с понятным кодом и безопасным сообщением.

Нужно добавить policy для manual resolution. В этом срезе не требуется полноценный пользовательский UI ручного разрешения конфликтов, но API должен уметь вернуть результат manual resolution required с причиной, field-level diff, предложенными вариантами и ссылкой на доменный resolver или будущую workflow/task operation.

Нужно обеспечить идемпотентность sync-операций. Mutating sync должен иметь idempotency scope, включающий adapter profile, external system, operation, object type, external id или internal object reference и fingerprint нормализованного payload. Повтор с тем же scope и fingerprint должен возвращать прежний result или pending state; повтор с другим fingerprint должен возвращать conflict.

Нужно связать sync/conflict diagnostics с TraceContext и Observability. Диагностика должна показывать trace id, adapter profile, object type, operation, policy version, mapping version, conflict class, decision, domain owner result и безопасные details без раскрытия секретов, скрытых полей и персональных данных без прав.

Нужно реализовать where-used для SyncPolicy и ConflictPolicy. Администратор должен видеть, какие adapter profiles, object types, operations, mapping profiles, workflow statuses/transitions, доменные модули и external systems используют конкретную policy.

Нужно добавить HealthCheck provider для sync/conflict policies. Проверки должны находить bidirectionalпрофили без SyncPolicy, операции без ConflictPolicy, last writer wins без явной версии или timestamp policy, manual resolution без resolverа, field-level merge без field mapping, ссылки на несуществующие mapping profiles, ExternalId policy conflicts, невалидные права, отсутствующие TestA datasets и несовместимые версии APIContract.

Нужно подготовить TestAсценарии для dryrun sync, reject with explanation, internal wins, external wins, explicit last writer wins, manual resolution required, fieldlevel conflict, duplicate ExternalId, permission denied, domain validation failed, idempotency repeat/conflict, trace propagation, HealthCheck provider checks и отсутствия побочных эффектов при dryrun.

Нужно обновить Help модуля API: назначение SyncPolicy и ConflictPolicy, отличие policy contract от adapter runtime, настройка sourceoftruth, dryrun sync, explainable diff, fieldlevel conflict classes, manual resolution required, идемпотентность, диагностика и границы с EventBus, Queue, Security, Workflow*, FieldConfiguration и доменными модулями.

  1. Границы Ответственности

API владеет SyncPolicy, ConflictPolicy, policy versions, dryrun sync, explainable diff, SyncPlan, SyncApplyRequest/SyncApplyResult contract, whereused policies, APIlevel diagnostics и безопасным export policyконфигурации.

API не владеет runtime доставки, retry, deadletter, schedule, webhook delivery, внешними HTTPклиентами конкретных систем и долгими фоновыми job. Эти части остаются в EventBus, Queue и конкретных adapter-задачах.

API не применяет доменные изменения напрямую. Доменные модули владеют сохранением записей, бизнесвалидацией, workflowspecific применением, record locks, ФЛК, post-functions и человекочитаемым результатом применения.

EventBus владеет событиями, event log, inbox/outbox, idempotency registry для событий, subscriptions, webhook delivery, retry и dead-letter доставки. API может сформировать sync decision и event intent, но не должен становиться EventBus.

Queue владеет фоновым выполнением, scheduling, retry/backoff/timeout, worker state и job dead-letter. API может сформировать queued decision или job request через общий контракт, но не исполняет Queue runtime.

Security владеет правами, masking, service accounts, grants/denies, field security, view security и безопасными отказами доступа. API обязан проверять права на dry-run, apply request, diff visibility, policy management и diagnostics.

FieldConfiguration владеет field keys, типами и семантикой полей. Workflow* владеет статусами, переходами и доступностью workflow-действий. API использует эти контракты в diff и policy, но не дублирует их модели.

В этот срез не входит конкретный Jira adapter, email adapter, webhook adapter, внешний ticket-system adapter, полный UI ручного merge, интеграция с конкретным внешним REST API, перенос данных конкретного потребителя и изменение доменных модулей Tasks/VirtualRef/RQST/EC сверх стандартного SyncApply contract.

  1. Критерии Приемки

В модуле API есть модель SyncPolicy, связанная с IntegrationAdapterProfile, object type, operation, direction, mapping profile и APIContract version.

В модуле API есть модель ConflictPolicy с вариантами internal wins, external wins, explicit last writer wins, manual resolution, field-level merge и reject with explanation.

Поведение по умолчанию безопасное: при отсутствии policy конфликт не приводит к записи данных и возвращает reject with explanation.

Dry-run sync возвращает SyncPlan с normalized payload, matched ExternalId, internal snapshot, proposed changes, conflict list, policy decision, required permissions, trace id и safe diagnostics.

Dryrun sync не сохраняет запись, не меняет ExternalId, не выполняет workflowпереходы, не публикует события, не ставит Queue jobs и не отправляет внешние запросы.

Fieldlevel conflict classes стандартизированы и возвращаются машинночитаемо вместе с человекочитаемым объяснением.

API передает применение изменений доменному модулю через SyncApplyRequest и получает SyncApplyResult; прямое знание физической структуры записи в API не появляется.

Идемпотентность sync-операций использует стабильный scope и fingerprint; повтор того же payload возвращает прежний result или pending state, другой payload с тем же key возвращает conflict.

Security проверяет права на управление policy, dry-run, apply request, diff visibility и diagnostics; скрытые значения маскируются.

TraceContext проходит через dry-run, apply request, domain result, diagnostics, HealthCheck и Observability signals.

Where-used показывает использование SyncPolicy и ConflictPolicy в adapter profiles, object types, operations, mapping profiles, workflow actions и доменных модулях.

HealthCheck выявляет отсутствующие или битые sync/conflict policies, невалидные mapping references, несовместимые versions, опасные last writer wins настройки, manual resolution без resolver-а, проблемы прав и отсутствие TestA coverage.

TestA покрывает dryrun sync, несколько conflict policies, idempotency repeat/conflict, permission denial, domain validation failure, duplicate ExternalId, trace propagation, HealthCheck checks и отсутствие побочных эффектов при dryrun.

Help содержит руководство администратора и разработчика по SyncPolicy, ConflictPolicy, dryrun sync, explainable diff, fieldlevel conflicts, manual resolution required, идемпотентности и границам ответственности.

-

Реализован первый срез I128-2830 для существующего модуля API.

Что сделано:

Не входит в этот PR:

Проверка:

-

Реализован второй APIсрез I1282831 поверх I128-2830.

Что сделано:

Границы:

Проверки:

База PR: feature/I1282830apicontractregistry, потому что I1282831 зависит от открытого PR #1329 / I1282830.

-

Реализован третий APIсрез I1282832 поверх I128-2831.

Что сделано:

Границы:

Проверки:

База PR: feature/I1282831apimappingexternalids, потому что I1282832 зависит от открытого PR #1330 / I128-2831.

1. Связанные задачи

1.1. 🔗 blocks: I128-2793

[I128-2793] Ввести TraceContext для сквозной трассировки операций Статус: Завершено | Автор: Ilya Mikhaylenko

1.2. 🔗 blocks: I128-2794

[I128-2794] Реализовать системную событийную шину EventBus Статус: Завершено | Автор: Ilya Mikhaylenko

1.3. 🔗 blocks: I128-2795

[I128-2795] Расширить Queue как runtime фоновых заданий, retry и расписаний Статус: Завершено | Автор: Ilya Mikhaylenko

1.4. 🔗 blocks: I128-2797

[I128-2797] Расширить Security для проектных прав, полей, действий и аудита доступа Статус: Завершено | Автор: Ilya Mikhaylenko

1.5. 🔗 blocks: I128-2798

[I128-2798] Реализовать HealthCheck для workflow-проектов и задач Статус: Завершено | Автор: Ilya Mikhaylenko

1.6. 🔗 blocks: I128-2799

[I128-2799] Подготовить TestA-контракты системных JSON и end-to-end сценариев Статус: Завершено | Автор: Ilya Mikhaylenko

1.7. 🔗 blocks: I128-2818

[I128-2818] Реализовать наблюдаемость Observability для промышленных модулей Статус: Завершено | Автор: Ilya Mikhaylenko

1.8. 🔗 blocks: I128-2830

[I128-2830] Реестр API-контрактов и профилей внешней интеграции Статус: Завершено | Автор: Ilya Mikhaylenko

1.9. 🔗 blocks: I128-2831

[I128-2831] Mapping внешних интеграций и реестр ExternalId в модуле API Статус: Завершено | Автор: Ilya Mikhaylenko