feat: add email notification service with SMTP support
Some checks failed
Build and Deploy GooSeek / build-and-deploy (push) Failing after 8m22s

- Create pkg/email package (sender, templates, types)
- SMTP client with TLS, rate limiting, async sending
- HTML email templates with GooSeek branding
- Integrate welcome + password reset emails in auth-svc
- Add limit warning emails (80%/100%) in llm-svc middleware
- Add space invite endpoint with email notification in thread-svc
- Add GetUserEmail helper in JWT middleware
- Add SMTP config to .env, config.go, K8s configmap

Made-with: Cursor
This commit is contained in:
home
2026-03-03 02:50:17 +03:00
parent 7a40ff629e
commit 52134df4d1
12 changed files with 767 additions and 92 deletions

View File

@@ -1,97 +1,51 @@
# LLM Routing по тарифам ✅
# Email Notification Service
## Архитектура
## Статус: Готово
## Что реализовано
### Пакет `backend/pkg/email/`
- `types.go` — типы уведомлений (Welcome, PasswordReset, LimitWarning, SpaceInvite, SystemAlert)
- `sender.go` — SMTP клиент с TLS, rate limiting (1 письмо/тип/24ч), async отправка
- `templates.go` — HTML шаблоны с брендингом GooSeek
### Интеграции
| Сервис | Уведомления | Файл |
|--------|-------------|------|
| auth-svc | Welcome, Password Reset | `backend/cmd/auth-svc/main.go` |
| llm-svc | Limit Warning (80%), Limit Exceeded (100%) | `backend/pkg/middleware/llm_limits.go` |
| thread-svc | Space Invite | `backend/cmd/thread-svc/main.go` |
### Новые API endpoints
- `POST /api/v1/spaces/:id/invite` — приглашение в Space по email
- `GET /api/v1/spaces/:id/invites` — список приглашений
### Конфигурация
```env
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=noreply@gooseek.ru
SMTP_PASSWORD=
SMTP_FROM=GooSeek <noreply@gooseek.ru>
SMTP_TLS=true
SITE_URL=https://gooseek.ru
SITE_NAME=GooSeek
```
┌─────────────────────────────────────────────────────────┐
│ llm-svc │
│ │
│ POST /api/v1/generate │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ resolveProvider │ │
│ │ (tier) │ │
│ └────────┬────────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ ▼ ▼ │
│ ┌──────┐ ┌────────┐ │
│ │ FREE │ │ PRO │ │
│ └──┬───┘ └───┬────┘ │
│ │ │ │
│ ▼ ▼ │
│ Ollama Timeweb │
│ (local) (cloud) │
└─────────────────────────────────────────────────────────┘
```
## Роутинг по тарифам
| Тариф | Провайдер | Модель | Лимиты |
|-------|-----------|--------|--------|
| **free** | Ollama (local) | qwen3.5:9b | 50 req/day, 2000 tokens/req |
| **pro** | Timeweb | gpt-4o, claude, etc | 500 req/day, 8000 tokens/req |
| **business** | Timeweb | all models | 5000 req/day, 32000 tokens/req |
## API Endpoints
### POST /api/v1/generate
```json
{
"providerId": "auto", // или "ollama", "timeweb", etc
"key": "qwen3.5:9b", // модель
"messages": [{"role": "user", "content": "..."}],
"options": {
"maxTokens": 1000,
"temperature": 0.7,
"stream": true
}
}
```
### POST /api/v1/embed
```json
{
"input": "Текст для эмбеддинга",
"model": "qwen3-embedding:0.6b"
}
```
### GET /api/v1/providers
Возвращает список доступных провайдеров с указанием tier.
---
## Ollama конфигурация
| Параметр | Значение |
|----------|----------|
| OLLAMA_NUM_PARALLEL | 4 |
| OLLAMA_MAX_LOADED_MODELS | 2 |
| OLLAMA_FLASH_ATTENTION | true |
| Модель генерации | qwen3.5:9b |
| Модель эмбеддингов | qwen3-embedding:0.6b |
## Пропускная способность
| Сценарий | Одновременно | RPM |
|----------|--------------|-----|
| Короткие ответы | 6-8 чел | ~40-60 |
| Средние ответы | 4-6 чел | ~20-30 |
| Эмбеддинги | 10+ чел | ~800+ |
---
## Файлы изменены
- `backend/cmd/llm-svc/main.go` — роутинг по тарифу, /embed endpoint
- `backend/internal/llm/ollama.go` — qwen3.5:9b, убран токен, GenerateEmbedding
- `backend/internal/llm/client.go` — убран OllamaToken
- `backend/deploy/k8s/ollama.yaml` — GPU + параллельность
- `backend/deploy/k8s/ollama-models.yaml` — без авторизации
---
- `backend/pkg/email/types.go` — новый
- `backend/pkg/email/sender.go` — новый
- `backend/pkg/email/templates.go` — новый
- `backend/pkg/config/config.go` — SMTP конфиг
- `backend/pkg/middleware/jwt.go` — GetUserEmail()
- `backend/pkg/middleware/llm_limits.go` — email при лимитах
- `backend/internal/usage/repository.go` — GetUserEmail()
- `backend/cmd/auth-svc/main.go` — welcome + reset emails
- `backend/cmd/llm-svc/main.go` — emailSender в LLMLimits
- `backend/cmd/thread-svc/main.go` — invite endpoint + email
- `backend/deploy/k8s/configmap.yaml` — SMTP переменные
- `.env` — SMTP переменные
## Сервер
- IP: 5.187.77.89