Як створювати і заповнювати документацію

Аудиторія: автор сторінки (людина або AI) перед/під час роботи — «новий сервіс? UI з нуля? оновлення під зміну коду?». Мета: чекліст і сценарії крок за кроком.

Правила формату (теги, шаблон, обов’язкові секції) — у CONVENTIONS. Як ця документація фізично існує (канали, sync, локальний vault) — у README.


Робочий процес доки — 3 правила

Дуже важливо — знай і пам’ятай завжди. Без цих правил доку просто перестають оновлювати.

  1. Маленькими порціями, одразу. Оновив щось у docs/ — комить і заливай зараз, не збирай великий батч. Маленький апдейт, що вже поїхав, кращий за ідеальний, що лежить тиждень.
  2. docs — публікаційна гілка. Працюй на master чи будь-якій feature-гілці → мердж у docsпуш. Сайт збирається саме з docs кожного сервісу, тож docs — твоє «тестове» дзеркало, де одразу видно результат.
  3. Змінив код — відпишись про доку. Завжди один рядок підсумку: «оновив docs/X» або «доки на це ще нема». Мовчазних змін коду без статусу доки не лишаємо — інакше доку тихо забувають.

Головний принцип

Ітеративно, не одним заходом. Спершу — скелет, потім заповнюємо по одному файлу вузькими питаннями. Не намагатись описати все в голові й одразу писати полотна тексту — забудеш половину, перевантажиш неважливим.


Цикл заповнення ноди (універсальний)

Діє для UI, сервісу, сутності, flow, ролі — будь-якого файлу.

  1. Юзер → важливі речі. Числа, умови, нюанси, причини. Без художки.
  2. AI → аналіз + уточнення. Якщо є прогалини або двозначності — 3-5 вузьких питань. Якщо все зрозуміло — одразу п. 3.
  3. AI → формулювання. Текст під шаблон сторінки. Тільки те що юзер сказав. Ніяких «для повноти».
  4. Юзер → рев’ю і правки. Просить доповнити/виправити/прибрати. Повторюємо 2-4 поки не ок.
  5. Фіксація → наступна нода.

Стоп-сигнали:

  • AI починає вигадувати деталі → зупиняємось, лишаємо TODO.
  • Юзер просить «розпиши глибше» без нових фактів → значить дійшли до межі знань, більше нема що додати.

Сценарій 1 — Старт у новому сервісі

