laravel-12-tech-specs/task06-event-manager.md

348 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Техническое задание: Система управления мероприятиями (Event Manager)
## 1. Описание проекта
Веб-платформа для создания и продвижения мероприятий с регистрацией участников, расписанием и обсуждениями. Проект закрепляет навыки CRUD, валидации дат и вместимости, разграничения прав и совместной работы через Git.
**Команда:** 23 человека
---
## 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