Skip to content

Repository files navigation

fitweek

План тренировок и питания на неделю.

Веб-приложение на одного пользователя: недельный план питания и тренировок, журнал фактически выполненного, замеры тела и графики прогресса.

Что умеет

  • Сегодня — приёмы пищи по времени, тренировка, добавки, кольца «калории и белок к плану дня», заметка дня.
  • Неделя — обзор семи дней: выполнение, калории, белок, тренировка.
  • План недели — чем питаться, чем заниматься и какие добавки принимать в каждый день недели.
  • Справочники (раскрываются по клику) — три раздела:
    • Питание — блюда с ккал и БЖУ, рецептами и порциями.
    • Тренировки — шаблоны и каталог упражнений. В самой тренировке ведётся журнал подходов (вес, повторы, RPE) с таймером отдыха.
    • Добавки — что принимать и в какой дозировке.
  • Прогресс — измерения, состав тела, калории и белок по дням, соблюдение плана, тоннаж, объём по группам мышц, кардио, прогрессия по упражнению.
  • Настройки — часовой пояс, тема, бэкап и восстановление базы, смена пароля.

Как это устроено

Шаблон отделён от факта. «План недели» — это шаблон. Когда вы открываете дату, из него один раз создаются строки журнала за этот день. Дальше день живёт сам: правка плана или блюда не меняет прошлое.

Из этого следуют три правила:

  • БЖУ в журнале — снимок, а не ссылка. Исправили калорийность блюда — история за прошлые месяцы осталась прежней, метрики не «поехали».
  • Цель на день — это план на день. Цель считается как сумма блюд, назначенных на этот день недели.
  • Просмотр прошлой даты. Автоматически заводится только сегодняшний день. Пропущенный день открывается кнопкой «Заполнить день».

Начало работы

Первый вход: если INIT_USERNAME/INIT_PASSWORD не заданы, приложение покажет экран первичной настройки и предложит придумать логин и пароль.

База поднимается пустой — никаких заготовленных блюд, упражнений и планов. Порядок заполнения такой:

  1. Справочники → Питание → Приёмы пищи — завтрак, обед, ужин: из них собирается день.
  2. Справочники → Питание → Блюда — что едите, с калориями и БЖУ.
  3. Справочники → Тренировки → Упражнения — каталог движений: из них собираются шаблоны тренировок.
  4. Справочники → Тренировки → Шаблоны — готовые тренировки, которые потом назначаются на дни недели.
  5. Справочники → Добавки — если принимаете.
  6. План недели — расставить всё это по дням.

Структура

Сервер: Node + TypeScript + Fastify + SQLite (libsql) + Drizzle ORM

Клиент: React + Vite + Tailwind + Recharts

shared/   zod-схемы и типы, общие для сервера и клиента
server/   Fastify API, Drizzle-схема, миграции, тесты
web/      React-приложение

Локальный запуск

npm install
cp .env.example .env
npm run build && npm start

Открыть приложение на http://localhost:8080.

Docker

Готовый образ лежит во встроенном registry GitHub — ghcr.io/dkrut/fitweek.

echo "SESSION_SECRET=$(openssl rand -hex 32)" > .env
docker compose up -d

Собрать образ из этого чекаута вместо загрузки — раскомментировать build: . у сервиса app в docker-compose.yml и запустить:

docker compose up --build -d

Поднимаются два контейнера: приложение и Caddy перед ним. Наружу смотрит только Caddy — приложение доступно ему по внутренней сети и напрямую не публикуется. Порты меняются переменными HTTP_PORT и HTTPS_PORT.

База лежит в томе fitweek_data (/data/app.db внутри контейнера).

Переменные окружения

Переменная По умолчанию Назначение
SESSION_SECRET Обязателен. Подпись сессионной куки
SITE_ADDRESS :80 Домен для HTTPS; по умолчанию — обычный http
HTTP_PORT / HTTPS_PORT 80 / 443 Порты, которые слушает Caddy
DATA_DIR /data Каталог файла БД
INIT_USERNAME / INIT_PASSWORD Создать учётку при первом запуске
PORT 8080 Порт приложения внутри сети docker
TZ Europe/Moscow Часовой пояс: от него зависит, какой день «сегодня»
IMAGE_TAG latest Тег образа ghcr.io/dkrut/fitweek, который тянет compose

Про TZ

Границу суток определяет сервер: журнал хранится по его календарю, и клиент спрашивает «какое сегодня» у него, а не у браузера. Если часовой пояс контейнера не совпадает с вашим, несколько часов в сутки «сегодня» в приложении будет означать соседнюю дату. Данные при этом не портятся, но путает.

Настройки → Часовой пояс показывают дату сервера и дату браузера рядом и предупреждают о расхождении. Если оно есть — задайте свой пояс и перезапустите контейнер:

echo "TZ=Asia/Tbilisi" >> .env

HTTPS

По умолчанию SITE_ADDRESS не задан, и приложение отдаётся по обычному http на порту 80.

Впишите домен:

echo "SITE_ADDRESS=fitweek.example.com" >> .env && docker compose up -d

Дальше Caddy делает всё сам: получает сертификат, продлевает его без простоя и перенаправляет http на https.

Сертификат бесплатный, от Let's Encrypt по протоколу ACME (если тот недоступен, Caddy идёт к резервному центру) — регистрироваться и что-то настраивать не надо. Владение доменом подтверждается запросом на ваш же сервер, поэтому нужны A-запись на его адрес и открытые снаружи порты 80 и 443: центр выдачи стучится строго на них, и сдвинутые HTTP_PORT/HTTPS_PORT выдачу сломают. На голый IP-адрес сертификат не выдают, только на доменное имя.

Сертификаты лежат в томе caddy-data, и том обязателен: без него каждый перезапуск запрашивал бы новые и упёрся бы в недельный лимит выдачи. Чтобы получать письма об истечении, задайте почту — как, написано в комментарии в начале Caddyfile.

Флаг Secure у сессионной куки приложение ставит само, по протоколу запроса: пришёл по https — кука с флагом, пришёл по http в локальной сети — без него.

Настройка прокси живёт в Caddyfile и монтируется в контейнер.

Бэкапы

Настройки → Данные → Выгрузить бэкап — JSON со всеми данными: справочники, план недели, журнал, замеры. Восстановить из бэкапа в том же разделе заменяет текущее содержимое целиком.

Учётная запись и сессии в файл не попадают: при восстановлении в чистый экземпляр логин и пароль придётся задать заново, данные от этого не пострадают.

About

Comprehensive web‑based tool for managing fitness goals. The platform integrates a smart workout planner, a customizable meal system with macro tracking, and clear progress dashboards. It helps users stay consistent, track their transformation, and reach results faster through a structured, data‑driven approach.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages