laravel-12-tech-specs/task02-online-store.md

377 lines
17 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.

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