Skip to content

Структура даних ​

Прийнятий напрям · 5 жовтня 2026, ролі вирішено 11 жовтня 2026 · десять таблиць створено 11 жовтня 2026: користувачі, компанії, власники, магазини, зайнятості, запрошення, графіки, зміни, запити на зміни та елементи «Чекає на вас»; графіки, магазини й людей також редагують уручну, доки цього не робить асистент · описи магазинів і людей та погодинне навантаження магазину створено 14 жовтня 2026, їх поки ніщо не читає · перерви у змінах, шаблони змін і перевірку чергового керівника зроблено 14 жовтня 2026 · кілька змін на день в однієї людини (розділені зміни) зроблено 14 жовтня 2026 · причину при кожному відхиленні й те, хто схвалив зміну, зроблено 14 жовтня 2026 · людиночитні id замість UUID зроблено 15 жовтня 2026 · спільне ядро API зроблено 15 жовтня 2026, не розгорнуто: компанія стала командою з ролями, додано сесії входу, скидання пароля, API-ключі, передачу власності та чергу завдань, на Prisma 8 · id у спільному для всіх продуктів Agentfy вигляді (два слова, дванадцять символів) зроблено 15 жовтня 2026 · час початку перерви, кількість чеків на касира за годину й розрахунки для денного вигляду графіка та аркуша місяця зроблено 16 жовтня 2026, не розгорнуто · права керівника у своєму магазині й запис про те, хто змінював людей, запрошення та магазини, зроблено 19 жовтня 2026, не розгорнуто · керівник необов’язковий для працівника, щодо запитів такого працівника вирішує власник, перевірка чергового керівника — лише в магазині з керівником, а запити, що чекають на керівника, який іде, переходять власникові, створено 23 жовтня 2026, не розгорнуто · каталог посад у кожної команди, з якого посаду людини обирають замість уписаної вручну, створено 30 жовтня 2026, не розгорнуто · правила, прочитані в описі, зберігаються поруч із ним, збудовано 10 листопада 2026, не розгорнуто

Shiffty зберігав би все про магазин — людей, правила, графіки та запити на зміну — у власній базі даних, згрупованій за компанією та магазином; агент нічого не зберігає і щоразу отримує факти наново.

Людина — це одне, її місце в магазині — інше. Усе, що людина може бачити чи просити, випливає з цього місця, а не з самої людини.

Як це згруповано ​

Команда — це бізнес власника (до 15 жовтня 2026 — компанія), і вона має магазини. Магазин має керівників, працівників, правила, графіки та одного агента. Користувач — людина, яка може увійти; зайнятість — місце цієї людини в одному магазині, з роллю, і в зайнятості працівника вказано керівника, якому він підпорядковується. Схема — намір, а не набір таблиць:

text
team ────┬─ team_member (user, role owner|admin|member)
         ├─ position (name, description, active|archived)
         └─ store ─┬─ employment (user, role manager|employee, manager, position, hours, skills, status)
                   │     ├─ availability_rule / availability_exception / absence / preference
                   │     └─ agent_conversation (agentfy_conversation_id, grant)
                   ├─ store_rules, shift_template, coverage_requirement, traffic
                   ├─ schedule (period, draft|published, version)
                   │     ├─ shift (employment, date, start, end, template, origin)
                   │     └─ change_request (kind, status, proposal, colleague, decision)
                   ├─ agentfy_agent (agent_id, provisioning_id, status)
                   └─ invitation (name, email, role, link, expires, status)
user ─── inbox_item («чекає на вас»)

Що є що ​

ЩоОдним рядком
КомандаКлієнт: бізнес власника, з одним або кількома магазинами (до 15 жовтня 2026 — компанія)
Учасник командиЛюдина в команді з роллю в ній: її єдиний власник, адміністратор або учасник — усі, хто працює в її магазинах, учасники
ПосадаОдин запис власного списку посад команди («Касир», «Комірник»): назва, опис для асистента і чи її ще дають людям
Правила описуТе, що асистент прочитав в описі магазину, посади чи людини; зберігається, доки опис не зміниться (з 10 листопада 2026)
МагазинОдна торгова точка; майже все інше належить магазину
КористувачЛюдина, яка може увійти
ЗайнятістьМісце людини в одному магазині: керівник або працівник, керівник, якому підпорядковується працівник, посада зі списку команди, години за договором, навички і статус — запрошений, активний або неактивний
Правило доступності, виняток із доступностіКоли людина може працювати: регулярний порядок і разові зміни в ньому
ВідсутністьВідпустка чи хвороба: дні, на які людину ніколи не ставлять
ПобажанняЧого людина хотіла б; враховується, коли можливо
Правила магазинуГодини роботи, відпочинок, максимум годин, тривалість зміни, перерви
Шаблон зміниСтандартні зміни, з яких будується графік
Вимога до покриттяСкільки людей якої ролі потрібно кожної години
ВідвідуваністьНаскільки завантажений магазин за годинами і звідки взято цифру
ГрафікОдин період одного магазину, чернеткою або опублікований, з версією
ЗмінаОдна людина працює один відрізок одного дня — і хто її поставив: розв'язувач, керівник чи запит на зміну
Запит на змінуПро що просили, запропонована зміна, причетний колега, рішення і статус
Розмова з агентомЗв'язок однієї зайнятості з її чатом з агентом магазину і чинний дозвіл діяти
Запис про агента магазинуЯкий агент на Agentfy належить цьому магазину і чи він готовий
ЗапрошенняПропозиція ролі в магазині названій людині, з одноразовим посиланням, терміном дії і статусом
Запис «чекає на вас»Одна справа, яка чекає на одну людину
СесіяОдин пристрій, на якому людина увійшла: дає не входити знову й може бути завершена з боку сервера
Скидання пароляОдноразове посилання, надіслане листом, щоб вибрати новий пароль
API-ключКлюч, яким програма користується замість входу людини, для однієї команди, з тим, що їй дозволено
Передача власностіПропозиція власника передати команду іншому учасникові — доки її не приймуть або не скасують
ЗавданняРобота, яку API виконує у фоні, до терміну або за розкладом

