← Повернутися до блогу
7 листопада 2025 р.

З Excel на телефон: як ми створили Kalendarz Lekarza Stażysty

FlutterМобільний ДодатокCase StudyМедицинаFirebaseApp StoreGoogle Play

Десь у Польщі молодий лікар саме планує наступні 13 місяців свого післядипломного стажування — з телефону. Рік тому цей самий лікар сидів би над Excel-файлом, день за днем зафарбовуючи комірки і сподіваючись, що макроси все правильно порахують.

Це історія Kalendarz Lekarza Stażysty — мобільного додатку, який ми збудували в Otocolobus, щоб замінити застарілу Excel-систему для польських лікарів-стажистів. Додаток працює на iOS та Android, і щомісяця ним користується близько 1000 лікарів.

Ось як це було.

Проблема: таблиця, яка нікому не подобалась

У Польщі кожен випускник медичного університету повинен пройти структуроване післядипломне стажування (staż podyplomowy), перш ніж зможе практикувати самостійно. Стажування триває 13 місяців і включає часткові стажування з різних спеціальностей — внутрішня медицина, хірургія, педіатрія, гінекологія, невідкладна допомога та інші — кожне з визначеним обсягом часу, який встановлює регіональна лікарська палата (Izba Lekarska).

Роками інструментом для планування цих стажувань був Excel-файл, напханий макросами. Робота виглядала так: відкриваєш сітку днів і вручну зафарбовуєш кожну комірку, щоб позначити спеціальність — один колір на внутрішню медицину, інший на хірургію, ще інший на педіатрію і так далі. Коли весь графік розмальований, макроси зчитували кольори комірок і підраховували, чи тривалість кожного часткового стажування відповідає вимогам.

На папері він працював. На практиці — це було пекло.

Інтерфейс був абсолютно неінтуїтивний. Молоді лікарі — більшість із яких бачила цей файл уперше в житті — мусили самотужки розбиратися, який колір відповідає якій спеціальності, як правильно його наносити і як читати результат макросів. Ніякого онбордингу, жодної легенди, яка б одразу мала сенс. Просто райдужна таблиця і надія на краще.

Ручне зафарбовування було нормою, а помилки — повсякденністю. Неправильний колір на одній комірці, випадкове перетягування, що зафарбувало цілий тиждень, або пропущений день у блоці — цього вистачало, щоб збити весь розрахунок. Макроси слухняно підсумовували те, що знаходили — сміття на вході, сміття на виході. Лікарі виявляли, що графік не сходиться, через тижні — іноді вже після початку стажування, яке виявилося коротшим або довшим за вимоги. Виправлення означало повернення до таблиці, пошук неправильного кольору комірка за коміркою і перемальовування — часто з нуля.

Файл працював тільки на комп'ютері. Лікар, який хотів глянути свій графік дорогою до лікарні, мав надіслати собі файл на пошту або зробити скріншот. Поділитися планом із колегами чи керівником стажування означало пересилати Excel-файли туди-сюди електронкою.

Це була система, збудована інженерами для інженерів — не для завантажених лікарів, яким потрібна швидка і надійна відповідь на запитання «Де я маю бути в понеділок?»

Рішення: чому Flutter?

Коли ми взялися за проєкт, потрібно було випустити додаток на iOS та Android малою командою і в стислі терміни. Це одразу звузило вибір.

Ми обрали Flutter з кількох причин.

По-перше — один кодбейс на обидві платформи. При команді нашого розміру підтримка окремих кодових баз на Swift і Kotlin була нереальною. Flutter дав нам один кодбейс, що компілюється у нативну продуктивність на обох платформах — без компромісів у швидкості чи відчутті інтерфейсу.

По-друге — додаток за своєю природою локальний. Графіки лікарів — це персональні дані, які не потребують спільного бекенду. Все живе на пристрої, що радикально спростило архітектуру. Жодних акаунтів, жодної бази на сервері, жодного API для підтримки. Це також вирішило питання приватності — графіки стажувань лікарів ніколи не покидають їхній телефон.

По-третє — віджетна система Flutter дозволила нам зручно побудувати інтерфейс навколо календаря, який відчувається нативно на обох платформах. Екран планування — серце всього додатку — мав бути настільки інтуїтивним, щоб лікар міг у ньому розібратися без жодної інструкції. Саме в цьому була вся ідея: замінити щось заплутане на щось очевидне.

Ми використовуємо Firebase Analytics, щоб розуміти патерни використання та знаходити точки тертя, але сам додаток після встановлення працює повністю офлайн.

Архітектура: навмисно проста

Одним із найкращих рішень було те, що ми вирішили не будувати.

