# Техническое задание: Онлайн-магазин с корзиной ## 1. Описание проекта Веб-приложение интернет-магазина с каталогом товаров, корзиной покупок и оформлением заказов. Проект закрепляет навыки CRUD, работы с отношениями многие-ко-многим, загрузки изображений, разграничения прав и совместной работы через Git. **Команда:** 2–3 человека --- ## 2. Функциональные требования ### 2.1. Аутентификация и регистрация - Регистрация, вход, выход (Laravel Breeze) - Восстановление пароля (опционально) ### 2.2. Каталог товаров - Просмотр списка товаров с пагинацией - Детальная страница товара - Фильтрация по категориям - Поиск по названию и описанию - Сортировка по цене, дате добавления, названию ### 2.3. Управление товарами (админка) - CRUD товаров: название, описание, цена, изображение, количество на складе, наличие - CRUD категорий товаров - Загрузка изображений товаров (валидация: jpg/png, макс. 2MB) - Привязка товара к нескольким категориям ### 2.4. Корзина - Добавление товара в корзину (количество) - Изменение количества в корзине - Удаление позиции из корзины - Отображение итоговой суммы - Корзина сохраняется в сессии (для гостей) или в БД (для авторизованных) ### 2.5. Оформление заказа - Форма оформления заказа: имя, телефон, email, адрес доставки, комментарий - Перенос позиций корзины в заказ - Очистка корзины после оформления - Просмотр своих заказов (покупатель) ### 2.6. Управление заказами (админка) - Просмотр списка всех заказов - Изменение статуса заказа (новый, в обработке, отправлен, доставлен, отменён) - Детали заказа (список товаров, сумма, данные покупателя) ### 2.7. Дашборд администратора - Статистика: количество товаров, заказов, пользователей - Последние заказы - Товары, заканчивающиеся на складе --- ## 3. Структура базы данных ### Таблица `users` | Поле | Тип | Описание | |---|---|---| | id | BIGINT UNSIGNED | Первичный ключ | | name | VARCHAR(255) | Имя | | email | VARCHAR(255) | Email (unique) | | password | VARCHAR(255) | Хеш пароля | | role | ENUM('admin', 'order_manager', 'customer') | Роль | | phone | VARCHAR(20) \| NULL | Телефон | | created_at | TIMESTAMP | | | updated_at | TIMESTAMP | | ### Таблица `categories` | Поле | Тип | Описание | |---|---|---| | id | BIGINT UNSIGNED | Первичный ключ | | name | VARCHAR(255) | Название категории | | slug | VARCHAR(255) | URL-идентификатор (unique) | | description | TEXT \| NULL | Описание | | created_at | TIMESTAMP | | | updated_at | TIMESTAMP | | ### Таблица `products` | Поле | Тип | Описание | |---|---|---| | id | BIGINT UNSIGNED | Первичный ключ | | name | VARCHAR(255) | Название товара | | slug | VARCHAR(255) | URL-идентификатор (unique) | | description | TEXT | Описание | | price | DECIMAL(10, 2) | Цена | | image | VARCHAR(255) \| NULL | Путь к изображению | | stock_quantity | INT | Количество на складе | | is_available | BOOLEAN | Доступен для покупки | | created_at | TIMESTAMP | | | updated_at | TIMESTAMP | | ### Таблица `category_product` (многие-ко-многим) | Поле | Тип | Описание | |---|---|---| | category_id | BIGINT UNSIGNED | FK → categories | | product_id | BIGINT UNSIGNED | FK → products | ### Таблица `carts` | Поле | Тип | Описание | |---|---|---| | id | BIGINT UNSIGNED | Первичный ключ | | user_id | BIGINT UNSIGNED \| NULL | Пользователь (FK → users), NULL для гостей | | session_id | VARCHAR(255) \| NULL | ID сессии для гостей | | created_at | TIMESTAMP | | | updated_at | TIMESTAMP | | ### Таблица `cart_items` | Поле | Тип | Описание | |---|---|---| | id | BIGINT UNSIGNED | Первичный ключ | | cart_id | BIGINT UNSIGNED | FK → carts | | product_id | BIGINT UNSIGNED | FK → products | | quantity | INT | Количество | ### Таблица `orders` | Поле | Тип | Описание | |---|---|---| | id | BIGINT UNSIGNED | Первичный ключ | | user_id | BIGINT UNSIGNED \| NULL | Покупатель (FK → users) | | total_amount | DECIMAL(10, 2) | Итоговая сумма | | status | ENUM('new', 'processing', 'shipped', 'delivered', 'cancelled') | Статус | | customer_name | VARCHAR(255) | Имя получателя | | customer_phone | VARCHAR(20) | Телефон | | customer_email | VARCHAR(255) | Email | | shipping_address | TEXT | Адрес доставки | | comment | TEXT \| NULL | Комментарий | | created_at | TIMESTAMP | | | updated_at | TIMESTAMP | | ### Таблица `order_items` | Поле | Тип | Описание | |---|---|---| | id | BIGINT UNSIGNED | Первичный ключ | | order_id | BIGINT UNSIGNED | FK → orders | | product_id | BIGINT UNSIGNED | FK → products | | quantity | INT | Количество | | price | DECIMAL(10, 2) | Цена на момент заказа | --- ## 4. Маршруты и контроллеры ```php // Публичные маршруты Route::get('/', [ProductController::class, 'index'])->name('home'); Route::get('/products/{product:slug}', [ProductController::class, 'show'])->name('products.show'); // Корзина Route::prefix('cart')->name('cart.')->group(function () { Route::get('/', [CartController::class, 'index'])->name('index'); Route::post('/add/{product}', [CartController::class, 'add'])->name('add'); Route::patch('/update/{cartItem}', [CartController::class, 'update'])->name('update'); Route::delete('/remove/{cartItem}', [CartController::class, 'remove'])->name('remove'); }); // Аутентифицированные маршруты Route::middleware('auth')->group(function () { // Оформление заказа Route::get('/checkout', [OrderController::class, 'create'])->name('checkout'); Route::post('/checkout', [OrderController::class, 'store'])->name('checkout.store'); Route::get('/my-orders', [OrderController::class, 'myOrders'])->name('orders.my'); Route::get('/my-orders/{order}', [OrderController::class, 'show'])->name('orders.show'); // Админка Route::prefix('admin')->name('admin.')->middleware('can:access-admin-panel')->group(function () { Route::resource('products', AdminProductController::class); Route::resource('categories', AdminCategoryController::class); Route::resource('orders', AdminOrderController::class)->only(['index', 'show', 'update']); Route::patch('orders/{order}/status', [AdminOrderController::class, 'updateStatus'])->name('orders.status'); Route::get('dashboard', [AdminDashboardController::class, 'index'])->name('dashboard'); }); }); ``` ### Контроллеры - `ProductController` — публичный каталог и детальный просмотр - `CartController` — управление корзиной - `OrderController` — оформление и просмотр своих заказов - `AdminProductController` — CRUD товаров (с загрузкой изображений) - `AdminCategoryController` — CRUD категорий - `AdminOrderController` — управление заказами и статусами - `AdminDashboardController` — панель администратора --- ## 5. Роли, Gates и Policies ### Роли | Роль | Описание | |---|---| | `admin` | Полный доступ, управление пользователями, товарами, заказами | | `order_manager` | Просмотр и обновление статусов заказов | | `customer` | Просмотр каталога, корзина, оформление заказов, просмотр своих заказов | ### Gates ```php Gate::define('access-admin-panel', function (User $user) { return in_array($user->role, ['admin', 'order_manager']); }); Gate::define('manage-products', function (User $user) { return $user->role === 'admin'; }); Gate::define('manage-categories', function (User $user) { return $user->role === 'admin'; }); Gate::define('manage-orders', function (User $user) { return in_array($user->role, ['admin', 'order_manager']); }); ``` ### Policies **ProductPolicy:** - `view` — все (публичный каталог) - `create`, `update`, `delete` — только admin **CategoryPolicy:** - `create`, `update`, `delete` — только admin **OrderPolicy:** - `view` — владелец заказа или admin/order_manager - `updateStatus` — admin или order_manager - `create` — все аутентифицированные --- ## 6. Требования к интерфейсу (Bootstrap 5) ### Компоненты - **Навбар** — логотип, ссылки, корзина (с бейджем количества), профиль - **Карточки товаров** — изображение, название, цена, бейдж наличия, кнопка «В корзину» - **Каталог** — боковая панель с категориями + сетка товаров (`col-md-4`) - **Корзина** — таблица позиций с кнопками +/- количества, итоговая сумма - **Форма заказа** — Bootstrap-форма с валидацией - **Модальное окно** — быстрый просмотр товара - **Таблица заказов** — статусы с цветными бейджами, кнопка просмотра деталей - **Дашборд** — карточки статистики (`card` + `row`/`col`) ### Цветовая схема статусов заказа - Новый — `bg-info` - В обработке — `bg-warning` - Отправлен — `bg-primary` - Доставлен — `bg-success` - Отменён — `bg-danger` --- ## 7. Git-workflow для команды ### Распределение модулей (для 2 человек) | Участник | Модуль | Ветки | |---|---|---| | **Участник A** | Товары, категории, загрузка изображений, админка | `feature/products-crud`, `feature/categories`, `feature-image-upload` | | **Участник B** | Корзина, оформление заказа, заказы, UI | `feature/cart`, `feature/checkout`, `feature-orders` | ### Распределение модулей (для 3 человек) | Участник | Модуль | Ветки | |---|---|---| | **Участник A** | Товары, категории, загрузка изображений | `feature/products-crud`, `feature/categories`, `feature-image-upload` | | **Участник B** | Корзина, оформление заказа, заказы | `feature/cart`, `feature/checkout`, `feature-orders` | | **Участник C** | Аутентификация, админка, дашборд | `feature/admin-dashboard`, `feature/admin-orders`, `feature-statistics` | ### Правила 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/products-crud checkout develop branch feature/cart checkout feature/products-crud commit id: "feat: add products CRUD with images" commit id: "feat: add categories CRUD" checkout feature/cart commit id: "feat: add cart session logic" commit id: "feat: add checkout form" checkout develop merge feature/products-crud tag: "PR + review" merge feature/cart 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/products-crud checkout develop branch feature/cart checkout develop branch feature/admin-dashboard checkout feature/products-crud commit id: "feat: add products CRUD" commit id: "feat: add image upload" checkout feature/cart commit id: "feat: add cart management" commit id: "feat: add checkout flow" checkout feature/admin-dashboard commit id: "feat: add admin panel" commit id: "feat: add order management" checkout develop merge feature/products-crud tag: "PR + review" merge feature/cart tag: "PR + review" merge feature/admin-dashboard tag: "PR + review" checkout main merge develop tag: "release v1.1" ``` --- ## 8. Критерии приёмки ### Обязательно - [ ] CRUD товаров с загрузкой изображений (валидация формата и размера) - [ ] CRUD категорий - [ ] Связь многие-ко-многим (товар ↔ категории) - [ ] Корзина работает (добавление, изменение количества, удаление) - [ ] Оформление заказа с валидацией всех полей - [ ] Уменьшение `stock_quantity` при оформлении заказа - [ ] Просмотр своих заказов (покупатель) - [ ] Управление статусами заказов (админ/менеджер) - [ ] Policies: покупатель не может управлять товарами/чужими заказами - [ ] Адаптивная Bootstrap-вёрстка - [ ] Flash-сообщения при действиях - [ ] Пагинация каталога - [ ] Git-история: минимум 3 ветки на участника, PR с ревью ### Дополнительно (бонусные баллы) - [ ] Поиск товаров по названию/описанию - [ ] Сортировка товаров (цена, дата, название) - [ ] Фильтрация по нескольким категориям - [ ] Избранное (wishlist) - [ ] Промокоды со скидкой - [ ] Генерация PDF-чека заказа --- ## 9. Дополнительные задания (для продвинутых) 1. **Промокоды:** система скидок с уникальными кодами и процентом/фиксированной суммой 2. **Избранное:** добавление товаров в wishlist (многие-ко-многим user ↔ product) 3. **Отзывы к товарам:** рейтинг 1–5 + текст, модерация 4. **Тесты:** PHPUnit Feature-тесты для CartController и OrderController 5. **API:** RESTful API для каталога товаров (resource-маршруты с JSON) 6. **Кэширование:** кэширование каталога через Laravel Cache 7. **Soft Deletes:** мягкое удаление товаров и категорий --- ## 10. Рекомендуемые материалы - Laravel Docs: https://laravel.com/docs/12.x - Laravel Filesystem (загрузка файлов): https://laravel.com/docs/12.x/filesystem - Laravel Many-to-Many Relationships: https://laravel.com/docs/12.x/eloquent-relationships#many-to-many - Bootstrap 5 Cards: https://getbootstrap.com/docs/5.3/components/card/ - Laravel Session & Cart: https://laravel.com/docs/12.x/session