Замість клаптикової системи ми зробили єдину платформу клієнтського обслуговування і випустили її за три місяці з фіксованим обсягом робіт. Поділ традиційний і свідомий: публічний маркетинговий сайт, кабінет клієнта поверх API і внутрішні інструменти команди на розширеній адмінці там, де розширення доречне.
Публічний сайт — це маркетингова поверхня: серверний рендеринг для SEO, i18n там, де бізнес реально працює більш ніж однією мовою, без клієнтського JavaScript там, де достатньо серверної відповіді. Це найдешевша в експлуатації частина системи і перше, що бачить клієнт, тому саме сюди йде бюджет на полірування.
Кабінет клієнта — місце, де відбувається робота. Клієнт реєструється, потрапляє в авторизовану панель, заповнює профіль, відкриває заявку на послугу, завантажує супровідні документи, бачить, як оновлюється стрічка статусу, і спілкується з командою у гілці повідомлень, прив'язаній до заявки. Більше жодних "ви отримали мого листа?". Стан кожної заявки видно і клієнту, який її подав, і відповідальному співробітнику — в одному вигляді, в один і той самий момент.
Внутрішня адмінка — це back-office інструмент, розширений там, де розширення виправдане: користувальницькі списки з тими фільтрами, які команда справді застосовує, інлайн-дії для сортування й призначення, гілки коментарів на кожній заявці, заплановані роботи, прив'язані до картки клієнта, звіти, які співробітники витягують самі, не звертаючись до нас. Ми не будували окремий "операційний дашборд" як застосунок. Внутрішня адмінка, яку сприймали як повноцінну продуктову поверхню, закрила дев'яносто відсотків потреб команди.
Знизу лежить реляційна база даних зі схемою, спроєктованою під ті запити, що бізнес виконує насправді: часткові індекси на відкритих заявках, напівструктуровані колонки для специфічних для типу послуги полів, зовнішні ключі скрізь, де зв'язок реальний. Черга фонових задач виконує те, що не повинно блокувати запит: повідомлення електронною поштою та push про зміни статусу, нагадування про заявки без відповіді, нічні звіти, антивірусну перевірку завантажених документів.
Автентифікація сесійна і для команди, і для клієнтів — без токенів, що ходять навколо, без SaaS-постачальника автентифікації. Рольовий доступ розрізняє ролі команди (адмін, редактор, переглядач) і клієнта (власник акаунта, делегований користувач). Кожна дія, що змінює стан, записується в журнал аудиту з прив'язкою до користувача й заявки і доступна для запитів з адмінки. Пошук іде через повнотекстові індекси бази даних по всій історії клієнта, з обмеженням за роллю.
Постачальник платежів підключений для платних послуг, де він був потрібен, за тим самим фоновим воркером, щоб обробка webhook не блокувала потік запитів. Інтеграція досить узагальнена, щоб у майбутньому заміна постачальника була обмеженою зміною.