Інвентаризація об’єктів з якими людина має справу щоб закрити свої jobs. Джерело: CLAUDE.md, jtbd.md, research.md. Де поле лише припускається — [?]. Сутність без жодного job — секція «Під питанням», не тут.
Поля:
id — унікальний ідентифікаторemail — логінpassword_hashrole — trainer |
athlete (незмінна після реєстрації) |
created_atJob: передумова для всього — без аккаунту немає жодного job. Пов’язана з: Профіль тренера або Профіль атлета (1:1 через role).
Поля:
user_id (FK → User Account)name — повне ім’яbio [?] — короткий опис для майбутньої сторінки профілюavatar_url [?]Job: J1 — тренер надсилає план; J2 — тренер бачить що сталося; E1 — відчуття контролю. Пов’язана з: User Account · Trainer-Athlete Connection · Training Program · Trainer Feedback.
Поля:
user_id (FK → User Account)name — повне ім’яavatar_url [?]birth_date [?] — для розрахунків [?]height_cm [?]Job: J3 — атлет бачить план сьогодні; J4 — логує підхід; J5 — бачить прогрес. Пов’язана з: User Account · Trainer-Athlete Connection · Workout Log · Nutrition Log · Body Progress Entry · Personal Record.
Два об’єкти в одному потоці: спочатку Інвайт (одноразовий), потім стала Connection.
Invite Code / Link:
code — короткий унікальний рядок (генерує тренер)trainer_id (FK → Trainer Profile)expires_at [?] — чи є термін діїused_by — athlete_id після активаціїstatus — pending |
used |
Connection:
trainer_id (FK → Trainer Profile)athlete_id (FK → Athlete Profile)connected_atstatus — active |
archived [?] |
Job: Передумова для J1 і J2 — без зв’язку тренер не може надіслати план, не бачить даних атлета. Пов’язана з: Trainer Profile · Athlete Profile · Training Program · Trainer Feedback.
Шаблон, який тренер будує і призначає атлету. Містить тижневий розклад.
Поля:
idtrainer_id (FK → Trainer Profile)name — назва програми (напр. «Силовий цикл — осінь»)description [?]duration_weeks [?] — скільки тижнів програма розрахованаscheduled_days — масив днів тижня [S, M, T, W, T, F, S], підтверджено: Pushr pill-row patternassigned_to — athlete_id (FK → Athlete Profile) — в MVP 1 програма : 1 атлет [?] або 1:N [?]assigned_atstatus — draft |
active |
completed [?] |
Job: J1 — тренер складає і доставляє план; J3 — атлет бачить що треба сьогодні. Пов’язана з: Trainer Profile · Athlete Profile · Workout Session · Workout Log.
Один тренувальний день всередині програми. Містить список вправ з цільовими параметрами.
Поля:
idprogram_id (FK → Training Program)day_of_week — mon |
tue |
… або порядковий номер |
week_number [?] — якщо програма диференціює тижні (тиждень 1 vs тиждень 2)name [?] — напр. «День A — жим», «Ноги»notes [?] — загальні нотатки тренера до дняorder — порядок у програміJob: J1 (структурний будівельний блок плану); J3 (що показується атлету сьогодні). Пов’язана з: Training Program · Planned Exercise · Workout Log.
Базовий довідниковий запис. Може бути спільним або тренером-власним.
Поля:
idname — назва («Присідання зі штангою», «Жим лежачи»)video_url [?] — YouTube / URL; підтверджено: Future Pro єдиний конкурент з цим (BM)description [?] — текстова інструкціяcreated_by [?] — trainer_id (власна) або null (системна/загальна)muscle_groups [?] — теги груп м’язівПримітка MVP: Чи є глобальний каталог або тренер просто вводить назву вправи inline — [?] відкрите рішення. Мінімум для MVP: тренер вводить назву тексту + необов’язковий відео-посилання.
Job: J3 — атлет бачить назву і може відкрити відео; J1 — тренер конструює план. Пов’язана з: Planned Exercise · Set Log.
Інстанція вправи всередині Workout Session з цільовими параметрами. Відрізняється від Set Log — це план, не факт.
Поля:
idsession_id (FK → Workout Session)exercise_id (FK → Exercise) або exercise_name inline [?]target_sets — ціль кількість підходівtarget_reps — ціль повторень (або діапазон: «8–12»)target_weight_kg [?] — може бути порожнє для вправ з власною вагоюrest_seconds [?] — час відпочинку між підходамиnotes — нотатки тренера до вправиorder — порядок у сесіїJob: J1 і J3 — саме це бачить атлет як «план сьогодні». Пов’язана з: Workout Session · Exercise · Set Log.
Факт виконання атлетом конкретної Workout Session. Контейнер для Set Logs.
Поля:
idathlete_id (FK → Athlete Profile)session_id (FK → Workout Session) — прив’язаний до плану або null для «вільного» тренування [?]date — дата виконанняstarted_at [?] — час початкуcompleted_at [?] — час завершенняstatus — in_progress |
completed |
athlete_note [?] — нотатка атлета після тренування (самопочуття, коментар)Job: J2 — тренер бачить факт виконання; J4 — атлет логує підходи (через Set Logs); E2 — зусилля атлета стають видимими. Пов’язана з: Athlete Profile · Workout Session · Set Log · Trainer Feedback.
Один записаний підхід всередині Workout Log. Найатомарніша одиниця виконання.
Поля:
idworkout_log_id (FK → Workout Log)planned_exercise_id (FK → Planned Exercise) або exercise_name inline [?]set_number — номер підходу (1, 2, 3…)actual_reps — скільки зробивactual_weight_kg — яка вага (0 для власної ваги)rpe [?] — оцінка складності (1–10), Rate of Perceived Exertionnote [?] — короткий коментар до підходуlogged_at — timestampЦе ключова сутність J4. Саме сюди йде введення між сетами.
Job: J4 — атлет фіксує підхід за секунди; J2 — тренер бачить реальні дані; J5 — основа для розрахунку PR і графіків прогресу. Пов’язана з: Workout Log · Planned Exercise · Exercise · Personal Record (обчислюється з цих даних).
Async текстовий коментар тренера до тренування або до тижня.
Поля:
idtrainer_id (FK → Trainer Profile)athlete_id (FK → Athlete Profile)linked_to — workout_log_id (до конкретного тренування) або week_ref (дата тижня) — обидва варіанти в CLAUDE.mdtext — текст коментаряcreated_atread_at [?] — чи атлет переглянув (для notification badge)Job: J2 — тренер відповідає по суті (не «ну як?»); E2 — атлет відчуває що зусилля бачать; S2 — розмова про результат, а не виправдання. Пов’язана з: Trainer Profile · Athlete Profile · Workout Log.
Контейнер для всіх записів харчування за один день.
Поля:
idathlete_id (FK → Athlete Profile)dateJob: J4-суміжне (логування їжі аналогічно логуванню підходу — ручне введення); J5 — макрос-графіки в динаміці; підтверджено: Lifesum/Garmin/Noom — manual entry норма (Г3). Пов’язана з: Athlete Profile · Nutrition Entry.
Один прийом їжі або продукт всередині дня.
Поля:
idnutrition_day_id (FK → Nutrition Day Log)name — назва страви / продукту (вільний текст)calories_kcalprotein_gfat_gcarbs_gmeal_type [?] — breakfast |
lunch |
dinner |
snack |
logged_atJob: та сама логіка що J4 — ручне введення з мінімальною фрикцією; підтверджено: макро-прогрес-бари Lifesum (П3). Пов’язана з: Nutrition Day Log.
Виміри тіла атлета в певний момент часу.
Поля:
idathlete_id (FK → Athlete Profile)dateweight_kg — вага тіла (основне поле)waist_cm [?] — обхват талії (опціонально)chest_cm [?] — обхват грудей (опціонально)hips_cm [?] — обхват стегон (опціонально)photo_url [?] — nice-to-have в MVP (CLAUDE.md)note [?]Примітка: Виміри [?] позначені — їхня корисність для тренера не підкріплена jobs (jtbd.md: «жоден job не каже “тренер переглядає обміри”»). Вага тіла — так (J5). Сантиметри можна відкласти.
Job: J5 — атлет бачить динаміку ваги в часі (прогрес-графік). Пов’язана з: Athlete Profile.
Максимальна вага або кількість повторень для конкретної вправи, зафіксована атлетом.
Тип: обчислюваний або кешований.
Поля (якщо Варіант Б):
athlete_id (FK → Athlete Profile)exercise_id / exercise_namemax_weight_kg — максимальна вага за 1 підхідmax_reps_at_weight [?] — повтори при цій вазіachieved_at — дата і лог підходу де це сталосяJob: J5 — «місяць тому я піднімав менше» — PR є прямим доказом прогресу. Пов’язана з: Set Log · Exercise · Athlete Profile.
Trainer Profile ──────────── Training Program
│ │
│ (через Connection) ├── Workout Session
│ │ │
Athlete Profile ─────── ──── ──── │ Planned Exercise ── Exercise
│ │ │
├── Workout Log ─────────────┘ Set Log
│ │ │
│ └── Trainer Feedback (агрегат → PR)
│
├── Nutrition Day Log
│ └── Nutrition Entry
│
└── Body Progress Entry
Trainer-Athlete Connection (Invite Code → Connection)
links: Trainer Profile ↔ Athlete Profile
enables: усі потоки вище
Ці об’єкти або не мають підтвердженого job, або MVP свідомо обходить їх.
| Об’єкт | Чому під питанням |
|---|---|
| Ціль атлета (Goal) | CLAUDE.md згадує «goals» в athlete view, але жоден job не формулює «хочу поставити ціль». Може бути полем в Athlete Profile (goal_weight_kg [?]), не окремою сутністю. |
| Глобальний каталог вправ | MVP може обійтись inline-назвою вправи в полі тексту. Повноцінний каталог з пошуком — складність без підтвердженого job; тренер просто вводить «Присідання». |
| Нотифікація (Notification) | CLAUDE.md: «in-app notification badges, no real push». Потребує або лічильника (simple: computed з unread feedback) або окремої таблиці. Механізм, не first-class entity. |
| Тренувальний тиждень (Week) | Структурна одиниця всередині Program. Може бути просто week_number на Workout Session, а не окрема таблиця. |
| Фото-прогрес (Photo) | CLAUDE.md: nice-to-have. Немає підтвердженого job окрім J5 (підтип). Поле photo_url в Body Progress Entry вистачає для MVP. |
| Пошук тренерів / Маркетплейс | Свідомо виключено — MVP використовує invite code. З’явиться тільки з post-MVP потребою. |
| Ачівки / Бейджи | Design direction: «light gamification». Жоден job не вимагає. Не будувати в MVP. |
| Пресети харчування (Nutrition Presets) | CLAUDE.md згадує «presets» поряд з manual entry. Що саме — [?]. Можливо збережені попередні записи, а не окрема сутність. |
Виведено з jobs, не з «так роблять усі». Кожен пункт глобальної навігації = вхід у job-кластер.
Навігація різна для двох ролей — вони відкривають продукт з різною метою і мають різні головні екрани. Одна нижня панель з умовним рендерингом по role.
┌─────────────────────────────────────────────────────┐
│ [Сьогодні] [Харчування] [Прогрес] │
└─────────────────────────────────────────────────────┘
| Пункт | Job | Логіка вибору |
|---|---|---|
| Сьогодні | J3 · J4 | Атлет відкриває продукт щоб знати що робити зараз і одразу логувати. Це головний щоденний кластер — home tab. |
| Харчування | nutrition · J5 | Логування їжі — окремий ритм (не прив’язаний до тренування), своя частота (3–4 рази на день). Заслуговує окремого входу. |
| Прогрес | J5 · S2 | Атлет перевіряє прогрес рідше (раз на тиждень / після плато). Тут же: історія тренувань, PRs, замір тіла, фідбек тренера. |
Чому не 4 або 5 пунктів:
┌─────────────────────────────────────────────────────┐
│ [Атлети] [Програми] [Профіль] │
└─────────────────────────────────────────────────────┘
| Пункт | Job | Логіка вибору |
|---|---|---|
| Атлети | J2 · E1 | Тренер відкриває продукт щоб знати хто тренувався, хто ні, кому залишити фідбек. Це щоденний home — список клієнтів з останньою активністю. |
| Програми | J1 | Побудова і призначення планів — другий за частотою кластер. Не щодня, але регулярно (новий цикл, зміна програми). |
| Профіль | [SIROTA + Connection prereq] | Тут живе «Запросити атлета» (генерація інвайту) — рідкісна, але критична дія. Також: вихід, налаштування. Профіль заслуговує таба у тренера більше ніж у атлета, бо містить invite flow. |
Чому не більше:
Main job: відкрити застосунок → зрозуміти що тренувати сьогодні (вправу, сети, повтори, вагу) → залогувати виконання.
Launch app
│
▼ (0 тапів)
┌────────────────────────────────────────┐
│ Сьогодні — план на день │ ← J3 ЗАКРИТО тут
│ Жим лежачи · 4×8 · 80 кг │ (0 тапів)
│ Тяга верхнього блока · 3×12 · 55к│
│ [Почати тренування] │
└────────────────────────────────────────┘
│
│ тап 1: «Почати тренування»
▼
┌────────────────────────────────────────┐
│ Активне тренування │
│ Жим лежачи — Підхід 1 / 4 │
│ Ціль: 8 повт · 80 кг │
│ [ Факт: ___ повт ] [ ___ кг ] │
│ [Зберегти підхід] │
└────────────────────────────────────────┘
│
│ тап 2: «Зберегти підхід»
▼
J4 ЗАКРИТО. Перший сет залоговано.
Результат: 0 тапів до J3 · 2 тапи до J4
2 тапи — в межах норми. J3 закривається на landing screen без жодного тапу — це найважливіший архітектурний вибір. Якби «Сьогодні» не було home tab, а атлет мусив би навігувати до нього, J3 коштував би +1 тап і відтік зростав.
Атлет: bottom nav → Сьогодні · Харчування · Прогрес
Тренер: bottom nav → Атлети · Програми · Профіль
Обидва: header icon → Профіль / аватар (атлет), нотифікація-badge
[Атлет]
«Почати тренування» → на екрані Сьогодні, якщо є план на сьогодні
«Зберегти підхід» → в Активному тренуванні, після кожного сета
«Наступна вправа» → в Активному тренуванні, між вправами
«Завершити тренування» → в Активному тренуванні, після останнього сета
«Додати їжу» → FAB / кнопка на екрані Харчування
[Тренер]
«Залишити фідбек» → в картці конкретного тренування атлета
«Призначити програму» → в картці атлета або в деталях програми
«Запросити атлета» → в Профілі (не в nav, але доступно)
«Зберегти програму» → в Конструкторі програм (inline action)
[Атлет]
Записати замір тіла → всередині Прогресу, secondary action
Переглянути старе тренування → Прогрес → Історія → деталь
Змінити пароль / вийти → Профіль (хедер-іконка)
[Тренер]
Редагувати програму → Програми → список → деталь → edit
Генерувати інвайт-код → Профіль → «Запросити атлета»
Архівувати атлета [?] → всередині картки атлета, secondary action
| Дія | Роль | Тапів від home | Job |
|---|---|---|---|
| Побачити план сьогодні | Атлет | 0 | J3 |
| Залогувати перший підхід | Атлет | 2 | J4 |
| Додати їжу | Атлет | 2 (Харчування → Додати) | nutrition |
| Переглянути PRs | Атлет | 1 (Прогрес → одразу видно) | J5 |
| Побачити хто тренувався | Тренер | 0 | J2 · E1 |
| Переглянути конкретне тренування | Тренер | 2 (Атлети → клієнт → тренування) | J2 |
| Залишити фідбек | Тренер | 3 (Атлети → клієнт → тренування → фідбек) | J2 |
| Створити програму | Тренер | 2 (Програми → Створити → Builder) | J1 |
| Запросити нового атлета | Тренер | 2 (Профіль → Запросити) | Connection |
Фідбек = 3 тапи — єдина критична дія що перевищує 2. Компроміс: фідбек залишається на 3 тапах, бо він є відповіддю на перегляд тренування (тренер повинен ПОБАЧИТИ дані перш ніж коментувати — 2 тапи виправдані). Альтернатива — «швидкий фідбек» прямо з огляду клієнта (1 тап) — може бути додана якщо підтвердиться що тренер коментує не переглядаючи деталі.
Виведено з того що людина намагається зробити, не з конкурентних патернів. Job у дужках → посилання на jtbd.md. Немає job → [SIROTA]. Empty/error — це стани екрана, не екрани. Глибина мінімальна — рівні додаємо на кроці 3.
[T] — потрібен primary-персоні (Максим, тренер)
[A] — потрібен secondary-персоні (Оля, атлет)
[TA] — потрібен обом
Реєстрація [TA] [prereq · Connection]
├── гілка: тренер (вибір ролі)
└── гілка: атлет (вибір ролі → ввести інвайт-код)
Вхід [TA] [prereq]
Примітка: реєстрація — один екран з двома гілками після вибору ролі. Інвайт-код для атлета — частина цього ж флоу, не окремий екран.
Тренер відкриває продукт щоб: знати що відбувається з клієнтами (J2) і надіслати наступний план (J1).
Мої атлети — огляд [T] (J2 · E1)
└── Атлет — активність і фідбек [T] (J2)
└── Деталі тренування (тренер-вид) [T] (J2)
└── Залишити фідбек [T] (J2 · E2)
Програми — список [T] (J1)
├── Конструктор програми [T] (J1)
│ └── Редактор дня / сесії [T] (J1)
└── Призначити програму атлету [T] (J1)
Запросити атлета (інвайт) [T] (J1 prereq · Connection)
Головний екран тренера: «Мої атлети — огляд» — відкривається першим після входу. Тренер бачить всіх клієнтів, останню активність, кому ще не залишив фідбек. Закриває E1 (контроль, не хаос) і є точкою входу в J2.
Атлет відкриває продукт щоб: знати що робити сьогодні (J3) і записати підхід між сетами (J4).
Сьогодні — план на день [A] (J3) ← головний екран атлета
└── Активне тренування / Логер [A] (J4)
└── Завершення тренування [A] (E2)
Прогрес [A] (J5)
└── Історія тренувань [A] (J5 · S2)
Харчування — сьогодні [A] (nutrition · J5)
└── Додати їжу [A] (nutrition)
Записати замір тіла [A] (J5)
Головний екран атлета: «Сьогодні» — відкривається першим після входу. Атлет бачить програму на сьогодні без будь-якого пошуку. Це J3; якщо цей екран не спрацьовує — 90% відтоку.
Профіль / Налаштування [TA] [SIROTA]
Профіль — жоден з визначених jobs не вимагає окремого екрана профілю. Потрібен як технічна оболонка (вийти, змінити пароль), але не обслуговує жодну людську мотивацію з jtbd.md. Мінімізувати; не вкладати зусилля.
| Відсутній екран | Чому |
|---|---|
| Пошук / каталог тренерів | MVP = invite code. Маркетплейс — post-MVP. |
| Чат з тренером | Out of MVP (CLAUDE.md). Фідбек = async текст до тренування. |
| Нотифікації — окремий екран | Notification badge — механізм, не destination. Badge на іконці, не сторінка. |
| Налаштування харчування / цілі | Goal entity під питанням (jtbd.md). Немає підтвердженого job. |
| Список вправ / бібліотека | Exercise catalog — під питанням (jtbd.md). MVP = inline ввід назви. |
| Onboarding tour / welcome screen | Немає підтвердженого job. Перший реальний екран = головний (Сьогодні / Мої атлети). |
Матриця покриття: jobs × екрани. ✓ — екран бере участь у закритті job. Порожньо — не бере.
Ціль: жодного порожнього рядка і стовпця.
AUTH і ТРЕНЕР [T]
| № | Скор | Повна назва |
|---|---|---|
| 1 | Реєстр | Реєстрація |
| 2 | Вхід | Вхід |
| 3 | Атл-огляд | Мої атлети — огляд |
| 4 | Атл-фідбек | Атлет — активність і фідбек |
| 5 | Деталі-T | Деталі тренування (тренер-вид) |
| 6 | Фідбек-T | Залишити фідбек |
| 7 | Програми | Програми — список |
| 8 | Констр | Конструктор програми |
| 9 | Редактор | Редактор дня / сесії |
| 10 | Признач | Призначити програму атлету |
| 11 | Інвайт-T | Запросити атлета (інвайт) |
АТЛЕТ [A] і СПІЛЬНІ [TA]
| № | Скор | Повна назва |
|---|---|---|
| 12 | Сьогодні | Сьогодні — план на день |
| 13 | Логер | Активне тренування / Логер |
| 14 | Заверш | Завершення тренування |
| 15 | Прогрес | Прогрес |
| 16 | Історія | Історія тренувань |
| 17 | Харчув | Харчування — сьогодні |
| 18 | Їжа+ | Додати їжу |
| 19 | Замір | Записати замір тіла |
| 20 | Профіль | Профіль / Налаштування |
| Job | Реєстр | Вхід | Атл-огляд | Атл-фідбек | Деталі-T | Фідбек-T | Програми | Констр | Редактор | Признач | Інвайт-T |
|---|---|---|---|---|---|---|---|---|---|---|---|
| M · план↔виконання | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
| J1 · тренер доставляє план | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |||||
| J2 · тренер бачить що сталося | ✓ | ✓ | ✓ | ✓ | |||||||
| J3 · атлет знає що сьогодні | |||||||||||
| J4 · атлет фіксує підхід | |||||||||||
| J5 · атлет бачить прогрес | |||||||||||
| E1 · контроль тренера | ✓ | ✓ | ✓ | ✓ | ✓ | ||||||
| E2 · зусилля видимі | ✓ | ✓ | |||||||||
| S1 · тренер виглядає профі | ✓ | ✓ | ✓ | ||||||||
| S2 · атлет відповідає цифрами |
| Job | Сьогодні | Логер | Заверш | Прогрес | Історія | Харчув | Їжа+ | Замір | Профіль |
|---|---|---|---|---|---|---|---|---|---|
| M · план↔виконання | ✓ | ✓ | ✓ | ||||||
| J1 · тренер доставляє план | ✓ | ||||||||
| J2 · тренер бачить що сталося | ✓ | ✓ | |||||||
| J3 · атлет знає що сьогодні | ✓ | ||||||||
| J4 · атлет фіксує підхід | ✓ | ||||||||
| J5 · атлет бачить прогрес | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |||
| E1 · контроль тренера | |||||||||
| E2 · зусилля видимі | ✓ | ✓ | |||||||
| S1 · тренер виглядає профі | |||||||||
| S2 · атлет відповідає цифрами | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Стовпці без жодного ✓ — екран є, job нема.
Знайдено: 2
Проблема: жоден job не формулює «увійти в систему» як людську мотивацію. Вхід — prereq, не destination. Рішення: визнати як infrastructure prereq — виключити з job-матриці, не видаляти. Полірований auth UX побічно посилює S1, але це не primary use case. В MVP достатньо мінімального брендованого логін-екрана.
Проблема: MVP Профіль = тільки logout і зміна пароля. Жодна людська мотивація з jtbd.md не закривається тут.
Рішення: прив’язати до S1 — додати поле bio (1–2 речення) в профілі тренера, видиме підключеним атлетам.
Вартість: одне текстове поле у формі тренера. Результат: атлет бачить «Максим, сертифікований тренер, 2 роки онлайн» — підтримує professional impression (S1). Після рішення → додати ✓ при Профіль × S1.
Рядки без жодного ✓ — job є, екрана нема.
Знайдено: 0. Кожен job з jtbd.md покрито хоча б одним екраном.
Попередження — single point of failure (не orphan, але ризик):
| Job | Єдиний екран що закриває | Ризик |
|---|---|---|
| J3 · атлет знає що сьогодні | Сьогодні — план на день | Якщо екран не відображає план — J3 повністю провалюється. Design priority #1. |
| J4 · атлет фіксує підхід | Активне тренування / Логер | Якщо Логер незручний — J4 мертвий, J2 порожній. Design priority #2. |