Make name fields in projects, tasks, clients and tags unique; fixes ST-265

This commit is contained in:
Constantin Graf
2024-06-19 16:01:50 +02:00
committed by Gregor Vostrak
parent 313cee2db0
commit 512089ccbd
21 changed files with 602 additions and 90 deletions

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace App\Http\Controllers\Api\V1;
use App\Exceptions\Api\EntityStillInUseApiException;
use App\Http\Requests\V1\Tag\TagStoreRequest;
use App\Http\Requests\V1\Tag\TagUpdateRequest;
use App\Http\Requests\V1\Client\ClientStoreRequest;
use App\Http\Requests\V1\Client\ClientUpdateRequest;
use App\Http\Resources\V1\Client\ClientCollection;
use App\Http\Resources\V1\Client\ClientResource;
use App\Models\Client;
@@ -52,7 +52,7 @@ class ClientController extends Controller
*
* @operationId createClient
*/
public function store(Organization $organization, TagStoreRequest $request): ClientResource
public function store(Organization $organization, ClientStoreRequest $request): ClientResource
{
$this->checkPermission($organization, 'clients:create');
@@ -71,7 +71,7 @@ class ClientController extends Controller
*
* @operationId updateClient
*/
public function update(Organization $organization, Client $client, TagUpdateRequest $request): ClientResource
public function update(Organization $organization, Client $client, ClientUpdateRequest $request): ClientResource
{
$this->checkPermission($organization, 'clients:update', $client);

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace App\Http\Requests\V1\Client;
use App\Models\Client;
use App\Models\Organization;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
*/
class ClientStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, array<string|ValidationRule>>
*/
public function rules(): array
{
return [
'name' => [
'required',
'string',
'min:1',
'max:255',
(new UniqueEloquent(Client::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Client> $builder */
return $builder->whereBelongsTo($this->organization, 'organization');
}))->withCustomTranslation('validation.client_name_already_exists'),
],
];
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace App\Http\Requests\V1\Client;
use App\Models\Client;
use App\Models\Organization;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
* @property Client $client Client from model binding
*/
class ClientUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, array<string|ValidationRule>>
*/
public function rules(): array
{
return [
'name' => [
'required',
'string',
'min:1',
'max:255',
(new UniqueEloquent(Client::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Client> $builder */
return $builder->whereBelongsTo($this->organization, 'organization');
}))->ignore($this->client->getKey())->withCustomTranslation('validation.client_name_already_exists'),
],
];
}
}

View File

@@ -6,11 +6,13 @@ namespace App\Http\Requests\V1\Project;
use App\Models\Client;
use App\Models\Organization;
use App\Models\Project;
use App\Rules\ColorRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
@@ -26,11 +28,14 @@ class ProjectStoreRequest extends FormRequest
{
return [
'name' => [
// TODO: unique
'required',
'string',
'min:1',
'max:255',
(new UniqueEloquent(Project::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Project> $builder */
return $builder->whereBelongsTo($this->organization, 'organization');
}))->withCustomTranslation('validation.project_name_already_exists'),
],
'color' => [
'required',

View File

@@ -6,14 +6,17 @@ namespace App\Http\Requests\V1\Project;
use App\Models\Client;
use App\Models\Organization;
use App\Models\Project;
use App\Rules\ColorRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
* @property Project $project Project from model binding
*/
class ProjectUpdateRequest extends FormRequest
{
@@ -26,10 +29,13 @@ class ProjectUpdateRequest extends FormRequest
{
return [
'name' => [
// TODO: unique
'required',
'string',
'max:255',
(new UniqueEloquent(Project::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Project> $builder */
return $builder->whereBelongsTo($this->organization, 'organization');
}))->ignore($this->project->getKey())->withCustomTranslation('validation.project_name_already_exists'),
],
'color' => [
'required',

View File

@@ -4,9 +4,16 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\Tag;
use App\Models\Organization;
use App\Models\Tag;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
*/
class TagStoreRequest extends FormRequest
{
/**
@@ -18,11 +25,14 @@ class TagStoreRequest extends FormRequest
{
return [
'name' => [
// TODO: unique
'required',
'string',
'min:1',
'max:255',
(new UniqueEloquent(Tag::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Tag> $builder */
return $builder->whereBelongsTo($this->organization, 'organization');
}))->withCustomTranslation('validation.tag_name_already_exists'),
],
];
}

View File

@@ -4,9 +4,17 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\Tag;
use App\Models\Organization;
use App\Models\Tag;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
* @property Tag $tag Tag from model binding
*/
class TagUpdateRequest extends FormRequest
{
/**
@@ -18,11 +26,14 @@ class TagUpdateRequest extends FormRequest
{
return [
'name' => [
// TODO: unique
'required',
'string',
'min:1',
'max:255',
(new UniqueEloquent(Tag::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Tag> $builder */
return $builder->whereBelongsTo($this->organization, 'organization');
}))->ignore($this->tag->getKey())->withCustomTranslation('validation.tag_name_already_exists'),
],
];
}

View File

@@ -6,10 +6,12 @@ namespace App\Http\Requests\V1\Task;
use App\Models\Organization;
use App\Models\Project;
use App\Models\Task;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
@@ -25,11 +27,14 @@ class TaskStoreRequest extends FormRequest
{
return [
'name' => [
// TODO: unique
'required',
'string',
'min:1',
'max:255',
(new UniqueEloquent(Task::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Task> $builder */
return $builder->where('project_id', '=', $this->input('project_id'));
}))->withCustomTranslation('validation.task_name_already_exists'),
],
'project_id' => [
'required',

View File

@@ -5,11 +5,15 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\Task;
use App\Models\Organization;
use App\Models\Task;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent;
/**
* @property Organization $organization Organization from model binding
* @property Task $task Task from model binding
*/
class TaskUpdateRequest extends FormRequest
{
@@ -22,11 +26,14 @@ class TaskUpdateRequest extends FormRequest
{
return [
'name' => [
// TODO: unique
'required',
'string',
'min:1',
'max:255',
(new UniqueEloquent(Task::class, 'name', function (Builder $builder): Builder {
/** @var Builder<Task> $builder */
return $builder->where('project_id', '=', $this->task->project_id);
}))->ignore($this->task->getKey())->withCustomTranslation('validation.task_name_already_exists'),
],
];
}