An open API service indexing awesome lists of open source software.

https://github.com/nikitadev-work/pr-manager-service

Микросервис, который автоматически назначает ревьюеров на Pull Request’ы (PR), а также позволяет управлять командами и участниками.
https://github.com/nikitadev-work/pr-manager-service

clean-architecture go golang http openapi postgresql

Last synced: about 2 months ago
JSON representation

Микросервис, который автоматически назначает ревьюеров на Pull Request’ы (PR), а также позволяет управлять командами и участниками.

Awesome Lists containing this project

README

          

# PR Manager Service

Сервис для управления pull request’ами и назначениями ревьюеров внутри команд.

Основной стек:
- Go 1.23
- PostgreSQL 16
- Docker / docker compose
- Prometheus + Grafana + Loki + Node Exporter
- k6 для нагрузочного тестирования
- golangci-lint для статического анализа

---

### Для быстрой проверки сервиса выполните `docker compose up` в корне проекта, после этого вам будут доступны [следующие компоненты](README.md#url-адреса-инфраструктуры)

## Документация

- [Окружение, локальная разработка и команды Makefile](docs/environment-and-makefile.md)
- [Тестирование (unit, integration, k6, Postman)](docs/testing.md)
- [Отчет по нагрузочному тестированию](docs/load-testing-report.md)

---

