338 lines
17 KiB
Markdown
338 lines
17 KiB
Markdown
# Техническое задание: Система бронирования помещений и оборудования
|
||
|
||
## 1. Описание проекта
|
||
|
||
Веб-приложение для бронирования конференц-залов, рабочих мест или оборудования с календарём, подтверждением заявок и управлением расписанием. Проект закрепляет навыки CRUD, валидации дат и времени, разграничения прав и совместной работы через Git.
|
||
|
||
**Команда:** 2–3 человека
|
||
|
||
---
|
||
|
||
## 2. Функциональные требования
|
||
|
||
### 2.1. Аутентификация и регистрация
|
||
- Регистрация, вход, выход (Laravel Breeze)
|
||
|
||
### 2.2. Каталог ресурсов
|
||
- Просмотр списка доступных ресурсов (помещения, оборудование)
|
||
- Фильтрация по категориям (конференц-залы, переговорки, проекторы, ноутбуки)
|
||
- Детальная страница ресурса (описание, вместимость, фото, календарь бронирований)
|
||
- Поиск по названию ресурса
|
||
|
||
### 2.3. Управление ресурсами (админ)
|
||
- CRUD ресурсов: название, описание, категория, вместимость/количество, изображение, доступен ли
|
||
- CRUD категорий ресурсов
|
||
- Загрузка изображений ресурсов
|
||
|
||
### 2.4. Бронирование
|
||
- Создание заявки на бронирование: ресурс, дата начала, дата окончания (или время), цель
|
||
- **Валидация:** проверка на пересечение с существующими бронированиями того же ресурса
|
||
- Просмотр своих бронирований (статусы: ожидание, подтверждено, отклонено, завершено, отменено)
|
||
- Отмена бронирования (пользователь — если статус «ожидание»)
|
||
- Календарь бронирований ресурса (визуальное отображение занятых дат)
|
||
|
||
### 2.5. Управление бронированиями (модератор/админ)
|
||
- Просмотр всех бронирований
|
||
- Подтверждение/отклонение заявки
|
||
- Изменение дат бронирования
|
||
- Отмена бронирования с комментарием
|
||
|
||
### 2.6. Дашборд модератора
|
||
- Статистика: количество ресурсов, бронирований (по статусам)
|
||
- Последние заявки, ожидающие подтверждения
|
||
- Популярные ресурсы
|
||
|
||
### 2.7. Дашборд пользователя
|
||
- Мои активные бронирования
|
||
- История бронирований
|
||
- Быстрая ссылка на создание заявки
|
||
|
||
---
|
||
|
||
## 3. Структура базы данных
|
||
|
||
### Таблица `users`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| name | VARCHAR(255) | Имя |
|
||
| email | VARCHAR(255) | Email (unique) |
|
||
| password | VARCHAR(255) | Хеш пароля |
|
||
| role | ENUM('admin', 'moderator', 'user') | Роль |
|
||
| phone | VARCHAR(20) \| NULL | Телефон |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
### Таблица `resource_categories`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| name | VARCHAR(255) | Название категории |
|
||
| slug | VARCHAR(255) | URL-идентификатор (unique) |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
### Таблица `resources`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| name | VARCHAR(255) | Название ресурса |
|
||
| slug | VARCHAR(255) | URL-идентификатор (unique) |
|
||
| description | TEXT | Описание |
|
||
| category_id | BIGINT UNSIGNED | Категория (FK → resource_categories) |
|
||
| capacity | INT \| NULL | Вместимость (для помещений) |
|
||
| quantity | INT \| NULL | Количество (для оборудования) |
|
||
| image | VARCHAR(255) \| NULL | Изображение |
|
||
| is_available | BOOLEAN | Доступен для бронирования |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
### Таблица `bookings`
|
||
| Поле | Тип | Описание |
|
||
|---|---|---|
|
||
| id | BIGINT UNSIGNED | Первичный ключ |
|
||
| resource_id | BIGINT UNSIGNED | Ресурс (FK → resources) |
|
||
| user_id | BIGINT UNSIGNED | Инициатор (FK → users) |
|
||
| start_datetime | DATETIME | Дата и время начала |
|
||
| end_datetime | DATETIME | Дата и время окончания |
|
||
| purpose | TEXT | Цель бронирования |
|
||
| status | ENUM('pending', 'confirmed', 'rejected', 'completed', 'cancelled') | Статус |
|
||
| rejection_reason | TEXT \| NULL | Причина отклонения |
|
||
| created_at | TIMESTAMP | |
|
||
| updated_at | TIMESTAMP | |
|
||
|
||
---
|
||
|
||
## 4. Маршруты и контроллеры
|
||
|
||
```php
|
||
// Публичные маршруты
|
||
Route::get('/', [ResourceController::class, 'index'])->name('resources.index');
|
||
Route::get('/resources/{resource:slug}', [ResourceController::class, 'show'])->name('resources.show');
|
||
Route::get('/resources/{resource:slug}/calendar', [ResourceController::class, 'calendar'])->name('resources.calendar');
|
||
|
||
// Аутентифицированные маршруты
|
||
Route::middleware('auth')->group(function () {
|
||
// Бронирования пользователя
|
||
Route::get('/my-bookings', [BookingController::class, 'myBookings'])->name('bookings.my');
|
||
Route::resource('bookings', BookingController::class)->except(['index', 'show']);
|
||
Route::post('/bookings/{booking}/cancel', [BookingController::class, 'cancel'])->name('bookings.cancel');
|
||
|
||
// Панель модератора
|
||
Route::prefix('moderator')->name('moderator.')->middleware('can:be-moderator')->group(function () {
|
||
Route::get('dashboard', [ModeratorDashboardController::class, 'index'])->name('dashboard');
|
||
Route::get('bookings', [ModeratorBookingController::class, 'index'])->name('bookings.index');
|
||
Route::get('bookings/{booking}', [ModeratorBookingController::class, 'show'])->name('bookings.show');
|
||
Route::post('bookings/{booking}/confirm', [ModeratorBookingController::class, 'confirm'])->name('bookings.confirm');
|
||
Route::post('bookings/{booking}/reject', [ModeratorBookingController::class, 'reject'])->name('bookings.reject');
|
||
});
|
||
|
||
// Админка
|
||
Route::prefix('admin')->name('admin.')->middleware('can:access-admin-panel')->group(function () {
|
||
Route::resource('resources', AdminResourceController::class);
|
||
Route::resource('categories', AdminCategoryController::class);
|
||
Route::resource('users', AdminUserController::class);
|
||
Route::get('dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
|
||
});
|
||
});
|
||
```
|
||
|
||
### Контроллеры
|
||
- `ResourceController` — публичный каталог и календарь бронирований
|
||
- `BookingController` — создание/отмена бронирований, мои бронирования
|
||
- `ModeratorBookingController` — просмотр, подтверждение, отклонение
|
||
- `ModeratorDashboardController` — панель модератора
|
||
- `AdminResourceController` — CRUD ресурсов
|
||
- `AdminCategoryController` — CRUD категорий
|
||
- `AdminUserController`, `AdminDashboardController` — админка
|
||
|
||
---
|
||
|
||
## 5. Роли, Gates и Policies
|
||
|
||
### Роли
|
||
| Роль | Описание |
|
||
|---|---|
|
||
| `admin` | Полный доступ, управление ресурсами, категориями, пользователями |
|
||
| `moderator` | Подтверждение/отклонение бронирований, управление расписанием |
|
||
| `user` | Создание бронирований, просмотр своих бронирований и доступных ресурсов |
|
||
|
||
### Gates
|
||
|
||
```php
|
||
Gate::define('be-moderator', function (User $user) {
|
||
return in_array($user->role, ['admin', 'moderator']);
|
||
});
|
||
|
||
Gate::define('access-admin-panel', function (User $user) {
|
||
return $user->role === 'admin';
|
||
});
|
||
```
|
||
|
||
### Policies
|
||
|
||
**ResourcePolicy:**
|
||
- `view` — все аутентифицированные
|
||
- `create`, `update`, `delete` — только admin
|
||
|
||
**BookingPolicy:**
|
||
- `create` — все аутентифицированные (если ресурс доступен)
|
||
- `view` — владелец бронирования или moderator/admin
|
||
- `update` — moderator/admin (даты) или владелец (только если status = pending)
|
||
- `cancel` — владелец (если status = pending или confirmed) или moderator/admin
|
||
- `confirm`, `reject` — только moderator или admin
|
||
|
||
---
|
||
|
||
## 6. Требования к интерфейсу (Bootstrap 5)
|
||
|
||
### Компоненты
|
||
- **Навбар** — логотип, каталог ресурсов, «Мои бронирования», профиль
|
||
- **Карточки ресурсов** — изображение, название, категория (бейдж), вместимость
|
||
- **Форма бронирования** — выбор ресурса, дата/время начала и окончания (input type="datetime-local"), цель
|
||
- **Календарь ресурса** — таблица или упрощённый календарь с подсветкой занятых дней
|
||
- **Таблица бронирований** — ресурс, даты, статус (цветные бейджи), действия
|
||
- **Модальное окно** — подтверждение/отклонение бронирования (с полем причины)
|
||
- **Дашборд** — карточки статистики (`card` + `row`/`col`)
|
||
- **Алерты** — flash-сообщения об успехе/ошибке
|
||
|
||
### Цветовая схема статусов бронирования
|
||
- Ожидание — `bg-warning`
|
||
- Подтверждено — `bg-success`
|
||
- Отклонено — `bg-danger`
|
||
- Завершено — `bg-secondary`
|
||
- Отменено — `bg-light text-muted`
|
||
|
||
### Валидация формы бронирования
|
||
- Дата начала — не в прошлом
|
||
- Дата окончания — позже даты начала
|
||
- Сообщение об ошибке при пересечении с существующим бронированием
|
||
|
||
---
|
||
|
||
## 7. Git-workflow для команды
|
||
|
||
### Распределение модулей (для 2 человек)
|
||
|
||
| Участник | Модуль | Ветки |
|
||
|---|---|---|
|
||
| **Участник A** | Ресурсы, категории, изображения, календарь | `feature/resources-crud`, `feature/categories`, `feature-resource-images` |
|
||
| **Участник B** | Бронирования, валидация, модерация, дашборды | `feature/bookings-crud`, `feature-booking-validation`, `feature-booking-calendar` |
|
||
|
||
### Распределение модулей (для 3 человек)
|
||
|
||
| Участник | Модуль | Ветки |
|
||
|---|---|---|
|
||
| **Участник A** | Ресурсы, категории, загрузка изображений | `feature/resources-crud`, `feature/categories`, `feature-resource-images` |
|
||
| **Участник B** | Бронирования, валидация пересечений, календарь | `feature/bookings-crud`, `feature-booking-validation`, `feature-booking-calendar` |
|
||
| **Участник C** | Управление бронированиями (модератор), дашборды | `feature/moderator-panel`, `feature/dashboards`, `feature-booking-statuses` |
|
||
|
||
### Правила
|
||
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/resources-crud
|
||
checkout develop
|
||
branch feature/bookings-crud
|
||
checkout feature/resources-crud
|
||
commit id: "feat: add resources CRUD"
|
||
commit id: "feat: add resource categories"
|
||
checkout feature/bookings-crud
|
||
commit id: "feat: add bookings CRUD"
|
||
commit id: "feat: add booking validation"
|
||
checkout develop
|
||
merge feature/resources-crud tag: "PR + review"
|
||
merge feature/bookings-crud 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/resources-crud
|
||
checkout develop
|
||
branch feature/bookings-crud
|
||
checkout develop
|
||
branch feature/moderator-panel
|
||
checkout feature/resources-crud
|
||
commit id: "feat: add resources CRUD"
|
||
commit id: "feat: add booking calendar"
|
||
checkout feature/bookings-crud
|
||
commit id: "feat: add bookings CRUD"
|
||
commit id: "feat: add booking validation"
|
||
checkout feature/moderator-panel
|
||
commit id: "feat: add moderator panel"
|
||
commit id: "feat: add booking statuses"
|
||
checkout develop
|
||
merge feature/resources-crud tag: "PR + review"
|
||
merge feature/bookings-crud tag: "PR + review"
|
||
merge feature/moderator-panel tag: "PR + review"
|
||
checkout main
|
||
merge develop tag: "release v1.1"
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Критерии приёмки
|
||
|
||
### Обязательно
|
||
- [ ] CRUD ресурсов с загрузкой изображений
|
||
- [ ] CRUD категорий ресурсов
|
||
- [ ] Создание бронирования с валидацией дат (не в прошлом, окончание > начала)
|
||
- [ ] **Валидация пересечения:** нельзя забронировать ресурс на время, которое уже занято
|
||
- [ ] Отмена бронирования пользователем (если статус «ожидание»)
|
||
- [ ] Подтверждение/отклонение бронирования модератором
|
||
- [ ] Просмотр своих бронирований (фильтрация по статусу)
|
||
- [ ] Календарь бронирований ресурса (визуальное отображение)
|
||
- [ ] Policies: пользователь не может управлять чужими бронированиями
|
||
- [ ] Адаптивная Bootstrap-вёрстка
|
||
- [ ] Flash-сообщения
|
||
- [ ] Пагинация каталога ресурсов и списка бронирований
|
||
- [ ] Git-история: минимум 3 ветки на участника, PR с ревью
|
||
|
||
### Дополнительно (бонусные баллы)
|
||
- [ ] Повторяющиеся бронирования (еженедельно, ежемесячно)
|
||
- [ ] Уведомления (email при подтверждении/отклонении)
|
||
- [ ] Экспорт бронирований в CSV/ICS (календарь)
|
||
- [ ] Поиск ресурсов по названию
|
||
- [ ] Фильтрация по вместимости
|
||
- [ ] Рейтинг ресурсов (пользователи оценивают)
|
||
- [ ] Soft Deletes для ресурсов
|
||
|
||
---
|
||
|
||
## 9. Дополнительные задания (для продвинутых)
|
||
|
||
1. **Повторяющиеся бронирования:** возможность забронировать ресурс на каждую неделю/месяц
|
||
2. **Уведомления:** email при подтверждении/отклонении/напоминании за день
|
||
3. **ICS-экспорт:** генерация .ics-файла для добавления в Google/Apple Calendar
|
||
4. **Конфликты:** визуальное отображение конфликтов при создании бронирования
|
||
5. **Тесты:** PHPUnit Feature-тесты для BookingController (валидация пересечений)
|
||
6. **API:** RESTful API для каталога ресурсов и создания бронирований
|
||
7. **Queue:** асинхронная отправка email-уведомлений
|
||
|
||
---
|
||
|
||
## 10. Рекомендуемые материалы
|
||
|
||
- Laravel Docs: https://laravel.com/docs/12.x
|
||
- Laravel Validation (custom rules): https://laravel.com/docs/12.x/validation#custom-validation-rules
|
||
- Bootstrap 5 Forms: https://getbootstrap.com/docs/5.3/forms/overview/
|
||
- Carbon (работа с датами): https://carbon.nesbot.com/docs/
|
||
- Laravel Policies: https://laravel.com/docs/12.x/authorization#creating-policies
|