Files
obsidian/Projects/Pulse/Architecture.md
2026-02-06 14:12:11 +00:00

325 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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*