Техническое задание: Система бронирования помещений и оборудования
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. Маршруты и контроллеры
// Публичные маршруты
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
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 |
Правила
- Ветка
develop — основная ветка разработки
- Каждый участник создаёт фич-ветки от
develop
- Минимум 3 PR на участника
- Обязательный код-ревью перед мёржем
- Conventional Commits
Визуализация workflow (2 участника)
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 участника)
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. Критерии приёмки
Обязательно
Дополнительно (бонусные баллы)
9. Дополнительные задания (для продвинутых)
- Повторяющиеся бронирования: возможность забронировать ресурс на каждую неделю/месяц
- Уведомления: email при подтверждении/отклонении/напоминании за день
- ICS-экспорт: генерация .ics-файла для добавления в Google/Apple Calendar
- Конфликты: визуальное отображение конфликтов при создании бронирования
- Тесты: PHPUnit Feature-тесты для BookingController (валидация пересечений)
- API: RESTful API для каталога ресурсов и создания бронирований
- Queue: асинхронная отправка email-уведомлений
10. Рекомендуемые материалы