tradein/auth 4: Team-API — CRUD сотрудников, квоты, статистика (org-scoped) #2554

Open
opened 2026-07-30 06:21:24 +00:00 by lekss361 · 0 comments
Owner

Часть эпика #2549 (шаг 4/8). Блокирован: после #2552 (auth-core, нужен current-user dependency). Worker: backend-engineer.

Scope

  • app/api/v1/team.py (новый роутер, префикс /api/v1/team/* — НЕ /admin/*):
    • POST /team/employees — создать сотрудника (username, пароль, display_name, monthly_limit); manager создаёт только в своём поддереве (manager_id = self.id), admin — куда угодно.
    • PATCH /team/employees/{id} — block/unblock (is_active), смена monthly_limit, reset пароля.
    • GET /team/employees — список + quota-status (used/remaining за текущий период); manager видит ТОЛЬКО manager_id = self.id, admin — всех.
    • GET /team/employees/{id}/history — история оценок (переиспользовать SQL-паттерн account_drilldown из app/api/v1/audit.py по user_events).
  • app/schemas/team.py (новый).
  • app/core/rbac.py: gate /api/v1/team/* → admin | manager; employee → 403.
  • Квота: запись monthly_limit в account_quota_overrides (upsert-паттерн миграции 191); account_quota.py логику НЕ переписывать.

DoD

  • Негативный тест org-изоляции обязателен: manager A не видит и не может патчить сотрудников manager B (403/пустой список, без утечки).
  • Смена лимита отражается в /api/v1/trade-in/quota сотрудника немедленно (без рестарта).
  • Origin/Referer-check на POST/PATCH.

Что НЕ делать

Фронт (шаг 6), seed существующих юзеров (шаг 7).

Часть эпика #2549 (шаг 4/8). **Блокирован**: после #2552 (auth-core, нужен current-user dependency). Worker: backend-engineer. ## Scope - `app/api/v1/team.py` (новый роутер, префикс `/api/v1/team/*` — НЕ `/admin/*`): - `POST /team/employees` — создать сотрудника (username, пароль, display_name, monthly_limit); manager создаёт только в своём поддереве (`manager_id = self.id`), admin — куда угодно. - `PATCH /team/employees/{id}` — block/unblock (`is_active`), смена `monthly_limit`, reset пароля. - `GET /team/employees` — список + quota-status (used/remaining за текущий период); manager видит ТОЛЬКО `manager_id = self.id`, admin — всех. - `GET /team/employees/{id}/history` — история оценок (переиспользовать SQL-паттерн account_drilldown из `app/api/v1/audit.py` по `user_events`). - `app/schemas/team.py` (новый). - `app/core/rbac.py`: gate `/api/v1/team/*` → admin | manager; employee → 403. - Квота: запись `monthly_limit` в `account_quota_overrides` (upsert-паттерн миграции 191); `account_quota.py` логику НЕ переписывать. ## DoD - **Негативный тест org-изоляции обязателен**: manager A не видит и не может патчить сотрудников manager B (403/пустой список, без утечки). - Смена лимита отражается в `/api/v1/trade-in/quota` сотрудника немедленно (без рестарта). - Origin/Referer-check на POST/PATCH. ## Что НЕ делать Фронт (шаг 6), seed существующих юзеров (шаг 7).
lekss361 added the
auth
scope/backend
security
tradein
labels 2026-07-30 06:23:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2554
No description provided.