348 lines
18 KiB
Markdown
348 lines
18 KiB
Markdown
# Техническое задание: Система управления мероприятиями (Event Manager)
|
||
|
||
## 1. Описание проекта
|
||
|
||
Веб-платформа для создания и продвижения мероприятий с регистрацией участников, расписанием и обсуждениями. Проект закрепляет навыки CRUD, валидации дат и вместимости, разграничения прав и совместной работы через Git.
|
||
|
||
**Команда:** 2–3 человека
|
||
|
||
---
|
||
|
||
## 2. Функциональные требования
|
||
|
||
### 2.1. Аутентификация и регистрация
|
||
- Регистрация, вход, выход (Laravel Breeze)
|
||
|
||
### 2.2. Каталог мероприятий
|
||
- Просмотр списка мероприятий с пагинацией
|
||
- Фильтрация по категориям (конференции, воркшопы, вебинары, митапы)
|
||
- Фильтрация по дате (сегодня, неделя, месяц, будущие)
|
||
- Поиск по названию и описанию
|
||
- Детальная страница мероприятия (обложка, описание, место, дата, организатор, список участников, комментарии)
|
||
|
||
### 2.3. Управление мероприятиями (организатор/админ)
|
||
- CRUD мероприятий: название, описание, обложка, категория, дата начала/окончания, место (адрес или онлайн-ссылка), вместимость, стоимость (бесплатно/платно)
|
||
- Загрузка обложки мероприятия (валидация: jpg/png, макс. 2MB)
|
||
- Управление участниками (просмотр списка, отмена регистрации участника)
|
||
|
||
### 2.4. Регистрация на мероприятие
|
||
- Кнопка «Зарегистрироваться» на странице мероприятия
|
||
- **Валидация:** проверка на наличие свободных мест (если вместимость ограничена)
|
||
- **Валидация:** пользователь не может зарегистрироваться дважды
|
||
- Отмена регистрации (пользователь — до начала мероприятия)
|
||
- Список участников мероприятия (публичный)
|
||
|
||
### 2.5. Комментарии и обсуждения
|
||
- Добавление комментариев к мероприятию
|
||
- Удаление своего комментария
|
||
- Удаление любого комментария (админ/организатор)
|
||
- Пагинация комментариев
|
||
|
||
### 2.6. Панель организатора
|
||
- Мои мероприятия (созданные мной)
|
||
- Статистика по каждому: количество зарегистрированных, свободные места
|
||
- Список участников с возможностью экспорта
|
||
- Управление комментариями
|
||
|
||
### 2.7. Панель участника
|
||
- Мои мероприятия (на которые зарегистрирован)
|
||
- Прошедшие мероприятия (история)
|
||
- Рекомендации (похожие мероприятия)
|
||
|
||
### 2.8. Панель администратора
|
||
- Управление пользователями и ролями
|
||
- Модерация мероприятий (скрыть/показать)
|
||
- Общая статистика платформы
|
||
|
||
---
|
||
|
||
## 3. Структура базы данных
|
||
|
||
### Таблица `users`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| name | VARCHAR(255) | Имя |
|
||
| email | VARCHAR(255) | Email (unique) |
|
||
| password | VARCHAR(255) | Хеш пароля |
|
||
| role | ENUM('admin', 'organizer', 'participant') | Роль |
|
||
| avatar | VARCHAR(255) \| NULL | Аватар |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
### Таблица `categories`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| name | VARCHAR(255) | Название категории |
|
||
| slug | VARCHAR(255) | URL-идентификатор (unique) |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
### Таблица `events`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| title | VARCHAR(255) | Название мероприятия |
|
||
| slug | VARCHAR(255) | URL-идентификатор (unique) |
|
||
| description | TEXT | Описание |
|
||
| cover_image | VARCHAR(255) \| NULL | Обложка |
|
||
| category_id | BIGINT UNSIGNED | Категория (FK → categories) |
|
||
| organizer_id | BIGINT UNSIGNED | Организатор (FK → users) |
|
||
| start_datetime | DATETIME | Дата и время начала |
|
||
| end_datetime | DATETIME | Дата и время окончания |
|
||
| location | VARCHAR(255) | Место проведения (адрес или «Онлайн») |
|
||
| location_url | VARCHAR(255) \| NULL | Ссылка для онлайн-мероприятий |
|
||
| capacity | INT \| NULL | Вместимость (NULL = без ограничений) |
|
||
| price | DECIMAL(10, 2) \| NULL | Стоимость (NULL = бесплатно) |
|
||
| is_published | BOOLEAN | Опубликован ли |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
### Таблица `event_user` (регистрация на мероприятие)
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| event_id | BIGINT UNSIGNED | FK → events |
|
||
| user_id | BIGINT UNSIGNED | FK → users |
|
||
| registered_at | TIMESTAMP | Дата регистрации |
|
||
| attended | BOOLEAN | Присутствовал ли |
|
||
|
||
### Таблица `comments`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| body | TEXT | Текст комментария |
|
||
| user_id | BIGINT UNSIGNED | Автор (FK → users) |
|
||
| event_id | BIGINT UNSIGNED | Мероприятие (FK → events) |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
---
|
||
|
||
## 4. Маршруты и контроллеры
|
||
|
||
```php
|
||
// Публичные маршруты
|
||
Route::get('/', [EventController::class, 'index'])->name('events.index');
|
||
Route::get('/events/{event:slug}', [EventController::class, 'show'])->name('events.show');
|
||
|
||
// Аутентифицированные маршруты
|
||
Route::middleware('auth')->group(function () {
|
||
// Регистрация на мероприятие
|
||
Route::post('/events/{event}/register', [EventController::class, 'register'])->name('events.register');
|
||
Route::post('/events/{event}/unregister', [EventController::class, 'unregister'])->name('events.unregister');
|
||
|
||
// Комментарии
|
||
Route::resource('events.comments', CommentController::class)->scoped(['events' => 'event'])->only(['store', 'destroy']);
|
||
|
||
// Мои мероприятия (участник)
|
||
Route::get('/my-events', [ParticipantController::class, 'index'])->name('participant.events');
|
||
|
||
// Панель организатора
|
||
Route::prefix('organizer')->name('organizer.')->middleware('can:be-organizer')->group(function () {
|
||
Route::resource('events', OrganizerEventController::class);
|
||
Route::get('events/{event}/attendees', [OrganizerEventController::class, 'attendees'])->name('events.attendees');
|
||
Route::post('events/{event}/attendees/{user}/remove', [OrganizerEventController::class, 'removeAttendee'])->name('events.attendees.remove');
|
||
Route::get('dashboard', [OrganizerDashboardController::class, 'index'])->name('dashboard');
|
||
});
|
||
|
||
// Админка
|
||
Route::prefix('admin')->name('admin.')->middleware('can:access-admin-panel')->group(function () {
|
||
Route::resource('users', AdminUserController::class);
|
||
Route::patch('events/{event}/toggle-publish', [AdminEventController::class, 'togglePublish'])->name('events.publish');
|
||
Route::get('dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
|
||
});
|
||
});
|
||
```
|
||
|
||
### Контроллеры
|
||
- `EventController` — публичный каталог, регистрация/отмена
|
||
- `CommentController` — создание/удаление комментариев
|
||
- `ParticipantController` — мои мероприятия (участник)
|
||
- `OrganizerEventController` — CRUD мероприятий организатором
|
||
- `OrganizerDashboardController` — панель организатора
|
||
- `AdminUserController`, `AdminEventController`, `AdminDashboardController` — админка
|
||
|
||
---
|
||
|
||
## 5. Роли, Gates и Policies
|
||
|
||
### Роли
|
||
| Роль | Описание |
|
||
|---|---|
|
||
| `admin` | Полный доступ, модерация мероприятий, управление пользователями |
|
||
| `organizer` | Создание/редактирование своих мероприятий, просмотр участников |
|
||
| `participant` | Регистрация на мероприятия, комментарии, просмотр расписания |
|
||
|
||
### Gates
|
||
|
||
```php
|
||
Gate::define('be-organizer', function (User $user) {
|
||
return in_array($user->role, ['admin', 'organizer']);
|
||
});
|
||
|
||
Gate::define('access-admin-panel', function (User $user) {
|
||
return $user->role === 'admin';
|
||
});
|
||
```
|
||
|
||
### Policies
|
||
|
||
**EventPolicy:**
|
||
- `view` — все (если опубликован), организатор/admin (если не опубликован)
|
||
- `create` — organizer или admin
|
||
- `update`, `delete` — организатор мероприятия или admin
|
||
- `register` — participant (не зарегистрирован на это мероприятие, есть свободные места)
|
||
|
||
**CommentPolicy:**
|
||
- `create` — все аутентифицированные
|
||
- `delete` — автор комментария, организатор мероприятия или admin
|
||
|
||
---
|
||
|
||
## 6. Требования к интерфейсу (Bootstrap 5)
|
||
|
||
### Компоненты
|
||
- **Навбар** — логотип, каталог, «Мои мероприятия», профиль
|
||
- **Карточки мероприятий** — обложка, название, дата (бейдж), категория (бейдж), вместимость
|
||
- **Страница мероприятия** — большая обложка, описание, место, дата, кнопка регистрации, список участников, комментарии
|
||
- **Модальное окно** — быстрая регистрация (подтверждение)
|
||
- **Таблица участников** — имя, email, дата регистрации, кнопка удаления (организатор)
|
||
- **Форма мероприятия** — Bootstrap-форма с загрузкой обложки, datetime-local для дат
|
||
- **Дашборд организатора** — статистика (карточки), таблица мероприятий
|
||
- **Адаптивная сетка** — `col-md-4` для карточек, `col-md-8` + `col-md-4` для основного контента и сайдбара
|
||
|
||
### Цветовая схема категорий
|
||
- Конференция — `bg-primary`
|
||
- Воркшоп — `bg-success`
|
||
- Вебинар — `bg-info`
|
||
- Митап — `bg-warning`
|
||
|
||
---
|
||
|
||
## 7. Git-workflow для команды
|
||
|
||
### Распределение модулей (для 2 человек)
|
||
|
||
| Участник | Модуль | Ветки |
|
||
|---|---|---|
|
||
| **Участник A** | Мероприятия, категории, обложки, регистрация | `feature/events-crud`, `feature/categories`, `feature-event-covers` |
|
||
| **Участник B** | Участники, комментарии, панель организатора, UI | `feature/event-registration`, `feature-attendees`, `feature-capacity-validation` |
|
||
|
||
### Распределение модулей (для 3 человек)
|
||
|
||
| Участник | Модуль | Ветки |
|
||
|---|---|---|
|
||
| **Участник A** | Мероприятия, категории, загрузка обложек | `feature/events-crud`, `feature/categories`, `feature-event-covers` |
|
||
| **Участник B** | Регистрация, участники, валидация вместимости | `feature/event-registration`, `feature-attendees`, `feature-capacity-validation` |
|
||
| **Участник C** | Комментарии, панель организатора, каталог, UI | `feature/comments`, `feature-organizer-panel`, `feature-event-catalog-ui` |
|
||
|
||
### Правила
|
||
1. Ветка `develop` — основная ветка разработки
|
||
2. Каждый участник создаёт фич-ветки от `develop`
|
||
3. Минимум 3 PR на участника
|
||
4. Обязательный код-ревью перед мёржем
|
||
5. Conventional Commits
|
||
|
||
### Визуализация workflow (2 участника)
|
||
|
||
```mermaid
|
||
gitGraph
|
||
commit id: "init" tag: "v1.0"
|
||
branch develop
|
||
checkout develop
|
||
branch feature/events-crud
|
||
checkout develop
|
||
branch feature/event-registration
|
||
checkout feature/events-crud
|
||
commit id: "feat: add events CRUD"
|
||
commit id: "feat: add event categories"
|
||
checkout feature/event-registration
|
||
commit id: "feat: add event registration"
|
||
commit id: "feat: add attendees management"
|
||
checkout develop
|
||
merge feature/events-crud tag: "PR + review"
|
||
merge feature/event-registration tag: "PR + review"
|
||
checkout main
|
||
merge develop tag: "release v1.1"
|
||
```
|
||
|
||
### Визуализация workflow (3 участника)
|
||
|
||
```mermaid
|
||
gitGraph
|
||
commit id: "init" tag: "v1.0"
|
||
branch develop
|
||
checkout develop
|
||
branch feature/events-crud
|
||
checkout develop
|
||
branch feature/event-registration
|
||
checkout develop
|
||
branch feature/comments
|
||
checkout feature/events-crud
|
||
commit id: "feat: add events CRUD"
|
||
commit id: "feat: add event covers"
|
||
checkout feature/event-registration
|
||
commit id: "feat: add event registration"
|
||
commit id: "feat: add attendees management"
|
||
checkout feature/comments
|
||
commit id: "feat: add event comments"
|
||
commit id: "feat: add organizer panel"
|
||
checkout develop
|
||
merge feature/events-crud tag: "PR + review"
|
||
merge feature/event-registration tag: "PR + review"
|
||
merge feature/comments tag: "PR + review"
|
||
checkout main
|
||
merge develop tag: "release v1.1"
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Критерии приёмки
|
||
|
||
### Обязательно
|
||
- [ ] CRUD мероприятий с загрузкой обложки
|
||
- [ ] CRUD категорий мероприятий
|
||
- [ ] Регистрация на мероприятие с валидацией вместимости
|
||
- [ ] Отмена регистрации (до начала мероприятия)
|
||
- [ ] Список участников мероприятия
|
||
- [ ] Комментарии к мероприятиям (создание + удаление)
|
||
- [ ] Панель организатора (мои мероприятия, статистика, участники)
|
||
- [ ] Policies: участник не может редактировать мероприятия, организатор не может редактировать чужие мероприятия
|
||
- [ ] Адаптивная Bootstrap-вёрстка
|
||
- [ ] Flash-сообщения
|
||
- [ ] Пагинация каталога и комментариев
|
||
- [ ] Git-история: минимум 3 ветки на участника, PR с ревью
|
||
|
||
### Дополнительно (бонусные баллы)
|
||
- [ ] Поиск мероприятий по названию/описанию
|
||
- [ ] Фильтрация по дате (сегодня, неделя, месяц)
|
||
- [ ] Экспорт списка участников в CSV
|
||
- [ ] Рейтинг мероприятия (после завершения)
|
||
- [ ] Похожие мероприятия (рекомендации)
|
||
- [ ] Уведомления (email при регистрации / напоминание)
|
||
- [ ] Soft Deletes для мероприятий
|
||
|
||
---
|
||
|
||
## 9. Дополнительные задания (для продвинутых)
|
||
|
||
1. **Билеты:** генерация PDF-билета с QR-кодом при регистрации
|
||
2. **Уведомления:** email при регистрации и напоминание за день до мероприятия
|
||
3. **Онлайн-мероприятия:** интеграция с Zoom/Jitsi (сохранение ссылки, автоматическая отправка)
|
||
4. **Тесты:** PHPUnit Feature-тесты для EventController (регистрация, валидация вместимости)
|
||
5. **API:** RESTful API для каталога мероприятий
|
||
6. **Queue:** асинхронная отправка email-уведомлений
|
||
7. **Events & Listeners:** событие «регистрация на мероприятие» → отправка email
|
||
|
||
---
|
||
|
||
## 10. Рекомендуемые материалы
|
||
|
||
- Laravel Docs: https://laravel.com/docs/12.x
|
||
- Laravel File Uploads: https://laravel.com/docs/12.x/filesystem#file-uploads
|
||
- Bootstrap 5 Cards: https://getbootstrap.com/docs/5.3/components/card/
|
||
- Bootstrap 5 Modal: https://getbootstrap.com/docs/5.3/components/modal/
|
||
- Laravel Policies: https://laravel.com/docs/12.x/authorization#creating-policies
|