Skip to content

Akoridj/test-task-for-junior-backend-developer

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Task Service

Сервис для управления задачами с HTTP API на Go. Поддерживает создание, редактирование, удаление, просмотр задач и настройку периодичности задач.

Требования

  • Go 1.23+
  • Docker и Docker Compose

Быстрый запуск через Docker Compose

docker compose up --build

После запуска сервис будет доступен по адресу http://localhost:8080.

Если postgres уже запускался ранее со старой схемой, пересоздайте volume:

docker compose down -v
docker compose up --build

Причина: SQL-файлы из migrations/ монтируются в docker-entrypoint-initdb.d и применяются только при инициализации пустого data volume.

Swagger

Swagger UI:

http://localhost:8080/swagger/

OpenAPI JSON:

http://localhost:8080/swagger/openapi.json

API

Базовый префикс API:

/api/v1

Задачи (Tasks)

  • POST /api/v1/tasks - создание задачи (с опциональной периодичностью)
  • GET /api/v1/tasks - список задач (шаблоны скрыты)
  • GET /api/v1/tasks?date=2026-04-15 - задачи на конкретную дату
  • GET /api/v1/tasks/{id} - получение задачи по ID
  • PUT /api/v1/tasks/{id} - обновление задачи
  • DELETE /api/v1/tasks/{id} - удаление задачи

Периодичность (Recurrence)

  • GET /api/v1/tasks/{id}/recurrence - получить правило периодичности
  • PUT /api/v1/tasks/{id}/recurrence - обновить правило периодичности
  • DELETE /api/v1/tasks/{id}/recurrence - удалить правило периодичности

Фича: периодичность задач

Описание

Многие задачи для медицинского персонала выполняются периодически. Фича позволяет задать настройки периодичности при создании задачи, после чего система автоматически генерирует конкретные экземпляры задач на нужные даты.

Типы периодичности

Тип Описание Ключевые параметры
daily Каждый N-й день interval_days (по умолчанию 1)
monthly Каждое определенное число месяца day_of_month (1–30)
specific_dates Только на указанные даты specific_dates (массив дат)
even_odd По четным или нечетным дням месяца even_odd ("even" / "odd")

Архитектура: шаблон → экземпляры

При создании задачи с правилом периодичности создается задача-шаблон (is_template = true). Шаблон не отображается в обычном списке задач.

Фоновый планировщик (scheduler) запускается при старте приложения и каждый час проверяет активные правила периодичности. Для каждого правила, на ближайшие 7 дней, он генерирует экземпляры задач - обычные задачи со ссылкой на шаблон (parent_task_id) и конкретной датой (scheduled_date).

Экземпляры создаются со статусом new, независимо от статуса шаблона.

Примеры использования

Создание ежедневной задачи (каждый день):

curl -X POST http://localhost:8080/api/v1/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Обход пациентов",
    "description": "Обойти палаты 1-5",
    "recurrence": {
      "type": "daily",
      "interval_days": 1,
      "start_date": "2026-04-01"
    }
  }'

Создание задачи каждый 3-й день:

curl -X POST http://localhost:8080/api/v1/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Еженедельная инвентаризация",
    "recurrence": {
      "type": "daily",
      "interval_days": 3,
      "start_date": "2026-04-01",
      "end_date": "2026-12-31"
    }
  }'

Ежемесячная задача (15-го числа):

curl -X POST http://localhost:8080/api/v1/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Формирование отчетности",
    "recurrence": {
      "type": "monthly",
      "day_of_month": 15,
      "start_date": "2026-04-01"
    }
  }'

Задача на конкретные даты:

curl -X POST http://localhost:8080/api/v1/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Плановая операция",
    "recurrence": {
      "type": "specific_dates",
      "specific_dates": ["2026-04-15", "2026-05-01", "2026-06-10"],
      "start_date": "2026-04-01"
    }
  }'

Задача по четным дням:

curl -X POST http://localhost:8080/api/v1/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Формирование отчетности (четные дни)",
    "recurrence": {
      "type": "even_odd",
      "even_odd": "even",
      "start_date": "2026-04-01"
    }
  }'

Получение задач на конкретную дату:

curl http://localhost:8080/api/v1/tasks?date=2026-04-15

Просмотр правила периодичности:

curl http://localhost:8080/api/v1/tasks/1/recurrence

Принятые решения и предположения

Архитектурные решения

  1. Шаблон vs экземпляр. Задача с правилом периодичности становится шаблоном (is_template = true). На основе шаблона автоматически создаются конкретные экземпляры задач (is_template = false, parent_task_id указывает на шаблон). Это позволяет:

    • Отображать в списке только реальные задачи с конкретными датами
    • Сохранять историю всех выполненных экземпляров
    • Менять статус каждого экземпляра независимо
  2. Отдельная таблица recurrence_rules. Правило периодичности - отдельная сущность (Single Responsibility). Одна задача = одно правило (UNIQUE constraint).

  3. Фоновый планировщик (scheduler). Запускается при старте приложения как горутина. Проверяет правила каждый час и генерирует задачи на 7 дней вперед. Идемпотентен - не создает дубликаты.

  4. Каскадное удаление. При удалении шаблона все его экземпляры и правило удаляются автоматически (ON DELETE CASCADE в БД).

Граничные случаи

  1. Диапазон дней месяца - 1..30. Согласно заданию, для monthly допустимы числа от 1 до 30.

  2. Февраль и короткие месяцы. Если day_of_month = 30, а в месяце нет 30-го числа (например, февраль), задача на этот месяц не создается. Это корректное поведение - ежемесячная задача «на 30-е число» не может появиться в месяце без 30-го числа.

  3. Дубликаты. Перед созданием экземпляра scheduler проверяет ExistsByParentAndDate. Это гарантирует идемпотентность при перезапусках.

  4. Статус экземпляров. Все автоматически созданные экземпляры получают статус new. Статус шаблона при этом не влияет на экземпляры.

  5. Обновление правила. При обновлении правила периодичности все будущие экземпляры со статусом new удаляются. Scheduler пересоздаст их при следующем тике по новому правилу.

  6. Часовой пояс. Все даты обрабатываются в UTC. Предполагается, что клиент передает даты в формате YYYY-MM-DD.

  7. Look-ahead = 7 дней. Scheduler генерирует задачи на 7 дней вперед, чтобы пользователи могли видеть ближайшие запланированные задачи. При необходимости значение легко изменить.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Go 99.1%
  • Dockerfile 0.9%