Telegram Desktop side-panel does NOT forward initData when WebApp is
opened via ReplyKeyboardButton.web_app. Resulting in empty initData
and falling back to client cabinet for everyone.
Inline-keyboard buttons (web_app inside the message) open the MiniApp
in modal mode where initData is correctly forwarded.
/start now sends two messages:
1. Welcome + reply-keyboard at bottom (works on mobile)
2. Inline-keyboard with role buttons (works on Desktop too)
Users.role теперь хранит CSV-список ролей: 'manager,measurer'.
Парсим, добавляем, отзываем — все через sheets.parse_roles / grant_role /
revoke_role / list_users_with_role. Старые однострочные значения работают
как раньше (legacy compat).
Backend:
- /api/me возвращает roles[] (массив), role (главная для legacy-UI),
plus capabilities {measurer, assembler} для staff
- /api/grant_role (admin-only) — добавить/отозвать роль
- /api/staff_list (manager-only) — список сотрудников по роли
(будет использоваться в dropdown «выбрать замерщика»)
- При role=staff отдаём отдельный кабинет; если у юзера нет measurer/
assembler — возвращаем error=no_staff_role
Bot:
- /start — 3-я reply-кнопка [🔧 Я сотрудник]. При тапе MiniApp получает
?role=staff и решает кабинет по capabilities.
- /whoami — сотрудник присылает свой Telegram ID, пересылает куратору
чтобы тот выдал роль через /api/grant_role.
MiniApp:
- renderStaff() — заглушка кабинета сотрудника с шапкой (имя, аватар,
список ролей) и пустым inbox («Пока пусто»). Если есть measurer —
быстрая кнопка «Сделать новый замер».
- При error=no_staff_role — экран с инструкцией как получить роль.
- CSS .staff-head / .staff-no-role.
Cache bust v=20260513f.
Bot: упрощён до одного шага — /start показывает 2 reply-кнопки
[👤 Я менеджер] [🏠 Я клиент], обе уже WebApp — открывают кабинет
сразу с нужным role= в query. Никаких промежуточных меню.
MiniApp: новый брендированный загрузочный экран с логотипом ZOV
(inline SVG, fill = walnut #6B4A2B), дыхательной анимацией 2.2s,
тонкой полоской прогресса и подписью «Открываем кабинет · ZOV».
Splash прячется (350мс минимум + fade-out) после рендера главного
экрана или маунта подэкрана (Podbor/Clients/Measurements).
Cache bust v=20260513c.
/start теперь показывает только две reply-кнопки внизу:
[👤 Я менеджер] [🏠 Я клиент]
Тап «Я менеджер» → меню менеджера (4 ряда):
🤖 Подбор техники | 📐 Новый замер ← WebApp
👥 Мои клиенты | 🏠 Кабинет ← WebApp
ℹ️ Что умеет бот?| 📞 Куратор ← текст
📋 Чек-лист встречи | ⬅️ Сменить роль ← текст
Тап «Я клиент» → меню клиента (3 ряда):
🏠 Мой кабинет | 📐 Мой замер ← WebApp
📞 Связь с менеджером | ℹ️ О сервисе ← текст
⬅️ Сменить роль
«⬅️ Сменить роль» в любом меню → возврат к выбору роли.
Заменён inline-keyboard на reply-keyboard (постоянная панель снизу).
Now after /start, manager sees a bottom keyboard (4 rows) for fast access:
Row 1: 🤖 Подбор техники | 📐 Новый замер ← WebApp
Row 2: 👥 Мои клиенты | 🏠 Кабинет ← WebApp
Row 3: ℹ️ Что умеет бот? | 📞 Куратор ← text
Row 4: 📋 Чек-лист встречи ← text
WebApp buttons jump straight to a MiniApp screen via ?go=<podbor|measure|clients>;
app.js parses ?go on load and pre-sets location.hash so the right module mounts.
Added /menu (re-show keyboard) and /hide (remove). Text buttons trigger
in-chat info responses (bot description, contact, meeting checklist).
Cache bust v=20260513b.