Поля за командою, правилами та відвідуваністю перелічено у Вхідних даних; там це теж чернетка.

Правила, які важать ​

  • Користувач — це людина; зайнятість — місце цієї людини в одному магазині. Що вона може бачити й робити, визначає зайнятість — а для власника те, що він володіє командою.
  • Кожна людина має рівно одне місце (11 жовтня 2026): власник — свою команду, усі інші — один магазин. Списку команд чи магазинів, з якого треба вибирати в застосунку, немає.
  • Працівник підпорядковується керівникові того самого магазину або жодному. Керівник необов’язковий з 23 жовтня 2026 (рішення власника; до того працівник міг бути без керівника, лише поки в магазині не було керівників). Залишити працівника без керівника може лише власник; керівник переводить працівників свого магазину до іншого його керівника, але не «до жодного». Люди керівника — це зайнятості, у яких вказано його; керівники підзвітні власникові.
  • Керівники й працівники приєднуються лише за запрошенням від власника (або, з 15 жовтня 2026, адміністратора команди), яке надходить листом. З 19 жовтня 2026 керівник магазину теж запрошує працівників до свого магазину. Самі реєструються лише власники.
  • Доступ до агента дається за зайнятістю, а не за користувачем. Людина говорить з агентом того магазину, де працює, з правами своєї ролі там.
  • Команду пов'язано з командою Agentfy, а магазин — з агентом Agentfy власними ідентифікаторами Shiffty. Див. Інтеграцію з Agentfy.
  • Увесь стан живе в Shiffty. Графіки, запити й рішення зберігаються тут; агент щоразу отримує факти через інструменти, і Shiffty не покладається ні на що з того, що агент пам'ятає.
  • Облікові дані Agentfy живуть в оточенні API і ніколи — в базі даних.
  • Локальної заміни Agentfy більше немає (14 жовтня 2026, рішення власника). З 13 жовтня API міг сам грати Agentfy на машині розробника і зберігав операції, розмови, запуски, події та повідомлення цієї заміни в п'яти власних таблицях; міграція 20261016T1038_drop_fake_agentfy (16 жовтня 2026) їх видаляє. Таблиці справжньої інтеграції лишаються. Див. Інтеграцію з Agentfy.
  • Хто вирішує щодо запиту на зміну (11 жовтня 2026, з рішення, що кожен працівник має конкретного керівника): запит працівника йде його керівникові; якщо той ще не приєднався — будь-якому керівникові магазину. Працівник без керівника, працівник магазину без активного керівника і керівник надсилають запити власникові — з 23 жовтня 2026, коли керівник став необов’язковим; до того запит працівника без керівника йшов будь-якому керівникові магазину. Коли керівника деактивують, запити, що чекають на нього, переходять власникові, а якщо він був останнім активним керівником магазину — і ті, що чекають на будь-якого керівника. Тож у запиту завжди є хтось, хто щодо нього вирішує. Ніхто не вирішує щодо власного запиту.
  • Час — магазину. Магазин має часовий пояс (11 жовтня 2026). Години роботи, дата і час зміни — це годинник на стіні магазину; «сьогодні», поточний тиждень і те, який тиждень триває зараз, рахуються в часовому поясі магазину — ніколи не сервера і ніколи не того, хто дивиться. Години зміни — це час, який минає насправді, тож зміна в ніч переведення годинника на годину коротша або довша.
  • Дані працівників чутливі. Доступність, відсутності та причини, які називають люди, — особиста інформація. Де ці дані зберігаються і хто їх бачить, лишається відкритим питанням, яке треба вирішити до будь-якого пілоту.

Де це зберігатиметься ​

PostgreSQL на Neon, через Prisma — з 15 жовтня 2026 Prisma 8: схема лежить поруч із кожною частиною API, міграції написано на TypeScript. API в репозиторії налаштовано так; на машині розробника замість цього використовується локальний PostgreSQL.

Спільне ядро (15 жовтня 2026, SHIF-25; не розгорнуто). API тепер стоїть на тому самому ядрі, що й наші інші продукти: таблиці мають імена малими літерами, кожен час зберігається з часовим поясом, а компанія та її власник стали командою та її учасниками. Одна міграція перенесла всі наявні рядки в нові таблиці, зберігши всі id; секрети, запечатані старим ключем, — облікові дані агента, збережений контекст чату — перенести не вдалося, і вони видаються заново, коли знадобляться. Таблиці, які додало ядро:

  • Користувач — тепер ще з роллю на платформі (admin відкриває налаштування всієї платформи, це не роль у команді) і статусом.
  • Команда — бізнес власника: назва та статус.
  • Учасник команди — людина в команді: owner (рівно один), admin або member, і чи вона ще в ній, чи пішла. Усі, хто працює в магазинах команди, — її учасники; адміністратор може робити з людьми й запрошеннями команди те саме, що й власник, але не може передати команду.
  • Сесія — один пристрій, на якому увійшли. Вхід повертає короткочасний токен доступу і токен оновлення; кожне оновлення замінює токен оновлення, а повторне використання старого завершує всю сесію — отже, він є в когось іще. Вихід або новий пароль завершують сесії на сервері.
  • Скидання пароля — одноразове посилання на годину, надіслане листом; зберігається лише його відбиток.
  • API-ключ — для програми замість людини: одна команда, назва, що їй дозволено (поки що — читати команду), термін дії та коли ключ востаннє використали; зберігається лише відбиток, сам ключ показується один раз. Передача команди завершує ключі попереднього власника.
  • Передача власності — власник пропонує команду іншому учасникові; коли той приймає, він стає власником, а попередній — адміністратором.
  • Завдання — фонова робота, зберігається в базі, щоб кілька копій API не виконували її двічі: на ній працюють перезавантаження налаштувань і звіряння учасників з агентами.

