- Introduced new models for `Organization` and `ReviewTask` to manage organizations and review tasks. - Implemented API endpoints for CRUD operations on organizations and tasks, including scanning organizations for repositories and PRs. - Developed a background worker for sequential processing of review tasks with priority handling and automatic retries. - Created frontend components for managing organizations and monitoring task queues, including real-time updates and filtering options. - Added comprehensive documentation for organization features and quick start guides. - Fixed UI issues and improved navigation for better user experience.
358 lines
9.1 KiB
Markdown
358 lines
9.1 KiB
Markdown
# 🏢 Организации и Очередь Задач
|
||
|
||
## 📋 Новая функциональность
|
||
|
||
### 1. **Поддержка организаций** 🏢
|
||
|
||
Теперь можно добавлять целые организации (не только отдельные репозитории):
|
||
- Одна кнопка - сканирование всех репозиториев
|
||
- Автоматический поиск всех PR
|
||
- Создание задач на review
|
||
|
||
### 2. **Очередь задач** 📝
|
||
|
||
Review выполняются **последовательно** (по одному):
|
||
- Задачи ставятся в очередь
|
||
- Worker обрабатывает по одной
|
||
- Приоритеты: HIGH > NORMAL > LOW
|
||
- Автоматический retry при ошибках
|
||
|
||
---
|
||
|
||
## 🎯 Как использовать
|
||
|
||
### Добавить организацию:
|
||
|
||
```bash
|
||
POST /api/organizations
|
||
{
|
||
"name": "inno-js",
|
||
"platform": "gitea",
|
||
"base_url": "https://git.bro-js.ru",
|
||
"api_token": "your_token" // опционально
|
||
}
|
||
```
|
||
|
||
### Сканировать организацию:
|
||
|
||
```bash
|
||
POST /api/organizations/1/scan
|
||
```
|
||
|
||
**Что произойдет:**
|
||
1. ✅ Найдет все репозитории в организации
|
||
2. ✅ Добавит отсутствующие репозитории в БД
|
||
3. ✅ Найдет все открытые PR
|
||
4. ✅ Создаст задачи на review
|
||
5. ✅ Worker автоматически начнет обработку
|
||
|
||
---
|
||
|
||
## 📊 Структура БД
|
||
|
||
### Таблица `organizations`:
|
||
|
||
```sql
|
||
CREATE TABLE organizations (
|
||
id INTEGER PRIMARY KEY,
|
||
name VARCHAR NOT NULL,
|
||
platform VARCHAR NOT NULL, -- gitea/github/bitbucket
|
||
base_url VARCHAR NOT NULL,
|
||
api_token VARCHAR, -- encrypted, optional
|
||
webhook_secret VARCHAR NOT NULL,
|
||
config JSON,
|
||
is_active BOOLEAN DEFAULT TRUE,
|
||
last_scan_at DATETIME,
|
||
created_at DATETIME,
|
||
updated_at DATETIME
|
||
);
|
||
```
|
||
|
||
### Таблица `review_tasks`:
|
||
|
||
```sql
|
||
CREATE TABLE review_tasks (
|
||
id INTEGER PRIMARY KEY,
|
||
pull_request_id INTEGER NOT NULL,
|
||
status VARCHAR NOT NULL, -- pending/in_progress/completed/failed
|
||
priority VARCHAR NOT NULL, -- low/normal/high
|
||
created_at DATETIME,
|
||
started_at DATETIME,
|
||
completed_at DATETIME,
|
||
error_message VARCHAR,
|
||
retry_count INTEGER DEFAULT 0,
|
||
max_retries INTEGER DEFAULT 3,
|
||
FOREIGN KEY (pull_request_id) REFERENCES pull_requests(id)
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 Task Worker
|
||
|
||
### Как работает:
|
||
|
||
```python
|
||
while True:
|
||
# 1. Проверить есть ли in_progress задача
|
||
if has_in_progress_task():
|
||
wait()
|
||
continue
|
||
|
||
# 2. Взять следующую pending задачу
|
||
task = get_next_pending_task()
|
||
|
||
if not task:
|
||
wait()
|
||
continue
|
||
|
||
# 3. Отметить как in_progress
|
||
task.status = "in_progress"
|
||
|
||
# 4. Выполнить review
|
||
try:
|
||
execute_review(task)
|
||
task.status = "completed"
|
||
except:
|
||
task.retry_count += 1
|
||
if task.retry_count >= task.max_retries:
|
||
task.status = "failed"
|
||
else:
|
||
task.status = "pending" # retry
|
||
|
||
# 5. Подождать 10 секунд
|
||
await asyncio.sleep(10)
|
||
```
|
||
|
||
### Гарантии:
|
||
|
||
✅ **Один review одновременно** - проверяется наличие `in_progress` задач
|
||
✅ **Приоритеты** - высокий приоритет обрабатывается первым
|
||
✅ **Retry** - автоматически повторяет при ошибках (до 3 раз)
|
||
✅ **FIFO** - старые задачи обрабатываются первыми (при равном приоритете)
|
||
|
||
---
|
||
|
||
## 📡 API Endpoints
|
||
|
||
### Organizations:
|
||
|
||
```
|
||
GET /api/organizations # Список организаций
|
||
POST /api/organizations # Создать организацию
|
||
GET /api/organizations/{id} # Получить организацию
|
||
PUT /api/organizations/{id} # Обновить организацию
|
||
DELETE /api/organizations/{id} # Удалить организацию
|
||
POST /api/organizations/{id}/scan # Сканировать организацию
|
||
```
|
||
|
||
### Tasks:
|
||
|
||
```
|
||
GET /api/tasks # Список задач
|
||
GET /api/tasks?status=pending # Фильтр по статусу
|
||
GET /api/tasks/worker/status # Статус worker'а
|
||
POST /api/tasks/{id}/retry # Повторить задачу
|
||
DELETE /api/tasks/{id} # Удалить задачу
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 Пример сканирования
|
||
|
||
### Request:
|
||
|
||
```bash
|
||
POST /api/organizations/1/scan
|
||
```
|
||
|
||
### Response:
|
||
|
||
```json
|
||
{
|
||
"organization_id": 1,
|
||
"repositories_found": 15,
|
||
"repositories_added": 3,
|
||
"pull_requests_found": 8,
|
||
"tasks_created": 8,
|
||
"errors": []
|
||
}
|
||
```
|
||
|
||
### Логи:
|
||
|
||
```
|
||
🔍 Сканирование организации inno-js на https://git.bro-js.ru
|
||
Найдено репозиториев: 15
|
||
✅ Добавлен репозиторий: inno-js/project-a
|
||
✅ Добавлен репозиторий: inno-js/project-b
|
||
✅ Добавлен репозиторий: inno-js/project-c
|
||
📝 Создана задача для PR #5: Add feature X
|
||
📝 Создана задача для PR #12: Fix bug Y
|
||
📝 Создана задача для PR #3: Update docs
|
||
...
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 Worker Logs
|
||
|
||
```
|
||
🚀 Task Worker запущен
|
||
|
||
================================================================================
|
||
📋 Начало обработки задачи #1
|
||
PR ID: 5
|
||
Приоритет: normal
|
||
================================================================================
|
||
|
||
🤖 Запуск AI review для PR #5
|
||
✅ Review завершен для PR #5
|
||
✅ Задача #1 успешно завершена
|
||
|
||
================================================================================
|
||
📋 Начало обработки задачи #2
|
||
PR ID: 12
|
||
Приоритет: normal
|
||
================================================================================
|
||
|
||
🤖 Запуск AI review для PR #12
|
||
✅ Review завершен для PR #12
|
||
✅ Задача #2 успешно завершена
|
||
|
||
⏳ Задача #3 уже выполняется
|
||
...
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 Приоритеты задач
|
||
|
||
### Установка приоритета:
|
||
|
||
```python
|
||
# В коде при создании задачи
|
||
task = ReviewTask(
|
||
pull_request_id=pr.id,
|
||
priority="high" # "low" / "normal" / "high"
|
||
)
|
||
```
|
||
|
||
### Порядок обработки:
|
||
|
||
1. **HIGH** - критичные PR (hotfix, security)
|
||
2. **NORMAL** - обычные PR (по умолчанию)
|
||
3. **LOW** - некритичные PR (docs, refactoring)
|
||
|
||
При равном приоритете - FIFO (First In, First Out)
|
||
|
||
---
|
||
|
||
## 🔧 Конфигурация Worker
|
||
|
||
### В коде:
|
||
|
||
```python
|
||
# backend/app/workers/task_worker.py
|
||
|
||
class ReviewTaskWorker:
|
||
def __init__(self):
|
||
self.poll_interval = 10 # секунд между проверками
|
||
```
|
||
|
||
### Изменить интервал:
|
||
|
||
```python
|
||
worker.poll_interval = 5 # проверять каждые 5 секунд
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 Мониторинг
|
||
|
||
### Статус worker'а:
|
||
|
||
```bash
|
||
GET /api/tasks/worker/status
|
||
```
|
||
|
||
```json
|
||
{
|
||
"running": true,
|
||
"current_task_id": 15,
|
||
"poll_interval": 10
|
||
}
|
||
```
|
||
|
||
### Статистика задач:
|
||
|
||
```bash
|
||
GET /api/tasks
|
||
```
|
||
|
||
```json
|
||
{
|
||
"items": [...],
|
||
"total": 50,
|
||
"pending": 10,
|
||
"in_progress": 1,
|
||
"completed": 35,
|
||
"failed": 4
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🛠️ Troubleshooting
|
||
|
||
### Worker не обрабатывает задачи:
|
||
|
||
```bash
|
||
# Проверить статус
|
||
curl http://localhost:8000/api/tasks/worker/status
|
||
|
||
# Проверить есть ли pending задачи
|
||
curl http://localhost:8000/api/tasks?status=pending
|
||
|
||
# Проверить логи backend
|
||
journalctl -u ai-review -f
|
||
```
|
||
|
||
### Задача застряла в in_progress:
|
||
|
||
```bash
|
||
# Вручную сбросить статус в БД
|
||
sqlite3 backend/review.db
|
||
UPDATE review_tasks SET status='pending', started_at=NULL WHERE id=123;
|
||
```
|
||
|
||
### Retry failed задачи:
|
||
|
||
```bash
|
||
POST /api/tasks/123/retry
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ Преимущества
|
||
|
||
1. **Последовательная обработка** - не перегружаем Ollama
|
||
2. **Приоритеты** - важные PR быстрее
|
||
3. **Автоматический retry** - устойчивость к ошибкам
|
||
4. **Масштабируемость** - легко добавлять организации
|
||
5. **Мониторинг** - видно состояние очереди
|
||
|
||
---
|
||
|
||
## 🎉 Готово!
|
||
|
||
Теперь можно:
|
||
- ✅ Добавлять организации целиком
|
||
- ✅ Сканировать все репозитории
|
||
- ✅ Автоматически ставить PR в очередь
|
||
- ✅ Обрабатывать последовательно
|
||
- ✅ Мониторить прогресс
|
||
|
||
**Попробуйте!** 🚀
|
||
|