200 lines
12 KiB
Markdown
200 lines
12 KiB
Markdown
# Контекст проекта InviteMe
|
||
|
||
## Назначение
|
||
|
||
InviteMe — внутреннее веб-приложение для компании **Integrita**, предназначенное для организации регистрации гостей на корпоративные мероприятия. Является упрощённым аналогом Timepad: загрузка списка участников, генерация персональных QR-кодов, рассылка приглашений, контроль входа на мероприятии и административная аналитика.
|
||
|
||
## Бизнес-процесс
|
||
|
||
### 1. Подготовка до мероприятия
|
||
|
||
1. Администратор создаёт учётные записи организаторов и сотрудников на входе.
|
||
2. Организатор создаёт новое мероприятие в админ-панели.
|
||
3. Организатор формирует Excel-файл со столбцами:
|
||
- `Отдел`
|
||
- `ФИО`
|
||
- `Должность`
|
||
- `e-mail`
|
||
- `название фото`
|
||
4. Собирает фотографии гостей. Название каждого файла должно совпадать со значением в столбце `название фото`.
|
||
5. В админ-панели выбирает созданное мероприятие и загружает Excel. Система создаёт записи гостей в рамках этого мероприятия и генерирует для каждого уникальный QR-код.
|
||
6. Загружает фото (по одному или ZIP-архивом) в папку `app/static/uploads/photos/`.
|
||
7. При необходимости вручную добавляет, редактирует или блокирует гостей.
|
||
8. Запускает массовую рассылку приглашений. Каждый гость получает письмо с QR-кодом.
|
||
|
||
### 2. Вход на мероприятие
|
||
|
||
1. Сотрудники на входе открывают страницу `/check-in` на телефоне/планшете.
|
||
2. Авторизуются под учётной записью `staff`.
|
||
3. Проверяют гостей одним из способов:
|
||
- Сканирование QR-кода с экрана телефона или распечатки.
|
||
- Поиск по ФИО (вводят фамилию, выбирают из выпадающего списка).
|
||
4. На экране отображается крупное фото гостя, отдел, должность, email и кнопка «Отметить вход».
|
||
5. Сотрудник сверяет фото с гостем и нажимает кнопку.
|
||
6. Если гость уже был отмечен, система показывает предупреждение и время входа.
|
||
|
||
### 3. Аналитика во время и после мероприятия
|
||
|
||
1. Организатор в админ-панели видит:
|
||
- Общее количество гостей.
|
||
- Количество пришедших.
|
||
- Процент посещаемости.
|
||
- Список последних входов.
|
||
2. Может быстро проверить по ФИО, пришёл ли конкретный человек.
|
||
3. Может выгрузить отчёт в Excel с отметкой о посещении и временем входа для каждого участника.
|
||
|
||
## Роли пользователей
|
||
|
||
| Роль | Возможности |
|
||
|---|---|
|
||
| Администратор | Полный доступ: управление пользователями, всеми мероприятиями, гостями, рассылка, аналитика, отчёты |
|
||
| Организатор | Создание и управление своими мероприятиями, гостями, рассылка, аналитика, отчёты |
|
||
| Сотрудник на входе | Страница `/check-in`: выбор мероприятия, сканирование QR, поиск, отметка входа |
|
||
|
||
Пользователи создаются и управляются через веб-интерфейс администратора. При первом запуске создаются учётные записи по умолчанию:
|
||
|
||
- `admin` / `admin`
|
||
- `staff` / `staff`
|
||
|
||
> В production пароли обязательно меняются через переменные окружения или файл `.env`.
|
||
|
||
## Архитектура
|
||
|
||
```text
|
||
┌─────────────┐ ┌─────────────┐ ┌─────────────────┐
|
||
│ Браузер │──────│ Flask │──────│ SQLite │
|
||
│ (Admin/ │ │ (Python) │ │ (inviteme.db) │
|
||
│ Organizer/ │ │ │ └─────────────────┘
|
||
│ Staff) │ └──────┬──────┘
|
||
└─────────────┘ │
|
||
┌────────────────┼────────────────┐
|
||
│ │ │
|
||
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
|
||
│ QR-сервис │ │ Email │ │ Excel │
|
||
│ (qrcode) │ │ (SMTP) │ │ (openpyxl)│
|
||
└────────────┘ └───────────┘ └───────────┘
|
||
```
|
||
|
||
- **Flask** обрабатывает HTTP-запросы и рендерит HTML-шаблоны.
|
||
- **SQLite** хранит пользователей, мероприятия, гостей и историю входов.
|
||
- **Локальная файловая система** хранит фото и QR-коды.
|
||
- **SMTP** используется для отправки приглашений.
|
||
|
||
## Поток данных
|
||
|
||
### Импорт гостей
|
||
|
||
```text
|
||
Создание мероприятия в админ-панели
|
||
↓
|
||
Excel-файл
|
||
↓
|
||
excel_service.read_guests_from_excel()
|
||
↓
|
||
Создание/обновление записей Guest в SQLite (с привязкой к мероприятию)
|
||
↓
|
||
qr_service.generate_qr_for_guest() для каждого нового гостя
|
||
↓
|
||
Готовность к рассылке
|
||
```
|
||
|
||
### Рассылка приглашений
|
||
|
||
```text
|
||
Гость с invitation_sent = false
|
||
↓
|
||
email_service.send_invitation()
|
||
↓
|
||
HTML-шаблон + QR-код как вложение
|
||
↓
|
||
Отправка через SMTP
|
||
↓
|
||
invitation_sent = true
|
||
```
|
||
|
||
### Проверка входа
|
||
|
||
```text
|
||
QR-код → URL /check-in?token=<uuid>
|
||
↓
|
||
Загрузка карточки гостя
|
||
↓
|
||
POST /api/check-in/<token>
|
||
↓
|
||
Проверка: уже отмечен?
|
||
↓
|
||
Создание записи CheckIn или возврат ошибки 409
|
||
```
|
||
|
||
## Формат Excel
|
||
|
||
Обязательные столбцы (имена должны совпадать точно):
|
||
|
||
| Столбец | Описание | Пример |
|
||
|---|---|---|
|
||
| `Отдел` | Название отдела | IT |
|
||
| `ФИО` | Полное имя | Иванов Иван Иванович |
|
||
| `Должность` | Должность гостя | Разработчик |
|
||
| `e-mail` | Email для рассылки | ivanov@company.com |
|
||
| `название фото` | Имя файла фото | ivanov.jpg |
|
||
|
||
> Важно: значение в столбце `название фото` должно точно совпадать с именем загруженного файла, включая расширение.
|
||
|
||
## Хранение файлов
|
||
|
||
```text
|
||
app/static/uploads/
|
||
├── photos/ # Фото гостей
|
||
├── qrcodes/ # Сгенерированные QR-коды
|
||
├── reports/ # Выгруженные отчёты
|
||
└── temp/ # Временные файлы при загрузке
|
||
```
|
||
|
||
Эти папки создаются автоматически при старте приложения.
|
||
|
||
## Ограничения и предположения
|
||
|
||
- Приложение рассчитано на сотни гостей. При необходимости масштабирования на тысячи рекомендуется перейти с SQLite на PostgreSQL.
|
||
- Все фото и QR-коды хранятся локально на диске. Перед переносом на другой сервер их нужно копировать отдельно (они не хранятся в git).
|
||
- Рассылка писем происходит синхронно. Для очень больших списков (сотни писем) рекомендуется рассылать партиями.
|
||
- QR-код содержит прямую ссылку на страницу входа. При переносе на другой хост необходимо указать корректный `BASE_URL` в `.env` или при загрузке Excel.
|
||
|
||
## Чеклист перед мероприятием
|
||
|
||
- [ ] Созданы учётные записи организаторов и сотрудников на входе.
|
||
- [ ] Создано мероприятие в админ-панели.
|
||
- [ ] Подготовлен Excel со списком гостей.
|
||
- [ ] Собраны и загружены фото всех гостей.
|
||
- [ ] Загружен Excel в админ-панель в рамках нужного мероприятия.
|
||
- [ ] Проверено, что QR-коды сгенерированы.
|
||
- [ ] Настроен SMTP и отправлено тестовое письмо.
|
||
- [ ] Разосланы приглашения.
|
||
- [ ] Протестирована страница `/check-in` на телефоне/планшете.
|
||
- [ ] Проверена работа камеры и сканирования QR.
|
||
- [ ] Проверен поиск по ФИО.
|
||
- [ ] Настроено резервное копирование базы и загруженных файлов.
|
||
|
||
## Распространённые проблемы
|
||
|
||
### Гость не находится по QR
|
||
- Проверьте, что гость не заблокирован (`is_active = true`).
|
||
- Проверьте, что QR-код не был перегенерирован, а старый распечатан.
|
||
|
||
### Фото не отображается на странице входа
|
||
- Проверьте точное совпадение имени файла в Excel и в папке `uploads/photos/`.
|
||
- Проверьте, что файл действительно загружен.
|
||
|
||
### Письма не отправляются
|
||
- Проверьте настройки SMTP в `.env`.
|
||
- Для Yandex/Google используйте пароль приложения, а не основной пароль.
|
||
- Проверьте логи консоли Flask.
|
||
|
||
### QR-код ведёт на localhost
|
||
- Укажите `BASE_URL` в `.env`.
|
||
- Или введите базовый URL при загрузке Excel в админ-панели.
|
||
|
||
## История изменений
|
||
|
||
- **2026-08-28** — Первая рабочая версия (MVP). Реализованы импорт Excel, QR-коды, рассылка, check-in, аналитика.
|
||
- **2026-08-28** — Добавлены пользователи, роли и поддержка нескольких мероприятий.
|