З 11 жовтня 2026 існують десять таблиць, створених міграціями, і більше нічого з цієї сторінки. Шість із них замінюють п'ять таблиць від 6 жовтня (компанії з учасниками без ролі та працівники, які не могли увійти); тестові дані того часу видалено, як дозволив власник. Графіки та зміни додано того самого дня, потім запити на зміни та елементи «Чекає на вас». 14 жовтня 2026 додано таблицю погодинного навантаження магазину.

  • Користувач — ім'я, пошта й пароль, який зберігається лише як хеш. Запрошена людина не має пароля, доки не прийме запрошення.

  • Команда (до 15 жовтня 2026 — компанія) — бізнес власника: назва.

  • Учасник команди (до 15 жовтня 2026 — лише власник, як учасник компанії) — див. вище.

  • Магазин — магазин команди: назва, адреса, час відкриття і закриття (одне відкриття на день, закриття того самого дня), його часовий пояс (стандартна назва на кшталт Europe/London, обов'язковий), опис, порядок сортування і статус, active або inactive. Новий магазин стає в кінець списку власника. Опис (з 14 жовтня 2026) — простий текст до 4000 знаків, задуманий як контекст для майбутнього асистента: формат магазину, розташування, покупці, особливості; поки його ніщо не читає.

  • Погодинне навантаження магазину (14 жовтня 2026) — звичайна кількість чеків на касі за одну годину одного дня тижня в одному магазині: з понеділка по неділю, по одному значенню на кожен годинний слот від відкриття до закриття; слот називається за годиною початку (17 — це 17:00–18:00; неповна остання година — теж слот). Ціле число, нуль або більше; незаповнений слот невідомий і не зберігається. Значення поза поточними годинами роботи зберігаються, але не показуються, тож коли повернути попередні години, вони з'являються знову. З 16 жовтня 2026 їх читає денний вигляд графіка (нижче); прогнозу й досі немає, і графік за ними ніщо не будує. Поруч магазин зберігає кількість чеків на касира за годину (16 жовтня 2026): скільки чеків один касир пробиває за годину, ціле число від 1 до 10 000, 80, доки його не змінять; редагують її ті самі люди, що й погодинне навантаження. Один рядок на магазин, день і годину, а не один блок чисел на магазин — так сама база даних перевіряє кожне значення, а майбутній читач може спитати про одну годину.

  • Зайнятість — місце людини в одному магазині: керівник або працівник, керівник, якому підпорядковується працівник (керівника з іншого магазину відхиляє сама база даних), посада зі списку команди (до 30 жовтня 2026 — уписана вільним текстом, див. Посада нижче), години за договором на тиждень, опис і статус, invited, active або inactive. Одна на людину. Навичок поки що немає. Опис (з 14 жовтня 2026) — простий текст до 4000 знаків, задуманий як контекст для майбутнього асистента: сильні сторони, навички, обмеження; поки його ніщо не читає. Бачать його лише ті, хто може його змінювати: власник і керівник — для працівників свого магазину. Людина ніколи не бачить власного опису (рішення про приватність, ухвалене під час розробки, чекає підтвердження власника; див. відкриті питання).

  • Посада (30 жовтня 2026, на прохання власника) — один запис власного списку посад команди, який заповнює власник: назва до 100 знаків, єдина в команді без урахування регістру й пробілів по краях («Касир» і « касир» — одна посада), необов'язковий опис до 2000 знаків — контекст для асистента, як і в людини, — і статус, active або archived. Один список на весь бізнес, спільний для всіх його магазинів (відповідь власника того ж дня). Додає, перейменовує, описує й архівує посади лише власник; керівники й працівники читають активні. Видалення немає: архівну посаду не дають нікому новому, і вона лишається в тих, хто її має. Людина має одну посаду або жодної; її обирають зі списку й ніколи не вписують — у запрошенні та у вікні людини. Інструменти асистента для людей віддають посаду кожної людини з її описом, а розв'язувач передає агентові опис посади один раз, разом із людьми, які її мають, так само як опис людини. Уписані раніше посади збережено: коли з'явився список, різні непорожні посади кожної команди стали її активними посадами — пробіли по краях прибрано, те саме слово в різному регістрі пораховано один раз, у написанні, яке зберегла більшість, — кожній людині дано її посаду, а поле з вільним текстом видалено. Порожня посада не дала жодної.

  • Правила опису (10 листопада 2026, на прохання власника) — для одного опису, магазину, посади чи людини: правила, які асистент у ньому прочитав, кожне зі словами, з яких його взято, або «правил немає» з причиною, і відбиток тексту, з якого їх прочитали. Один запис на опис, замінюється під час кожного нового збереження; правила, чий відбиток не збігається з нинішнім текстом опису, застаріли й перечитуються перед наступним планом. API ніколи не пише їх сам: у ньому немає мовної моделі (Агент і розв'язувач).

  • Запрошення — до команди й одного з її магазинів, для названої людини та пошти, на роль керівника або працівника, з терміном дії сім днів і статусом: очікує, прийняте або відкликане (з 15 жовтня 2026 — revoked); прострочене показується як прострочене. Зберігається лише відбиток (хеш) посилання. З 15 жовтня 2026 посилання надсилається листом і, як і раніше, один раз показується тому, хто запросив, — щоб передати, якщо лист не дійшов; повторне запрошення тієї самої адреси замінює те, що очікує. Запрошення створює людину та її зайнятість зі статусом invited; прийняття задає пароль, робить зайнятість active, а людину — учасником команди; відкликання знову видаляє запрошену людину.

  • Графік — тиждень одного магазину, з понеділка до неділі (замість «періоду» зі схеми — тиждень, і версії немає), чернетка або опублікований, з короткою приміткою на кшталт «Made by hand · not sent yet» і моментом публікації. Один на магазин і тиждень.

  • Зміна — одна людина в один день тижня графіка: час початку й кінця, ділянка (торговий зал, каса або черговий керівник) і хто її поставив (демо-дані, керівник, запит або асистент). Людина має працювати в магазині графіка, і нічого іншого не прийме сама база даних. Зміна має вкладатися в години роботи магазину й закінчуватися після початку, тож через північ зміна не йде. З 14 жовтня 2026 людина може мати кілька змін в один день — розділені зміни, наприклад 12:00–14:00 і 18:00–20:00, — до трьох, і зміни однієї людини в один день не можуть перетинатися: одна закінчується о 14:00, наступна починається о 14:00 — так можна. Перетин не прийме сама база даних; межа в три зміни — правило API. З 14 жовтня 2026 зміна має й перерву у хвилинах — від 0 до 180, кроком 5, коротшу за саму зміну; наявні зміни її не мають. З 16 жовтня 2026 перерва може мати й час початку: тоді вся перерва, від початку на її хвилини, має лежати всередині зміни, а зміна без перерви початку не має — інше відхиляє API, а початок поза зміною не прийме сама база даних. Перерва без початку — це «час не задано», як у всіх перерв до цього дня; екрани пишуть «1 h break 13:00–14:00», де час відомий. Схвалена зміна годин зберігає початок перерви, доки перерва вміщується в новий час, інакше початок скидається; під час обміну він переходить разом зі зміною.

  • Шаблон зміни (14 жовтня 2026) — іменована заготовка зміни магазину, наприклад «Ранок 06:00–10:00» чи «День 09:00–18:00 · перерва 60 хв»: назва, початок і кінець, перерва, ділянка або без неї та місце у списку магазину. До десяти на магазин, під час збереження — у годинах роботи магазину. Це лише заготовка: зміна, зроблена з неї, копіює значення й не зберігає посилання на шаблон, тож зміна чи видалення шаблону не змінює жодної зміни. Якщо години магазину потім зміняться, шаблон, що опинився поза ними, зберігається, позначається й не пропонується, доки його не виправлять. З 16 жовтня 2026 перерва шаблону теж може мати час початку, за тим самим правилом, що й у зміни, і зміна із шаблону його копіює.

  • Запит на зміну — прохання однієї людини змінити одну зі своїх змін у своєму магазині: вид (вихідний, вихідний із заміною, обмін, інші години), саму зміну як структуровану пропозицію — прибрати зміну, віддати її колезі, зсунути її час або обміняти дві зміни, щоразу зі зміною такою, якою вона була в момент прохання; вихідний і вихідний із заміною стосуються дня, тож у день із кількома змінами запит бере кожну з них (14 жовтня 2026), а обмін та інші години стосуються однієї зміни, — колегу, якого запитали (якщо є), і його відповідь, хто вирішує (конкретний керівник, будь-який керівник магазину або власник), заголовок, рядок-підсумок, слова самої людини, позначку («Covered», «Fits rules», «No overtime», «Needs a call», «No cover»), рядки перевірок, хто, коли і як вирішив — людина, автоматично або, пізніше, асистент, — а для відхилення — названа причина (14 жовтня 2026). Статус іде так: чекає на колегу → чекає на рішення → схвалено або відхилено; поки запит чекає, людина може його відкликати (відкликано, із моментом відкликання). «Зараз» і «Якщо схвалити» обчислюються з пропозиції й не зберігаються. У начерку запит належить графіку; створений належить магазину і може охоплювати два тижні (обмін).

  • Елемент «Чекає на вас» — одне, що чекає на відповідь однієї людини: прохання колеги замінити чи обмінятися (пов'язане із запитом) або опублікований тиждень власних змін, який треба підтвердити. Зберігає відповідь і коли її дано. У начерку він належить користувачеві; створений належить зайнятості.

Що відбувається із запитом. Запит, якому потрібен колега, спершу чекає на нього. Колега може відмовитися без пояснень; тоді запит закінчується як відхилений, і ніхто щодо нього не вирішував, а працівник бачить це в «Моїх запитах». Що відбувається далі, не спроєктовано, тож більше нічого не створено. Запит, який ніхто не закриває, іде одразу тому, хто вирішує. Схвалення заново перевіряє зміни й змінює їх одним кроком, усе або нічого: якщо зміни вже не ті, про які був запит, або тепер порушиться правило, нічого не змінюється, і тому, хто вирішує, повідомляється, що графік змінився. Відхилення нічого не змінює в графіку і завжди пояснюється (правило власника, 14 жовтня 2026): керівник або власник пише причину від 3 до 500 символів, працівник бачить її у своєму запиті, а скасування відхилення її стирає. Колезі, який відмовився, причина й далі не потрібна. Кожне рішення каже, хто його ухвалив (правило власника, 14 жовтня 2026): записується, чи вирішила людина — і хто саме, — чи рішення було автоматичним або асистента, а запит, списки запитів, схвалені зміни в графіку, діалог зміни та «Мої зміни» показують «Approved by Daniel Okafor» або «Approved automatically». Зараз кожне рішення ухвалює людина: ніщо не схвалюється автоматично, і асистент нічого не вирішує; два інші способи записуються, щоб таке рішення, коли воно з'явиться, ніколи не показувалося як чиєсь. Рішення, ухвалені до 14 жовтня 2026, вважаються рішеннями людини, якщо її записано, інакше — автоматичними. Рішення можна скасувати, поки тиждень не закінчився: скасування схвалення повертає зміни як були і не проходить, якщо їх відтоді знову змінювали.

Перевіряє поки не асистент. У демо-запитах рядки перевірок слово в слово з прототипів. Запит, створений через API, отримує власні фіксовані перевірки API: у годинах роботи, щонайменше 11 годин відпочинку (від останньої зміни одного дня до першої зміни наступного; перерва всередині розділеного дня відпочинком не вважається), години за тиждень проти договору, жодних перетинів з іншими змінами людини того дня і не більше трьох змін на день, той самий магазин — і з 14 жовтня 2026 попередження, якщо схвалення залишить частину годин роботи дня без чергового керівника там, де зараз він є («Approving leaves no manager on duty on Wed, Oct 21, 16:00–20:00»). Рядки рахуються, коли запит створено, і зберігаються з ним; під час рішення їх наново не рахують. За ними немає ні розв'язувача, ні правил покриття; асистент, який писав би ці рядки, з'явиться пізніше.

Чи триває тиждень зараз чи минув, не зберігається. Це випливає з дат і сьогоднішнього дня магазину: тиждень, неділя якого скінчилася, минув; опублікований тиждень, до якого входить сьогодні, триває; пізніший опублікований чекає; чернетка лишається чернеткою, доки її тиждень не скінчиться. Години зміни — відпрацьовані години: кінець мінус початок мінус перерва (14 жовтня 2026); години дня — сума його змін. Їх використовує все, що рахує години: тиждень людини проти договору, попередження й перевірки запитів про години за тиждень, підсумки тижня, магазину й людини та те, що повертають інструменти асистента (до 19 жовтня 2026 — також тексти демо асистента). Понаднормові людини за тиждень — години понад її години за договором. Хто не має годин за договором, не має й понаднормових.

Черговий керівник на всі години роботи (14 жовтня 2026). Для кожного дня тижня — відкритим вважається кожен день, бо магазин має один час роботи на всі дні — зміни на ділянці черговий керівник разом мають покривати години роботи магазину; перерви не враховуються, бо людина в магазині. API знаходить непокриті відрізки за годинником магазину й віддає їх разом із тижнем власникові та керівникам («Tue: no manager on duty 06:00–08:00, 20:00–22:00»). Це лише попередження: через нього нічого не відхиляється, зокрема публікація, — принцип власника, що правила тут підказують, а не забороняють. Рахується ділянка зміни, а не роль людини: ділянка каже, хто відповідає за цей відрізок, тож керівник на касі не рахується, а будь-хто, кого поставили на ділянку чергового керівника, рахується. Цей вибір наш, власникові його ще підтвердити. З 23 жовтня 2026 перевірка діє лише в магазині з активним керівником: магазин, який власник веде сам із працівниками, не показує прогалин (замість прогалини щодня), його запити не отримують попередження про чергового керівника, а розв’язувач не планує там чергування. Це теж наш вибір, власникові його ще підтвердити.

Розрахунки денного вигляду (16 жовтня 2026). Для кожного годинного слоту кожного дня тижня — тих самих слотів, що й у погодинного навантаження — API віддає разом із тижнем чотири числа по всьому магазину, хоч би що відфільтрував екран: звичайну кількість чеків у цей день тижня й годину (невідоме лишається невідомим); потрібно кас — чеки, поділені на кількість чеків на касира й округлені вгору, не менше однієї, поки магазин відкритий, і невідомо, якщо невідомі чеки; скільки людей на касі — у змінах ділянки «каса» — і скільки на зміні взагалі. Люди рахуються в людино-годинах: людина входить у годину тією частиною, яку вона там перебуває (зміна з 09:30 дає 0,5 у годині 09:00), мінус частина перерви з відомим початком, що потрапила в цю годину. Перерва без заданого початку не віднімається ніде, тож ця людина вважається присутньою всю зміну, а день каже, скільки в ньому таких перерв. Числа округлюються до одного знака після коми, а година, у якій на касі менше людей, ніж потрібно кас, позначається. Це правило підрахунку наше, власникові його ще підтвердити. Воно лише показує: через нього нічого не відхиляється й нічого не планується.

Аркуш місяця (16 жовтня 2026). Для календарного місяця API віддає кожен тиждень із понеділка по неділю, що його зачіпає, — від чотирьох до шести — з його статусом (опублікований, чернетка або графіка немає); рядок на кожну людину, як у тижні, з її змінами по днях і схваленими змінами; і для кожної людини лише в межах календарного місяця: зміни, відпрацьовані години, вихідні — дні в тижні з графіком, у які вона не має зміни, — і договір для порівняння: години на тиждень × днів у місяці ÷ 7, тож тиждень, який місяць покриває лише частково, рахується за своїми днями в ньому (жовтень 2026: 31 день, 4,43 тижня). Це правило наше, власникові його ще підтвердити. Місяць лише для читання; його бачать власник і керівники магазину, працівник — ні.

Що показує API. Тижні магазину, один тиждень у вигляді однієї сітки всіх, кого може бачити той, хто питає, — спершу керівники, потім працівники, у кожного рядка роль людини, кому вона підпорядковується і чи може той, хто питає, його редагувати (14 жовтня 2026; до того працівники й керівники були двома окремими сітками), — де день людини показує всі його зміни, з намальованими на них запитами, тиждень, до якого входить сьогодні, власні зміни людини та години «цього тижня» для магазинів і людей. З кожним тижнем він віддає й дні без чергового керівника, а для кожного магазину — його шаблони змін (лише власникові та керівникам магазину). Для демо асистента за сценарієм (видалено із застосунку 19 жовтня 2026; відтоді його не викликає жоден екран) API також відповідає, лише для читання, які колеги могли б узяти одну зі змін того, хто питає, — підмінити (заміна бере кожну зміну того, хто питає, того дня, і взяти її може колега, який того дня працює в інші години) чи обмінятися на одну зі своїх змін того самого тижня (пропонується лише для дня з однією зміною, бо обмін переносить одну зміну) — з тими самими фіксованими перевірками, що й запит, без попереджень. Працівник бачить свої зміни лише в опублікованих тижнях. Керівник бачить графіки свого магазину, власник — графіки всіх магазинів.

Редагування вручну ​

Власник вирішив 11 жовтня 2026, що згодом кожна зміна йтиме через асистента, а доки асистента немає, кожну зміну має бути можливо зробити й уручну. Усе описане нижче створено (11 жовтня 2026, не розгорнуто) — це і є той тимчасовий захід: асистент має перебрати ці дії на себе за тими самими правилами.

  • Хто редагує графіки. Власник редагує кожен рядок тижнів будь-якого магазину — і працівників, і керівників. Керівник редагує лише працівників свого магазину: рядки керівників — власника, тож власні зміни керівника йдуть власникові запитами. Рядки керівників керівник бачить лише для перегляду, як і до однієї сітки. Працівник не редагує нічого. Людина з іншої компанії або працівник отримує «не знайдено»; керівникові на рядку керівника кажуть, що це графік власника.
  • Тижні. Тиждень створюють порожнім або копією попереднього (кожна зміна на тиждень пізніше); копія керівника переносить лише зміни працівників. Публікація — одна дія для всього тижня, для керівників і працівників однаково. Люди, які пішли, і зміни поза сьогоднішніми годинами роботи до копії не потрапляють. Тиждень редагують, поки він чернетка, і публікують один раз (момент публікації записується). Опублікований або поточний тиждень ті самі люди й далі можуть редагувати. Минулий тиждень змінити не можна.
  • Зміни. Зміну додають, змінюють або видаляють у сітці тижня: людина — це рядок, день — стовпець; змінюються час, перерва — і, якщо треба, час її початку — і ділянка. Пропонуються шаблони змін магазину: вибраний шаблон заповнює час, перерву й ділянку, які ще можна змінити, а порожній день можна заповнити шаблоном у два кліки. День людини показує всі його зміни, кожна відкривається окремо, і пропонує ще одну — зокрема із шаблону, — доки в дні менше трьох змін. Діють ті самі правила, що й скрізь, у часовому поясі магазину: у годинах роботи, усередині тижня, людина працює в магазині, до трьох змін на день, що не перетинаються. Менше 11 годин відпочинку й більше годин, ніж за договором, показуються як попередження й не заважають. Усе, що записано вручну, позначається як поставлене керівником, правки власника теж.
  • Зміна з відкритим запитом заблокована. Поки запит щодо неї чекає на колегу чи на рішення, її не можна змінити чи видалити; рішення або відкликання запиту її звільняє. Тож рішення ніколи не натрапить на зміну, яка непомітно змінилася під ним.
  • Запити вручну. Працівник — і керівник, для своїх змін, — створює запит через форму: одна з його змін на цьому чи наступному тижні, що йому потрібно (вихідний, заміна колегою, обмін на зміну колеги того самого тижня, інші години) і необов'язкова причина, що зберігається як його власні слова. Вихідний і заміна беруть кожну зміну цього дня, і форма про це каже. Пропонуються активні колеги магазину з тією самою роллю. Запит проходить ті самі перевірки й те саме правило, хто вирішує, що й раніше. Запит можна відкликати, доки щодо нього не вирішили: у графіку нічого не змінюється, відкрите прохання до колеги зникає, а запит зникає зі списку того, хто схвалює, і з лічильників.
  • Шаблони змін (14 жовтня 2026). Власник — для будь-якого магазину, керівники магазину — для свого додають, змінюють, переставляють і видаляють його шаблони (до десяти) у розділі «Shift templates»: на сторінці магазину у власника, у «Графіках» у керівника. Працівникові дивитися нічого.
  • Магазини. Власник редагує назву, адресу, години роботи, часовий пояс, статус і опис магазину; з 19 жовтня 2026 (рішення власника) керівники магазину теж редагують його години роботи й опис, і більше нічого в ньому. Погодинне навантаження редагують власник і керівники магазину, бо вони знають його відвідуваність (14 жовтня 2026, чекає підтвердження власника), і вони ж — кількість чеків на касира за годину поруч із ним (16 жовтня 2026). Нові години не приймаються, якщо хоч одна поточна чи майбутня зміна опинилася б поза ними, і зміни, що заважають, називаються. За нового часового поясу кожна зміна зберігає свій час за годинником — 08:00 лишається 08:00, уже в новому поясі.
  • Люди. Власник редагує посаду людини, години на тиждень, керівника (керівника того самого магазину, як вирішено 11 жовтня 2026) і статус. Керівник редагує посаду й години на тиждень тих, хто йому підпорядковується; з 19 жовтня 2026 (рішення власника) також керівника — іншого керівника того самого магазину — і статус будь-якого працівника свого магазину, але ніколи керівника й ніколи свій власний, а ще запрошує працівників до свого магазину й відкликає ці запрошення. Опис (14 жовтня 2026): власник пише його для будь-якого керівника чи працівника, зокрема під час запрошення; керівник — для будь-якого працівника свого магазину, але не для керівників і не для себе; усе інше API відхиляє. Роль і магазин уручну не змінюються. Якщо зробити людину неактивною, її історія лишається: зміни до сьогодні та запити зберігаються. Її зміни після сьогодні спершу перелічуються й видаляються лише після підтвердження власника. Це не проходить, поки щодо однієї з цих змін відкрито запит, а для керівника — поки йому ще хтось підпорядковується. Посади (30 жовтня 2026): власник веде список команди на People → Positions — додає посаду, змінює її назву чи опис, архівує її й повертає назад; посаду людини потім обирають з активних, або жодної. Керівник обирає її для тих, хто йому підпорядковується, як раніше змінював посаду, і не може додавати чи змінювати посади.
  • Хто змінив (19 жовтня 2026). Кожна зміна людини, запрошення чи магазину — власником або керівником, на екрані чи пізніше через асистента — записується: хто, його роль, вид зміни (деактивовано, знову активовано, новий керівник, запрошено, відкликано, змінено) і назви змінених полів, але ніколи не їхні значення. З 30 жовтня 2026 записується й кожна зміна посади (додано, змінено, архівовано, повернуто). На екрані цей запис поки ніщо не показує.

Їх ніде не розгорнуто; див. Що створено.

Ідентифікатори ​

Кожен запис, на який може послатися людина чи партнер, має читабельний id, і цей id — його первинний ключ (15 жовтня 2026, SHIF-26; не розгорнуто): store-calm-rivers-k8m4p2d7n9x3, а не 0b5c…-…. Другого id поруч немає: читабельний і є ключем рядка, і всі посилання на нього використовують його.

Форма — префікс – прикметник – іменник – дванадцять символів, лише малі ASCII, одна в усіх продуктах Agentfy з 15 жовтня 2026 (SHIF-28; формат нижче). Префікс каже, що це за запис: це ім'я моделі запису в схемі бази даних, повністю, малими літерами, слова через дефіс, без скорочень (15 жовтня 2026, SHIF-27; правило одне для всіх продуктів Agentfy). До SHIF-27 частина префіксів були скороченнями (org, emp, sched, tmpl, req та інші); одна міграція замінила кожен із них повним ім'ям і залишила решту кожного id — слова й символи — як була. Виняток один: слово Organization пишеться org (24 жовтня 2026, SHIF-40, рішення власника для всіх продуктів Agentfy), тож у OrganizationConversation префікс org-conversation; міграція 20261024T1456_org_id_prefixes перейменувала наявні id organization-…, теж зберігши решту кожного id. Id organization-… більше не розпізнається: запис за ним просто не знаходиться.

ЗаписМодельПрефікс
Команда (до 15 жовтня 2026 — компанія)Teamteam
Учасник командиTeamMemberteam-member
КористувачUseruser
МагазинStorestore
ЗайнятістьEmploymentemployment
ЗапрошенняTeamInvitationteam-invitation
ГрафікScheduleschedule
ЗмінаShiftshift
Шаблон зміниShiftTemplateshift-template
Погодинне навантаженняStoreHourlyLoadstore-hourly-load
Запит на змінуChangeRequestchange-request
Елемент «Чекає на вас»InboxIteminbox-item
НалаштуванняSettingsetting
Розмова з агентомOrganizationConversationorg-conversation
Повідомлення чатуOrganizationChatMessageorg-chat-message
СесіяAuthSessionauth-session
Скидання пароляPasswordResetpassword-reset
API-ключTeamApiKeyteam-api-key
Передача власностіTeamOwnershipTransferteam-ownership-transfer
ЗавданняJobjob
Правила описуDescriptionRuledescription-rule

Останні п'ять з'явилися з ядром API (15 жовтня 2026, SHIF-25).

  • Слова — для людей, а не для унікальності. Вони беруться зі списків пакета human-id версії 4.1.3 (ліцензія MIT) як є — 200 прикметників і 300 іменників, однакових в усіх продуктах Agentfy. Останні дванадцять символів випадкові: їх вибирає nanoid 3.3.11 (MIT) з криптографічного джерела серед 32 літер і цифр, які не сплутати (немає i, l, o, u): 60 біт, близько 76 разом зі словами. За мільйона записів одного виду новий id збігається з наявним приблизно один раз на 10¹⁷.
  • Унікальність забезпечує база. Первинний ключ не прийме повтор; тоді API вибирає новий id і записує знову, до п'яти разів. Id вибирає API один раз, під час створення запису, і він не змінюється; у ньому немає імені, дати, ролі чи секрету.
  • Префікс може містити дефіси, тому id ніколи не ріжеться по дефісах, щоб його знайти. API порівнює початок id зі списком префіксів, спочатку найдовші: store-hourly-load-… — це погодинне навантаження магазину, а не магазин.
  • API перевіряє вид кожного переданого id. Адреса магазину з id зайнятості всередині або щось, що зовсім не id, отримує 400 ще до пошуку. Правильний за формою id однаково проходить звичайні права: чужий магазин виглядає так само, як неіснуючий.
  • Записи, створені до 15 жовтня 2026, отримали нові id однією міграцією, яка переписала всі посилання на них, зокрема всередині збереженої пропозиції запиту. Id, що вже залишили Shiffty, збережено: компанія, магазин, зайнятість чи власник, яких Agentfy знає за id, чат, чий збережений контекст запечатано його id, і запит, зроблений через асистента. У цих небагатьох лишається попередній UUID, і він і далі приймається; новим записам UUID не видається. Стара адреса з переписаним UUID тепер нічого не знаходить.
  • Перейменування SHIF-27 змінило префікс кожного id зі старим префіксом, зокрема тих, які Agentfy вже знав. Продакшну в Shiffty немає, такі id були лише в локальних базах; Agentfy (або, до 14 жовтня 2026, його локальна заміна) і далі знає такий запис за старим id. Для локальної бази шлях назад — make seed. Контекст розмови, запечатаний старим id, скинуто.
  • Компанія стала командою (15 жовтня 2026, SHIF-25), тож префікси пішли за перейменованими моделями: міграція ядра перетворила company-…, company-member-… і invitation-… на team-…, team-member-… і team-invitation-… — у кожному id і в кожному посиланні на нього, так само, як це зробив SHIF-27, і залишила решту кожного id. Як і там, власні записи Agentfy та відтворюваний запит провіжинінгу залишено як були, а локальна база, підключена до Agentfy, скидається через make seed.
  • Не змінено: те, як речі називає Agentfy (id його команди, агента й чату), ключі, що роблять повторний виклик безпечним (idempotency keys), записи аудиту, видані доступи та облікові дані агента зберігають свої ідентифікатори.

Формат id ​

Зроблено 15 жовтня 2026 (SHIF-28), не розгорнуто · один формат в Agentfy, Bonsite, Securify, Shiffty і Store Deputy, за правилом власника від 15 жовтня 2026

ЧастинаЩо це
Форма<prefix>-<adjective>-<noun>-<suffix>, наприклад user-calm-rivers-k8m4p2d7n9x3
Префіксповне ім'я моделі в kebab-case, слово Organization пишеться org, з таблиці вище
Прикметник, іменникпо одному слову зі списків adjectives і nouns пакета human-id 4.1.3, малими; без дієслів і прислівників, без власних слів; слово з чимось, крім a–z, було б виключене (у 4.1.3 таких немає)
Суфіксрівно 12 символів із 0123456789abcdefghjkmnpqrstvwxyz (base32 Крокфорда малими)
Випадковістькриптографічна: crypto.randomBytes, суфікс — через customRandom пакета nanoid 3.3.11
Версіїhuman-id 4.1.3 і nanoid 3.3.11, закріплені точно в api/package.json
Деapi/src/slices/setup/id/domain/idFormat.ts: formatId, isCanonicalId, isLegacyId, LEGACY_ID_FORMATS

Нові id створюються лише в цьому вигляді, функцією formatId, і ніщо не створює id інакше. API приймає переданий id у цьому вигляді — з префіксом свого запису й обома словами зі списків — або в одному з попередніх виглядів Shiffty, які він лише читає:

Попередній вигляд (LEGACY_ID_FORMATS)ПрикладВидавався
префікс – прикметник – іменник – шість символів, із власними списками слів Shiffty (human-id без 13 прикметників і 6 іменників, idWords.ts)store-calm-rivers-k8m4p215 жовтня 2026, SHIF-26 і SHIF-27, до SHIF-28
UUID, збережений міграцією SHIF-260b5c…-…до 15 жовтня 2026

Уже видані id не переписуються: старий і далі працює, новий запис отримує новий вигляд. Вигляд із дієсловом, із суфіксом іншої довжини чи з шістнадцяткових цифр, зі словом не зі списків отримує 400, якщо це не один із попередніх виглядів вище.

Та сама перевірка в усіх продуктах: за джерела, що віддає байти 0, 1, 2, … по черзі, formatId('user', source) дорівнює user-afraid-swans-nmkjhgfedcba. Спершу вибирається прикметник, потім іменник (кожен — за одним чи двома байтами, прочитаними як число, обрізаними маскою до потрібної списку кількості біт і вибраними заново, якщо поза діапазоном), потім суфікс (19 байтів одним запитом, nanoid читає їх з останнього).

Не вирішено ​

  • Де розміщено дані працівників і хто яку їх частину може бачити.
  • Як довго зберігаються запити, рішення та старі графіки.
  • Чи зможе людина згодом працювати більш ніж в одному магазині, а керівник — вести кілька, і що тоді станеться з правилом «одна людина — один агент».
  • Вирішено 20 жовтня 2026: власник має власного агента, одного на компанію, з ключем за id компанії; його розмова називає власника за id користувача, а не за зайнятістю (Інтеграція з Agentfy). Не вирішено: що відбувається з розмовою власника, коли компанія переходить до іншого власника.
  • Законні правила перерв і зміни через північ: ні те, ні інше поки не можна зберегти. Коли припадає перерва, зберегти можна з 16 жовтня 2026, але ніщо її не пропонує.
  • Чи потрібен мінімальний проміжок між змінами одного дня (зараз його немає), чи правильна межа в три зміни на день і чи може людина взяти вихідний лише на частину розділеного дня (зараз вихідний і заміна беруть увесь день).
  • Чи рахувати в перевірці чергового керівника ділянку (як зараз) чи роль людини, чи може магазин бути зачинений у деякі дні (зараз відкритим вважається кожен день) і чи перераховувати перевірки запиту під час рішення.
  • Чи рахувати понаднормові за тиждень відносно годин за договором (як зараз) чи за іншим правилом, наприклад за граничною тривалістю із закону.
  • Як довго зберігаються вирішені й відкликані запити та відповіді в «Чекає на вас» (відповіді поки зникають зі списку через сім днів) і чи можуть інші запити змінювати більше однієї зміни (вихідний і заміна розділеного дня вже змінюють).
  • Чи має копія тижня в керівника переносити й зміни керівників, що означає неактивний магазин для його графіків і чи може людина перейти до іншого магазину чи на іншу роль (уручну зараз не можна).
  • Скільки триває вхід. Вхід власний у Shiffty (вирішено 6 жовтня 2026): хеші паролів і, з 15 жовтня 2026, сесії — у цій базі; терміни — 15 хвилин для токена доступу і 30 днів для сесії без використання — це типові значення ядра, а не вибір власника. Див. Екрани.

Куди далі ​