Sitemap
Дерево екранів. Кожен екран — тільки якщо за ним стоїть job. Роль: T тренер · A атлет · TA обидва.
AUTH — передумова для всіх jobs
TA
Реєстрація
prereq
S1
J1
вибір ролі; атлет вводить інвайт-код
TA
Вхід
SIROTA
auth infrastructure; виключений з job-матриці
Тренер [T] — Максим, primary persona
T
Мої атлети — огляд
J2
E1
└
T
Атлет — активність і фідбек
J2
└
T
Деталі тренування (тренер-вид)
J2
E1
E2
└
T
Залишити фідбек
J2
E2
T
Програми — список
J1
E1
S1
├
T
Конструктор програми
J1
└
T
Редактор дня / сесії
J1
└
T
Призначити програму атлету
J1
T
Запросити атлета (інвайт)
J1
S1
prereq
Атлет [A] — Оля, secondary #1
A
Сьогодні — план на день
J3
J1↓
└
A
Активне тренування / Логер
J4
J2↑
└
A
Завершення тренування
E2
J5
S2
A
Прогрес
J5
E2
S2
└
A
Історія тренувань
J5
S2
A
Харчування — сьогодні
J5
S2
└
A
Додати їжу
J5
S2
A
Записати замір тіла
J5
S2
Спільні [TA]
TA
Профіль / Налаштування
SIROTA
logout, пароль; bio тренера → S1 після рішення
User Flows
Mermaid flowchart TD · [екран] = sitemap · {рішення} · (стан) · ((кінець))
MAIN JOB · J3 + J4
Знати, що тренувати сьогодні, і залогувати виконання
Хто: атлет (Оля) · Частота: 3–5 разів на тиждень
flowchart TD
A(Запуск застосунку) --> B{"Автентифікований?"}
B -->|ні| C["Вхід"]
C --> B
B -->|так| D{"Підключений до тренера?"}
D -->|ні| E["Сьогодні — план на день"]
E --> F("Стан: немає тренера — введи інвайт-код")
F --> Z1(("Тупик: очікуємо інвайт від тренера"))
D -->|так| G("Завантажуємо план...")
G --> H{"Завантажено?"}
H -->|ні| I("Помилка мережі")
I --> J{"Повторити?"}
J -->|так| G
J -->|ні| Z2(("Тупик: немає з'єднання"))
H -->|так| K{"План на сьогодні є?"}
K -->|ні| L["Сьогодні — план на день"]
L --> M("Стан: план не призначено — чекаємо від тренера")
M --> Z3(("Тупик: чекаємо план"))
K -->|так| N["Сьогодні — план на день"]
N --> O("Тап — Почати тренування")
O --> P["Активне тренування / Логер"]
P --> Q{"Заповнив вагу і повтори?"}
Q -->|ні| R("Стан: поля порожні — кнопка неактивна")
R --> P
Q -->|так| S("Тап — Зберегти підхід")
S --> T{"Збережено?"}
T -->|ні| U("Помилка збереження підходу")
U --> V{"Повторити?"}
V -->|так| S
V -->|ні| Z4(("Тупик: дані підходу втрачено"))
T -->|так| W{"Останній підхід вправи?"}
W -->|ні| X("Таймер відпочинку")
X --> P
W -->|так| Y{"Остання вправа у тренуванні?"}
Y -->|ні| AA("Перехід до наступної вправи")
AA --> P
Y -->|так| AB("Тап — Завершити тренування")
AB --> AC["Завершення тренування"]
AC --> OK1(("Успіх: тренування залоговано"))
Рішення
- Підключений до тренера? — без інвайту план недоступний
- Завантажено? — мережева помилка; retry або тупик
- План на сьогодні є? — тренер підключений, план ще не призначено
- Заповнив поля? — inline validation, кнопка неактивна
- Збережено? — збій синхронізації; retry або втрата підходу
Стани
- Empty / немає тренера — інструкція «отримай інвайт»
- Empty / план не призначено — атлет чекає від тренера
- Loading — завантаження плану блокує UI
- Error / мережа — retry або кешований fallback
- Error / збереження підходу — retry або попередження
J1
Тренер створює і призначає план
Хто: тренер (Максим) · Коли: початок нового тижня або новий клієнт
flowchart TD
A(Вхід у застосунок) --> B["Мої атлети — огляд"]
B --> C("Тап — вкладка Програми")
C --> D["Програми — список"]
D --> E{"Є програми?"}
E -->|ні| F("Стан: список порожній")
F --> G("Тап — Створити програму")
E -->|так| G
G --> H["Конструктор програми"]
H --> I("Ввести назву і опис програми")
I --> J("Тап — Додати день / сесію")
J --> K["Редактор дня / сесії"]
K --> L("Ввести вправу: назва, сети, повтори, вага")
L --> M{"Ще вправи у цьому дні?"}
M -->|так| L
M -->|ні| N{"Ще дні у програмі?"}
N -->|так| J
N -->|ні| O("Тап — Зберегти програму")
O --> P{"Збережено?"}
P -->|ні| Q("Помилка збереження програми")
Q --> R{"Повторити?"}
R -->|так| O
R -->|ні| Z1(("Тупик: програму не збережено"))
P -->|так| S["Програми — список"]
S --> T("Тап — Призначити атлету")
T --> U["Призначити програму атлету"]
U --> V{"Є підключені атлети?"}
V -->|ні| W("Стан: немає жодного атлета")
W --> X["Запросити атлета (інвайт)"]
X --> Y{"Атлет прийняв інвайт?"}
Y -->|ні| Z2(("Тупик: чекаємо підключення атлета"))
Y -->|так| U
V -->|так| AA("Вибрати атлета зі списку")
AA --> AB("Вибрати дату початку")
AB --> AC("Тап — Підтвердити призначення")
AC --> AD{"Призначено?"}
AD -->|ні| AE("Помилка призначення")
AE --> AF{"Повторити?"}
AF -->|так| AC
AF -->|ні| Z3(("Тупик: план не призначено"))
AD -->|так| OK1(("Успіх: план призначено атлету"))
Рішення
- Є програми? — порожній список → одразу «Створити»
- Ще вправи? / Ще дні? — цикл побудови програми
- Збережено? — мережева помилка; retry або тупик
- Є підключені атлети? — invite flow якщо немає
- Призначено? — збій призначення; retry або тупик
Стани
- Empty / немає програм — порожній список
- Empty / немає атлетів — потрібний invite flow
- Error / збереження — мережа або validation
- Error / призначення — збій прив'язки до атлета
Nutrition
Атлет логує харчування
Хто: атлет · Частота: 3–4 рази на день
flowchart TD
A(Відкрив застосунок) --> B("Тап — вкладка Харчування")
B --> C("Завантажуємо записи за сьогодні...")
C --> D{"Завантажено?"}
D -->|ні| E("Помилка мережі")
E --> F{"Повторити?"}
F -->|так| C
F -->|ні| Z1(("Тупик: харчування недоступне"))
D -->|так| G["Харчування — сьогодні"]
G --> H{"Є записи за сьогодні?"}
H -->|ні| I("Стан: нічого не залоговано — показники нульові")
H -->|так| Jj("Підсумок: ккал / білки / жири / вуглеводи")
I --> K("Тап — Додати їжу")
Jj --> K
K --> L["Додати їжу"]
L --> M("Ввести назву страви")
M --> N("Ввести калорії")
N --> O{"Додати макроси?"}
O -->|ні| P("Тап — Зберегти")
O -->|так| Q("Ввести білки / жири / вуглеводи")
Q --> P
P --> R{"Збережено?"}
R -->|ні| S("Помилка збереження запису")
S --> T{"Повторити?"}
T -->|так| P
T -->|ні| Z2(("Тупик: запис страви втрачено"))
R -->|так| U["Харчування — сьогодні"]
U --> V("Оновлений підсумок: ккал і макроси додано")
V --> W{"Додати ще одну страву?"}
W -->|так| K
W -->|ні| OK1(("Успіх: харчування залоговано"))
Рішення
- Завантажено? — retry або тупик
- Є записи? — empty state перший запис дня
- Додати макроси? — лише ккал обов'язково
- Збережено? — retry або втрата запису
- Додати ще? — цикл без виходу з контексту
Стани
- Loading — денні записи при відкритті вкладки
- Empty — нульові показники + CTA «Додати»
- Error / мережа — не завантажились дані
- Error / збереження — не зберігся запис страви
J2 + E2
Тренер переглядає прогрес і залишає фідбек
Хто: тренер (Максим) · Коли: після тренування клієнта · Частота: кілька разів на тиждень
flowchart TD
A(Вхід у застосунок) --> B["Мої атлети — огляд"]
B --> C{"Є підключені атлети?"}
C -->|ні| D("Стан: список порожній — запроси першого атлета")
D --> E["Запросити атлета (інвайт)"]
E --> Z1(("Тупик: чекаємо підключення"))
C -->|так| F("Підсумок активності: хто тренувався, хто ні")
F --> G("Вибрати клієнта зі списку")
G --> H["Атлет — активність і фідбек"]
H --> I{"Є тренування без фідбеку?"}
I -->|ні| Jj("Стан: всі тренування вже прокоментовано")
Jj --> Z2(("Тупик: нема що переглядати"))
I -->|так| K("Завантажуємо деталі тренувань...")
K --> L{"Завантажено?"}
L -->|ні| M("Помилка мережі")
M --> N{"Повторити?"}
N -->|так| K
N -->|ні| Z3(("Тупик: дані клієнта недоступні"))
L -->|так| O("Вибрати конкретне тренування")
O --> P["Деталі тренування (тренер-вид)"]
P --> Q{"Дані виглядають коректно?"}
Q -->|ні| R("Стан: аномальні дані")
R --> S["Залишити фідбек"]
Q -->|так| S
S --> T("Написати текстовий коментар")
T --> U{"Коментар не порожній?"}
U -->|ні| V("Стан: поле порожнє — кнопка неактивна")
V --> T
U -->|так| W("Тап — Надіслати фідбек")
W --> X{"Фідбек збережено?"}
X -->|ні| Y("Помилка відправки")
Y --> Z{"Повторити?"}
Z -->|так| W
Z -->|ні| Z4(("Тупик: фідбек не надіслано"))
X -->|так| OK1(("Успіх: фідбек надіслано"))
Рішення
- Є підключені атлети? — empty без invite
- Є тренування без фідбеку? — empty якщо все прокоментовано
- Завантажено? — мережева помилка
- Дані коректні? — anomaly flag перед фідбеком
- Коментар не порожній? — кнопка неактивна
- Фідбек збережено? — retry або тупик
Стани
- Empty / немає атлетів — invite flow
- Empty / всі прокоментовано — нема дій
- Loading — деталі тренувань клієнта
- Anomaly — різкі зміни в даних
- Error / мережа — дані клієнта недоступні
- Error / відправка — фідбек не надіслано
Матриця трасування
Jobs × Екрани. ✓ — екран бере участь у закритті job. Стовпці без ✓ підсвічені червоним.
Job |
Реєстр |
Вхід ⚠ |
Атл-огляд |
Атл-фідбек |
Деталі-T |
Фідбек-T |
Програми |
Констр |
Редактор |
Признач |
Інвайт-T |
Сьогодні |
Логер |
Заверш |
Прогрес |
Історія |
Харчув |
Їжа+ |
Замір |
Профіль ⚠ |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AUTH + ТРЕНЕР [T] | ||||||||||||||||||||
| Mплан↔виконання | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||||||||
| J1тренер доставляє план | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |||||||||||||
| J2тренер бачить що сталося | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||||||||||||||
| J3атлет знає що сьогодні | ✓ | |||||||||||||||||||
| J4атлет фіксує підхід | ✓ | |||||||||||||||||||
| J5атлет бачить прогрес | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||||||||||||||
| E1контроль тренера | ✓ | ✓ | ✓ | ✓ | ✓ | |||||||||||||||
| E2зусилля видимі | ✓ | ✓ | ✓ | ✓ | ||||||||||||||||
| S1тренер виглядає профі | ✓ | ✓ | ✓ | |||||||||||||||||
| S2атлет відповідає цифрами | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||||||||||||||
Реєстр = Реєстрація
Атл-огляд = Мої атлети — огляд
Атл-фідбек = Атлет — активність і фідбек
Деталі-T = Деталі тренування (тренер-вид)
Фідбек-T = Залишити фідбек
Констр = Конструктор програми
Признач = Призначити програму атлету
Інвайт-T = Запросити атлета (інвайт)
Заверш = Завершення тренування
Харчув = Харчування — сьогодні
Їжа+ = Додати їжу
Замір = Записати замір тіла
Дефекти покриття
Екран-сирота #1
Вхід
Жоден job не формулює «увійти в систему» як людську мотивацію. Auth — prereq, не destination.
Визнати як infrastructure prereq і виключити з матриці. Логін-екран присутній у кожному продукті — це не дефект дизайну. Брендований вигляд побічно підсилює S1.
Екран-сирота #2 · [SIROTA]
Профіль / Налаштування
MVP Профіль = тільки logout і зміна пароля. Жодна людська мотивація з jtbd.md тут не закривається.
Додати поле bio тренера (1–2 речення), видиме підключеним атлетам → прив'язати до S1. Вартість: одне поле у формі. Сутність Trainer Profile вже має bio [?].
Single point of failure — не сироти, але критичний ризик
J3
Сьогодні — план на день
Єдиний екран що закриває J3. Якщо не відображає план — J3 повністю провалюється, 90% відтоку. Design priority #1.
J4
Активне тренування / Логер
Єдиний екран що закриває J4. Якщо Логер незручний — J4 мертвий, J2 порожній, петля ламається. Design priority #2.