CONVENTIONS

Правила ведення документації

Аудиторія: розробники проєкту. Це особистий довідник, не онбординг. Мета: за 10 секунд згадати значення/умову/послідовність під час дискусії чи рефакторингу. Цей файл також читається AI (Claude Code, Cursor) — правила написані так, щоб AI міг за ними створювати й оновлювати документи без додаткових пояснень.

Як це все технічно влаштовано (канали, sync, локальний vault) — у README. Процес заповнення (як робити поетапно) — у AUTHORING.


Принципи

  1. Довідник, не туторіал. Пишемо так, щоб знайти потрібне за 10 секунд, а не читати з початку.
  2. UI — хребет, бек — опорні картки. Читач стартує з UI (що бачить у програмі) і переходить на бек по лінках (що це тригерить / звідки оновлюється).
  3. API — це Swagger, не markdown. Контракт API живе в auto-Swagger самого сервісу (через routing-controllers). У docs описуємо тільки бізнес-нюанси і ставимо deeplink на конкретний endpoint у Swagger UI.
  4. Схематично + нюанси. Не описуємо що робить кожна стрічка. Описуємо що є, в якому порядку, які числа/умови, які нюанси і чому вони такі.
  5. Чому, не як. Якщо рішення неочевидне — пояснюємо чому так зробили, не як зроблено на рівні синтаксису.
  6. Один файл — одна одиниця. UI-секція і бек-сервіс живуть у різних файлах і пов’язуються лінками.
  7. Файл ↔ нода Canvas. Кожен файл у docs/ має бути представлений як нода на Canvas (локальному Canvas.canvas сервісу або глобальному architecture/Canvas.canvas). Якщо підтема надто мала щоб мати окрему ноду — зливаємо з батьківським файлом у секцію.
  8. Не посилайся на те, чого немає на Canvas. Wiki-лінки [[X]] у тілі файлів можна ставити тільки на файли які представлені нодою на Canvas. Якщо хочеться послатись на дрібну підтему — злий її у файл який є на Canvas, і посилайся через [[файл#секція|Секція]].

Межа глибини

Описуємо:

  • Числа: таймаути, інтервали, ліміти, пороги
  • Умови, фільтрації, послідовність кроків
  • Залежності: хто що тригерить, хто від кого залежить
  • Нюанси поведінки які можуть здивувати або стати предметом суперечки
  • Чому саме таке рішення — якщо неочевидне

Не описуємо:

  • Синтаксис виклику методів
  • Деталі транспорту (fetch vs axios, Promise.race vs Promise.all) — якщо не впливає на поведінку
  • Інфраструктура без бізнес-логіки (IPC, ping між вікнами, tab-to-tab запити)
  • Імена полів і типи які очевидні з коду
  • Запит/відповідь endpoint’ів — це робота Swagger, не markdown

Правило великого пальця: якщо без цього факту читач може прийняти помилкове рішення — описуємо. Якщо це тільки як зроблено, без впливу на поведінку — пропускаємо. У сумнівах — описуємо коротко в секції «Нюанси».


Структура репозиторіїв

Root (stack-docs/)

stack-docs/
├── README.md             # людська шпаргалка про систему
├── CONVENTIONS.md        # цей файл
├── AUTHORING.md          # процес створення/оновлення
├── glossary.md           # глобальні терміни
├── architecture/         # мапа сервісів, RMQ-зв'язки
│   ├── Canvas.canvas
│   └── overview.md
├── entities/             # крос-сервісні сутності (User, Lady, Message)
├── roles/                # каталог ролей доступу
├── scripts/              # sync.mjs, inject-doc-meta.mjs
└── services/             # symlinks/snapshots сервісних доків (gitignore)

Сервіс (<service>/docs/)

docs/
├── Canvas.canvas         # локальний Canvas сервісу
├── index.md              # навігаційний індекс (опційно)
├── glossary.md           # ТІЛЬКИ сервіс-специфічні терміни (опційно)
├── ui/                   # UI-екрани, секції, колонки, діалоги
├── services/             # бек-сервіси: інтервали, сендери, runner'и
├── entities/             # сутності даних
├── flows/                # процеси: логін, ініціалізація
├── system/               # інфраструктура: БД, settings, оновлення
└── api/                  # огляд API (тільки бек-сервіси): індекс груп + посилання на Swagger
  • UI-файли — українською як в розмові в команді (Чат.md, Колонка фаворитів.md). Це єдина мова якою ми обговорюємо інтерфейс — нема сенсу вгадувати англ відповідник для пошуку.
  • Для meta і flow-кроків — kebab-case або просте англ (Login.md).
  • Виняток: для бек-файлів що відповідають класу/сервісу в коді — PascalCase, щоб назва файлу збігалась з іменем класу (NetworkService.md, ChatSender.md).
  • Допускається один рівень вкладеності якщо тема розгалужується (entities/chat/Invites.md). Глибше — знак що треба рефакторити.
  • Home.md не використовуємо — вхід через Canvas.canvas.

Шаблон сторінки

Обов’язковий початок

#Тег1 #Тег2
 
[[Назва-файлу]]
 
# Людська назва
 
`контекстна стрічка: шлях в коді або "(UI-елемент)"` — одна фраза опису
  • Теги — тип сторінки (див. нижче). Один рядок, без ком.
  • Backlink [[Назва-файлу]] — для зворотного пошуку в Obsidian.
  • H1 — як називаємо в розмові (для UI), або назва класу/сервісу (для бек).
  • Контекстна стрічка — для бек: шлях `src/...ts`. Для UI: (UI-елемент) або (UI-секція). Для роле/ентіті — пропускаємо.

Опційні секції (використовувати за потреби)

## Що це / Що показує
Один абзац: роль елемента в системі.
 
## Числа / Інтервали / Таймаути
Таблиця або список з бізнес-значеннями.
 
## Логіка / Умови / Фільтри
Пронумерований список або таблиця.
 
## Нюанси
Неочевидні моменти з поясненням *чому*.
 
## Зв'язки
- Тригерить: [[...]]
- Оновлюється від: [[...]]
- Читає: [[...]]
- Стартує: [[...]]
 
## Чому так
Пояснення неочевидних архітектурних рішень. Тільки коли справді є причина.

Порядок секцій — приблизно такий як вище, але можна адаптувати. Обов’язкова тільки «шапка» (теги + backlink + H1 + контекстна стрічка + одна фраза).


Типи сторінок і теги

Теги типу сторінки

ТипТегВміст
UI-елемент#UIЕкран, секція, колонка, діалог, тулбар
Сервіс#ServiceФоновий процес, сендер, runner, контролер
Інтервал#IntervalДодатковий тег для сервісів з таймером
Сутність#EntityСтруктура даних: чат, лист, нотатка, таск
Процес#FlowПослідовність кроків: логін, логаут, ініціалізація
Система#SystemІнфраструктура без бізнес-логіки (БД, settings, tabs)
Роль#RoleРоль доступу (director, supervisor, operator …)
API#APIОгляд API-групи бек-сервісу + лінки на Swagger
Архітектура#ArchitectureКрос-сервісна картина — лежить тільки в root
Мета#MetaСамі конвенції, індекси, глосарії

Теги типу можна комбінувати (#Service #Interval). Один з цих тегів обов’язковий у шапці кожного файла.

Сервісні теги (автоматичні)

Кожен файл під services/<service>/ на сайті отримує тег з назвою сервісу (#electron, #golden, #client, #stack, #prime, #udate, #chathouse, #academy, #ai). Це робить inject-doc-meta при білді — руками не писати.

Для чого: на зібраному сайті клік по тегу #electron дає список усіх документів у відповідному сервісі.

Винятки коли варто додати сервісний тег руками: root-документ який крос-сервісний, але переважно про конкретний сервіс — наприклад entities/<X> де сутність живе в RMQ-обміні, але споживається переважно одним сервісом. Тоді в шапку додаємо #<service> руками — він з’явиться як додатковий ярлик.

Стан-теги (опціонально, де доречно)

ТегСенсКоли ставити
#TODOДокумент незавершений або потребує уточненняКоли лишаєш TODO: ... у тексті, додай тег у шапку. Клік по #TODO на сайті дає список усього що треба добити.
#fixОписана логіка є кривою/тимчасовою. Документуємо як є зараз, але хочемо переписати.Коли документ описує реальну поведінку коду який є костилем, hack’ом, технічним боргом. Не для UI-багів — для архітектурних плям. Сигнал «коли торкатимемось — переписати і код, і цей документ».

Стан-теги ставимо в тому ж рядку з тегом типу:

#Service #fix

Зніми #TODO коли всі недоробки в документі закриті. Зніми #fix коли код переписаний і документ оновлений.

Теги — єдиний інструмент фільтрації, тримаємо їх дисципліновано.


Лінки і навігація

Wiki-лінки (всередині vault)

Всередині свого сервісу — звичайний [[Назва файлу]]:

Дивись [[Login screen]], тригерить [[OperatorRunner]].

На глобальний контент (root) — пишемо повний шлях від кореня vault:

Доступ обмежено [[roles|роллю operator]].
Користувач визначений у [[entities/Lady]].

На інший сервіс — повний шлях через services/:

Дивись [[services/golden/api/index|Golden API]].
Cleanup runner стартується по подіях [[services/stack/flows/UserSignup]].

Якщо ти редагуєш у режимі «один сервіс» (vault — тільки твій сервіс), крос-сервісні wikilinks показуватимуться сірими у твоєму локальному Obsidian. На зібраному сайті вони працюють. Це не баг — пиши лінк нормально.

URL-лінки (зовні)

  • Swagger endpoint — звичайний URL deeplink:
    [getOperatorLadies (golden)](https://api.besocial.tech/golden/api-docs/v2#/Electron%20API/ElectronApiController.getOperatorLadies)
    
  • Жодних інших зовнішніх систем у markdown без необхідності.

Правила лінкування

  • UI → бек: обов’язкова секція Зв'язки з лінками на сервіси/ендпоінти що цей UI використовує.
  • UI → API: не описуємо запит/відповідь у markdown — ставимо deeplink на Swagger. Якщо є бізнес-нюанс який Swagger не показує (особлива комбінація ролі + whitelist, наприклад) — описуємо саме нюанс.
  • Бек → UI: в секції Зв'язки — куди йде результат сервісу.
  • Бек → ентіті: лінк на [[entities/X]] (локальний або глобальний).

Правила для UI-сторінок

  • Назва — як звемо в команді («колонка фаворитів»), а не як в коді (FavoritesColumn.tsx)
  • Шлях до коду — опційний. Якщо компонент складний — можна вказати, але зазвичай не треба
  • Обов’язкова секція Зв'язки — звідки дані (лінк на бек-ендпоінт у Swagger), що тригерить (лінк на дію)
  • Описуємо: які дані показуються, які дії доступні, які фільтри й стани, які обмеження
  • Не описуємо: верстку, стилі, компоненти, імена пропсів, форму запиту/відповіді

Правила для Service-сторінок

  • Шлях у коді — обов’язковий у шапці
  • #Interval — якщо є таймер
  • Секції: Інтервал (якщо є), Логіка, Нюанси, Зв'язки
  • Нюанси зазвичай найцінніше: stop-листи, watchdog’і, захисти від подвійного запуску, рандомізації
  • Доступ за ролями — якщо ендпоінт має guard([...]), перерахуй ролі або пошлися на [[roles/<role>]]. Не дублюй логіку гварда — Swagger її показує. Описуй бізнес-причину обмеження якщо вона неочевидна.

Правила для Entity-сторінок

  • Описуємо структуру даних і ключові властивості сутності
  • Глобальні ентіті (живуть у RMQ-обміні між сервісами або в спільних таблицях) — у stack-docs/entities/
  • Локальні (тільки всередині одного сервісу) — в <service>/docs/entities/
  • Лінки на сервіси які цю сутність продукують/споживають

Правила для Flow-сторінок

  • Структура — пронумерований список кроків
  • Короткі flow (≤3 кроки) — описуємо в одному файлі
  • Довгі flow — окрема сторінка на крок, у головній тільки список з лінками
  • Крос-сервісні flow (наприклад user signup що зачіпає stack + golden + RMQ) — у stack-docs/architecture/flows/

Правила для API-сторінок

Один файл <service>/docs/api/index.md на сервіс. Зміст:

  • Короткий опис чим API цього сервісу занят
  • URL Swagger UI (локальний і прод)
  • Таблиця-інвентар груп (тег → URL-префікс → стан міграції → к-ть ендпоінтів)
  • Конвенція відповідей (success/error формат — посилання на eталон)
  • Окремі ендпоінти не описуємо — Swagger їх вже показує

Якщо є бізнес-нюанс конкретної групи ендпоінтів якого Swagger не показує — окрема сторінка api/<group>.md з тегом #API.

Правила для Role-сторінок

Усі ролі — в одному файлі roles на рівні root. Один рядок таблиці на роль (код + кому + коротке призначення). Не розводимо окремий файл на кожну роль — це довідник, а не онбординг.

Якщо якась роль вимагає глибшого опису (складна матриця доступів, багатокроковий процес видачі) — виносимо тільки її в окремий файл roles/<role>.md і лінкуємо з таблиці.


Canvas

Canvas.canvas — головний вхід у документацію.

  • Глобальний architecture/Canvas.canvas — мапа сервісів верхнього рівня. Ноди = сервіси. Стрілки = HTTP/RMQ-зв’язки.
  • Локальний <service>/docs/Canvas.canvas — мапа всередині сервісу (як зараз в електроні). Ноди = файли в docs/ цього сервісу.

Кольори по типах

ТипКолірHex
UIблакитний#2196f3
Serviceзелений#66bb6a
Entityфіолетовий#ab47bc
Flowпомаранчевий#ffa726
Systemсіро-зелений#78909c
Roleжовтий#ffd54f
APIбірюзовий#26a69a
Metaчервоний#e03131

Типи стрілок (підпис на стрілці)

  • тригерить — натискання/подія запускає процес
  • оновлює — сервіс пише дані в UI/entity
  • читає — UI читає дані з entity/store
  • стартує — один сервіс стартує інший (ініціалізація)
  • викликає — крос-сервіс HTTP виклик
  • публікує / слухає — RMQ події

Групи

Обводимо ноди одного типу в групу з кольоровим підписом (наприклад «Інтервали оператора», «Сервіси TU»). Використовуємо для ≥3 нод одного типу в одному місці.


Як оновлювати

  1. Після зміни коду — відкрий відповідний файл у docs/ і онови його частиною того самого коміту. Коміт з логікою без оновлення доків — це борг.
  2. Через AI — «онови docs/xxx.md під зміну в src/yyy.ts». AI читає цей файл і дотримується формату.
  3. При видаленні коду — видаляй і відповідні доки. Мертвих сторінок бути не повинно.
  4. При додаванні нової логіки — новий файл за шаблоном.

Оновлюємо коли: змінюються числа, умови, фільтри, порядок кроків, залежності між сервісами, контракт ендпоінтів (нові поля, нові гварди ролей).

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


Для AI-асистентів

Коли тебе попросили створити або оновити документ:

  1. Прочитай цей файл повністю перед роботою з docs/
  2. Визнач тип сторінки (UI/Service/Entity/Flow/System/Role/API) і використовуй відповідний шаблон
  3. Дотримуйся межі глибини: бізнес-нюанси — так, синтаксис/транспорт — ні; запит/відповідь endpoint’у — нікуди не пиши, це робота Swagger
  4. Перевір чи не треба оновити пов’язані файли (секція Зв'язки)
  5. Після оновлення сервісу перевір чи не треба оновити UI-сторінку що читає його дані, і навпаки
  6. Якщо створюєш новий файл — додай його ноду в локальний Canvas.canvas з правильним кольором і типовими зв’язками
  7. Якщо створюєш новий сервіс — додай ноду на глобальному architecture/Canvas.canvas у root
  8. Якщо не вистачає інформації — задай 3-5 вузьких запитань. Не вигадуй. Краще лиши TODO: уточнити X ніж напиши неправду.