# Systemer — документація Джерело: https://www.systemer.app/docs Операційна система для сервісного бізнесу: клієнти й угоди, проєкти й завдання, гроші, звіти, команда та облік часу в одному контексті. --- ## Початок роботи Що таке Systemer, у якому порядку заводити дані й чому перший тиждень варто починати з ставок команди. ### Що це Systemer — операційна система для сервісного бізнесу: агенції, студії, консалтингу. В одному місці живуть клієнти й угоди, проєкти й завдання, гроші та звіти, команда й облік часу. Сенс не в тому, щоб замінити пʼять інструментів одним, а в тому, щоб цифри в них нарешті сходились: година, залогована виконавцем, стає собівартістю в звіті прибутковості проєкту й рядком у рахунку клієнту без жодного перенесення руками. Продукт мультиорганізаційний із першого дня. Ви працюєте в межах своєї організації, і дані однієї організації недоступні іншій на рівні бази даних, а не фільтра в коді. ### Перші кроки Порядок заведення даних має значення: кожен наступний крок спирається на попередній. - Організація і юрособа. Юрособа — це те, від чийого імені виставляються рахунки й підписуються документи. Їх може бути кілька. - Рахунки й початкові залишки. Без них Cash Flow рахує рух, але не залишок. - Команда і ставки. Поки немає ставок, собівартість години невідома, і жоден звіт про маржу не порахується. - Контрагенти. Можна завести руками або імпортувати. - Проєкти. Зазвичай зʼявляються з виграних угод, але перші кілька простіше завести напряму. > Ставки — не бюрократія, а вимикач половини продукту. Прибутковість проєкту, беззбиткова ставка, маржа клієнта й сигнал «проєкт виходить за бюджет» рахуються від собівартості години. Без ставок ці екрани показують прочерки, і це навмисно: нуль замість невідомої величини — неправда. ### Як влаштована навігація Меню впорядковане за життєвим циклом агенції — клієнт, робота, гроші, — а не за алфавітом модулів. Зверху два екрани, з яких починається день: Центр керування показує те, що потребує рішення, дашборд — цифри. Власник і адміністратор після входу потрапляють у Центр керування, решта ролей — на дашборд. Причина проста: черга рішень власника для виконавця здебільшого порожня, і відкривати її щоранку означало б показувати людині екран, де для неї нічого немає. --- ## Центр керування Вісім сигналів, кожен із поясненням, звідки взявся, і дією, куди веде. Плюс порада AI за конкретними числами сигналу. ### Навіщо він Дашборд відповідає на питання «які в нас цифри». Центр керування відповідає на інше: «що сьогодні потребує рішення». Це різні екрани, і другий важливіший, бо цифра без наслідку не змінює нічого. Сигнал — не картка й не сповіщення. У кожного є три частини: сама подія, пояснення, з чого вона порахована, і дія, що веде туди, де рішення ухвалюється. ### Які бувають сигнали - Прогнозується касовий розрив — планові платежі перевищують очікуваний залишок. - Рахунки прострочені — строк оплати минув, гроші не надійшли. - Проєкти виходять за бюджет — витрачено понад 80% кошторису. - Ретейнери під загрозою — години зʼїдені або маржа впала нижче 20%. - Операції чекають на розмітку — без категорії вони не потрапляють у звіти. - Угоди без руху — стадія не мінялась понад тиждень. - Тиждень не закритий годинами — без годин не рахується ні собівартість, ні маржа. - Пропозиції AI чекають на рішення — AI нічого не застосовує сам. Кожен сигнал має власний дозвіл і власну умову тарифу. Керівник проєктів без доступу до фінансів фінансових сигналів не бачить узагалі — не бачить із замком, а не бачить зовсім. Порожній Центр означає, що рішень на сьогодні немає, і це нормальний стан, а не помилка. ### Що робити з сигналом У кожного сигналу є кнопка «Що робити?». Вона дає два-чотири конкретні кроки, складені з чисел саме цього сигналу: не загальна порада про касові розриви, а те, що можна зробити з вашими рахунками цього тижня. > Модель не рахує й не може: усі числа приходять до неї готовими рядками з уже порахованого сигналу. Вона переставляє й формулює, але не обчислює — тому нової цифри в пораді взятися нізвідки. Жодна дія не застосовується сама: рішення й дія лишаються за вами. --- ## Клієнти, ліди й угоди Контрагенти, воронка лідів і угод, партнерські винагороди й перехід виграної угоди в проєкт. ### Контрагенти Контрагент — будь-яка сторона, з якою є гроші або зобовʼязання: клієнт, підрядник, постачальник, орендодавець. Один довідник, а не три, бо той самий контрагент часто буває і клієнтом, і підрядником. На картці контрагента видно не тільки контакти й історію, а й економіку: виручка, собівартість і маржа за весь час співпраці, а для проєктів за часом і матеріалами — тренд маржі за останні дванадцять місяців. ### Ліди й угоди Лід — це контакт, який ще не став розмовою про гроші. Угода — розмова про конкретну суму на конкретній стадії. Воронка стадій налаштовується під ваш процес. Виграна угода вимагає проєкту. Це не формальність: проєкт — місце, де в угоди зʼявляються години, собівартість і маржа. Проєкт успадковує контрагента, суму, валюту й відповідального, тож створення займає один крок. > Угода, закрита без проєкту, назавжди лишається сумою без собівартості. Через рік на питання «скільки ми на цьому заробили» відповіді не буде — не тому, що звіт поганий, а тому, що дані для неї не збирались. ### Партнерство Партнери, які приводять клієнтів, ведуться окремою воронкою зі своїми стадіями — від заявки до активної співпраці — і рівнем партнера. Це не та сама воронка, що продажі: партнерство розвивається місяцями й іншими кроками, і змішувати його з угодами означало б зіпсувати обидві конверсії. --- ## Проєкти й завдання Моделі оплати, шаблони проєктів, етапи й майлстоуни, завдання й таймер на картці. ### Моделі оплати Модель оплати проєкту визначає, як рахується його економіка й що можна виставити клієнту. - Фіксована ціна — виручка відома наперед, маржа залежить від того, скільки годин ви витратите. - Час і матеріали — виручка рахується з логованих годин за ставкою продажу на дату роботи. - Ретейнер — щомісячна сума з лімітом годин; години понад ліміт стають окремим рядком рахунку. - Разова робота — короткий проєкт без окремого кошторису. - Внутрішній — робота на себе: години збираються, рахунок не виставляється. ### Шаблони Агенція робить той самий тип роботи десятками разів. Шаблон проєкту створює структуру — етапи, завдання, ролі — за один крок, тому новий проєкт заводиться не за півгодини, а за хвилину. ### Етапи й майлстоуни Майлстоун — точка, до якої привʼязані і здача роботи, і етапний платіж. Завдяки цьому графік платежів за проєктом не ведеться окремо від графіка робіт. ### Завдання й час На картці завдання є таймер: година логується двома кліками, без переходу в окремий екран обліку часу. Активний таймер видно з будь-якої сторінки, а таймер, що йде довше дванадцяти годин, зупиняється сам. --- ## Команда, ставки й облік часу Собівартість години з накладними, версіонування ставок, тижнева сітка, таймер і облік часу з Telegram. ### Собівартість години Собівартість години людини складається з двох частин. Пряма вартість — зарплата й податки, поділені на планові білабельні години. Частка накладних — пул накладних витрат організації, поділений на суму планових білабельних годин усієї команди. Сума цих двох частин і є беззбитковою ставкою: нижче неї година приносить збиток. Пул накладних складають витрати з категорій із типом «накладні» — оренда, софт, бухгалтерія — і вартість людей, позначених як накладні: адміністрація, яка не продає години, але коштує грошей. Розклад пулу на рядки відкривається зі звіту ставок, і кожен рядок веде в операції, з яких він склався. > Більшість систем обліку рахує собівартість як «зарплата ÷ години». Людина, продана вище власної зарплати, виглядає в них прибутковою — навіть коли її ставка нижча за беззбиткову з накладними, і кожна її година насправді збиткова. Systemer рахує обидві величини й прямо показує, скільки людей потрапило в цей розрив. ### Ставки версіонуються Кожна ставка має дату, з якої вона діє. Підвищення зарплати не переписує історію: проєкт, зроблений торік, і далі рахується за торішньою собівартістю. Зріз місяця фіксується окремо, тому питання «скільки коштувала година в липні» має рівно одну відповідь. ### Як логуються години - Тижнева сітка — години вводяться прямо в клітинці, кнопка «як минулого тижня» переносить структуру попереднього тижня. - Таймер на картці завдання — для роботи, яку ви робите просто зараз. - Telegram — команда /time 3 Альфа записує три години на проєкт «Альфа» без відкриття застосунку. У тижневій сітці й у таймері години округлюються до чверті. Це не обмеження точності, а визнання того, що облік часу з точністю до хвилини все одно неточний, а сітка з дробами нечитабельна. ### Завантаження «Хто вільний наступного тижня» — щоденне питання керівника проєктів. Екран завантаження показує його по людях на тиждень і на період, підсвічуючи перевантаження. Без нього облік часу лишається звітністю про минуле замість інструмента планування. --- ## Гроші: рахунки, операції, планування Дві дати на кожній операції, транзакція проти руху по рахунку, аналітика через алокації, звірка з банком і касовий розрив. ### Дві дати на операції У кожної операції є дата руху грошей і період визнання. Річна передплата, отримана в січні, — це гроші в січні й дохід дванадцятьма частинами протягом року. Без цієї пари неможливо порахувати P&L методом нарахування, а без нього прибуток місяця показує не роботу, а моменти оплат. ### Операція — не рух по рахунку Операція — господарська подія. Рух по рахунку — її наслідок. Переказ між власними рахунками — це одна операція з двома рухами, а не витрата плюс дохід. Саме тому в Systemer переказ не роздуває ні виручку, ні витрати, і в історії рахунку видно «звідки → куди». ### Аналітика через алокації Розріз — категорія, проєкт, угода, напрям, конверт — береться з розподілу суми, а не з полів самої операції. Одна виплата може ділитися між трьома проєктами, і кожен звіт побачить свою частину. Операція без категорії у звіти не потрапляє й окремо нагадує про себе сигналом у Центрі керування. ### Звірка з банком Звірка відповідає на одне питання: чи можна вірити залишку на екрані. Виписка завантажується файлом або приходить із банку автоматично, платежі зіставляються з операціями, а розбіжності лишаються видимими, доки їх не розберуть. ### Планування й касовий розрив Платіжний календар збирає планові надходження й виплати. Якщо в якийсь день прогнозний залишок стає відʼємним, це касовий розрив — і про нього ви дізнаєтесь у Центрі керування заздалегідь, а не в день платежу. Конверти й бюджети дозволяють відкласти гроші під зобовʼязання — податки, зарплату, резерв — і бачити, скільки лишилось справді вільних коштів. --- ## Рахунки клієнтам і документи Рахунок із проєкту й із логованих годин, часткові оплати, кредит-нота, акти й договори, нагадування про прострочення. ### Рахунок Рахунок виставляється з проєкту, з угоди або вручну. Для проєктів за часом і матеріалами є окремий шлях: секція «Години до виставлення» на картці проєкту збирає ще не виставлені години й перетворює їх на рядки рахунку за ставкою продажу на дату роботи. Зміна ставки посеред періоду дає два рядки, а не одну усереднену цифру. > Годину неможливо виставити двічі. Це не перевірка в коді, яку можна обійти, а обмеження в базі даних: кожен запис часу привʼязується щонайбільше до одного рахунку. Оплата може бути частковою: рахунок показує оплачено, лишилось і прострочення. Номер присвоюється автоматично при видачі — дата й порядковий номер за цю дату; автонумерацію можна вимкнути й вводити номери вручну. Пропущений номер не перевикористовується: діра в нумерації пояснювана, два документи з одним номером — ні. ### Кредит-нота Якщо суму виставленого рахунку треба зменшити заднім числом — знижка, повернення, помилка в позиціях — це робиться кредит-нотою з обовʼязковою причиною, а не редагуванням рахунку. Зменшити можна лише неоплачений залишок. Кредит-ноту можна скасувати; видалити — ні. ### Документи Акт, договір і додаток складаються з позицій і друкуються в PDF із реквізитами юрособи й контрагента, сумами й датами. Суми прописом рахуються автоматично. ### Нагадування Прострочений рахунок нагадує про себе сам: клієнту йде лист за налаштованим графіком, а ви бачите стан у звіті дебіторки й у Центрі керування. --- ## Підписки й ретейнери Щомісячна сума з лімітом годин, автоматичне виставлення за минулий період і рядок за години понад ліміт. ### Як влаштований ретейнер Підписка — це щомісячна сума, ліміт годин і період. Години команди по проєкту підписки списуються з ліміту; те, що понад ліміт, стає окремим рядком у рахунку. ### Автоматичне виставлення Якщо увімкнути автовиставлення, чернетка рахунку за минулий місяць створюється сама, з рядком за перевитрачені години. Виставляється саме той період, що закінчився: скільки годин зʼїдено понад ліміт, стає відомо лише після кінця місяця. > Проєкт, що обслуговується підпискою, не можна виставити ще й погодинно: години вже входять у рахунок ретейнера. Спроба зробити це зупиняється з поясненням, а не створює другий рахунок за ту саму роботу. Квартальні й річні підписки виставляються вручну — автоматика поки що працює лише для місячних. ### Здоровʼя ретейнера Ретейнер, у якому години зʼїдені або маржа впала нижче двадцяти відсотків, потрапляє в Центр керування як сигнал. Звіт підписок показує MRR і стан кожної підписки окремо. --- ## Звіти Десять звітів — від P&L і Cash Flow до прибутковості проєктів і воронки продажів. Кожна сума розкривається до операцій. ### Які звіти є - P&L — прибуток і збиток методом нарахування, за періодом визнання. - Cash Flow — рух грошей за датою оплати, з поділом на операційну й фінансову діяльність. - План-факт — заплановане проти зробленого. - Дебіторка і кредиторка — хто винен вам і кому винні ви, за строками. - Управлінський баланс — активи, зобовʼязання й капітал, включно з боргом перед власником. - Реєстр розрахунків — стан відносин із кожним контрагентом. - Прибутковість проєктів — виручка, собівартість і маржа по кожному проєкту. - Ставки і завантаження — собівартість години кожного, беззбиткова ставка й утилізація. - Воронка продажів — конверсія по стадіях. - Підписки і MRR — регулярна виручка й стан ретейнерів. ### Кожна цифра пояснювана Показник без можливості розкрити його до первинних даних у Systemer не зʼявляється. Маржа проєкту розкривається до годин і витрат, накладні на годину — до конкретних операцій оренди й софту, залишок на рахунку — до руху по ньому. Це правило, а не властивість окремих екранів. Кожна таблиця має фільтри зверху, підсумок знизу й експорт у XLSX. Суми показуються з розділювачем тисяч і валютою після числа; відʼємні — з мінусом, а не в дужках. ### Звіти за ролями Людина шукає «мій звіт», а не «звіт по X». Тому крім переліку звітів є готові набори для власника, керівника проєктів і фінансиста. --- ## AI Де саме AI допомагає, чому він не рахує числа сам і чому жодна його дія не застосовується без підтвердження. ### Де він працює - Категоризація операцій — пропонує категорію для нової операції за її описом і історією. - Розбір банківської виписки — витягує платежі з файла, який не підходить під жоден стандартний формат. - Пояснення звіту — переказує, що змінилось у P&L або Cash Flow, звичайною мовою. - Порада до сигналу — два-чотири кроки за числами конкретного сигналу Центру керування. - Чернетки текстів і комерційних пропозицій. - Розпізнавання чеків і голосових повідомлень у Telegram. - Асистент — запитайте про стан справ і отримаєте відповідь із переліком джерел, з яких вона зібрана. ### AI не рахує Усі числа, які бачить модель, приходять до неї вже порахованими — готовими рядками з тих самих функцій, що малюють звіт на екрані. Модель формулює й упорядковує, але не обчислює. Це свідоме обмеження: порада з вигаданою цифрою гірша за відсутність поради, бо виглядає так само впевнено. ### Нічого не застосовується само AI пропонує — рішення ухвалюєте ви. Пропозиція чекає в черзі, доки її не приймуть або не відхилять, і сама по собі нічого не змінює. Кожне звернення до моделі записується в журнал: що спитали, що відповіли, скільки коштувало. AI-дії витрачають кредити, і місячний обсяг залежить від тарифу. Витрачені кредити видно в налаштуваннях, а перевищення не блокує роботу мовчки. --- ## Інтеграції Банк, імпорт виписок, Telegram, ClickUp, пошта й сповіщення в браузер. ### Банк і виписки Monobank підключається за ключем і віддає операції автоматично — і для особистого, і для корпоративного рахунку, і для еквайрингу. Виписки інших банків завантажуються файлом: є готові профілі для ПриватБанку й Monobank, а також універсальний CSV із ручним зіставленням колонок. Повторне завантаження тієї самої виписки не створює дублікатів: рядки зіставляються за реквізитами платежу. ### Telegram Бот приймає витрати й доходи одним повідомленням, розпізнає фото чека й голосове повідомлення, логує години командою /time і надсилає сповіщення. Для більшості щоденних дій застосунок відкривати не обовʼязково. ### ClickUp Якщо команда працює в ClickUp, простори, списки й задачі синхронізуються в проєкти й завдання Systemer. Списаний час теж переноситься — за останні два тижні, з привʼязкою до людини, проєкту й задачі за поштою в картці людини. Таймер, залишений на ніч, і запис без відомого автора не зараховуються мовчки: синхронізація показує, скільки годин і з якої причини не потрапили в облік. ### Пошта й сповіщення Рахунки, нагадування й дайджести надсилаються поштою з фірмовим оформленням. Стан доставки видно в системі: лист, який не дійшов, не вважається надісланим. Сповіщення також можуть приходити в браузер і в Telegram — канал обирається в налаштуваннях. --- ## Вебхуки Обмін подіями з іншими системами в обидва боки: підпис і повтори вихідних, ключ і формат тіла для вхідних. ### Що це Вебхук — це спосіб для іншої системи дізнаватись про те, що сталось у Systemer, не питаючи нас про це щохвилини. Ви вказуєте адресу й перелік подій; щойно одна з них настає, ми надсилаємо на цю адресу підписаний POST із JSON. Звідси інтегрується будь-що, що вміє приймати HTTP: сценарій у n8n чи Make, чужа CRM, бот у чаті команди, власний сервіс. Підписка налаштовується в Налаштування → Вебхуки й потребує права керувати інтеграціями. > Підписка на «усі події» не підтримується навмисно. Перелік завжди явний: поява нової події в продукті не має сама почати відправляти дані в систему, власник якої про цю подію не знає. ### Як підключити - Налаштування → Вебхуки → «Нова адреса». Адреса приймача має бути на https. - Оберіть події. Надсилатимуться лише вони. - Збережіть секрет підпису. Він показується один раз: у нас він зберігається в сховищі секретів і не читається назад. - Натисніть «Надіслати тест» — у журналі доставок зʼявиться подія webhook.ping із відповіддю вашого сервера. Якщо секрет загубився, створіть новий кнопкою «Новий секрет»: попередній лишається чинним ще добу, тому оновлення приймача не призводить до розриву. ### Що приходить Заголовки запиту несуть ідентифікатор події, її тип і підпис. Ідентифікатор належить події, а не спробі доставки: повтор тієї самої події приходить із тим самим значенням, і саме за ним приймач має відкидати дублі. Заголовки ``` POST /hooks/systemer HTTP/1.1 Content-Type: application/json Systemer-Event-Id: 5f0c6f1e-... Systemer-Event-Type: deal.won Systemer-Signature: t=1790000000,v1=5257a869e7bcd... ``` Тіло ``` { "id": "5f0c6f1e-...", "type": "deal.won", "created_at": "2026-10-01T10:00:00Z", "organization_id": "0a9d...", "data": { "entity_type": "deal", "entity_id": "7c31...", "title": "Угоду виграно", "summary": null, "url": "https://www.systemer.app/ваша-організація/crm/deals/7c31...", "actor_person_id": "3b12..." } } ``` > Поля перелічені поіменно, а не віддаються «як є» з нашої бази. Внутрішні службові дані — кому саме пішло сповіщення всередині вашої команди, які права для цього потрібні — назовні не виходять ніколи. ### Як перевірити підпис Підписується рядок «мітка часу, крапка, сире тіло запиту» алгоритмом HMAC-SHA256 із вашим секретом. Мітка часу входить у підпис, а не стоїть поруч: інакше перехоплений запит можна було б переграти пізніше, підмінивши лише її. Node.js ``` import { createHmac, timingSafeEqual } from 'node:crypto'; export function verify(rawBody, header, secret) { const parts = Object.fromEntries(header.split(',').map((p) => p.split('='))); const timestamp = Number(parts.t); // Запит, старший за пʼять хвилин, відхиляємо — захист від переграння. if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false; const expected = createHmac('sha256', secret) .update(`${timestamp}.${rawBody}`) .digest('hex'); return header .split(',') .filter((p) => p.startsWith('v1=')) .some((p) => timingSafeEqual(Buffer.from(p.slice(3)), Buffer.from(expected))); } ``` - Перевіряйте підпис ДО того, як розбирати тіло: воно ще не ваше, поки підпис не зійшовся. - Підписів у заголовку може бути два — це доба після зміни секрета. Приймач має вважати запит дійсним, якщо збігся будь-який. - Відкидайте запити з міткою часу, старшою за пʼять хвилин. - Будьте ідемпотентними за Systemer-Event-Id: повтор доставки — штатна ситуація, а не помилка. ### Доставка й повтори Ми чекаємо на відповідь 2xx протягом пʼяти секунд. Довга робота на боці приймача має відбуватись після відповіді, а не до неї — інакше доставка вважається невдалою, хоча подію вже прийнято. - Мережева помилка, таймаут, 408, 429 і 5xx — повторюємо: через 10 секунд, 30 секунд, 2 хвилини, 10 хвилин, годину й шість годин. - Інші 4xx — не повторюємо. Це свідома відмова приймача, і шість однакових запитів нічого не змінять, лише сховають причину. - Після сьомої невдачі подія вважається недоставленою. Її видно в журналі, і її можна відправити знову кнопкою «Повторити». - Якщо поспіль не доходить сто подій, підписка вимикається, а власник отримує сповіщення. Це не мовчазне зникнення інтеграції — вимкнення видно на екрані з поясненням. Події не надсилаються миттєво: черга розбирається кожні пʼять хвилин. Це стеля затримки, а не типове значення. > Журнал доставок показує не лише код відповіді, а й її початок. Питання «чому не доходить» майже завжди має відповідь у тілі відповіді вашого сервера, а не в коді статусу. ### Вхідні: коли надсилають нам Зворотний напрямок: зовнішня система надсилає POST нам, і в Systemer зʼявляється лід, задача або операція. Джерело створюється в Налаштування → Вебхуки → Вхідні; воно має свою адресу, свій ключ і рівно один намір. > Операція ззовні лягає ЧЕРНЕТКОЮ і не впливає на жоден звіт, доки людина її не підтвердить. Це не обережність заради обережності: зовнішня система надсилає намір, а не факт. Баг чи дубль на її боці інакше миттєво стає рядком у звіті, а звіт — підставою для рішення про гроші. - Один намір на джерело. Ключ, що вміє створювати і лід, і операцію, потрапивши не в ті руки, коштує більше за два ключі. - Контекст, якого запит не несе — рахунок для операції, проєкт для задачі, відповідальний за лід, — задається в налаштуваннях джерела один раз. - Ключ показується один раз при створенні. Новий ключ можна створити будь-коли; старий перестає діяти тієї ж секунди. ### Вхідні: як надіслати запит Ключ передається заголовком Systemer-Key або як Bearer-токен в Authorization — обидва приймаються. Тіло — JSON. Новий лід ``` POST /api/webhooks/inbound/<ідентифікатор джерела> Systemer-Key: whin_... Systemer-Idempotency-Key: form-2026-10-01-17f3 Content-Type: application/json { "name": "Олена Ковальчук", "company": "ТОВ «Приклад»", "email": "olena@example.com", "phone": "+380671234567", "message": "Потрібен редизайн сайту" } ``` Чернетка операції ``` { "kind": "expense", "amount": "2400.50", "currency": "UAH", "date": "2026-10-01", "description": "Хостинг за жовтень", "counterparty": "Hetzner" } ``` - Валюта операції має збігатися з валютою рахунку, обраного в джерелі, — інакше запит відхиляється з поясненням. - Переказ ззовні не приймається: це рух між вашими власними рахунками, і зовнішня система про них не знає. - Сума приймається і рядком, і числом, але рядок точніший: число в JSON — це double, і 2400.50 в ньому вже не 2400.50. ### Вхідні: що ми відповідаємо - 201 — запис створено. У тілі відповіді його тип та ідентифікатор. - 401 — джерела немає або ключ не підходить. Відповідь однакова навмисно: інакше адреса стає способом дізнатись, які джерела існують. - 409 — джерело на паузі. - 422 — тіло або налаштування джерела не дають створити запис. Причина — у полі error, і вона написана для людини. - 500 — наш збій. Саме цей запит має сенс повторити. Надішліть заголовок Systemer-Idempotency-Key — і повтор із тим самим значенням поверне той самий результат замість другого запису. Без нього ключем стає хеш тіла: повтором вважається рівно однакове тіло, що слабше, але краще, ніж нічого. Кожен запит видно в журналі джерела: що створилось або чому відхилено. Тіло запиту зберігається 30 днів — далі лишається сам запис без вмісту. ### Які події доступні - CRM: ліду й угоді призначено відповідального, лід конвертовано, угода перейшла на новий етап, угоду виграно, угоду втрачено. - Проєкти: проєкту призначено відповідального, проєкт наближається до бюджету, проєкт перевищив бюджет, задачі призначено виконавця. - Фінанси: рахунок прострочено, прогнозується касовий розрив, маржа помітно впала. Внутрішні події — листування в чатах, робота над самою Systemer, підказки AI — назовні не виходять. Перелік розширюється, і кожна нова подія зʼявляється в переліку вимкненою: щоб вона почала надходити, її треба обрати. --- ## Скринька і Supporter Листування з клієнтами з Telegram, Instagram, Viber та інших месенджерів у CRM: як підключити Supporter і як виглядає обмін в обидва боки. ### Що це Скринька — спільна для команди стрічка розмов із клієнтами з месенджерів і соцмереж. Самі підключення до Telegram, Instagram, Viber, WhatsApp і Facebook тримає Supporter — окремий сервіс, який пересилає повідомлення клієнтів у Systemer і забирає відповіді агентів назад. Systemer із месенджерами напряму не говорить. Кожна розмова — бесіда в «Клієнти → Скринька»: видно канал, імʼя співрозмовника, хто з команди відповідає і чи чекає клієнт на відповідь. Бесіду можна звʼязати з лідом або контрагентом — і листування стає частиною історії клієнта, а не лишається в чиємусь телефоні. > Скринька спільна: її бачить кожен, хто має дозвіл «Доступ до скриньки», без запрошення в конкретну бесіду. Призначення агента — лише спосіб домовитись, хто відповідає, а не межа доступу. Це навмисно інакше, ніж у внутрішніх чатах, де бесіду бачать лише учасники. ### Підключення - Налаштування → Скринька → «Підключити Supporter». Створюється конектор і два секрети: ключ, яким Supporter надсилає події нам, і секрет, яким ми підписуємо відповіді. Обидва показуються один раз. - Адресу для Supporter (POST /api/webhooks/supporter/) і ключ вставте в налаштування Supporter. - Адресу Supporter для відповідей і секрет підпису задайте в конекторі. Поки адреси немає, повідомлення клієнтів приймаються, а відповіді агентів чекають у черзі. - Оберіть, кому призначати нові бесіди: ця людина отримує сповіщення про кожне повідомлення клієнта, доки бесіду не передали іншому. ### Supporter → Systemer Supporter надсилає POST на адресу конектора з ключем у заголовку Systemer-Key. Заголовок Systemer-Idempotency-Key необовʼязковий: без нього ключем повтору стає хеш тіла. Тіло — одна з чотирьох подій, поле type каже яка. message.received — повідомлення від клієнта ``` POST /api/webhooks/supporter/ Systemer-Key: inbk_… Content-Type: application/json { "type": "message.received", "conversation": { "ref": "tg:123456789", "channel": "telegram", "peer": { "ref": "tg-user:987", "name": "Олена Петренко", "handle": "@olena" } }, "message": { "ref": "tg-msg:42", "text": "Добрий день! Хочу дізнатись про вартість аудиту.", "sent_at": "2026-10-04T09:15:00+03:00", "attachments": [{ "url": "https://…/photo.jpg", "filename": "photo.jpg", "mime_type": "image/jpeg" }] } } ``` Агент відповідає або в Systemer, або в самому Supporter — і розмова має виглядати однаково в обох випадках. Тому подій про повідомлення дві: message.received несе слова клієнта, message.sent — відповідь, набрану в Supporter. Надсилати друге під виглядом першого не можна: у Скриньці відповідь менеджера стала б словами клієнта, під його імʼям, а бесіда позначилась би як така, що чекає на відповідь, хоча її вже дали. message.sent — агент відповів у Supporter ``` { "type": "message.sent", "conversation": { "ref": "telegram:conv:8c7d6e5f-…", "channel": "telegram", "peer": { "ref": "telegram:user:0f1a…", "name": "Олена Петренко" } }, "message": { "ref": "telegram:msg:aaaaaaaa-…", "text": "Дякуємо! Надішлю розрахунок сьогодні до вечора.", "sent_at": "2026-10-04T09:20:00+03:00", "reply_to_ref": "telegram:msg:bbbbbbbb-…", "attachments": [] }, "sender": { "name": "Анна Ковальчук" } } ``` - conversation.ref — ідентифікатор треду в Supporter. Повторне повідомлення з тим самим ref лягає в наявну бесіду. channel — один із: telegram, instagram, facebook, viber, whatsapp, email, web, other. - message.ref — ідентифікатор повідомлення в Supporter. Повтор із тим самим ref не створює дубля. Текст або вкладення — принаймні щось одне; вкладення лишаються за посиланням у Supporter. - message.sent — відповідь агента, набрана в Supporter. Лягає на бік менеджера, поруч із відповідями з CRM, і знімає з бесіди позначку «чекає на відповідь». sender.name показується як автор; без нього автор підписується «Інтеграція». - Стан такої відповіді за замовчуванням — «Надіслано», а не «Доставлено»: «пішло клієнту» і «месенджер підтвердив» — різні факти. Знаєте більше — передайте "status": "delivered"; дізнаєтесь пізніше — надішліть message.status. - message.status — стан доставки нашої відповіді: { "type": "message.status", "message_id": "", "status": "delivered" }. Стани: sent, delivered, read, failed (з полем error). - conversation.updated — змінились імʼя, нік або аватар співрозмовника; тіло — те саме поле conversation. - Відповідь 201 із conversation_id і message_id; повтор — 200 з duplicate: true і тим самим результатом; помилка в тілі — 422 з поясненням. - Увага на одну літеру: message.send — це тип НАШОГО конверта до Supporter, message.sent — подія Supporter до нас. Напрямки протилежні. ### Systemer → Supporter Відповідь агента їде POST-ом на адресу конектора одразу після надсилання; те, що не доїхало, добирає повторна доставка за розкладом 10 с, 30 с, 2 хв, 10 хв, 1 год, 6 год. Підпис — той самий, що у вихідних вебхуків: заголовок Systemer-Signature з t= і v1=.<тіло>">, секрет — із конектора. message.send — відповідь агента ``` POST <адреса Supporter> Systemer-Signature: t=1791234567,v1=5257a869… Systemer-Event-Type: message.send Content-Type: application/json { "id": "0f1a…", "type": "message.send", "created_at": "2026-10-04T09:20:00.000Z", "conversation": { "id": "…", "ref": "tg:123456789", "channel": "telegram", "peer_ref": "tg-user:987" }, "message": { "id": "0f1a…", "text": "Дякуємо! Надішлю розрахунок сьогодні.", "sent_at": "…", "reply_to_ref": null, "attachments": [] }, "sender": { "name": "Анна Ковальчук" } } ``` - Supporter відповідає 2xx, коли прийняв повідомлення в роботу. У тілі може повернути ref (ідентифікатор у месенджері) і status (sent, delivered або read), якщо знає його одразу. - Далі про стан доставки Supporter повідомляє подією message.status за message.id з конверта. Агент бачить стан під своїм повідомленням: у черзі, надіслано, доставлено, прочитано, не доставлено. - Вкладення у відповідях агентів поки не надсилаються — композер скриньки приймає лише текст. --- ## Доступи, тарифи й безпека Шість ролей, винятки на учасника, правило «тариф і роль» та ізоляція даних на рівні бази. ### Ролі - Власник — бачить усе, зокрема налаштування організації. - Адміністратор — усе, крім налаштувань організації. - Фінансист — гроші, рахунки, документи; ставки й зарплати не бачить. - Керівник проєктів — проєкти, завдання, люди, години команди, маржа проєктів; операції по рахунках не бачить. - Виконавець — свої завдання й свої години. - Бухгалтер — операції, звірка, рахунки й документи. Роль можна уточнити винятком на конкретного учасника: додати або забрати окремий дозвіл, не вигадуючи нової ролі. Виняток переважає роль. > Ставки й зарплати доступні лише власнику й адміністратору. Це не налаштування за замовчуванням, а вимога до моделі доступу: фінансист веде гроші компанії, але не бачить, скільки отримує конкретна людина. ### Тариф і роль Доступ до можливості перевіряється двічі: чи входить вона у ваш тариф і чи дозволена вашій ролі. Обидві умови мають виконатись. Можливість, якої немає в тарифі, показується із замком і поясненням, що вона дає, — а не зникає мовчки. Перелік тарифів і те, що входить у кожен, — на сторінці цін. ### Ізоляція та аудит Дані організацій розділені на рівні бази даних політиками доступу до рядків, а не фільтром у коді застосунку. Запит, який спробує прочитати чужий рядок, не поверне його навіть за помилки в коді. Зміни фінансових даних — операцій, рухів по рахунках, ставок і рахунків клієнтам — пишуться в аудит-лог. Нічого не видаляється назавжди: замість видалення запис позначається видаленим і лишається в історії. ---