§ 01О чём проектWhat this is
Компания на 4 500 человек, три отдела принимают заявки: IT, HR, АХО. У каждого — свой почтовый ящик и свой Bitrix24-pipeline. Сотрудник, у которого «не печатает принтер», должен сначала угадать, куда писать; потом написать письмо в свободной форме; потом ждать. A 4,500-person company, three departments accept requests: IT, HR, Facilities. Each has its own mailbox and its own Bitrix24 pipeline. An employee whose "printer won't print" first has to guess where to write, then compose a free-form email, then wait.
Корпоративный портал был — но им не пользовались. Долгая авторизация, форма из 14 полей, обязательное закрепление файла. There was a corporate portal — but nobody used it. Slow login, a 14-field form, mandatory file attachment.
Задача: сделать одну точку входа, доступную с телефона за секунду, на трёх языках, чтобы заявка попадала в правильный Bitrix24-pipeline уже с правильным тэгом и назначенным исполнителем. Goal: create a single entry point accessible from a phone in one second, in three languages, so that the request lands in the right Bitrix24 pipeline with the correct tag and assigned executor.
§ 02Дизайн UXUX Design
Главное правило: не больше четырёх нажатий от старта до поданной заявки. Это потолок, ниже которого сотрудник просто пишет письмо коллеге. The main rule: no more than four taps from start to submitted request. That's the ceiling — below it, the employee just emails a colleague.
- Шаг 1: выбор языка (запоминается)Step 1: language selection (remembered)
- Шаг 2: категория (4 кнопки)Step 2: category (4 buttons)
- Шаг 3: подкатегория (если нужна)Step 3: subcategory (if needed)
- Шаг 4: одно текстовое поле + опциональное фотоStep 4: one text field + optional photo
FSM реализуется через aiogram 3, состояния хранятся в Redis. Если сотрудник «потерял» бот на середине — state-recovery возвращает его на последний шаг, не начиная сначала. FSM is implemented via aiogram 3, states stored in Redis. If an employee "loses" the bot mid-flow — state recovery returns them to the last step without starting over.
§ 03Локализация без болиPainless localization
Три языка: узбекский (кириллица по умолчанию, латиница опционально), русский, английский. Не gettext: тут нет смысла, потому что строки короткие, переводы могут править non-tech люди. Three languages: Uzbek (Cyrillic by default, Latin optional), Russian, English. Not gettext — no point here since strings are short and translations can be edited by non-tech people.
Переводы лежат в Postgres-таблице с ключом (code, lang). HR-менеджер заходит в web-админку и правит формулировку «не работает интернет» на узбекском, не трогая код. Кэш в Redis на 5 минут.
Translations live in a Postgres table keyed by (code, lang). An HR manager opens the web admin and edits the Uzbek wording for "internet is down" without touching code. Redis cache with a 5-minute TTL.
§ 04Bitrix24 как тонкое местоBitrix24 as the bottleneck
Bitrix24 REST API — rate-limited, не идемпотентный, иногда отвечает 502 без объяснения причины. Прямые вызовы из handler'а — гарантированный путь к потерянным заявкам. Bitrix24 REST API is rate-limited, non-idempotent, and occasionally returns 502 with no explanation. Direct calls from the handler are a guaranteed path to lost requests.
Решение: outbox pattern. Handler пишет заявку в Postgres и кладёт событие CreateBitrixDeal в outbox-таблицу в той же транзакции. ARQ-worker подхватывает событие, идёт в Bitrix, обрабатывает 502 с экспоненциальным backoff. Если за 15 минут не удалось — алерт админу в Telegram.
Solution: outbox pattern. The handler writes the request to Postgres and places a CreateBitrixDeal event in the outbox table within the same transaction. An ARQ worker picks up the event, calls Bitrix, handles 502 with exponential backoff. If it fails for 15 minutes — an alert goes to the admin via Telegram.
§ 05ЦифрыNumbers
§ 06Что я вынесLessons learned
(а) Корпоративные пользователи — такие же люди, как остальные. Если интерфейс требует более 30 секунд — им воспользуется только тот, кому абсолютно необходимо. (a) Corporate users are people too. If the interface takes more than 30 seconds — only those who absolutely must will use it.
(б) Локализация на трёх языках — это не технический вопрос, это процесс. HR должен иметь возможность поменять формулировку без тикета на разработку. (b) Localization in three languages is not a technical question — it's a process. HR must be able to change wording without filing a development ticket.
(в) Внешние API — всегда тонкое место. Outbox + retry + алерт — скучные паттерны, которые ловят 100% инцидентов с Bitrix. (c) External APIs are always the bottleneck. Outbox + retry + alert — boring patterns that catch 100% of Bitrix incidents.