# 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*
