diff --git a/README.md b/README.md index c955644..064577b 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - [Функциональные возможности](#функциональные-возможности) - [Роли и права доступа](#роли-и-права-доступа) - [Установка и запуск](#установка-и-запуск) +- [Данные, сотрудники, интеграция с HR](#данные-сотрудники-интеграция-с-hr) - [Нефункциональные требования](#нефункциональные-требования) - [Вне scope](#вне-scope-не-реализуется-в-данной-версии) @@ -119,6 +120,15 @@ Старый вариант **только** с локальным Postgres на порту 5433: корневой `docker compose up -d` в TestingWebApp и в `.env` порт `5433` (или отдельные `DB_*` без `DATABASE_URL`) — оставлен для разработки без общего `Postgres_TG_Bots`. +### Данные, сотрудники, интеграция с HR + +- **Две роли кластера Postgres:** в **`clinic_tests`** — только сущности модуля тестирования (тесты, версии, назначения, попытки, локальные технические учётки при необходимости). В **`hr_bot_test`** (Postgres_TG_Bots / hr_web_viewer) — штат, справочники, существующий **RBAC** и веб-логины. Так мы не смешиваем схемы и не дублируем «источник правды» по людям. +- **Сотрудник в процессах** (назначения, дашборды, доступ к результатам) — везде по **`staff_members.id`**. Ссылки в `clinic_tests` храним как **тот же идентификатор** (логическая связь с `staff_members` в `hr_bot_test`); **ФИО, отдел, роли** подтягиваем из HR при отображении или кэшируем по согласованной политике, а не ведём второй кадровый учёт. +- **`telegram_id`** в данных сотрудника **не участвует** в бизнес-логике модуля: ни вход, ни проверка прав, ни выбор сотрудника в сценариях, ни фильтрация — только **справочная** информация при необходимости (отображение, история). +- **RBAC в перспективе:** единая система разрешений — та, что уже в HR (роли, `staff_role_assignments`, permissions). Модуль тестирования **не** развивает отдельную полную копию матрицы; проверка действий в целевом виде — через **HR** (внутренний API / токен / согласованные запросы к БД). Пока договор и API не готовы — допустимы временные флаги в `clinic_tests`, явно помечаемые как MVP. + +Детализация задач и варианты A.x: [docs/revision_task/card1.md](docs/revision_task/card1.md). + --- ## Нефункциональные требования diff --git a/backend/.env.example b/backend/.env.example index ebe1a27..bdda650 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,5 +1,7 @@ # Как в HR_TG_Bot: тот же Postgres из Postgres_TG_Bots (docker-compose.dev.yml), -# отдельная база clinic_tests — таблицы приложения не смешиваются с hr_bot_test. +# отдельная база clinic_tests — таблицы приложения не смешиваются с hr_bot_test +# (связь с штатом по staff_members.id; чтение hr_bot_test — отдельный DSN в коде, см. card1 A.x). +# telegram_id в бизнес-логике модуля не используем (только справка в HR). # # Локально (порт 5432 на хосте, как в Postgres_TG_Bots): # DATABASE_URL=postgresql://hr_bot_user:hrbot123@localhost:5432/clinic_tests diff --git a/docs/revision_task/BACKLOG.md b/docs/revision_task/BACKLOG.md index df92962..d8dd84b 100644 --- a/docs/revision_task/BACKLOG.md +++ b/docs/revision_task/BACKLOG.md @@ -12,6 +12,8 @@ **Первые спринты:** [sprint-01.md](sprint-01.md), [sprint-02.md](sprint-02.md) (и при наличии `sprint-02-testing`). +**Данные и интеграция с HR (зафиксировано):** один инстанс Postgres, **`clinic_tests`** — схема тестов; **`hr_bot_test`** — сотрудники и **RBAC**. Идентичность в процессах — **`staff_members.id`**; **`telegram_id`** только для справки, не для логики. Итоговая проверка прав — существующая HR-модель / API, без параллельной «второй» RBAC. Подробно: [card1](card1.md#хранение-связь-с-сотрудниками-rbac-зафиксировано), [README](../../README.md#данные-сотрудники-интеграция-с-hr). + --- ## A. Подготовка и база (фундамент) @@ -20,7 +22,7 @@ | --- | --- | | A.1 | Репозиторий, Docker Compose (PostgreSQL), .env, health | | A.2 | Схема БД, миграции: пользователи, подразделения, тесты, версии, попытки (см. [card1 V.1](card1.md)) | -| A.3 | Аутентификация: **локальная** **или** **через** [Postgres_TG_Bots](card1.md#часть-a--авторизация-по-паролю-бд-postgres_tg_bots) ([card1 A.x](card1.md)) | +| A.3 | Аутентификация: **локальная** (dev) **или** **через** [Postgres_TG_Bots / HR users](card1.md#часть-a--авторизация-по-паролю-бд-postgres_tg_bots); в прод — привязка к `staff_members.id`, RBAC из HR | | A.4 | CRUD тест/назначение/прохождение (база шагов `docs/шаги/`) + затем **B** | *Если A.1–A.4 частично сданы — добить по [sprint-01](sprint-01.md) и [card1](card1.md).* diff --git a/docs/revision_task/card1.md b/docs/revision_task/card1.md index a072b03..f98dd61 100644 --- a/docs/revision_task/card1.md +++ b/docs/revision_task/card1.md @@ -4,6 +4,13 @@ **Фактический стек репозитория [TestingWebApp](../../README.md):** Node.js (backend), PostgreSQL, Docker; фронт — SPA в `frontend/`. План доработок **не** привязывать к FastAPI, если в коде API на Express/Node. +### Хранение, связь с сотрудниками, RBAC (зафиксировано) + +- **Один кластер PostgreSQL** (как в [Postgres_TG_Bots](../../../Postgres_TG_Bots)): отдельные **базы** — **`clinic_tests`** (тесты, назначения, попытки, миграции модуля) и **`hr_bot_test`** (штат, справочники, уже реализованный **RBAC**). Таблицы модуля тестов **не** вешаем в `hr_bot_test`, чтобы не конфликтовать по именам (`users`, `departments` и т.д. уже заняты смыслами HR). +- **Сотрудник в бизнес-процессах модуля тестирования** идентифицируется по **`staff_members.id`** (БД `hr_bot_test` / экосистема [hr_web_viewer](../../../Postgres_TG_Bots/hr_web_viewer)). В `clinic_tests` храним **суррогатные ссылки** на сотрудника (например `staff_id` / UUID той же сущности), без дублирования ФИО и кадровых данных в долгую. +- **`telegram_id`** в данных сотрудника — **только справка** (в т.ч. для исторических выгрузок, отображения). **Ни назначения, ни проверок прав, ни выбор сотрудника в сценариях модуля** от `telegram_id` **не** зависят и не должны зависеть. +- **RBAC:** единая цель — опираться на **уже существующую** в клинике модель (роли, привязки к сотруднику, permissions). Проверка «можно ли действие» в конечном варианте — через **HR API** / общий auth-контур и/или согласованное чтение RBAC-таблиц; в `clinic_tests` **не** строим параллельную полную матрицу ролей. На переходных этапах допустимы упрощения (MVP-флаги), пока в контракте не зафиксировано иное. + --- ## Часть V — Версионирование (цель: корректная история при правках автора) @@ -51,15 +58,15 @@ ## Часть A — Авторизация по паролю, БД [Postgres_TG_Bots](../../../Postgres_TG_Bots) -**Контекст:** в `Postgres_TG_Bots`/`hr_web_viewer` учёт `users` с полями `username`, `password_hash` (Werkzeug `pbkdf2:sha256` / `scrypt` через `werkzeug.security` — см. `hr_web_viewer/models/user_models.py`). +**Контекст:** в `Postgres_TG_Bots`/`hr_web_viewer` учёт `users` с полями `username`, `password_hash` (Werkzeug `pbkdf2:sha256` / `scrypt` через `werkzeug.security` — см. `hr_web_viewer/models/user_models.py`). **Идентичность сотрудника** для сценариев тестов — по **`staff_members.id`** (см. блок «Хранение…» выше); **`telegram_id` не используем** в логике входа, назначений и прав. | ID | Задача | Критерий | | --- | --- | --- | -| A.1 | Режим `DATABASE_URL` (или `HR_DATABASE_URL`) на **ту же** БД, что и `Postgres_TG_Bots`, read-only **или** отдельный пользователь с `SELECT` на `users` (+ при необходимости `staff_members` для `department_id`) | Пример `.env` в `TestingWebApp` | +| A.1 | Вторичное соединение: `HR_DATABASE_URL` (или DSN) к **`hr_bot_test`**, read-only **или** отдельный пользователь с `SELECT` на `users` и `staff_members` (для связки логин → `staff_id`, подразделение и т.д.) **отдельно** от `DATABASE_URL` в **`clinic_tests`** | Пример `.env` в `TestingWebApp` | | A.2 | Реализация `verifyPassword` в Node, **совместимой** с `check_password_hash` (использовать пакет, понимающий префиксы `pbkdf2:sha256:` и `scrypt:`) | Тест: тот же хеш, что сгенерировал Werkzeug | -| A.3 | Логин: по `username` → взять `id`, `password_hash`; при успехе — JWT/сессия **TestingWebApp** с `user_id` (и маппинг на локальный UUID, если в приложении внутри свои `users` — **документировать** стратегию: single source = HR DB **или** sync) | Нет дублирования паролей в две таблицы в долгую | +| A.3 | Логин: по `username` → `users` в `hr_bot_test`; при успехе — токен **TestingWebApp** с привязкой к **`staff_members.id`** (и при необходимости к локальному `users` в `clinic_tests` только как технический mirror **без** отдельного жизненного цикла пароля). Пароли **только** в HR-таблице `users` | Нет дублирования паролей в долгую | | A.4 | Отключить/не использовать регистрацию с локальным `password_hash` в прод-режиме, если включён `HR_AUTH=1` | Флаг в `.env` | -| A.5 | Маппинг ролей: `users` не содержит `hr`/`manager` — связать `staff_members.web_login` = `users.username` и взять роль из существующей HR-модели **или** MVP: одна роль + админ-лист | Зафиксировать в README Card 1 | +| A.5 | Маппинг ролей: взять из **существующей** RBAC-модели HR (см. `staff_role_assignments` / roles & permissions) **или** согласованный вызов **HR API**; MVP — ограниченный набор, без опоры на `telegram_id` | [README — данные и интеграция](../../README.md#данные-сотрудники-интеграция-с-hr) | --- diff --git a/docs/revision_task/sprint-01.md b/docs/revision_task/sprint-01.md index 395733b..0fa2dc8 100644 --- a/docs/revision_task/sprint-01.md +++ b/docs/revision_task/sprint-01.md @@ -8,6 +8,8 @@ **Стек (факт по репозиторию [TestingWebApp](../../README.md)):** **Node.js** (API в `backend/`), **PostgreSQL**, **Docker**; фронтенд **desktop-first** SPA. Интеграция с [HR_TG_Bot](../../../HR_TG_Bot/README.md) / экосистемой — по готовности API-контрактов, **не** обязана совпадать с FastAPI, если в этом репо бэкенд на Node. При переносе на Python — пересмотреть только слой API, **смысл** [card1.md](card1.md) не меняется. +**Данные:** БД `clinic_tests` на общем кластере; сотрудник в сценариях — `staff_members.id`; `telegram_id` — только справка; RBAC — из HR. См. [card1 (вступление)](card1.md#хранение-связь-с-сотрудниками-rbac-зафиксировано). + --- ## Цель спринта diff --git a/docs/revision_task/task.md b/docs/revision_task/task.md index fe75905..2c93305 100644 --- a/docs/revision_task/task.md +++ b/docs/revision_task/task.md @@ -70,6 +70,15 @@ AI-помощник меняет это кардинально: Замена ручного сбора статистики на один экран с нужным срезом: сотрудник видит свои тесты и историю, руководитель — своё подразделение, директор — всю клинику с возможностью посмотреть любое подразделение и любого сотрудника. +### 2.6. Хранение в PostgreSQL, сотрудники и RBAC (зафиксировано для реализации) + +- **Один кластер PostgreSQL** (как в экосистеме Postgres_TG_Bots / HR): отдельная база **`clinic_tests`** — тесты, версии, назначения, попытки и миграции модуля; база **`hr_bot_test`** — штат, справочники, веб-логины и **уже реализованный RBAC**. Схемы не объединять в одну БД без отдельного решения: в `hr_bot_test` заняты имена и смыслы таблиц (`users`, `departments` и др.) под HR. +- Во **всех бизнес-процессах** модуля тестирования сотрудник идентифицируется по **`staff_members.id`**. В `clinic_tests` хранятся **ссылки** на этот идентификатор; кадровые данные и структура подразделений — из HR, без дублирования «второго реестра людей». +- Поле **`telegram_id`** у сотрудника **не используется** в логике модуля (вход, назначения, фильтры, права) — только как **справочная** информация при необходимости. +- **Разграничение прав** в целевом виде — через **существующую** в клинике систему (роли, permissions, привязки к сотруднику); модуль **не** строит параллельную полную копию RBAC. Допустимы временные упрощения до согласования API с HR. + +Детализация: [card1.md](card1.md) (вступление), [README](../../README.md#данные-сотрудники-интеграция-с-hr). + ## 3. Этапы | № | Этап | Формат | Кто принимает | @@ -204,8 +213,8 @@ AI-помощник меняет это кардинально: **Ключевые изменения:** - Собственная авторизация модуля тестирования отключается. Вход выполняется через HR (SSO, JWT или другой механизм, который будет определён командой HR). -- Пользователи, подразделения и роли приходят из HR — не хранятся в локальной БД модуля тестирования (или хранятся как кэш, синхронизируемый с HR). -- Разграничение прав доступа (кто что видит и что может делать) выполняется по ролям, приходящим из HR. Соответствие ролей HR-системы и возможностей модуля тестирования определяется отдельно в начале этапа. +- Пользователи, подразделения и роли приходят из HR — не хранятся в локальной БД модуля тестирования (или хранятся как кэш, синхронизируемый с HR). **Идентичность сотрудника** в данных и при интеграции — по **`staff_members.id`** (см. §2.6); идентификаторы **Telegram** в этих цепочках **не** используются. +- Разграничение прав доступа (кто что видит и что может делать) выполняется по **существующей** HR-модели RBAC (роли, permissions, привязка к `staff_members.id`). Соответствие ролей HR-системы и возможностей модуля тестирования определяется отдельно в начале этапа. - Назначение тестов остаётся внутри модуля тестирования (а не в HR). Это отдельный пользовательский сценарий, который удобнее оставить рядом с редактором и трекером. - Дашборды используют ФИО, подразделения и иерархию из HR. diff --git a/docs/шаги/01-project-setup.md b/docs/шаги/01-project-setup.md index 47e3b41..e7e1a69 100644 --- a/docs/шаги/01-project-setup.md +++ b/docs/шаги/01-project-setup.md @@ -26,7 +26,7 @@ ### 1.3. Настройка окружения -- PostgreSQL: общий кластер с [Postgres_TG_Bots](../../../Postgres_TG_Bots) / [HR_TG_Bot](../../../HR_TG_Bot) (`DATABASE_URL` в `backend/.env`, отдельная БД `clinic_tests` — см. [README — Установка и запуск](../../README.md#установка-и-запуск)). Опционально: локальный Postgres только для TestingWebApp — корневой `docker-compose.yml` (порт 5433). +- PostgreSQL: общий кластер с [Postgres_TG_Bots](../../../Postgres_TG_Bots) / [HR_TG_Bot](../../../HR_TG_Bot) (`DATABASE_URL` в `backend/.env`, отдельная БД `clinic_tests` — см. [README — Установка и запуск](../../README.md#установка-и-запуск)). Сотрудник в будущей интеграции — по **`staff_members.id`** в `hr_bot_test`; **`telegram_id`** в процессах модуля не используем. Опционально: локальный Postgres только для TestingWebApp — корневой `docker-compose.yml` (порт 5433). - Переменные окружения (`.env` по образцу `backend/.env.example`) - Настройка линтеров и форматтеров