143 lines
6.4 KiB
Markdown
143 lines
6.4 KiB
Markdown
# План: Мультифилиальность и роли пользователей
|
||
|
||
## Проблема
|
||
Сейчас приложение однофилиальное и одно-user-овое. Нужно поддержать:
|
||
- 5-20 филиалов
|
||
- Несколько тьюторов/админов
|
||
- Филиал студента определяется автоматически через его группу
|
||
|
||
---
|
||
|
||
## 1. База данных — схема
|
||
|
||
### Новые таблицы
|
||
|
||
```sql
|
||
-- Филиалы
|
||
CREATE TABLE branches (
|
||
id SERIAL PRIMARY KEY,
|
||
name VARCHAR(100) NOT NULL UNIQUE,
|
||
created_at TIMESTAMPTZ DEFAULT now()
|
||
);
|
||
|
||
-- Пользователи системы
|
||
CREATE TABLE users (
|
||
id SERIAL PRIMARY KEY,
|
||
name VARCHAR(150) NOT NULL,
|
||
password_hash VARCHAR(255) NOT NULL,
|
||
role VARCHAR(20) NOT NULL DEFAULT 'tutor', -- 'admin' или 'tutor'
|
||
branch_id INT REFERENCES branches(id), -- NULL для супер-админа
|
||
created_at TIMESTAMPTZ DEFAULT now()
|
||
);
|
||
```
|
||
|
||
### Изменения в существующих таблицах
|
||
|
||
| Таблица | Новое поле | Тип | Связь |
|
||
|---------|-----------|-----|-------|
|
||
| `groups` | `branch_id` | `INT` | `REFERENCES branches(id)` |
|
||
| `students` | `branch_id` | `INT` | `REFERENCES branches(id)` |
|
||
| `entries` | `branch_id` | `INT` | `REFERENCES branches(id)` |
|
||
| `group_photos` | `branch_id` | `INT` | `REFERENCES branches(id)` |
|
||
|
||
### Логика определения филиала
|
||
- Студент → в группе → группа привязана к филиалу → филиал определён
|
||
- При отправке записи `branch_id` берётся из группы студента
|
||
- Студенту не нужно выбирать филиал — он определяется автоматически
|
||
|
||
---
|
||
|
||
## 2. Аутентификация
|
||
|
||
- Вход по **имени + пароль** (без email)
|
||
- Пароли хранятся в `bcrypt` хеше
|
||
- Токен (JWT) выдаётся при логине, хранится в `sessionStorage`
|
||
- `requireAdmin` заменяется на `requireAuth` + проверку роли
|
||
|
||
---
|
||
|
||
## 3. Роли
|
||
|
||
| Роль | Возможности |
|
||
|------|-------------|
|
||
| **admin** | Всё: управление пользователями, филиалами, настройками, бэкапами + все данные |
|
||
| **tutor** | Управление записями, группами, студентами, файлами, ссылками — видит все группы |
|
||
|
||
---
|
||
|
||
## 4. Публичная форма
|
||
|
||
- Ссылка на форму одна (как сейчас)
|
||
- Студент вводит имя → система находит студента → определяет группу → определяет филиал
|
||
- Если студент новый (нет в базе) — варианты на обсуждение:
|
||
- Не пускать (только зарегистрированные студенты)
|
||
- Автоматически создать в группе "Не распределён"
|
||
|
||
---
|
||
|
||
## 5. Фронтенд — изменения
|
||
|
||
### Страница логина
|
||
- Поле "Имя" + "Пароль" вместо одного пароля
|
||
|
||
### Админ-панель
|
||
- В хедере/сайдбаре выпадающий список филиалов для фильтрации
|
||
- Группы — отображение филиала у каждой группы
|
||
- Студенты — отображение филиала у каждого студента
|
||
- Журнал — фильтр по филиалу
|
||
- Настройки — управление пользователями и филиалами (только для admin)
|
||
|
||
---
|
||
|
||
## 6. API — новые эндпоинты
|
||
|
||
| Метод | Путь | Описание |
|
||
|-------|------|----------|
|
||
| `POST` | `/api/auth/login` | Вход (имя + пароль → токен) |
|
||
| `GET` | `/api/branches` | Список филиалов |
|
||
| `POST` | `/api/branches` | Создать филиал (admin) |
|
||
| `DELETE` | `/api/branches/:id` | Удалить филиал (admin) |
|
||
| `GET` | `/api/users` | Список пользователей (admin) |
|
||
| `POST` | `/api/users` | Создать пользователя (admin) |
|
||
| `DELETE` | `/api/users/:id` | Удалить пользователя (admin) |
|
||
|
||
---
|
||
|
||
## 7. Миграция данных
|
||
|
||
- Существующие группы/студенты/записи автоматически попадут в филиал "Основной" (или первый созданный)
|
||
- `ADMIN_PASSWORD` из `.env` конвертируется в запись `users` с ролью `admin`
|
||
|
||
---
|
||
|
||
## 8. Структура файлов (рефакторинг)
|
||
|
||
```
|
||
server.js → рефакторинг на модули:
|
||
├── routes/
|
||
│ ├── auth.js (логин/аутентификация)
|
||
│ ├── branches.js (CRUD филиалов)
|
||
│ ├── users.js (CRUD пользователей)
|
||
│ ├── groups.js (существующие + branch_id)
|
||
│ ├── students.js (существующие + branch_id)
|
||
│ ├── entries.js (существующие + branch_id)
|
||
│ └── ...
|
||
├── middleware/
|
||
│ ├── auth.js (requireAuth, requireRole)
|
||
│ └── branch.js (branch scoping)
|
||
└── db.js (подключение к БД)
|
||
```
|
||
|
||
---
|
||
|
||
## Порядок реализации
|
||
|
||
1. **Миграция БД** — создать таблицы `branches`, `users`, добавить `branch_id` к существующим
|
||
2. **Миграция данных** — создать филиал "Основной", перенести существующие данные
|
||
3. **Бэкенд: аутентификация** — `auth.js` (логин, JWT, middleware)
|
||
4. **Бэкенд: CRUD филиалов и пользователей** — новые роуты
|
||
5. **Бэкенд: branch scoping** — добавить `branch_id` ко всем существующим запросам
|
||
6. **Фронтенд: логин** — новая страница логина
|
||
7. **Фронтенд: admin panel** — добавить фильтр филиалов, страницы управления
|
||
8. **Тестирование** — проверить все сценарии
|