Add Pulse architecture documentation

This commit is contained in:
Cosmo
2026-02-06 14:12:11 +00:00
parent a4bd417966
commit 86744a06da

View File

@@ -0,0 +1,324 @@
# Pulse — Архитектура проекта
## Обзор
**Pulse** — персональное productivity-приложение для управления задачами, привычками и напоминаниями с интеграцией Telegram-бота.
## Технологический стек
### Backend (pulse-api)
- **Язык:** Go 1.22
- **Web-фреймворк:** chi/v5
- **База данных:** PostgreSQL 16
- **ORM:** sqlx (raw SQL + struct mapping)
- **Аутентификация:** JWT (access 15 мин / refresh 365 дней)
- **Email:** Resend API
- **Telegram:** go-telegram-bot-api/v5
- **Scheduler:** robfig/cron/v3
- **Контейнеризация:** Docker + Docker Compose
### Frontend (pulse-web)
- **Фреймворк:** React 18
- **Сборщик:** Vite 5
- **Стили:** TailwindCSS
- **Состояние:** Zustand (auth), TanStack Query (data fetching)
- **Анимации:** Framer Motion
- **Иконки:** Lucide React
- **Контейнеризация:** nginx:alpine
### Инфраструктура
- **Хостинг:** VM Ubuntu (192.168.31.60)
- **Reverse proxy:** Nginx Proxy Manager
- **SSL:** Let's Encrypt (auto-renew)
- **Git:** Gitea (git.digital-home.site)
- **Домены:**
- API: api.digital-home.site
- Web: pulse.digital-home.site
## Структура Backend
```
homelab-api/
├── cmd/api/
│ └── main.go # Точка входа, инициализация
├── internal/
│ ├── bot/
│ │ ├── bot.go # Telegram bot, long polling
│ │ └── handlers.go # Обработчики команд и callback
│ ├── config/
│ │ └── config.go # Загрузка переменных окружения
│ ├── handler/
│ │ ├── auth.go # Регистрация, логин, JWT
│ │ ├── habits.go # CRUD привычек
│ │ ├── health.go # Health check
│ │ ├── profile.go # Профиль пользователя
│ │ └── tasks.go # CRUD задач
│ ├── middleware/
│ │ └── auth.go # JWT middleware
│ ├── model/
│ │ ├── habit.go # Модель привычки
│ │ ├── task.go # Модель задачи
│ │ └── user.go # Модель пользователя
│ ├── repository/
│ │ ├── db.go # Подключение к PostgreSQL
│ │ ├── habit.go # SQL-запросы для привычек
│ │ ├── task.go # SQL-запросы для задач
│ │ └── user.go # SQL-запросы для пользователей
│ ├── scheduler/
│ │ └── scheduler.go # Cron jobs для уведомлений
│ └── service/
│ ├── auth.go # Бизнес-логика авторизации
│ ├── email.go # Отправка email через Resend
│ ├── habit.go # Бизнес-логика привычек
│ └── task.go # Бизнес-логика задач
├── Dockerfile
├── docker-compose.yml
├── go.mod
└── go.sum
```
## Структура Frontend
```
pulse-web/
├── public/
│ └── favicon.svg # Иконка молния ⚡
├── src/
│ ├── api/
│ │ ├── client.js # Axios instance + interceptors
│ │ ├── habits.js # API привычек
│ │ ├── profile.js # API профиля
│ │ └── tasks.js # API задач
│ ├── components/
│ │ ├── CreateHabitModal.jsx
│ │ ├── CreateTaskModal.jsx
│ │ ├── EditHabitModal.jsx
│ │ ├── EditTaskModal.jsx
│ │ └── Navigation.jsx # Нижняя навигация
│ ├── pages/
│ │ ├── ForgotPassword.jsx
│ │ ├── Habits.jsx # Управление привычками
│ │ ├── Home.jsx # Главная (сегодня)
│ │ ├── Login.jsx
│ │ ├── Register.jsx
│ │ ├── ResetPassword.jsx
│ │ ├── Settings.jsx # Настройки профиля
│ │ ├── Stats.jsx # Статистика
│ │ ├── Tasks.jsx # Управление задачами
│ │ └── VerifyEmail.jsx
│ ├── store/
│ │ └── auth.js # Zustand store для авторизации
│ ├── App.jsx # Роутинг
│ ├── index.css # Глобальные стили
│ └── main.jsx # Entry point
├── Dockerfile
├── docker-compose.yml
├── index.html
├── nginx.conf
├── package.json
├── tailwind.config.js
└── vite.config.js
```
## База данных
### Таблицы
```sql
-- Пользователи
users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
username VARCHAR(100) NOT NULL,
password_hash VARCHAR(255) NOT NULL,
email_verified BOOLEAN DEFAULT FALSE,
telegram_chat_id BIGINT,
notifications_enabled BOOLEAN DEFAULT TRUE,
timezone VARCHAR(50) DEFAULT 'Europe/Moscow',
morning_reminder_time TIME DEFAULT '09:00',
evening_reminder_time TIME DEFAULT '21:00',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
)
-- Задачи
tasks (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
title VARCHAR(255) NOT NULL,
description TEXT,
icon VARCHAR(10) DEFAULT '📋',
color VARCHAR(7) DEFAULT '#6B7280',
due_date DATE,
priority INTEGER DEFAULT 0, -- 0=none, 1=low, 2=medium, 3=high
reminder_time TIME,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
)
-- Привычки
habits (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
name VARCHAR(255) NOT NULL,
description TEXT,
icon VARCHAR(10) DEFAULT '',
color VARCHAR(7) DEFAULT '#10B981',
frequency VARCHAR(20) DEFAULT 'daily', -- daily, weekly, custom
target_days INTEGER[], -- [1,3,5] для пн,ср,пт
target_count INTEGER DEFAULT 1,
reminder_time TIME,
archived BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
)
-- Логи привычек
habit_logs (
id SERIAL PRIMARY KEY,
habit_id INTEGER REFERENCES habits(id),
user_id INTEGER REFERENCES users(id),
date DATE NOT NULL,
count INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW()
)
-- Email токены
email_tokens (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
token VARCHAR(255) NOT NULL,
type VARCHAR(50) NOT NULL, -- verification, password_reset
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
)
```
## API Endpoints
### Авторизация
| Method | Endpoint | Описание |
|--------|----------|----------|
| POST | /auth/register | Регистрация |
| POST | /auth/login | Вход |
| POST | /auth/refresh | Обновить токены |
| POST | /auth/verify-email | Подтвердить email |
| POST | /auth/forgot-password | Запросить сброс пароля |
| POST | /auth/reset-password | Сбросить пароль |
### Профиль (требует JWT)
| Method | Endpoint | Описание |
|--------|----------|----------|
| GET | /profile | Получить профиль |
| PUT | /profile | Обновить профиль |
### Задачи (требует JWT)
| Method | Endpoint | Описание |
|--------|----------|----------|
| GET | /tasks | Список задач |
| GET | /tasks/today | Задачи на сегодня |
| POST | /tasks | Создать задачу |
| GET | /tasks/{id} | Получить задачу |
| PUT | /tasks/{id} | Обновить задачу |
| DELETE | /tasks/{id} | Удалить задачу |
| POST | /tasks/{id}/complete | Отметить выполненной |
| POST | /tasks/{id}/uncomplete | Снять отметку |
### Привычки (требует JWT)
| Method | Endpoint | Описание |
|--------|----------|----------|
| GET | /habits | Список привычек |
| POST | /habits | Создать привычку |
| GET | /habits/{id} | Получить привычку |
| PUT | /habits/{id} | Обновить привычку |
| DELETE | /habits/{id} | Удалить (архивировать) |
| POST | /habits/{id}/log | Отметить выполнение |
| GET | /habits/{id}/logs | История выполнений |
| DELETE | /habits/{id}/logs/{logId} | Удалить запись |
| GET | /habits/stats | Общая статистика |
| GET | /habits/{id}/stats | Статистика привычки |
## Telegram Bot
### Команды
| Команда | Описание |
|---------|----------|
| /start | Показать Chat ID |
| /tasks | Задачи на сегодня |
| /habits | Привычки на сегодня |
| /help | Справка |
### Inline кнопки
- ✅ Выполнено — отмечает задачу/привычку
- 🗑 Удалить — удаляет задачу
- ⏰ +30 мин — откладывает напоминание
### Уведомления
1. **Утреннее** (настраивается): задачи и привычки на сегодня
2. **Вечернее** (настраивается): итоги дня
3. **Индивидуальные**: по reminder_time каждой задачи/привычки
## Docker Compose
### Backend (homelab-api)
```yaml
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: homelab
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: homelab
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
api:
build: .
environment:
- DATABASE_URL=postgres://homelab:${DB_PASSWORD}@db:5432/homelab?sslmode=disable
- JWT_SECRET=${JWT_SECRET}
- RESEND_API_KEY=${RESEND_API_KEY}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
depends_on:
- db
networks:
- backend
- services_proxy
```
### Frontend (pulse-web)
```yaml
services:
web:
build: .
networks:
- services_proxy
```
## Дизайн
### Цвета
- **Primary (Deep Teal):** #115E59
- **Accent (Burnished Amber):** #F59E0B
- **Surface:** #F8FAFC
- **Text:** #1E293B
### Шрифты
- **Body:** Inter (Google Fonts)
### UI-компоненты
- Карточки с тенями и закруглениями (rounded-2xl)
- Backdrop blur для header
- Framer Motion анимации
- Inline кнопки в Telegram
## Репозитории
- **Backend:** https://git.digital-home.site/daniil/pulse-api
- **Frontend:** https://git.digital-home.site/daniil/pulse-web
---
*Создано: 2026-02-06*