## Навигация по данному README.md
- [Структура проекта](#структура-проекта)
- [URL-адреса инфраструктуры](#url-адреса-инфраструктуры)
- [Внешнее API и аутентификация](#внешнее-api-и-аутентификация)
- [Continuous Integration (CI)](#continuous-integration-ci)
- [Development Workflow](#development-workflow)
- [Реализованные требования](#реализованные-требования)
- [Допущения и принятые решения](#допущения-и-принятые-решения)

## Структура проекта

```text
.
├── pr-manager-service/
│ ├── cmd/
│ │ └── pr-manager-service/
│ ├── config/
│ ├── internal/
│ │ ├── app/
│ │ ├── adapters/
│ │ │ └── httpadapter/
│ │ ├── domain/
│ │ ├── repository/
│ │ ├── usecase/
│ │ └── integration-tests/
│ ├── migrations/
│ ├── go.mod
│ └── go.sum

├── common/
│ └── kit/ - общий модуль с логгером и метриками

├── ops/
│ ├── docker-compose.dev.yml
│ ├── prometheus.yml
│ ├── loki-config.yml
│ ├── promtail-config.yml
│ ├── grafana/
│ │ └── provisioning/
│ │ ├── datasources/
│ │ └── dashboards/
│ └── load-testing/

├── docs/
│ ├── contracts/ - спецификация openapi
│ └── postman/ - коллекция и окружение

├── .github/
│ └── workflows/
│ └── ci.yml
├── Makefile
└── README.md
```

---

## URL-адреса инфраструктуры

После `make dev-up` доступны:

- Сервис:
`http://localhost:8080`

- Swagger UI (документация API):
`http://localhost:8082`

- Prometheus:
`http://localhost:9090`

- Grafana:
`http://localhost:3000`
Логин/пароль по умолчанию: `admin / admin`.
Основные дашборды:
- **Main Service Metrics** — метрики HTTP-эндпоинтов и бизнес-метрики сервиса.
- **Node Exporter** — системные метрики хоста (CPU, память, диск).
- **Logs Dashboard** — дашборд логов из Loki.

- Loki:
`http://localhost:3100` — источник логов для Grafana.

- Node Exporter:
`http://localhost:9100` — системные метрики.

- Статус/health самого сервиса:
- `GET /health` — простой healthcheck.
- `GET /stats` — эндпоинт статистики (имя сервиса, версия, текущее время).

---

## Внешнее API и аутентификация

Основные эндпоинты сервиса:

- `POST /team/add` — создать команду с участниками.
- `GET /team/get` — получить команду и список участников.
- `POST /users/setIsActive` — активировать/деактивировать пользователя.
- `GET /users/getReview` — получить список PR, где пользователь назначен ревьюером.
- `POST /pullRequest/create` — создать PR и автоматически назначить ревьюеров.
- `POST /pullRequest/merge` — пометить PR как смерженный.
- `POST /pullRequest/reassign` — переназначить ревьюера.
- `GET /stats` — простой эндпоинт статистики сервиса (service name, version, time).
- `GET /health` — healthcheck.
- `GET /metrics` — метрики Prometheus.

Аутентификация:

- Заголовок: `Authorization: Bearer :`
- Примеры:
- администратор: `Authorization: Bearer admin:u1`
- пользователь: `Authorization: Bearer user:u2`

Роль проверяется в HTTP-адаптере (`auth.go`). Для админских операций (создание команд, PR и т.п.) требуется `admin`, для чтения ревью достаточно `user`.

---

## Continuous Integration (CI)

Проект использует GitHub Actions для автоматической проверки качества кода и запуска unit-тестов при каждом push или pull-request в ветку `main`.

Workflow расположен по пути:

```text
.github/workflows/ci.yml
```

Основные шаги:

1. Получение репозитория
2. Установка
3. Установка `golangci-lint`

4. Запуск линтера

5. Запуск unit-тестов usecase-слоя

Интеграционные и нагрузочные тесты в CI не запускаются, так как требуют развернутого docker-окружения и внешних сервисов и выходят за рамки простого CI для тестового задания.

---

## Development Workflow

Весь процесс разработки велся в GitHub Projects в формате Kanban-доски.
Для каждой задачи создавался отдельный task (issue) и соответствующая feature-ветка.

Подход включал:

- постановку задач в столбец *Backlog*;
- перемещение задач по стадиям *In Progress → Review → Done*;
- выполнение каждого функционального блока в отдельной ветке (`features/*`);
- создание pull request после завершения задачи;
- автоматическую проверку изменений через GitHub Actions (линтер + unit-тесты);
- поддержание чистой истории коммитов и прозрачного хода работы.

Такая организация позволила:
- структурировать выполнение задания в виде небольших автономных задач;
- легко отслеживать прогресс;
- проводить разработку в соответствии с best-practices Git Flow;
- обеспечить читаемость и воспроизводимость истории репозитория.

---

## Реализованные требования

Обязательная часть:

- Реализован основной REST API в соответствии с контрактом.
- Хранение данных в PostgreSQL, миграции выполнены через отдельный контейнер `migrate`.
- Разделение слоёв в духе Чистой архитектуры: HTTP-адаптер, usecase-слой, хранилище, доменная модель.
- Логирование через общий модуль (`common/kit/logger`).
- Метрики в формате Prometheus, экспорт по `/metrics`.
- Настроены Prometheus, Grafana, Loki, Node Exporter, дашборды для метрик и логов.
- Подготовлена Postman-коллекция и окружение.

Дополнительная часть:

- Добавлен простой эндпоинт статистики: `GET /stats` (имя, версия, время).
- Проведено нагрузочное тестирование решения (k6, два сценария). Отчёт в `load-testing-report.md`.
- Реализовано интеграционное/E2E-тестирование (HTTP-тесты в `internal/integration-tests`).
- Описана конфигурация и запуск линтера (`golangci-lint`, gofumpt, errcheck и др.).

---

## Допущения и принятые решения

- Файл `.env` был добавлен в репозиторий по требованию из письма на электронную почту. Так же для корректной автоматической проверки задания файл `docker-compose.yml` был перенесен в корень проекта из папки `/ops`
- Аутентификация реализована через простой формат токена `Authorization: Bearer :`, так как в задании не было требований к полноценной auth-системе. Это позволяет сфокусироваться на бизнес-логике сервиса.
- Эндпоинт `/stats` возвращает базовую информацию о сервисе (name, version, time), а не сложную бизнес-статистику. Для более подробных показателей используются метрики Prometheus и дашборды Grafana.
- Массовая деактивация и безопасная переназначаемость открытых PR не реализованы в рамках тестового задания из-за ограничения по времени. Архитектура usecase-слоя и интерфейсов хранилища позволяет добавить эту логику позднее.