Обновить спецификацию auth session-модели для admin API (#23).
Документировать refresh JWT, rotation/reuse и фазы внедрения. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+47
-4
@@ -173,7 +173,8 @@ EventHub — платформа для управления событиями
|
||||
- Поддержка 100 000+ пользователей.
|
||||
- Горизонтальное масштабирование добавлением новых узлов.
|
||||
- Все персистентные таблицы хранятся в `disc_copies` на каждом узле (задача #13).
|
||||
- Сессионные таблицы (`session`, `admin_session`) оставлены в `ram_copies` для скорости.
|
||||
- Сессионные таблицы: `auth_session` (единая модель refresh JWT) хранится в `disc_copies` для кластерной устойчивости.
|
||||
- Legacy-таблицы `session` и `admin_session` (`ram_copies`) сохранены для пользовательского `/v1/refresh` до фазы 2.
|
||||
- Индексы созданы для часто запрашиваемых полей (calendar_id, start_time, event_type, status и др.) (задача #13).
|
||||
- Полная репликация горячих таблиц между всеми узлами кластера (задача #14).
|
||||
- Автоматическое обнаружение узлов через DNS-имя `eventhub-node` или статический список (задача #14).
|
||||
@@ -263,6 +264,7 @@ src/
|
||||
- `GET /v1/admin/health` — состояние сервера.
|
||||
- `GET /v1/admin/stats` — статистика.
|
||||
- `POST /v1/admin/login` — вход администратора.
|
||||
- `POST /v1/admin/refresh` — обновление пары access/refresh JWT администратора.
|
||||
- `GET /v1/admin/users`, `GET /v1/admin/users/:id` — пользователи.
|
||||
- `GET /v1/admin/reports`, `GET /v1/admin/reports/:id` — жалобы.
|
||||
- `DELETE /v1/admin/reviews/:id` — удалить отзыв.
|
||||
@@ -276,9 +278,50 @@ src/
|
||||
- `GET /v1/admin/audit` — аудит.
|
||||
|
||||
## 6.1. Аутентификация и авторизация
|
||||
- Пользователи и администраторы используют разные эндпоинты и JWT-токены.
|
||||
- Access-токен имеет срок жизни 1 час, refresh-токен — 30 дней.
|
||||
- Все защищённые эндпоинты требуют заголовок `Authorization: Bearer <token>`.
|
||||
|
||||
### Общие принципы
|
||||
- Пользователи и администраторы используют разные эндпоинты и JWT-секреты.
|
||||
- Access-токен — короткоживущий stateless JWT (HS256).
|
||||
- Refresh-токен — 30 дней; для admin API реализован как подписанный JWT (фаза 1, #23).
|
||||
- Все защищённые эндпоинты требуют заголовок `Authorization: Bearer <access_token>`.
|
||||
|
||||
### Единая session-модель (`auth_session`, фаза 1 — admin)
|
||||
|
||||
Таблица Mnesia `auth_session` (`disc_copies`):
|
||||
| Поле | Описание |
|
||||
|------|----------|
|
||||
| `session_id` | Первичный ключ сессии устройства |
|
||||
| `family_id` | Семейство ротаций одной сессии |
|
||||
| `subject_id` | ID пользователя или администратора |
|
||||
| `subject_type` | `user` \| `admin` |
|
||||
| `client_type` | `admin` \| `web` \| `mobile` |
|
||||
| `current_jti` | Актуальный jti refresh JWT |
|
||||
| `expires_at` | Срок жизни сессии (30 дней) |
|
||||
| `revoked` | Флаг отзыва |
|
||||
|
||||
**Refresh JWT (admin)** — claims:
|
||||
- `typ=refresh`, `aud=admin`, `sub=<admin_id>`
|
||||
- `sid=<session_id>`, `fid=<family_id>`, `jti=<current_jti>`
|
||||
- `client=admin`, `exp`, `iat`
|
||||
|
||||
**Поток login admin** (`POST /v1/admin/login`):
|
||||
1. Проверка email/password.
|
||||
2. Создание записи `auth_session`.
|
||||
3. Ответ: `{ token, refresh_token, user }`.
|
||||
|
||||
**Поток refresh admin** (`POST /v1/admin/refresh`):
|
||||
1. Верификация подписи и срока refresh JWT.
|
||||
2. Сверка `jti` из JWT с `current_jti` в Mnesia.
|
||||
3. При совпадении — ротация: новый `jti`, новая пара токенов.
|
||||
4. При несовпадении (reuse) — `revoke_family`, ответ 401.
|
||||
|
||||
**Фазы внедрения:**
|
||||
- Фаза 1 (#23): admin API — реализовано.
|
||||
- Фаза 2: user `/v1/refresh` на той же модели.
|
||||
- Фаза 3: client web + mobile (тот же контракт `{token, refresh_token}`).
|
||||
|
||||
### Legacy user refresh (до фазы 2)
|
||||
- `POST /v1/login` + `POST /v1/refresh` используют opaque refresh-токен в таблице `session` (`ram_copies`).
|
||||
|
||||
## 7. ВЕРСИОНИРОВАНИЕ И СТАТУС
|
||||
Текущая версия: 1.5 (MVP, альфа). Включает:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# **Техническое задание EventHub**
|
||||
## 1. [EventHub Backend — Техническое задание](EventHubBackSpec.md)
|
||||
## 2. [EventHub Admin UI — Техническое задание](EventHubFrontAdminSpec.md)
|
||||
## 3. [Правила работы (workflow)](WORKFLOW.md)
|
||||
|
||||
# **Репозитории разработки EventHub**
|
||||
## 1. [EventHub Backend](https://git.sabilin.com/EventHub/EventHubBack)
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
# EventHub — правила работы
|
||||
|
||||
Живой документ процесса разработки. Дополняется по мере появления новых договорённостей.
|
||||
|
||||
**Репозитории:** `EventHubBack`, `EventHubFrontAdmin`, `EventHubSpec`
|
||||
**Трекер:** https://git.sabilin.com/EventHub
|
||||
**Cursor skill для задач:** `eventhub-gitea`
|
||||
|
||||
---
|
||||
|
||||
## 1. Задачи (Gitea)
|
||||
|
||||
### Язык
|
||||
Все задачи, комментарии и описания — **на русском**.
|
||||
Исключение: имена файлов, пути API, идентификаторы в backticks.
|
||||
|
||||
### Жизненный цикл
|
||||
|
||||
| Этап | Действие |
|
||||
|------|----------|
|
||||
| Старт | Прочитать issue → назначить на себя → комментарий «Беру в работу» |
|
||||
| План | **Предложить 1–3 варианта решения с trade-offs → ждать утверждения** |
|
||||
| Работа | После утверждения — код в репозитории-владельце; коммиты с `Refs EventHub/<repo>#N` |
|
||||
| Финиш | Тесты зелёные → комментарий с итогом → закрыть issue |
|
||||
|
||||
### Метки (единый набор во всех репо)
|
||||
|
||||
| Метка | Назначение |
|
||||
|-------|------------|
|
||||
| Bug | Дефект |
|
||||
| Task | Техническая задача |
|
||||
| Story | Пользовательская история |
|
||||
| Epic | Крупная инициатива |
|
||||
| Future | Отложено |
|
||||
|
||||
Синхронизация меток: `~/.cursor/skills/eventhub-gitea/scripts/sync-labels.ps1`
|
||||
|
||||
### Приоритеты
|
||||
`P0` → `P1` → `P2` (указывается в заголовке задачи).
|
||||
|
||||
---
|
||||
|
||||
## 2. Тестирование (обязательный gate)
|
||||
|
||||
**Нельзя** закрывать задачу и **нельзя** обновлять спеку, пока:
|
||||
|
||||
- пройдены релевантные тесты репозитория;
|
||||
- выполнена ручная проверка, если автотестов нет;
|
||||
- нет известных регрессий в затронутой области.
|
||||
|
||||
| Репозиторий | Минимум |
|
||||
|-------------|---------|
|
||||
| EventHubBack | `make test` / `make eunit` / целевые API-тесты |
|
||||
| EventHubFrontAdmin | `npm run lint`, `npm run build` |
|
||||
| EventHubSpec | ревью текста, ссылки на код |
|
||||
|
||||
---
|
||||
|
||||
## 3. Спецификация (после успешных тестов)
|
||||
|
||||
Если изменение затрагивает **поведение, API, модель данных или роли**:
|
||||
|
||||
1. Обновить соответствующий файл в `EventHubSpec/`:
|
||||
- backend → `EventHubBackSpec.md`
|
||||
- admin → `EventHubFrontAdminSpec.md`
|
||||
2. В комментарии к issue указать: «Спека обновлена: …»
|
||||
3. Спека описывает **фактическую** реализацию, не планы.
|
||||
|
||||
Что синхронизировать:
|
||||
- endpoint-ы (путь, метод, auth);
|
||||
- форматы запросов/ответов;
|
||||
- поля records/таблиц;
|
||||
- роли и права;
|
||||
- ограничения и допущения.
|
||||
|
||||
Чистый рефакторинг без смены контракта — обновление спеки не обязательно (написать в issue).
|
||||
|
||||
---
|
||||
|
||||
## 4. Расширение правил
|
||||
|
||||
При появлении новой договорённости в работе:
|
||||
|
||||
1. Добавить пункт в этот файл (раздел «Правила» ниже).
|
||||
2. При необходимости — задача `Task` в `EventHubSpec` на согласование.
|
||||
3. Для Cursor — обновить skill `eventhub-workflow`.
|
||||
|
||||
---
|
||||
|
||||
## Правила (накопительный список)
|
||||
|
||||
- Задачи в Gitea вести через skill `eventhub-gitea`; тексты на русском.
|
||||
- **Перед реализацией** — предложить оптимальные варианты решения; кодить только после утверждения варианта пользователем.
|
||||
- Перед закрытием issue — успешные тесты изменённого кода.
|
||||
- После успешных тестов — обновить спеку, если менялся внешний контракт.
|
||||
- Одна задача — один логический объём работы.
|
||||
- Код фичи — в репозитории-владельце; `EventHubSpec` — для документации и процесса.
|
||||
- Метки во всех репозиториях держать одинаковыми (`sync-labels.ps1`).
|
||||
- Секреты и токены не коммитить; Gitea token — только в env / `~/.cursor/secrets/`.
|
||||
|
||||
---
|
||||
|
||||
## История
|
||||
|
||||
| Дата | Изменение |
|
||||
|------|-----------|
|
||||
| 2026-07-07 | Правило: варианты решения и утверждение перед реализацией |
|
||||
| 2026-07-07 | Первая версия: Gitea workflow, gate тестирования, sync спеки |
|
||||
Reference in New Issue
Block a user