BUG-022: PATCH роли — duplicate salary_formulas при обновлении

Описание

При редактировании роли (PATCH /roles/{id}) с salary_formula в body — сервер возвращает 500. Причина: RoleService пытается INSERT новую запись в salary_formulas с тем же role_id, но unique constraint uq_salary_formulas_role (UNIQUE на role_id WHERE employee_id IS NULL) блокирует вставку.

Запрос

PATCH https://erp-test.nirbi.ru/api/v1/admin/roles/122373b9-fa03-434f-ab8c-e9f912ed2445
{
  "name": "Кассир",
  "description": "Работа на кассе\nПрием заказов",
  "permissions": ["pos.cash.deposit", "pos.cash.withdraw", "pos.discount.apply", "pos.orders.create", "pos.shift.close", "pos.shift.open", "pos.access"],
  "salary_formula": {
    "formula_type": "hourly",
    "hourly_rate": 350,
    "overtime_rate": 700,
    "norm_hours": null
  }
}

Ошибка

duplicate key value violates unique constraint "uq_salary_formulas_role"
Detail: Key (role_id)=(122373b9-fa03-434f-ab8c-e9f912ed2445) already exists.

Ожидаемое поведение

При PATCH с salary_formula:

  • Если формула для этой роли уже есть → UPDATE существующую
  • Если нет → INSERT новую
  • Если salary_formula = null → DELETE существующую

Фактическое поведение

RoleService.update() всегда делает INSERT → duplicate key если формула уже была создана при POST /roles.

Анализ

Та же проблема что BUG-019 (Store schedules) — нужен upsert вместо insert. В RoleService.update() при обработке salary_formula:

  1. Если формула уже есть для роли → нужно найти и обновить
  2. Если нет → создать

Затронутые сервисы

СервисПроблема
User ServiceRoleService.update() — INSERT salary_formula без предварительной проверки/DELETE