Skip to content

feat: R2 поддержки Cloud — запись страниц и вложений#57

Merged
YuriyEnshin merged 1 commit into
masterfrom
feat/cloud-phase2-write
Jul 2, 2026
Merged

feat: R2 поддержки Cloud — запись страниц и вложений#57
YuriyEnshin merged 1 commit into
masterfrom
feat/cloud-phase2-write

Conversation

@YuriyEnshin

Copy link
Copy Markdown
Owner

Что сделано

Фаза R2 (+ бывшая R3): полная поддержка Confluence Cloud — все операции записи работают.

Запись страниц (v2)

  • CreatePageAsync: POST /pages — числовой spaceId резолвится из ключа (GET /spaces?keys=, кэш в обе стороны: чтения сеют кэш для записи); parentId; без родителя страница уходит под домашнюю страницу пространства (v2-аналог «корня»).
  • UpdatePageAsync: PUT /pages/{id} со status:"current"; семантика knownVersion+1 сохранена; конфликт версий → чистый 409 (errors[].code=CONFLICT, проверено вживую) → ConfluenceConflictException; версия результата берётся из ответа — live-проба показала, что no-op PUT на Cloud принимается, но версию не поднимает; переносы через parentId подтверждены пробой.

Вложения

  • Upload/update data — v1-multipart эндпоинты, сохранённые Atlassian на Cloud (X-Atlassian-Token: nocheck), delete — v2. Media-type-логика (extensionless-вложения, drawio-твины) вынесена в ConfluenceApiHelpers и общая для обоих клиентов.

Нормализатор (эпоха 2→3)

Live e2e выявил фантомный «изменено на сервере» в compare для созданных утилитой страниц с макросами: Cloud добавляет ac:schema-version (и редактор — local-id/ac:local-id). Нормализатор теперь стрипает их при сравнении (на отправляемый контент не влияет), golden vector обновлён по контракту из confluence-import-export.mdc §11. Одноразовый сброс хэшей у всех пользователей — fallback на mtime до следующей синхронизации (by design).

Проверка

  • 471 юнит-тест зелёный (+14 новых на запись).
  • Сквозной e2e на живом Cloud-сайте: live-пробы write-API (409-семантика, no-op PUT, перенос через parentId, round-trip byte-stability) → upload create (страницы + вложение + маркеры) → force upload update (5 неизменённых пропущены, страница+вложение обновлены) → рукотворный конфликт «обе стороны» → upload merge корректно защитил обе стороны → разрешение → итоговый compare: ноль расхождений.

Cloud-поддержка утилиты на этом полная: Ф0 → R1 (чтение, v2.17.0) → R2 (запись, этот PR → v2.18.0).

🤖 Generated with Claude Code

…а Cloud

- ConfluenceCloudApiClient: CreatePageAsync (POST /pages, spaceId из ключа
  через кэшируемый резолв GET /spaces?keys=, parentId), UpdatePageAsync
  (PUT со status:"current", версия ровно current+1, конфликт → 409 →
  ConfluenceConflictException; версия результата берётся из ответа — no-op
  PUT на Cloud не поднимает версию); переносы через parentId работают
- вложения: upload/update data через живые v1-эндпоинты под /wiki
  (multipart + X-Atlassian-Token: nocheck), delete через v2; media-type
  хелперы вынесены в ConfluenceApiHelpers (общие для обоих клиентов)
- нормализатор: стрипание ac:schema-version и local-id/ac:local-id
  (подтверждённый на живом Cloud шум сервера/редактора) — устраняет
  фантомный «изменено на сервере» в compare; эпоха канонизации 2→3,
  golden vector обновлён
- e2e на живом Cloud: upload create (страницы+вложение), force update
  с пропуском неизменённых, конфликт «обе стороны» в merge, разрешение,
  итоговый compare без расхождений
- 471 тест зелёный (+14); CHANGELOG/README (RU+EN), agent-instructions

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@YuriyEnshin
YuriyEnshin merged commit ecd5f42 into master Jul 2, 2026
@YuriyEnshin
YuriyEnshin deleted the feat/cloud-phase2-write branch July 2, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant