Task Manager — навчальний/тестовий проєкт на Laravel 10 з веб-інтерфейсом і REST API для керування задачами.
Проєкт побудовано за кращими практиками: сервісний шар, репозиторії, політики доступу, обсервери, enum’и, кастомні винятки, черги, пошта, Swagger-документація, тести, аналізатори коду.
- PHP 8.2, Laravel 10
- MySQL (або сумісна СУБД)
- Laravel Breeze (web-аутентифікація)
- Laravel Sanctum (API токени)
- L5-Swagger (документація API)
- Queues + Mail (нагадування)
- PHP CS Fixer / Pint, Larastan, IDE Helper
- Pest / PHPUnit (тести)
- 🔐 Аутентифікація: web (Breeze) та API-токени (Sanctum)
- 📋 Задачі (Tasks): CRUD, фільтрація, сортування, пагінація
- 🏷 Enum’и:
TaskStatus,TaskPriorityз лейблами та стилями - 🧠 Бізнес-логіка:
TaskService+TaskRepository - 🛡 Політики доступу (Policy на
Task) - 👁 Обсервер
TaskObserver(нормалізація даних + аудит змін) - 💥 Кастомні винятки (наприклад,
DueDateInPastException) - 📧 Job: щоденні email-нагадування про задачі з дедлайном на завтра
- 📖 Swagger UI для тестування API
- 🧪 Тести: аутентифікація, токени, CRUD/сервіс
- 🧹 Аналіз та стиль коду
app/
├─ Console/ # Kernel, розклад Job’ів
├─ Enums/ # TaskStatus, TaskPriority
├─ Exceptions/ # Кастомні винятки (доменні/валідаційні)
├─ Http/
│ ├─ Controllers/Api # API-контролери
│ ├─ Controllers/Web # Web-контролери (Blade)
│ ├─ Requests/ # FormRequest валідація
│ └─ Resources/ # JsonResource для API
├─ Jobs/ # SendDueSoonReminders
├─ Mail/ # TaskPriorityMail
├─ Models/ # Eloquent моделі (Task, User)
├─ Observers/ # TaskObserver (normalize + audit)
├─ Policies/ # TaskPolicy
├─ Repositories/ # TaskRepository + Interface
└─ Services/ # TaskService (бізнес-правила)
- Клонування та підготовка:
git clone <repo-url>
cd task-manager
cp .env.example .env
composer install
php artisan key:generate- Налаштуй
.env:
DB_*— підключення до БДQUEUE_CONNECTION=databaseMAIL_*— SMTP для відправки листів (для dev можнаMAIL_MAILER=log)
- База + сидери:
php artisan migrate --seed- Черги (у окремому процесі):
php artisan queue:work- Генерація Swagger-документації:
php artisan l5-swagger:generate- Запуск dev-сервера:
php artisan serve- Web:
http://localhost:8000 - Swagger UI:
http://localhost:8000/api/documentation
Якщо користуєшся Docker — адаптуй URL/порти під свій
docker-compose.
POST /api/auth/token
Content-Type: application/json
{
"email": "user@example.com",
"password": "password",
"device_name": "Postman"
}
Відповідь (201):
{ "token": "1|abcd..." }Використання:
Authorization: Bearer {token}
DELETE /api/auth/token
Authorization: Bearer {token}
Відповідь: 204 No Content
GET /api/tasks?status=pending&priority=high&due_from=2025-10-01&sort=due_date&direction=asc&page=1
Authorization: Bearer {token}
POST /api/tasks
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "Нова задача",
"description": "Опціонально",
"priority": "high",
"status": "pending",
"due_date": "2025-10-05"
}
PUT /api/tasks/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"status": "done"
}
DELETE /api/tasks/{id}
Authorization: Bearer {token}
Повні схеми запитів/відповідей — у Swagger UI.
Запуск усіх тестів:
php artisan testАбо (якщо встановлено Pest):
./vendor/bin/pestКоманди (дивись у composer.json scripts, якщо додані):
# Стиль коду
./vendor/bin/pint
# Або PHP CS Fixer
./vendor/bin/php-cs-fixer fix --dry-run
# Статичний аналіз (Larastan)
./vendor/bin/phpstan analyse
# IDE helper (за потреби)
php artisan ide-helper:models -M
php artisan ide-helper:metaРекомендації:
- PSR-12, єдине вирівнювання операторів, без зайвих PHPDoc
- Enum’и — джерело правди для лейблів/стилів
- Контролери — тонкі; вся бізнес-логіка у сервісах/репозиторіях
- Валідація — через FormRequest
- Авторизація — через Policy
- Побічні ефекти — через події/обсервери/джоби
- Розклад у
App\Console\Kernel: щодня о 09:00 виконуєтьсяSendDueSoonReminders. - Якщо у задачі
due_date = завтра, користувачеві надсилається лист (див.TaskPriorityMail). - Для dev можна увімкнути
MAIL_MAILER=logі перевірятиstorage/logs/laravel.log.
Системні вимоги: Docker Desktop / Docker Engine з підтримкою Compose v2.
Використовується конфігурація (скорочено):
version: "3.9"
services:
php:
build:
context: ./docker/php
container_name: laravel-php
working_dir: /var/www/html
volumes:
- ./:/var/www/html
- ./docker/php/conf.d/php.ini:/usr/local/etc/php/conf.d/zz-custom.ini:ro
- ./docker/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/zz-xdebug.ini:ro
environment:
APP_ENV: local
PHP_IDE_CONFIG: serverName=laravel
XDEBUG_MODE: "debug,develop"
XDEBUG_CLIENT_HOST: "host.docker.internal"
XDEBUG_CLIENT_PORT: "9003"
extra_hosts:
- "host.docker.internal:host-gateway"
ports:
- "5173:5173"
depends_on:
- db
nginx:
image: nginx:1.27-alpine
container_name: laravel-nginx
ports:
- "8080:80"
volumes:
- ./:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
db:
image: mysql:8.0
container_name: laravel-mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: laravel
ports:
- "33060:3306"
volumes:
- db_data:/var/lib/mysql
mailpit:
image: axllent/mailpit:latest
container_name: laravel-mailpit
ports:
- "8025:8025"
- "1025:1025"
volumes:
db_data:Значення .env узгоджені з docker-compose.yml:
APP_NAME="Task Manager"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8080
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=laravel
QUEUE_CONNECTION=database
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
BROADCAST_DRIVER=log
# Sanctum / сесії для локального домену
SANCTUM_STATEFUL_DOMAINS=localhost:8080
SESSION_DOMAIN=localhost
# Пошта через Mailpit
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="noreply@example.com"
MAIL_FROM_NAME="${APP_NAME}"
# Vite (дев-режим)
VITE_HOST=0.0.0.0
VITE_PORT=5173-
Створення
.env, встановлення залежностей, ключ застосунку:docker compose up -d --build docker compose exec php cp .env.example .env docker compose exec php composer install docker compose exec php php artisan key:generate
-
Міграції та сидери:
docker compose exec php php artisan migrate --seed docker compose exec php php artisan storage:link
-
Генерація Swagger-документації:
docker compose exec php php artisan l5-swagger:generate -
Збірка фронтенд-активів (за потреби Vue/Vite):
docker compose exec php npm ci docker compose exec php npm run build # або дев-режим (залишити процес уforeground): docker compose exec php npm run dev -- --host
-
Черги/джоби (локальний режим):
docker compose exec php php artisan queue:work
- Веб-інтерфейс:
http://localhost:8080 - Swagger UI:
http://localhost:8080/api/documentation - Mailpit UI:
http://localhost:8025(SMTP:mailpit:1025) - MySQL:
localhost:33060(всередині мережі:db:3306)
- IDE server name:
laravel - Порт:
9003 - Path mapping: локальна коренева папка проєкту →
/var/www/html - За потреби перезапустити контейнер
phpпісля зміниxdebug.ini.
# Менеджмент
docker compose ps
docker compose logs -f --tail=100 nginx
docker compose logs -f --tail=100 php
# Artisan
docker compose exec php php artisan route:list
docker compose exec php php artisan schedule:run
docker compose exec php php artisan test
# Логи додатка
docker compose exec php tail -f storage/logs/laravel.log- Swagger білий екран: переконайся, що згенеровано
l5-swagger:generateі налаштовано коректні шляхи уconfig/l5-swagger.php. - Bearer-токен не відкликається: у тестах використовуй реальний
Authorization: Bearerабо додай fallback, якщо токен відсутній уcurrentAccessToken(). - Черги не відправляють пошту: перевір
queue:work,MAIL_*і таблицюjobs. - Часи/дати: впевнись, що
APP_TIMEZONEузгоджений з БД/PHP.
MIT