add explicit set levels
This commit is contained in:
parent
7e8850b1b2
commit
0d102fcee0
7 changed files with 223 additions and 0 deletions
|
|
@ -19,7 +19,9 @@ use App\Email\LaravelEmailFactory;
|
||||||
use App\Element\ElementRepository;
|
use App\Element\ElementRepository;
|
||||||
use App\Element\EloquentElementRepository;
|
use App\Element\EloquentElementRepository;
|
||||||
use App\Set\EloquentSetRepository;
|
use App\Set\EloquentSetRepository;
|
||||||
|
use App\Set\EloquentSetLevelRepository;
|
||||||
use App\Set\SetRepository;
|
use App\Set\SetRepository;
|
||||||
|
use App\Set\SetLevelRepository;
|
||||||
use App\Schedule\EloquentScheduleRepository;
|
use App\Schedule\EloquentScheduleRepository;
|
||||||
use App\Schedule\ScheduleRepository;
|
use App\Schedule\ScheduleRepository;
|
||||||
use App\User\EloquentUserRepository;
|
use App\User\EloquentUserRepository;
|
||||||
|
|
@ -55,6 +57,10 @@ class AppServiceProvider extends ServiceProvider
|
||||||
SetRepository::class,
|
SetRepository::class,
|
||||||
EloquentSetRepository::class,
|
EloquentSetRepository::class,
|
||||||
);
|
);
|
||||||
|
$this->app->bind(
|
||||||
|
SetLevelRepository::class,
|
||||||
|
EloquentSetLevelRepository::class,
|
||||||
|
);
|
||||||
$this->app->bind(
|
$this->app->bind(
|
||||||
ElementRepository::class,
|
ElementRepository::class,
|
||||||
EloquentElementRepository::class,
|
EloquentElementRepository::class,
|
||||||
|
|
|
||||||
11
backend/app/Set/CreateSetLevelDto.php
Normal file
11
backend/app/Set/CreateSetLevelDto.php
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Set;
|
||||||
|
|
||||||
|
final readonly class CreateSetLevelDto
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public Set $set,
|
||||||
|
public string $kind,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
88
backend/app/Set/EloquentSetLevelRepository.php
Normal file
88
backend/app/Set/EloquentSetLevelRepository.php
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Set;
|
||||||
|
|
||||||
|
use DomainException;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class EloquentSetLevelRepository implements SetLevelRepository
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private SetRepository $setRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function create(CreateSetLevelDto $dto): SetLevel
|
||||||
|
{
|
||||||
|
$kindExists = SetLevelModel::query()
|
||||||
|
->where('set_id', $dto->set->getId())
|
||||||
|
->where('kind', $dto->kind)
|
||||||
|
->exists();
|
||||||
|
if ($kindExists) {
|
||||||
|
throw new DomainException(
|
||||||
|
'level kind must be unique within set',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentMaximum = SetLevelModel::query()
|
||||||
|
->where('set_id', $dto->set->getId())
|
||||||
|
->max('depth');
|
||||||
|
$depth = $currentMaximum === null
|
||||||
|
? 0
|
||||||
|
: (int) $currentMaximum + 1;
|
||||||
|
$model = SetLevelModel::create([
|
||||||
|
'set_id' => $dto->set->getId(),
|
||||||
|
'kind' => $dto->kind,
|
||||||
|
'depth' => $depth,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new SetLevel(
|
||||||
|
id: $model->id,
|
||||||
|
set: $dto->set,
|
||||||
|
kind: $model->kind,
|
||||||
|
depth: $model->depth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find(int $id): ?SetLevel
|
||||||
|
{
|
||||||
|
$model = SetLevelModel::find($id);
|
||||||
|
|
||||||
|
return $model === null ? null : $this->toDomain($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findBySet(Set $set): array
|
||||||
|
{
|
||||||
|
$models = SetLevelModel::query()
|
||||||
|
->where('set_id', $set->getId())
|
||||||
|
->orderBy('depth')
|
||||||
|
->orderBy('id')
|
||||||
|
->get();
|
||||||
|
$levels = [];
|
||||||
|
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$levels[] = new SetLevel(
|
||||||
|
id: $model->id,
|
||||||
|
set: $set,
|
||||||
|
kind: $model->kind,
|
||||||
|
depth: $model->depth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function toDomain(SetLevelModel $model): SetLevel
|
||||||
|
{
|
||||||
|
$set = $this->setRepository->find($model->set_id);
|
||||||
|
if ($set === null) {
|
||||||
|
throw new RuntimeException('set level set not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SetLevel(
|
||||||
|
id: $model->id,
|
||||||
|
set: $set,
|
||||||
|
kind: $model->kind,
|
||||||
|
depth: $model->depth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
backend/app/Set/SetLevel.php
Normal file
33
backend/app/Set/SetLevel.php
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Set;
|
||||||
|
|
||||||
|
final readonly class SetLevel
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private int $id,
|
||||||
|
private Set $set,
|
||||||
|
private string $kind,
|
||||||
|
private int $depth,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function getId(): int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSet(): Set
|
||||||
|
{
|
||||||
|
return $this->set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKind(): string
|
||||||
|
{
|
||||||
|
return $this->kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDepth(): int
|
||||||
|
{
|
||||||
|
return $this->depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
backend/app/Set/SetLevelModel.php
Normal file
38
backend/app/Set/SetLevelModel.php
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Set;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property int $id
|
||||||
|
* @property int $set_id
|
||||||
|
* @property string $kind
|
||||||
|
* @property int $depth
|
||||||
|
*
|
||||||
|
* @method static Builder<static>|SetLevelModel newModelQuery()
|
||||||
|
* @method static Builder<static>|SetLevelModel newQuery()
|
||||||
|
* @method static Builder<static>|SetLevelModel query()
|
||||||
|
*
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
#[Fillable(['set_id', 'kind', 'depth'])]
|
||||||
|
class SetLevelModel extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'set_levels';
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'set_id' => 'integer',
|
||||||
|
'depth' => 'integer',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
20
backend/app/Set/SetLevelRepository.php
Normal file
20
backend/app/Set/SetLevelRepository.php
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Set;
|
||||||
|
|
||||||
|
use DomainException;
|
||||||
|
|
||||||
|
interface SetLevelRepository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws DomainException
|
||||||
|
*/
|
||||||
|
public function create(CreateSetLevelDto $dto): SetLevel;
|
||||||
|
|
||||||
|
public function find(int $id): ?SetLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<SetLevel>
|
||||||
|
*/
|
||||||
|
public function findBySet(Set $set): array;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('set_levels', function (Blueprint $table): void {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('set_id')
|
||||||
|
->constrained('sets')
|
||||||
|
->cascadeOnDelete();
|
||||||
|
$table->string('kind');
|
||||||
|
$table->unsignedInteger('depth');
|
||||||
|
$table->unique(['set_id', 'kind']);
|
||||||
|
$table->unique(['set_id', 'depth']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('set_levels');
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue