10 KiB
ADDED Requirements
Requirement: История правок страниц
Хаб SHALL хранить опубликованные версии страниц дерева проекта: код версии Eva (DOCH-…), код страницы, время правки
(UTC), автора (login, name), Markdown версии и число строк, добавленных и удалённых против предыдущей версии той же
страницы (порядок версий — по времени, затем по коду; у первой — против пустого текста). Время правки — время создания
версии в Eva (cmf_created_at). Версии страниц, которых нет в дереве проекта, хаб MUST NOT хранить; неопубликованные
версии (черновики) агент MUST NOT присылать.
При выдаче wiki_sync хаб SHALL дописывать в параметры команды known_versions — объект {<код страницы>: [<код версии>…]} по версиям, уже хранящимся у страниц текущей копии проекта (без копии — {}); в command.params в базе
поле MUST NOT записываться. Агент wiki SHALL после страниц прислать опубликованные версии страниц дерева, которых нет
в known_versions их страницы, пачками POST /agent/wiki/versions {command_id, versions}: версия — {page_code, code, created_at, author: {login, name}, html, attachments, links} (created_at — ISO-8601 со смещением; login и name
— строки или null, если Eva автора не отдала; attachments и links — как у страниц, по html версии), в пачке не
больше 50 версий, — и отчитаться done с result.versions —
числом присланных версий. Пачка по команде не в claimed или не wiki_sync — 409; неверная форма версии — 422
bad_versions с кодом версии и полем. Хаб SHALL переводить HTML версии в Markdown при приёме вне транзакции записи
(ссылки на вложения — текстом 📎 <имя> без ссылки, ссылки на страницы — page:<код>) и складывать в стадию команды.
По отчёту done с result.versions хаб SHALL в той же операции, что и копию (см. «Синхронизация вики»): добавить
версии из стадии к страницам, чьи коды есть в codes, отбросив остальные; удалить версии страниц, которых нет в
codes; посчитать «+/−» у новых версий и у версии, следующей за вставленной раньше неё; записать время применения
истории history_at. Присланных версий меньше result.versions — команда failed «нет версий: пришло N из M», копия и
история прежние. Отчёт done без result.versions (агент без истории) SHALL обновлять копию как прежде и не менять
историю и history_at. Отчёт failed и отброшенный отчёт по сменённому корню историю не меняют. Сброс корня SHALL
удалять историю проекта вместе с копией. Стадия версий очищается так же, как стадия страниц.
Scenario: Первая загрузка истории
- WHEN у
AWPCAдерево DOC-1, DOC-2; в хабе версий нет; выданwiki_sync - THEN в параметрах выдачи
known_versions = {}; агент прислал 3 версии DOC-1 и 2 версии DOC-2, отчётdone {versions: 5}; в хабе 5 версий, у первой версии каждой страницы «+N / −0»,history_atзаполнен
Scenario: Догрузка новых версий
- WHEN у DOC-1 в хабе версии DOCH-10, DOCH-11; в Eva опубликована DOCH-12
- THEN при выдаче
known_versions = {"DOC-1": ["DOCH-10", "DOCH-11"], …}; агент прислал только DOCH-12; у неё «+/−» против DOCH-11
Scenario: Агент без истории
- WHEN агент v1 отчитался
done {root_title, codes, eva_calls}безversions - THEN копия обновлена, версии и
history_atпрежние
Scenario: Страница ушла из дерева
- WHEN у DOC-3 в хабе 4 версии; новая синхронизация вернула
codesбез DOC-3 - THEN версий DOC-3 в хабе нет
Scenario: Версия чужой страницы
- WHEN в стадии версия с
page_code = DOC-99, которой нет вcodes - THEN версия не записана, команда
done
Scenario: Потерянная пачка версий
- WHEN отчёт
done {versions: 5}, в стадии 3 версии - THEN команда
failed«нет версий: пришло 3 из 5», копия и история прежние
Requirement: Маршруты истории вики
Хаб SHALL предоставлять под клиентским токеном (проект — project=<метка>, неизвестный — 404, без корня — 409
no_root), читая только базу хаба:
GET /wiki/changes?project=&since=&until=&author=&limit=— правки страниц текущей копии проекта со временем в[since, until].since,until— ISO-8601 со смещением илиZ(без смещения — 422); безuntil— текущее время; безsince—untilминус 24 часа;author— подстрока имени или логина без учёта регистра;limit— по умолчанию 500, 1–2000. Ответ —{since, until, synced_at, history_at, truncated, changes: [{at, page_code, title, path, version, author: {login, name}, added, removed}]}поatпо убыванию, затем поversionпо убыванию; правок большеlimit— первыеlimitиtruncated = true. Неверное время,sinceпозжеuntil,limitвне 1..2000 — 422bad_requestс именем параметра.history_at = null— история проекта ещё не загружалась.GET /wiki/pages/{code}/versions?project=—{code, title, versions: [{version, at, author: {login, name}, added, removed}]}, новые первыми; страницы нет в копии — 404.GET /wiki/pages/{code}/diff?project=&version=&offset=— правкаversion(без параметра — последняя) против предыдущей версии страницы:{code, title, path, version, prev_version, at, author: {login, name}, added, removed, index, total, offset, next_offset, diff}, гдеdiff— unified diff Markdown (контекст 3 строки; у первой версии — против пустого,prev_version = null) с символаoffsetдо 20 000 символов,next_offset— начало следующей части илиnull,index— номер версии от старой (с 1),total— число версий. Страницы нет в копии — 404; версии нет у страницы — 404no_version; у страницы нет версий — 404no_versions.
GET /wiki/pages/{code} SHALL дополнительно отдавать modified_at, modified_by: {login, name} (последняя версия;
нет версий — null) и versions — число версий. GET /wiki/status SHALL дополнительно отдавать history_at.
Scenario: Что сделали за сегодня
- WHEN у
AWPCA27.10 в 17:59 и 18:02 (MSK) Соснов опубликовал версии DOC-101252, 26.10 Молчанов — версию DOC-2;GET /wiki/changes?project=AWPCA&since=2026-10-27T00:00:00+03:00 - THEN две правки DOC-101252, новая первой, у каждой автор
{login: "sosnov-dvi@rshbeco.ru", name: "Дмитрий Соснов"},added/removed, путь страницы в дереве; правки DOC-2 нет
Scenario: Фильтр по автору
- WHEN
GET /wiki/changes?project=AWPCA&since=…&author=соснов - THEN только правки Соснова
Scenario: Дифф последней правки
- WHEN у DOC-101252 4 версии;
GET /wiki/pages/DOC-101252/diff?project=AWPCA - THEN
index = 4,total = 4,prev_version— третья версия,diffначинается с---и+++
Scenario: Длинный дифф
- WHEN дифф правки 45 000 символов, запрос без
offset - THEN первые 20 000 символов,
next_offset = 20000; запрос сoffset=40000— остаток,next_offset = null
Scenario: История ещё не загружена
- WHEN у
AWPCAкопия есть, агент v1,GET /wiki/changes?project=AWPCA - THEN 200,
history_at = null,changes = []
Scenario: Последняя правка в странице
- WHEN в хабе 4 версии DOC-101252, последняя — Соснов,
created_at = 2026-10-27T23:48:02+03:00;GET /wiki/pages/DOC-101252?project=AWPCA - THEN
modified_at = "2026-10-27T20:48:02+00:00",modified_by.name = "Дмитрий Соснов",versions = 4