Немає бекенд-сервера. Немає шару API. Немає автентифікації користувачів. Немає хмарної бази. Додаток — самодостатній.

Ось як виглядає архітектура:

┌─────────────────────────────────┐
│        Додаток Flutter          │
│                                 │
│  ┌───────────┐  ┌────────────┐  │
│  │ Інтерфейс │  │   Двигун   │  │
│  │ календаря │  │ стажувань  │  │
│  └─────┬─────┘  └─────┬──────┘  │
│        │              │         │
│  ┌─────▼──────────────▼──────┐  │
│  │  Локальне зберігання      │  │
│  │         даних             │  │
│  └───────────────────────────┘  │
│                                 │
│  ┌───────────────────────────┐  │
│  │    Firebase Analytics     │  │
│  └───────────────────────────┘  │
└─────────────────────────────────┘

Двигун стажувань обробляє всю логіку планування, яка раніше жила в макросах Excel — тривалість кожної спеціальності, законодавчі вимоги, розрахунки дат, виявлення конфліктів. Тільки замість того, щоб покладатися на те, що користувач сам усе правильно введе, додаток веде його крок за кроком і валідує дані на льоту. Неможливий графік створити не вийде — додаток просто не дасть.

Локальне зберігання даних означає миттєву відповідь. Жодного спінера в очікуванні відповіді від сервера. Відкриваєш додаток — бачиш графік. Усе.

Firebase Analytics — єдиний зовнішній сервіс. Він показує нам, якими функціями лікарі реально користуються, де відвалюються і що викликає труднощі. Цей зворотний зв'язок безцінний для ітерацій над UX.

Що ми винесли з цього досвіду

Починай із болю, а не з технології. Ми не йшли будувати Flutter-додаток. Ми йшли полагодити зламаний процес. Технологічні рішення випливали з обмежень — дві платформи, маленька команда, бекенд не потрібен, офлайн-перш за все. Кожне архітектурне рішення диктувалося проблемою, а не тим, що гарно виглядає в портфоліо.

Проста архітектура — це перевага, а не компроміс. Можна було легко все ускладнити. Акаунти! Хмарна синхронізація! Спільні календарі! Соціальні функції! Тільки от нічого з цього не було потрібно. Лікарі хотіли одного: надійного способу спланувати свої часткові стажування, не воюючи з таблицею. Чим простіша архітектура — тим менше того, що може зламатися. А для додатку, яким лікарі планують своє медичне навчання, надійність важливіша за кількість фіч.

Валідація перемагає документацію. Стара Excel-система мала документацію (десь). Ніхто її не читав. Наш додаток не потребує документації, бо запобігає помилкам у реальному часі. Кожне поле валідується, кожен конфлікт сигналізується одразу, а інтерфейс робить правильний шлях очевидним. Ця одна зміна — від «зафарбуй комірки і сподівайся, що макроси все порахують» до «додаток проведе тебе за руку» — зробила найбільшу різницю.

Аналітика — не опція. Firebase Analytics не коштує нам нічого, але дає все, що потрібно для усвідомлених рішень щодо продукту. Ми знаємо, що лікарі найактивніше користуються додатком у певні пори року (коли стартують нові цикли стажування), і точно знаємо, які екрани спричиняють найбільше труднощів. Без цих даних ми б стріляли наосліп.

Результати

Додатком користується близько 1000 лікарів щомісяця — на iOS та Android. Для контексту — це суттєва частка всіх лікарів-стажистів у Польщі в конкретному році.

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

Витрати на інфраструктуру — фактично нуль. Жодних серверів, жодної бази, жодного щомісячного рахунку від AWS. Єдина постійна стаття витрат — плата за Apple Developer Program та безкоштовний рівень Firebase.

Коли будувати просто

Не кожен проєкт має бути настільки мінімалістичним. Наша платформа аналітики реального часу для логістичного клієнта використовує ECS, DynamoDB Streams, CloudFront і повний стек AWS — бо та задача цього вимагала.

Але Kalendarz Lekarza Stażysty нагадує: найкраща архітектура — та, що розв'язує проблему з мінімальною складністю. Таблицю з макросами замінив мобільний додаток із локальним зберіганням і нульовим бекендом. Лікарі задоволені, кількість помилок впала, а о третій ночі нас ніщо не будить.

Іноді найрозумніша інженерія — знати, що не треба будувати.


В Otocolobus ми створюємо рішення, що відповідають задачі — чи то безсерверний мобільний додаток, чи то повномасштабна AWS-платформа. Маєте робочий процес, застряглий у таблицях, і хочете подивитися, як може виглядати сучасне рішення? Напишіть нам.