schedule explicit set levels

This commit is contained in:
Yisroel Baum 2026-08-11 22:57:15 +03:00
parent a64df64b76
commit 3cf1aff6a9
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
10 changed files with 156 additions and 38 deletions

View file

@ -13,6 +13,7 @@ class DatabaseSeeder extends Seeder
{
$this->call(UserSeeder::class);
$this->call(SetSeeder::class);
$this->call(SetLevelSeeder::class);
$this->call(ElementSeeder::class);
}
}

View file

@ -6,8 +6,11 @@ use App\Element\CreateElementDto;
use App\Element\Element;
use App\Element\ElementRepository;
use App\Set\Set;
use App\Set\SetLevel;
use App\Set\SetLevelRepository;
use App\Set\SetRepository;
use Illuminate\Database\Seeder;
use RuntimeException;
class ElementSeeder extends Seeder
{
@ -15,38 +18,31 @@ class ElementSeeder extends Seeder
'Bible' => [
[
'name' => 'Genesis',
'kind' => 'book',
'children' => [
[
'name' => 'Creation',
'kind' => 'portion',
'children' => [
[
'name' => 'Chapter 1',
'kind' => 'chapter',
'children' => [],
],
[
'name' => 'Chapter 2',
'kind' => 'chapter',
'children' => [],
],
],
],
[
'name' => 'Noah',
'kind' => 'portion',
'children' => [],
],
],
],
[
'name' => 'Exodus',
'kind' => 'book',
'children' => [
[
'name' => 'Shemot',
'kind' => 'portion',
'children' => [],
],
],
@ -55,32 +51,26 @@ class ElementSeeder extends Seeder
'Course' => [
[
'name' => 'Foundations',
'kind' => 'module',
'children' => [
[
'name' => 'Welcome',
'kind' => 'lesson',
'children' => [],
],
[
'name' => 'Core Concepts',
'kind' => 'lesson',
'children' => [],
],
],
],
[
'name' => 'Applied Practice',
'kind' => 'module',
'children' => [
[
'name' => 'Guided Exercise',
'kind' => 'lesson',
'children' => [],
],
[
'name' => 'Final Review',
'kind' => 'lesson',
'children' => [],
],
],
@ -89,31 +79,25 @@ class ElementSeeder extends Seeder
'Fitness Program' => [
[
'name' => 'Foundation Phase',
'kind' => 'phase',
'children' => [
[
'name' => 'Strength Day',
'kind' => 'workout',
'children' => [
[
'name' => 'Squat',
'kind' => 'exercise',
'children' => [],
],
[
'name' => 'Push-up',
'kind' => 'exercise',
'children' => [],
],
],
],
[
'name' => 'Mobility Day',
'kind' => 'workout',
'children' => [
[
'name' => 'Hip Flow',
'kind' => 'exercise',
'children' => [],
],
],
@ -122,11 +106,9 @@ class ElementSeeder extends Seeder
],
[
'name' => 'Build Phase',
'kind' => 'phase',
'children' => [
[
'name' => 'Full Body Circuit',
'kind' => 'workout',
'children' => [],
],
],
@ -137,6 +119,7 @@ class ElementSeeder extends Seeder
public function run(): void
{
$elementRepository = app(ElementRepository::class);
$setLevelRepository = app(SetLevelRepository::class);
foreach (app(SetRepository::class)->all() as $set) {
$definitions = self::ELEMENTS_BY_SET[$set->getName()] ?? null;
@ -147,6 +130,8 @@ class ElementSeeder extends Seeder
$this->seedChildren(
repository: $elementRepository,
set: $set,
levels: $setLevelRepository->findBySet($set),
depth: 0,
parentElement: null,
definitions: $definitions,
);
@ -156,16 +141,27 @@ class ElementSeeder extends Seeder
/**
* @param list<array{
* name: string,
* kind: string,
* children: list<mixed>
* }> $definitions
* @param list<SetLevel> $levels
*/
private function seedChildren(
ElementRepository $repository,
Set $set,
array $levels,
int $depth,
?Element $parentElement,
array $definitions,
): void {
if ($definitions === []) {
return;
}
$level = $levels[$depth] ?? null;
if ($level === null) {
throw new RuntimeException('element level not defined');
}
$siblings = $parentElement === null
? $repository->findTopLevelBySet($set)
: $repository->findByParentElement($parentElement);
@ -174,13 +170,12 @@ class ElementSeeder extends Seeder
$element = $this->findSibling(
siblings: $siblings,
name: $definition['name'],
kind: $definition['kind'],
level: $level,
);
if ($element === null) {
$element = $repository->create(new CreateElementDto(
set: $set,
name: $definition['name'],
kind: $definition['kind'],
level: $level,
parentElement: $parentElement,
));
$siblings[] = $element;
@ -189,6 +184,8 @@ class ElementSeeder extends Seeder
$this->seedChildren(
repository: $repository,
set: $set,
levels: $levels,
depth: $depth + 1,
parentElement: $element,
definitions: $definition['children'],
);
@ -201,12 +198,12 @@ class ElementSeeder extends Seeder
private function findSibling(
array $siblings,
string $name,
string $kind,
SetLevel $level,
): ?Element {
foreach ($siblings as $sibling) {
if (
$sibling->getName() === $name
&& $sibling->getKind() === $kind
&& $sibling->getLevel()->getId() === $level->getId()
) {
return $sibling;
}

View file

@ -0,0 +1,45 @@
<?php
namespace Database\Seeders;
use App\Set\CreateSetLevelDto;
use App\Set\SetLevelRepository;
use App\Set\SetRepository;
use Illuminate\Database\Seeder;
class SetLevelSeeder extends Seeder
{
private const array KINDS_BY_SET = [
'Bible' => ['book', 'portion', 'chapter'],
'Course' => ['module', 'lesson'],
'Fitness Program' => ['phase', 'workout', 'exercise'],
];
public function run(): void
{
$repository = app(SetLevelRepository::class);
foreach (app(SetRepository::class)->all() as $set) {
$kinds = self::KINDS_BY_SET[$set->getName()] ?? null;
if ($kinds === null) {
continue;
}
$existingKinds = array_map(function ($level): string {
return $level->getKind();
}, $repository->findBySet($set));
foreach ($kinds as $kind) {
if (in_array($kind, $existingKinds, true)) {
continue;
}
$repository->create(new CreateSetLevelDto(
set: $set,
kind: $kind,
));
$existingKinds[] = $kind;
}
}
}
}