laravel-12-tech-specs/task04-booking-system.md

17 KiB
Raw Permalink Blame History

Техническое задание: Система бронирования помещений и оборудования

1. Описание проекта

Веб-приложение для бронирования конференц-залов, рабочих мест или оборудования с календарём, подтверждением заявок и управлением расписанием. Проект закрепляет навыки CRUD, валидации дат и времени, разграничения прав и совместной работы через Git.

Команда: 23 человека


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

Правила

  1. Ветка develop — основная ветка разработки
  2. Каждый участник создаёт фич-ветки от develop
  3. Минимум 3 PR на участника
  4. Обязательный код-ревью перед мёржем
  5. 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. Критерии приёмки

Обязательно

  • 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. Рекомендуемые материалы