Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions app/Http/Controllers/Api/V1/AuthController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\LoginRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Passport\Client;
use OpenApi\Attributes as OA;

class AuthController extends Controller
{

/**
* @OA\Post(
* path="/auth/login",
* summary="Login",
* tags={"Auth"}
* )
*/
public function login(LoginRequest $request): JsonResponse
{
$credentials = $request->only('email', 'password');

if (!Auth::attempt($credentials)) {
return response()->json([
'error' => 'Неверные учетные данные'
], 401);
}

$user = Auth::user();
$token = $user->createToken('API Token')->accessToken;

return response()->json([
'user' => $user,
'access_token' => $token,
'token_type' => 'Bearer',
]);
}

/**
* @OA\Post(
* path="/auth/logout",
* summary="Logout",
* tags={"Auth"}
* )
*/
public function logout(Request $request): JsonResponse
{
$request->user()->token()->revoke();

return response()->json([
'message' => 'Успешный выход из системы'
]);
}


}

160 changes: 160 additions & 0 deletions app/Http/Controllers/Api/V1/TaskController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\StoreTaskRequest;
use App\Http\Requests\Api\UpdateTaskRequest;

use App\Services\Commands\CreateTask\Command as CreateTaskCommand;
use App\Services\Commands\CreateTask\Handler as CreateTaskHandler;
use App\Services\Commands\UpdateTask\Command as UpdateTaskCommand;
use App\Services\Commands\UpdateTask\Handler as UpdateTaskHandler;
use App\Services\Commands\DeleteTask\Command as DeleteTaskCommand;
use App\Services\Commands\DeleteTask\Handler as DeleteTaskHandler;
use App\Services\Queries\FetchAllTasks\Query as FetchAllTasksQuery;
use App\Services\Queries\FetchAllTasks\Fetcher as FetchAllTasksFetcher;
use App\Services\Queries\FetchTaskById\Query as FetchTaskByIdQuery;
use App\Services\Queries\FetchTaskById\Fetcher as FetchTaskByIdFetcher;
use App\Services\Exceptions\Tasks\TaskNotFoundException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use OpenApi\Attributes as OA;

class TaskController extends Controller
{
/**
* @OA\Get(
* path="/tasks",
* summary="Get tasks",
* tags={"Tasks"}
* )
*/
public function index(Request $request, FetchAllTasksFetcher $fetcher): JsonResponse
{
$page = (int) $request->get('page', 1);
$perPage = (int) $request->get('per_page', 15);

$query = FetchAllTasksQuery::fromPage($page, $perPage);
$result = $fetcher->fetch($query);

return response()->json([
'data' => $result->items,
'meta' => [
'current_page' => $page,
'per_page' => $perPage,
'total' => $result->total,
'last_page' => ceil($result->total / $perPage),
]
]);
}

/**
* @OA\Post(
* path="/tasks",
* summary="Create task",
* tags={"Tasks"}
* )
*/
public function store(StoreTaskRequest $request, CreateTaskHandler $handler): JsonResponse
{
$command = new CreateTaskCommand(
title: $request->title,
description: $request->description ?? '',
executorId: (int) $request->executor_id,
categoryId: (int) $request->category_id,
priorityId: (int) $request->priority_id,
creatorId: auth('api')->id(),
status: $request->status ?? 'новая',
dueDate: $request->due_date
);

$result = $handler->handle($command);

if ($result) {
return response()->json([
'message' => 'Задача успешно создана'
], 201);
}

return response()->json([
'message' => 'Ошибка при создании задачи'
], 500);
}

/**
* Получить задачу по ID
*/
public function show(int $id, FetchTaskByIdFetcher $fetcher): JsonResponse
{
try {
$query = new FetchTaskByIdQuery($id);
$taskDTO = $fetcher->fetch($query);

return response()->json([
'data' => $taskDTO
]);
} catch (TaskNotFoundException $e) {
return response()->json([
'message' => 'Задача не найдена'
], 404);
}
}

/**
* Обновить задачу
*/
public function update(int $id, UpdateTaskRequest $request, UpdateTaskHandler $handler): JsonResponse
{
try {
$command = new UpdateTaskCommand(
id: $id,
title: $request->title,
description: $request->description ?? '',
executorId: (int) $request->executor_id,
categoryId: (int) $request->category_id,
priorityId: (int) $request->priority_id,
creatorId: auth('api')->id(),
status: $request->status ?? 'новая',
dueDate: $request->due_date
);

$taskDTO = $handler->handle($command);

return response()->json([
'message' => 'Задача успешно обновлена',
'data' => $taskDTO
]);
} catch (TaskNotFoundException $e) {
return response()->json([
'message' => 'Задача не найдена'
], 404);
}
}

/**
* Удалить задачу
*/
public function destroy(int $id, DeleteTaskHandler $handler): JsonResponse
{
try {
$command = new DeleteTaskCommand($id);
$result = $handler->handle($command);

if ($result) {
return response()->json([
'message' => 'Задача успешно удалена'
]);
}

return response()->json([
'message' => 'Ошибка при удалении задачи'
], 500);
} catch (TaskNotFoundException $e) {
return response()->json([
'message' => 'Задача не найдена'
], 404);
}
}
}

25 changes: 25 additions & 0 deletions app/Models/Category.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Category extends Model
{
use HasFactory;

public $timestamps = false;

protected $fillable = [
'color',
'name',
'description',
];

public function tasks(): HasMany
{
return $this->hasMany(Task::class);
}
}
23 changes: 23 additions & 0 deletions app/Models/Priority.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Priority extends Model
{
use HasFactory;

public $timestamps = false;

protected $fillable = [
'name',
];

public function tasks()
{
return $this->hasMany(Task::class);
}
}
50 changes: 50 additions & 0 deletions app/Models/Task.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Task extends Model
{
use HasFactory;

protected $fillable = [
'title',
'description',
'status',
'due_date',
'priority_id',
'category_id',
'executor_id',
'creator_id',
];


protected $casts = [
'due_date' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];

public function priority()
{
return $this->belongsTo(Priority::class);
}

public function category()
{
return $this->belongsTo(Category::class);
}

public function executor()
{
return $this->belongsTo(User::class, 'executor_id');
}

public function creator()
{
return $this->belongsTo(User::class, 'creator_id');
}
}
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"license": "MIT",
"require": {
"php": "^8.2",
"darkaonline/l5-swagger": "^9.0",
"dedoc/scramble": "^0.12.30",
"fakerphp/faker": "^1.24",
"illuminate/support": "*",
Expand All @@ -18,6 +19,8 @@
"lcobucci/jwt": "^4.3",
"league/event": "^2.3.0",
"prog-time/tg-logger": "^1.0",
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0",
"tymon/jwt-auth": "^2.1",
"vagrant/ascii": "@dev",
"watson/rememberable": "^7.0"
Expand Down
Loading