first commit
This commit is contained in:
140
README.md
Normal file
140
README.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Тестовое задание
|
||||
|
||||
**Версия php** 8.5
|
||||
|
||||
**Laravel** 12
|
||||
|
||||
Контейнер с приложением работает на frankenphp
|
||||
|
||||
**На хост машине**
|
||||
|
||||
```bash
|
||||
make help
|
||||
make build
|
||||
make install # копирует .env.example в рабочий .env, для удобства,так же запускает миграции
|
||||
make run # заполнит базу и запустит тесты
|
||||
```
|
||||
|
||||
Необходимо задать переменные окружения
|
||||
|
||||
```dotenv
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=mysql
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_USERNAME=laravel
|
||||
DB_PASSWORD=secret
|
||||
```
|
||||
|
||||
Так же необходимо настроить сервисы, например через внешние .env
|
||||
Сейчас доступы хардкод в compose.yaml
|
||||
|
||||
```yaml
|
||||
mysql:
|
||||
image: mysql:8.4.8
|
||||
container_name: laravel_mysql
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: secret
|
||||
MYSQL_DATABASE: laravel
|
||||
MYSQL_USER: laravel
|
||||
MYSQL_PASSWORD: secret
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
networks:
|
||||
- laravel_network
|
||||
healthcheck:
|
||||
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-psecret" ]
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
interval: 30s
|
||||
phpmyadmin:
|
||||
image: phpmyadmin/phpmyadmin
|
||||
container_name: laravel_phpmyadmin
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:8585:80"
|
||||
environment:
|
||||
PMA_HOST: mysql
|
||||
PMA_PORT: 3306
|
||||
PMA_USER: laravel
|
||||
PMA_PASSWORD: secret
|
||||
PMA_ARBITRARY: 1
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- laravel_network
|
||||
```
|
||||
|
||||
## Маршруты
|
||||
|
||||
**/api namespace**
|
||||
|
||||
```php
|
||||
Route::prefix('tasks')->name('tasks.')->group(function () {
|
||||
Route::get('/', [TaskController::class, 'index'])->name('index');
|
||||
Route::post('/', [TaskController::class, 'store'])->name('store');
|
||||
Route::get('/{task}', [TaskController::class, 'show'])->name('show');
|
||||
Route::match(['put', 'patch'], '/{task}', [TaskController::class, 'update'])->name('update');
|
||||
Route::delete('/{task}', [TaskController::class, 'destroy'])->name('destroy');
|
||||
});
|
||||
```
|
||||
|
||||
Роуты не защищал, установлен пакет laravel/sanctum, можно настроить токены\
|
||||
|
||||
Родительский контроллер использует AuthorizesRequests, можно реализовать Policy
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
abstract class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
}
|
||||
```
|
||||
|
||||
Пример реализации
|
||||
|
||||
```php
|
||||
// в конструкторе контроллера
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Task::class, 'task');
|
||||
}
|
||||
```
|
||||
|
||||
**Тесты**
|
||||
|
||||
[Feature](laravel/tests/Feature/TaskControllerTest.php)
|
||||
|
||||
[Unit](laravel/tests/Unit/QueryFilterPipelineTest.php)
|
||||
|
||||
**Расширение фильтров**
|
||||
|
||||
[Конфиг](laravel/config/filters.php)
|
||||
|
||||
Фильтры должны реализовывать FilterInterface для работы в Pipeline
|
||||
|
||||
Requests содержащие фильтры должны реализовывать RequestFilterInterface
|
||||
|
||||
### Документация API
|
||||
|
||||
[Task](docs/task.md)
|
||||
|
||||
### Комментарий:
|
||||
|
||||
Апи может присылать полные дубли строк, думал делать вставку через upsert + уникальный ключ
|
||||
например по хешу основных строк, но выбрал более простой вариант с обычным заполнением
|
||||
|
||||
### Ссылка на хостинг
|
||||
|
||||
https://pma.din9xtr.tech/
|
||||
Reference in New Issue
Block a user