Робиться один раз при внесенні документації в новий репозиторій.

  1. У сервісному репо створити довгу гілку docs (git checkout -b docs && git push -u origin docs). Вся документація живе тут, не на master. У master доки потрапляють пізніше через мердж docsmaster коли відповідний код вже приземлився.
  2. На гілці docs створити папку docs/ (Obsidian vault). Чорнові сторінки маркуй #draft — на сайті будуть видні з фільтром.
  3. Додати CLAUDE.md в корені репо з посиланнями на CONVENTIONS і AUTHORING в root-репо (stack-docs/CONVENTIONS.md). Не копіюй CONVENTIONS — тільки посилайся.
  4. Створити порожній docs/Canvas.canvas.
  5. Створити docs/glossary.md тільки якщо є сервіс-специфічні терміни. Загальні — у glossary root-репо.
  6. Якщо це бек-сервіс — у docs/index.md додай лінк на корінь Swagger UI (https://api.besocial.tech/<service>/api-docs). Окремих сторінок про API в сервісних доках не пишемо: контракт описує сам Swagger, а мапа всіх Swagger-ів проекту живе в stack-docs (TODO).
  7. Додати ноду на глобальний architecture/Canvas.canvas у root зі стрілками куди цей сервіс ходить (RMQ/HTTP).
  8. Додати рядок <vault>:<repo>:docs у env.SERVICES у docs.yml.
  9. Локально: запустити node scripts/sync.mjs у stack-docs щоб новий сервіс з’явився у твоєму повному vault (symlink дивиться на ту гілку яку ти зараз тримаєш checked out локально — для редагування переключися на docs).

Сценарій 2 — Опис UI з нуля

Для нової програми або нової вкладки якої ще нема в доках. Протестовано на електроні — цей порядок дає найменше churn’у.

Фаза A — Скелет структури

  1. Описати екран AI — словесно або скрінами з підписами зон («колонка фаворитів», «хедер»). Достатньо назв з розмови, що робить поки не пишемо. Попросити: структурно підсумувати що зрозумів + запитати термінологію яку не впізнав. Не просити одразу писати файли.
  2. Термінологія → glossary. Перед створенням скелету зафіксувати всі абревіатури і доменні слова. Без глосарію AI буде гадати і накидати різні варіанти.
  3. Папки: AI створює docs/ui/, services/, entities/, flows/, system/. Імена UI-файлів — українською (див. CONVENTIONS).
  4. Скелет UI-файлів. AI за шаблоном робить порожні сторінки: шапка + H1 + контекстна стрічка + порожні секції. Логіку не заповнюємо — тільки структура.
  5. Canvas скелет. AI створює ноди для кожного файлу + групи по екранах (Login screen / App хедер / Workspace screen). Лінки і стрілки — в наступній фазі.

Фаза B — Заповнення по одній ноді

Йдемо послідовно, по одному файлу. Не більше одного в роботі.

  1. Юзер видає важливі речі — що на цьому екрані/елементі дійсно важливо: числа, умови, фільтри, нюанси, нетипова поведінка. Короткими фразами, без художки.
  2. AI аналізує і уточнює. Знаходить прогалини, суперечності, незрозумілі місця — задає 3-5 вузьких запитань. Якщо питань нема — одразу формулює.
  3. AI формулює текст під шаблон сторінки. Без додаткових абзаців «для повноти» — тільки те що юзер сказав, переведене в структурований формат.
  4. Юзер рев’ює результат: читає, просить редагувати неточності, прибрати зайве, доповнити пропущене.
  5. Фіксуємо → переходимо до наступної ноди.

Правило зупинки: якщо AI починає вгадувати або додавати «для повноти» — юзер зупиняє. Краще лишити TODO: уточнити X ніж написати неправду.

Фаза C — Зв’язки з беком

Коли всі UI-файли заповнені — проходимо по кожній секції Зв'язки і додаємо deeplink’и на конкретні Swagger-ендпоінти + лінки на бек-сервіси. Canvas дістає стрілки між UI і сервісами.


Сценарій 3 — Опис бек-сервісу з існуючого коду

  1. Вказати AI шлях до файлу коду (src/...).
  2. AI читає код і створює скелет за шаблоном Service: шапка з шляхом + Інтервал (якщо є) + Логіка + порожні Нюанси / Зв'язки.
  3. Уточнення нюансів і причин. Це найцінніше в бек-доках. AI запитує або пропонує варіанти, розробник підтверджує/виправляє:
    • чому саме такий таймаут
    • чому саме такий захист (watchdog, stop-list, isBusy)
    • які були інциденти/суперечки які сформували це рішення
  4. Лінки на UI що показує результати цього сервісу — в Зв'язки.
  5. Якщо це HTTP-контролер — НЕ описувати кожен ендпоінт. Описати групу як ціле, відіслати до Swagger UI deeplink, описати тільки нюанси яких в Swagger не видно (наприклад складні комбінації ролей чи бізнес-обмеження).

Сценарій 4 — Опис Flow (процесу)

Напр. логін, логаут, ініціалізація ранера.

  1. Назвати крок-за-кроком послідовність дій (AI читає код і пропонує, розробник коригує).
  2. Якщо кроків ≤3 — описуємо в одному файлі секціями.
  3. Якщо ≥4 — оглядова сторінка зі списком + окремий файл на крок.
  4. Кожен крок отримує секції Що робить, Нюанси (якщо є), Зв'язки.
  5. Крос-сервісний flow (зачіпає 2+ сервіси) — лежить у stack-docs/architecture/flows/, не в окремому сервісі.

Сценарій 5 — Оновлення при зміні коду

  1. Після зміни бізнес-логіки відкрити відповідний файл у docs/.
  2. Коротко сказати AI: «онови docs/xxx.md під зміну в src/yyy.ts».
  3. AI читає зміну, порівнює з поточним доком, робить правки. Людина рев’ює.
  4. Якщо забули — AI нагадає при наступній дотичній задачі (через CLAUDE.md сервісного репо).

Не оновлюємо при рефакторингу без зміни поведінки (перейменування, форматування, чищення типів).


Сценарій 6 — Canvas

Canvas — візуальна мапа.

  1. Оновлюємо після того як тематична група файлів стабілізувалась (не після кожного окремого файлу — це churn).
  2. Новий файл → нова нода на локальному Canvas.canvas сервісу з кольором відповідного типу.
  3. Стрілки підписуємо однаково: тригерить / оновлює / читає / стартує / викликає / публікує / слухає.
  4. Групи (обведення прямокутником) використовуємо для ≥3 нод одного типу в одному місці.
  5. Глобальний Canvas (stack-docs/architecture/Canvas.canvas) — оновлюємо тільки коли з’являється новий сервіс або змінюється топологія взаємодії (нова RMQ-черга, новий HTTP-канал).

Сценарій 7 — Нова роль доступу

Якщо в коді з’являється нове значення StackRoles.<name>:

  1. Додати рядок у таблицю в roles (код + кому видається + коротке призначення).
  2. Якщо роль вимагає глибшого опису (складна матриця доступів, багатокроковий процес видачі) — створити roles/<name>.md і лінкувати з таблиці. За замовчуванням — не створюємо.
  3. Якщо в Swagger контролерах ролі відображаються через кастомний декоратор — нічого більше не треба, ролі зʼявляться в описі ендпоінтів автоматично.

Сценарій 8 — Оновити самі CONVENTIONS / AUTHORING / glossary / roles

Ці файли живуть тільки тут, у root-репо stack-docs. Сервіси не мають своїх копій.

  1. Редагуєш потрібний файл прямо в stack-docs/.
  2. git commit && git push у master.
  3. CI стартує автоматично (push тригерить workflow). Через ~1.5 хв сайт docs.besocial.tech рендерить оновлене.
  4. Розробникам у сервісних репо лишається ручний sync — деталі в Сценарій 9 нижче.

Що міняти зі змістом:

  • CONVENTIONS — тільки коли реально вводимо нове правило формату (новий тип сторінки, новий тег, нова конвенція іменування). Дрібні правки тексту — теж сюди, але без зайвого churn’у.
  • AUTHORING — коли змінюється процес створення/оновлення сторінок (наприклад додали новий сценарій).
  • glossary — додаємо терміни як зустрічаємо. Видаляємо коли термін мертвий.
  • roles — оновлюємо коли в коді з’являється новий StackRoles.<name>.

Що НЕ робимо:

  • Не правимо ці файли у .shared-docs/ сервісного репо — це локальна кеш-копія, її переб’є наступний sync.
  • Не повертаємо локальні копії у <service>/docs/CONVENTIONS.md чи <service>/docs/AUTHORING.md — навмисно прибрали щоб уникнути розсинхрону.

Сценарій 9 — Підтягнути свіжі правила в свій сервісний репо

Коли в stack-docs оновили CONVENTIONS / AUTHORING (нове правило тегів, новий шаблон, новий сценарій) — щоб AI у твоєму сервісному репо читав свіжу версію, треба ручний sync. Без нього AI може діяти за застарілими правилами.

Один раз — клонувати stack-docs поряд зі своїм сервісом (припускаємо ~/work/services/<service>/ і ~/work/services/stack-docs/):

git clone git@github.com:it-monkeys/stack-docs.git ../stack-docs

Щораз коли потрібна свіжа копія (з кореня свого сервісного репо):

git -C ../stack-docs pull
node ../stack-docs/scripts/sync-shared-docs.mjs

Скрипт копіює CONVENTIONS.md і AUTHORING.md зі stack-docs у локальну папку .shared-docs/ твого сервісного репо. Папка в .gitignore — НЕ комітимо.

Коли запускати:

  • AI робить щось не за конвенцією — можливо читає стару копію, оновись
  • Знаєш що в stack-docs щойно мерджили нове правило (push у master)
  • Профілактично — раз на тиждень

Не треба:

  • Редагувати файли в .shared-docs/ напряму — це кеш, наступний sync перепише.
  • Комітити .shared-docs/ — папка в .gitignore.

Альтернатива (для просунутих): додати Claude Code hook SessionStart що тихо викликає sync при старті сесії. Плата — 1-3с затримки на старті, треба обробити offline-випадок. Поки ручний sync ОК.


Сценарій 10 — Нова крос-сервісна сутність

Якщо нова структура даних ходить через RMQ або зберігається в спільній таблиці і потрібна 2+ сервісам:

  1. Створити entities/<Name>.md у root.
  2. Описати поля що стабільні в контракті (не локальні implementation details).
  3. У сервісах що цю сутність використовують, в локальних Зв'язки ставити лінк [[entities/<Name>]].
  4. Якщо сутність ходить через RMQ — описати у Flow в architecture/flows/ і дати лінки на ноди-події в Canvas.

Сценарій 11 — Локальний прев’ю Quartz без CI

Якщо CI довгий (3-5 хв на запуск, у чергу йде кожен push), а ти ітеруєш над стилями чи розкладкою — підніми Quartz локально з hot-reload. Зміни в quartz-overrides/quartz/styles/custom.scss або <service>/docs/*.md стають видні в браузері за секунди.

Один раз — встановити передумови:

  1. Node ≥22 (Quartz вимагає). Через fnm:

    # 1) встановити fnm — у PowerShell (НЕ в Git Bash):
    winget install Schniz.fnm
     
    # 2) ВІДКРИЙ НОВИЙ Git Bash (старий не бачить щойно поставлений fnm) і виконай:
    echo 'eval "$(fnm env --use-on-cd --shell bash)"' >> ~/.bashrc && source ~/.bashrc
    fnm install 22

    Системний Node лишається твоїм default’ом (20 чи що там). 22 активується тільки коли ти cd у stack-docs/ — там лежить .node-version з 22, і fnm --use-on-cd сам перемикне поточний шелл. Вийдеш з папки — повернеться попередня версія.

  2. Клонувати Quartz поряд зі stack-docs (за тим самим патерном що й сервісні репо):

    cd /d/work/services            # підстав свій корінь де лежить stack-docs
    git clone https://github.com/jackyzha0/quartz.git ./quartz-local
    cd quartz-local && npm ci

Щораз коли потрібен прев’ю:

cd /d/work/services/stack-docs       # підстав свій шлях; fnm сам перемкне на v22 через .node-version
node -v                              # перевір що v22.x
node scripts/dev-preview.mjs

→ відкрий http://localhost:8080. Тримай скрипт запущеним поки правиш — Quartz сам перебудовується при кожній зміні. Зупинити — Ctrl+C у тому ж терміналі.

Troubleshooting:

  • node -v показує v20 після cd у stack-docs → fnm --use-on-cd не активний у твоєму шеллі. Перевір що в ~/.bashrc є eval "$(fnm env --use-on-cd --shell bash)" і ти зробив source ~/.bashrc (або просто перевідкрив термінал). Разовий workaround — fnm use 22 у поточному терміналі.
  • fnm: command not found після winget install → закрий і знову відкрий Git Bash. winget пише в PATH який підхоплюється тільки новими шеллами.
  • Cannot find module .../quartz-local/... → не клонував Quartz або клонував не в ../quartz-local від stack-docs. Скрипт шукає саме за цим шляхом.
  • Скрипт пише skipping <service> — not cloned locally → нормально; працює тільки з тими сервісами що в тебе є в ../.

Що робить скрипт:

  • Чистить ../quartz-local/content/
  • Копіює корінь stack-docs (md/canvas) у content/
  • Симлінкить docs/ кожного клонованого поряд сервісу у content/services/<vault>/
  • Копіює quartz-overrides/ поверх quartz-local/
  • Слідкує за змінами в stack-docs/ (root + quartz-overrides/) і ресинкає; Quartz сам бачить зміни в content/ і ребілдить
  • Запускає npx quartz build --serve

Обмеження локального прев’ю:

  • Сервіси яких нема у ../ пропускаються (працює тільки з тим що локально клоновано)
  • Не запускається CI-крок rewrite-service-wikilinks.mjs — деякі крос-сервісні wikilinks можуть 404-ити локально (на проді працюють)
  • Warning’и isn't yet tracked by git — нормально, ігноруй (це Quartz хоче читати git-історію content-папки якої тут не існує)

Правила розмови з AI

Що говорити:

  • Точний шлях файлу коду або назву UI-елемента
  • Що саме змінилось (одна фраза)
  • Який файл у docs/ онови або створи

Що AI має робити само:

  • Читати CONVENTIONS перед роботою з доками
  • Задавати вузькі питання коли йому бракує інформації (не гадати)
  • Пропонувати оновити пов’язані файли через Зв'язки
  • Після оновлення нагадувати про Canvas якщо структура змінилась

Антипатерни:

  • «Опиши весь сендер» — надто широко, AI напише полотно → перевантажить деталями. Краще: «зроби скелет chat-sender.md за шаблоном і задай питання по нюансам».
  • Заповнювати одразу всі 20 файлів — втратиш якість, не зможеш рев’ювити уважно.
  • Описувати реалізацію замість поведінки (див. правила глибини в CONVENTIONS).
  • Описувати запит/відповідь HTTP ендпоінта — це робота Swagger, в markdown тільки бізнес-нюанси.

Чеклист перед комітом змін у docs/

  • Новий файл має шапку за шаблоном (теги + backlink + H1 + контекстна стрічка)
  • Тип теги правильний (#UI, #Service, #Entity, #Flow, #System, #Role, #API, #Architecture, #Meta)
  • Для UI-сторінок — є секція ## Use cases
  • Секція Зв'язки заповнена або свідомо пропущена
  • Жодних описів синтаксису/транспорту без впливу на поведінку
  • Жодних імен функцій/методів/змінних у тілі тексту — процеси описані людською мовою (винятки: H1, контекстна стрічка, поля Entity, settings/env-ключі)
  • Жодних markdown-описів API: контракт ендпоінтів — у Swagger, в Зв'язки ставимо deeplink
  • Нові терміни додано в glossary (root) або локальний glossary.md сервісу
  • Якщо заповнив/створив сторінку — оновлено її мітку стану (✅/🟡/⬜) і підсумок у відповідному index.md (підпапка + зведена таблиця в root)
  • Якщо структурний файл — оновлено локальний Canvas.canvas
  • Якщо новий сервіс або нова взаємодія між сервісами — оновлено architecture/Canvas.canvas у root