pulse-api — Архитектура
Репозиторий: https://git.digital-home.site/daniil/pulse-api
Go module: github.com/daniil/homelab-api
URL: https://api.digital-home.site
Dev: http://192.168.31.60:8081
Общая архитектура
Классический Go REST API с разделением на слои:
Стек:
- Router:
go-chi/chi v5
- ORM:
jmoiron/sqlx (raw SQL + named queries)
- БД: PostgreSQL 16
- JWT:
golang-jwt/jwt v5
- Telegram:
go-telegram-bot-api v5
- Cron:
robfig/cron v3
- Email: Resend API (
service/email.go)
- Крипто:
golang.org/x/crypto (bcrypt для паролей)
Структура папок
API Эндпоинты
Публичные (без авторизации)
| Метод |
Путь |
Описание |
| GET |
/health |
Health check |
| POST |
/auth/register |
Регистрация: {email, username, password} |
| POST |
/auth/login |
Логин: {email, password} → {access_token, refresh_token, user} |
| POST |
/auth/refresh |
Обновление токена: {refresh_token} |
| POST |
/auth/verify-email |
Подтверждение email: {token} |
| POST |
/auth/resend-verification |
Повторная отправка: {email} |
| POST |
/auth/forgot-password |
Сброс пароля: {email} |
| POST |
/auth/reset-password |
Новый пароль: {token, new_password} |
Авторизованные (Bearer JWT)
Аутентификация/Профиль
| Метод |
Путь |
Описание |
| GET |
/auth/me |
Текущий пользователь |
| PUT |
/auth/me |
Обновить профиль |
| PUT |
/auth/password |
Сменить пароль: {old_password, new_password} |
| GET |
/profile |
Профиль |
| PUT |
/profile |
Обновить профиль |
Задачи
| Метод |
Путь |
Описание |
| GET |
/tasks |
Список задач. Query: ?completed=true/false |
| GET |
/tasks/today |
Задачи на сегодня |
| POST |
/tasks |
Создать: {title, description?, icon?, color?, due_date?, priority?, reminder_time?, is_recurring?, recurrence_type?, recurrence_interval?, recurrence_end_date?} |
| GET |
/tasks/{id} |
Получить задачу |
| PUT |
/tasks/{id} |
Обновить задачу |
| DELETE |
/tasks/{id} |
Удалить задачу |
| POST |
/tasks/{id}/complete |
Отметить выполненной |
| POST |
/tasks/{id}/uncomplete |
Снять отметку |
Привычки
| Метод |
Путь |
Описание |
| GET |
/habits |
Список привычек |
| POST |
/habits |
Создать: {name, description?, color?, icon?, frequency, target_days?, target_count?, reminder_time?, start_date?} |
| GET |
/habits/{id} |
Получить привычку |
| PUT |
/habits/{id} |
Обновить |
| DELETE |
/habits/{id} |
Удалить |
| POST |
/habits/{id}/log |
Отметить: {date?, count?, note?} |
| GET |
/habits/{id}/logs |
История отметок |
| DELETE |
/habits/{id}/logs/{logId} |
Удалить отметку |
| GET |
/habits/stats |
Общая статистика |
| GET |
/habits/{id}/stats |
Статистика привычки |
| GET |
/habits/{id}/freezes |
Заморозки привычки |
| POST |
/habits/{id}/freezes |
Создать заморозку |
| DELETE |
/habits/{id}/freezes/{freezeId} |
Удалить заморозку |
Финансы
| Метод |
Путь |
Описание |
| GET |
/finance/categories |
Категории расходов/доходов |
| POST |
/finance/categories |
Создать: {name, emoji?, type, budget?, color?, sort_order?} |
| PUT |
/finance/categories/{id} |
Обновить |
| DELETE |
/finance/categories/{id} |
Удалить |
| GET |
/finance/transactions |
Транзакции. Query: ?month=&year= |
| POST |
/finance/transactions |
Создать: {category_id, type, amount, description?, date} |
| PUT |
/finance/transactions/{id} |
Обновить |
| DELETE |
/finance/transactions/{id} |
Удалить |
| GET |
/finance/summary |
Сводка: баланс, доходы, расходы, по категориям |
| GET |
/finance/analytics |
Аналитика: тренды по месяцам |
Накопления
| Метод |
Путь |
Описание |
| GET |
/savings/categories |
Категории накоплений |
| POST |
/savings/categories |
Создать категорию |
| GET |
/savings/categories/{id} |
Получить |
| PUT |
/savings/categories/{id} |
Обновить |
| DELETE |
/savings/categories/{id} |
Удалить |
| GET |
/savings/categories/{id}/members |
Участники |
| POST |
/savings/categories/{id}/members |
Добавить участника |
| DELETE |
/savings/categories/{id}/members/{userId} |
Удалить участника |
| GET |
/savings/categories/{id}/recurring-plans |
Регулярные планы |
| POST |
/savings/categories/{id}/recurring-plans |
Создать план |
| PUT |
/savings/recurring-plans/{planId} |
Обновить план |
| DELETE |
/savings/recurring-plans/{planId} |
Удалить план |
| GET |
/savings/transactions |
Транзакции накоплений |
| POST |
/savings/transactions |
Создать транзакцию |
| GET |
/savings/transactions/{id} |
Получить |
| PUT |
/savings/transactions/{id} |
Обновить |
| DELETE |
/savings/transactions/{id} |
Удалить |
| GET |
/savings/stats |
Статистика |
Модели данных
User
Task
Habit
FinanceCategory / FinanceTransaction
Аутентификация
- JWT HS256 с двумя типами токенов:
access (короткий) и refresh (длинный)
- Middleware
Authenticate парсит Authorization: Bearer <token>, проверяет type == "access"
- UserID извлекается из claims и помещается в context:
GetUserID(ctx)
- Пароли хешируются bcrypt
- Email-верификация при регистрации через Resend API
- Password reset — одноразовые токены в таблице
email_tokens
Telegram Бот
Команды:
| Команда |
Действие |
/start |
Показать Chat ID (для привязки к аккаунту Pulse) |
/tasks |
Список задач на сегодня с inline-кнопками |
/habits |
Привычки на сегодня с inline-кнопками |
/done <id> или /done_<id> |
Отметить задачу выполненной |
/check <id> или /check_<id> |
Отметить привычку |
/help |
Справка |
Callback-кнопки:
donetask_<id> — выполнить задачу
deltask_<id> — удалить задачу
checkhabit_<id> — отметить привычку сегодня
checkhabit_<id>_yesterday — отметить привычку за вчера
Привязка: пользователь вводит /start, получает Chat ID, вставляет его в настройки Pulse → PUT /profile {telegram_chat_id: ...}
Scheduler (cron-напоминания)
internal/scheduler/scheduler.go — использует robfig/cron:
- Утренние напоминания (время из настроек пользователя)
- Вечерние напоминания
- Напоминания о задачах по
reminder_time
- Напоминания о привычках по
reminder_time
Конфигурация (env переменные)
| Переменная |
Описание |
Default |
DATABASE_URL |
PostgreSQL DSN |
postgres://homelab:homelab@db:5432/homelab |
JWT_SECRET |
Секрет для JWT |
change-me-in-production |
PORT |
Порт сервера |
8080 |
RESEND_API_KEY |
API ключ Resend (email) |
— |
FROM_EMAIL |
Email отправителя |
noreply@digital-home.site |
FROM_NAME |
Имя отправителя |
Homelab |
APP_URL |
Публичный URL приложения |
https://api.digital-home.site |
TELEGRAM_BOT_TOKEN |
Токен Telegram бота |
— |
Где искать что
| Задача |
Файл |
| Добавить новый эндпоинт |
handler/<domain>.go + роут в cmd/api/main.go |
| Изменить модель/таблицу |
model/<domain>.go + repository/db.go (migrations) |
| Логика уведомлений |
internal/scheduler/scheduler.go |
| Telegram команды |
internal/bot/handlers.go |
| Финансы (категории/транзакции) |
handler/finance.go, service/finance.go, repository/finance.go |
| Привычки |
handler/habits.go, service/habit.go, repository/habit.go |
| Задачи |
handler/tasks.go, service/task.go, repository/task.go |
| Накопления |
handler/savings.go, repository/savings.go |
| Email отправка |
service/email.go |
| JWT/Auth |
service/auth.go, middleware/auth.go |
| Конфиг |
config/config.go |