Персональный трекер здоровья с AI-аналитикой — тренировки, питание, анализы и самочувствие в одном месте.
Большинство фитнес-приложений решают одну задачу: считают шаги, или записывают тренировки, или напоминают про воду. AI Coach идёт дальше — он соединяет все данные и ищет закономерности между ними.
Примеры инсайтов, которые находит система:
- «В дни после плохого сна тоннаж на тренировках ниже на 23%»
- «Высокий стресс совпадает с пропусками тренировок в 70% случаев»
- «Среднее потребление белка 68 г при цели 160 г — это тормозит восстановление»
- «Гемоглобин ниже нормы, анализы требуют внимания»
Главный принцип — минимум трения: добавить тренировку за ~30 секунд, сфотографировать еду и получить БЖУ в 2 тапа, внести самочувствие за ~15 секунд.
Приложение состоит из независимых модулей. Каждый полезен сам по себе; вместе они дают AI-аналитику.
| Модуль | Цвет | Что делает |
|---|---|---|
| Тренировки | Оранжевый | Создание тренировок, каталог упражнений, рекорды (PR), баланс мышц, объём по периодам |
| Питание | Зелёный | Приёмы пищи, расчёт БЖУ и калорий, цели по питанию, история |
| Ощущения | Фиолетовый | Утренняя и вечерняя анкета за ~15 сек: сон, энергия, стресс, настроение |
| Анализы | Синий | Загрузка результатов анализов (фото/PDF), биомаркеры с референсами |
| AI-аналитика | — | Кросс-модульные паттерны, рекомендация дня, инсайты по периодам |
Модули включаются независимо — если нужны только анализы и самочувствие, тренировки не мешают.
Три способа — один профиль:
| Способ | Где |
|---|---|
| Telegram Mini App | Открыть через бота в Telegram — вход в ноль кликов |
| Google OAuth | Кнопка «Войти через Google» на веб-версии |
| Email + пароль | Классическая регистрация |
Аккаунты можно связать: войти через Telegram и Google — это один и тот же профиль.
- Docker + Docker Compose
make(или запускать команды вручную)
# 1. Скопируйте и настройте переменные окружения
cp .env.example .env
# 2. Откройте .env и заполните обязательные поля:
# JWT_SECRET=<любая длинная строка>
# FIELD_ENCRYPTION_KEY=<base64-ключ для шифрования анализов>
#
# Опционально (для AI-функций):
# OPENAI_API_KEY=<ваш ключ OpenAI>
#
# Опционально (для входа через Telegram):
# TELEGRAM_BOT_TOKEN=<токен вашего бота>
#
# Опционально (для входа через Google):
# GOOGLE_CLIENT_ID=<OAuth client id>
# 3. Поднять весь стек одной командой
make upПосле запуска:
| Адрес | Что открывается |
|---|---|
| http://localhost:8080 | Веб-приложение |
| http://localhost:8000/docs | Swagger UI (интерактивное API) |
| http://localhost:9001 | MinIO консоль (хранилище файлов) |
cd frontend
npm install
npm run dev # Vite на :5173, проксирует /api → :8000| Переменная | Обязательна | Описание |
|---|---|---|
JWT_SECRET |
да | Секрет подписи JWT-токенов |
FIELD_ENCRYPTION_KEY |
да | Ключ шифрования анализов (base64, 32 байта) |
OPENAI_API_KEY |
нет | Включает AI-обогащение инсайтов через GPT-4o-mini |
TELEGRAM_BOT_TOKEN |
нет | Вход через Telegram Mini App |
GOOGLE_CLIENT_ID |
нет | Вход через Google OAuth |
POSTGRES_USER |
нет | Пользователь БД (по умолч. aicoach) |
POSTGRES_PASSWORD |
нет | Пароль БД (по умолч. aicoach) |
DB_PORT |
нет | Порт PostgreSQL наружу (по умолч. 5432) |
REDIS_PORT |
нет | Порт Redis наружу (по умолч. 6379) |
API_PORT |
нет | Порт API снаружи (по умолч. 8000) |
WEB_PORT |
нет | Порт фронтенда снаружи (по умолч. 8080) |
Генерация
FIELD_ENCRYPTION_KEY:python3 -c "import secrets,base64; print(base64.b64encode(secrets.token_bytes(32)).decode())"
make up # сборка и запуск всего стека
make down # остановить контейнеры
make build # пересобрать образы
make migrate # применить миграции Alembic
make revision m="описание" # создать новую миграцию
make test # backend unit-тесты (pytest)
make lint # ruff + mypy + eslint + tsc
make fmt # авто-форматирование (ruff)
make logs # логи API в реальном времениai-personal/
├── backend/
│ ├── app/
│ │ ├── core/ # config, db, security, deps, cache
│ │ ├── models/ # SQLAlchemy-модели (все сущности)
│ │ ├── modules/ # модульная структура домена
│ │ │ ├── auth/ # Telegram / email / Google, JWT
│ │ │ ├── users/ # профиль, цели, параметры
│ │ │ ├── exercises/ # каталог упражнений (34 + кастомные)
│ │ │ ├── workouts/ # тренировки, рекорды, баланс мышц
│ │ │ ├── nutrition/ # питание, БЖУ, распознавание
│ │ │ ├── subjective/# ощущения (утро/вечер)
│ │ │ ├── health/ # анализы, биомаркеры
│ │ │ └── insights/ # AI: рекомендации и паттерны
│ │ ├── services/
│ │ │ ├── insights.py # движок корреляций (pure Python)
│ │ │ ├── ai.py # обёртка OpenAI (graceful degrade)
│ │ │ └── targets.py # формулы BMR/TDEE/БЖУ/подходов
│ │ ├── jobs/
│ │ │ └── worker.py # ARQ-воркер (generate_insights, ping)
│ │ └── tests/ # 29 unit-тестов
│ └── alembic/ # миграции БД
├── frontend/
│ └── src/
│ ├── features/
│ │ ├── ai/ # RecommendationCard, InsightsList, хуки
│ │ ├── workouts/ # тренировки, прогресс, Exercise Picker
│ │ ├── nutrition/ # приёмы пищи, дневная сводка
│ │ ├── feelings/ # анкеты самочувствия, графики
│ │ └── health/ # анализы, биомаркеры
│ ├── pages/ # Home, Workouts, Nutrition, Feelings, Health, Profile
│ └── components/ # PageHeader, Card, EmptyState, Layout
├── .github/workflows/ # CI: lint → test → build → push GHCR
├── docker-compose.yml
├── Makefile
└── TZ.md # полная техническая спецификация
Бэкенд
| Слой | Технология |
|---|---|
| Язык / фреймворк | Python 3.12 + FastAPI (async) |
| ORM / миграции | SQLAlchemy 2.0 (asyncpg) + Alembic |
| БД | PostgreSQL 16 |
| Кэш / брокер | Redis 7 + ARQ |
| Хранилище файлов | S3-совместимое (MinIO локально) |
| AI | OpenAI API (httpx, опционально) |
| Шифрование | Fernet (анализы), argon2 (пароли) |
| Тесты | pytest + pytest-asyncio |
| Качество кода | ruff + mypy |
Фронтенд
| Слой | Технология |
|---|---|
| Каркас | React 18 + TypeScript + Vite |
| Стили | Tailwind CSS (цвета модулей, тёмная тема) |
| UI | shadcn/ui (Radix UI) |
| Данные | TanStack Query + Zustand |
| Формы | react-hook-form + Zod |
| Графики | Recharts |
| Telegram | @telegram-apps/sdk-react |
Swagger UI доступен по адресу http://localhost:8000/docs после запуска.
Краткий обзор эндпоинтов (/api/v1):
POST /auth/telegram # вход через Telegram InitData
POST /auth/register # регистрация email
POST /auth/login # вход email
POST /auth/google # вход через Google
POST /auth/refresh # обновление токена
GET /users/me # профиль
PUT /users/me # обновить профиль, цели, модули
GET /exercises # каталог упражнений
POST /exercises # добавить своё упражнение
GET /workouts # история тренировок
POST /workouts # создать тренировку
GET /workouts/calendar # календарь с итогами месяца/года
GET /workouts/muscle-balance# баланс мышечных групп
GET /workouts/records # личные рекорды
GET /workouts/progress/volume # объём за период
GET /nutrition # история питания
POST /nutrition # добавить приём пищи
POST /nutrition/recognize # распознать еду по фото (AI)
GET /nutrition/daily-summary# сводка дня + цели
POST /subjective # сохранить анкету самочувствия
GET /subjective # история ощущений
GET /subjective/today # анкеты за сегодня
GET /health # список анализов
POST /health # добавить анализ вручную
POST /health/recognize # распознать анализ по фото/PDF (AI)
GET /ai/recommendations # рекомендация дня (кэш до конца суток)
GET /ai/insights?period=week# кросс-модульные инсайты за период
Система работает без обязательного ключа OpenAI — детерминированный движок (services/insights.py) ищет закономерности на чистом Python:
- Собирает данные по активным модулям пользователя за период
- Запускает 9 детекторов паттернов: корреляция Пирсона, пороговые правила, сравнение факта с целью
- Если задан
OPENAI_API_KEY— передаёт найденные паттерны в GPT-4o-mini для переформулировки на живой язык - Результат кэшируется в Redis до конца суток
Приоритет детекторов:
1. Отклонения в анализах (биомаркеры вне референса)
2. Дисбаланс мышечных групп (< 50% от цели)
3. Влияние сна на тренировочный тоннаж
4. Дефицит белка относительно цели
5. Калорийность vs цель (набор / похудение)
6. Стресс и пропуски тренировок
7. Влияние питания на настроение (корреляция)
8. Сон → энергия дня (корреляция)
9. Динамика веса тела
- Данные анализов и заметки шифруются at rest (Fernet, ключ из переменной окружения)
- Все эндпоинты scoped по
user_idчерез зависимости FastAPI — чужие данные недоступны - AI-инсайты и рекомендации видны только владельцу и не агрегируются
- Telegram InitData валидируется по HMAC-SHA256 с проверкой
auth_date≤ 24 ч - Пароли хэшируются через argon2
- Секреты только через переменные окружения, не в образах
GitHub Actions пайплайн на каждый PR и push в main:
lint → test → build → push GHCR
Образы публикуются в GitHub Container Registry с тегами:
sha-<git-sha>— иммутабельный (точный откат)main— latest для stagingvX.Y.Z— релизный тег
Подробное техническое задание с описанием всех экранов, моделей данных, формул расчёта и архитектурных решений — в файле TZ.md.