No description
Find a file
erius b46ce61a75 Removed goconst lint (annoying in tests)
Implmeneted some more integration tests
2026-06-05 05:35:18 +03:00
.zed Added Swagger UI 2026-06-04 16:37:49 +03:00
cmd/server Added Swagger UI 2026-06-04 16:37:49 +03:00
docs Added Swagger UI 2026-06-04 16:37:49 +03:00
internal Added Swagger UI 2026-06-04 16:37:49 +03:00
migrations Added Swagger UI 2026-06-04 16:37:49 +03:00
tests Removed goconst lint (annoying in tests) 2026-06-05 05:35:18 +03:00
.env Added Swagger UI 2026-06-04 16:37:49 +03:00
.golangci.yml Removed goconst lint (annoying in tests) 2026-06-05 05:35:18 +03:00
docker-compose.yml Update README 2026-06-05 01:59:16 +03:00
Dockerfile Update README 2026-06-05 01:59:16 +03:00
go.mod Added Swagger UI 2026-06-04 16:37:49 +03:00
go.sum Added Swagger UI 2026-06-04 16:37:49 +03:00
README.md Update README 2026-06-05 01:59:16 +03:00

Тестовое задание hitalent

Запуск

git clone https://git.erius.dev/erius/hitalent-task.git
cd hitalent-task
docker compose up --build

По умолчанию API доступно на http://localhost:8080

Также по умолчанию включен Swagger UI, досутпный на http://localhost:8080/docs

Переменные среды APP_HOST_PORT и POSTGRES_HOST_PORT меняют маппинги хост порта для контейнеров, в случае, если у вас заняты порты по умолчанию, можно сделать следующее:

APP_HOST_PORT=30000 POSTGRES_HOST_PORT=30001 docker compose up --build

Остановить работу и уничтожить контейнеры:

docker compose down

Тесты

Запуск Unit-тестов:

go test ./...

Запуск интеграционных тестов:

go test -tags=integration -v ./tests

Переменные среды APP_HOST_PORT и POSTGRES_HOST_PORT также можно использовать в контексте тестов:

APP_HOST_PORT=30000 POSTGRES_HOST_PORT=30001 go test -tags=integration -v ./tests

Генерация Swagger документации

Для генерации Swagger документации испольузется swag:

go install github.com/swaggo/swag/cmd/swag@latest

В случае внесения изменений в документацию API методов в handler:

swag init -g cmd/server/main.go --parseInternal --parseDependency

Миграции базы данных

Для миграций используется goose:

go install github.com/pressly/goose/v3/cmd/goose@latest

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

.
├── cmd
│   └── server       Серверный бинарник
├── internal
│   ├── config       Конфигурация приложения
│   ├── core         Общие сущности и функциональность
│   ├── handler      Транспортный уровень, взаимодействие с приложением посредством http
│   ├── middleware   Различные middleware для handler
│   ├── repository   Уровень данных, абстракции между прилоежнием и хранилищем
│   └── service      Бизнес логика приложения
├── migrations       Миграции БД
└── tests            Интеграционные тесты

Описание

Архитекутра 3-х уровневая - транспортный, бизнес логика и данные.

Траснпортный уровень реализован в пакете handler, обрабатывает HTTP запросы от клиента, передает запросы на уровень бизнес логики.

Бизнес логика реализована в пакете service, на данный момент занимается лишь валидацией данных, хранит и получает данные из уровня данных.

Уровень данных реализован в пакете repository, задает способ взаимодействия с БД или другими хранилищами.

Простая схема взаимодействия уровеней:

classDiagram
    direction TB

  namespace handler {
    class HTTPHandler {
      -service OrganizationService
    }
  }
  
  namespace service {
    class OrganizationService {
      <<interface>>
      +CreateDepartment(name, parentID) Department
      +GetDepartment(id, depth, includeEmployees) Department
      +UpdateDepartment(id, newName, newParentID) Department
      +RemoveDepartmentCascade(id) error
      +RemoveDepartmentReassign(id, reassignID) error
      +CreateEmployee(depID, fullName, position, hiredAt) Employee
    }
  }

  namespace repository {
    class DepartmentRepository {
      <<interface>>
      +Create(name, parentID) DepartmentRow
      +Get(id) DepartmentRow
      +Update(id, name, parentID) DepartmentRow
      +RemoveCascade(id) error
      +RemoveReassign(id, reassignID) error
      +GetDetails(id, depth, includeEmployees) DepartmentDetails
    }
    class EmployeeRepository {
      <<interface>>
      +Create(depID, fullName, position, hiredAt) EmployeeRow
      +Get(id) EmployeeRow
      +Update(id, depID, fullName, position, hiredAt) EmployeeRow
      +Remove(id) error
    }
  }

  HTTPHandler ..> OrganizationService : uses
  OrganizationService ..> DepartmentRepository : uses
  OrganizationService ..> EmployeeRepository : uses