gendesign/tradein-mvp/backend/app/api
bot-backend 4feb61c006
Some checks failed
CI Trade-In / changes (pull_request) Successful in 12s
CI / changes (pull_request) Successful in 15s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Failing after 5m27s
fix(tradein): резолвить роль из реестра, roles.yaml — только fallback (#3316)
Роль жила в двух местах сразу: люди заводятся в БД (`tradein_users.role`),
а `get_role` читал ТОЛЬКО `auth/roles.yaml` — и никто эти два источника не
сверял. Дефект двусторонний:

  * вверх: менеджер заводил сотрудника с именем, которое уже числится в
    roles.yaml админом (проверялись лишь regex и уникальность в БД) — на
    входе тот получал admin из YAML, то есть чтение ЛЮБОЙ чужой оценки
    (admin проходит мимо ownership-check в trade_in.py) и безлимитную квоту;
  * вниз: сотрудник, которого в roles.yaml нет, ловил KeyError → 403 на
    СОБСТВЕННУЮ оценку.

Источник теперь один и лечится один раз — в `app.core.auth.get_role`:
реестр (`tradein_users.role` / `auth.users.role`) спрашивается первым,
roles.yaml остаётся fallback для legacy-юзеров, у которых строки в реестре
нет. Реестр недоступен → тоже fallback: падение БД не выключает legacy-вход.
Вызывающие (rbac, trade_in, team, account_quota) не менялись.

Сопутствующее, чтобы поведение существующих аккаунтов не поехало:
  * rbac_guard выбирает матчер путей по РОДУ роли (роль реестра → DB_ROLE_PATHS),
    иначе employee/manager на legacy-пути получил бы 403 на всё;
  * get_user_scope отдаёт scope роли реестра из того же DB_ROLE_PATHS;
  * право на персональный `unlimited` осталось за roles.yaml (account_quota +
    _batch_quota_status) — фикс убирает эскалацию, а не раздаёт новую;
  * `_batch_quota_status` берёт роли из уже прочитанных строк — иначе список
    «Команды» снова стал бы N+1.

Defense-in-depth: create_employee отдаёт 409 на username, за которым в
roles.yaml числится не-employee роль.
2026-09-02 14:49:27 +05:00
..
public fix(mera/public): Infinity/NaN во входе — 422, и бюджет считает такие запросы 2026-08-30 00:11:56 +05:00
v1 fix(tradein): резолвить роль из реестра, roles.yaml — только fallback (#3316) 2026-09-02 14:49:27 +05:00
__init__.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00