From e800e5fd7f51704220238a4be1ec106fa93a8236 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Sat, 15 Aug 2026 22:51:52 +0300 Subject: [PATCH] add tanach seeder --- backend/database/seeders/TanachSeeder.php | 249 ++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 backend/database/seeders/TanachSeeder.php diff --git a/backend/database/seeders/TanachSeeder.php b/backend/database/seeders/TanachSeeder.php new file mode 100644 index 0000000..a3be174 --- /dev/null +++ b/backend/database/seeders/TanachSeeder.php @@ -0,0 +1,249 @@ + [ + 'Bereishis' => 50, + 'Shemos' => 40, + 'Vayikra' => 27, + 'Bamidbar' => 36, + 'Devarim' => 34, + ], + "Nevi'im" => [ + 'Yehoshua' => 24, + 'Shoftim' => 21, + 'Shmuel Alef' => 31, + 'Shmuel Beis' => 24, + 'Melachim Alef' => 22, + 'Melachim Beis' => 25, + 'Yeshayahu' => 66, + 'Yirmiyahu' => 52, + 'Yechezkel' => 48, + 'Hoshea' => 14, + 'Yoel' => 4, + 'Amos' => 9, + 'Ovadiah' => 1, + 'Yonah' => 4, + 'Michah' => 7, + 'Nachum' => 3, + 'Chavakuk' => 3, + 'Tzefaniah' => 3, + 'Chaggai' => 2, + 'Zechariah' => 14, + 'Malachi' => 3, + ], + 'Kesuvim' => [ + 'Tehillim' => 150, + 'Mishlei' => 31, + 'Iyov' => 42, + 'Shir HaShirim' => 8, + 'Rus' => 4, + 'Eichah' => 5, + 'Koheles' => 12, + 'Esther' => 10, + 'Daniel' => 12, + 'Ezra' => 10, + 'Nechemiah' => 13, + 'Divrei HaYamim Alef' => 29, + 'Divrei HaYamim Beis' => 36, + ], + ]; + + public function run(): void + { + $this->call(UserSeeder::class); + + $user = app(UserRepository::class)->findByEmail( + new EmailAddress(UserSeeder::EMAIL), + ); + if ($user === null) { + throw new RuntimeException('seeded user not found'); + } + + $setRepository = app(SetRepository::class); + $tanach = $this->findTanach($setRepository); + if ($tanach === null) { + $tanach = $setRepository->create(new CreateSetDto( + name: self::SET_NAME, + creator: $user, + )); + } + + $levels = $this->seedLevels( + repository: app(SetLevelRepository::class), + tanach: $tanach, + ); + $this->seedElements( + repository: app(ElementRepository::class), + tanach: $tanach, + levels: $levels, + ); + } + + private function findTanach(SetRepository $repository): ?Set + { + foreach ($repository->all() as $set) { + if ($set->getName() === self::SET_NAME) { + return $set; + } + } + + return null; + } + + /** + * @return array{ + * chelek: SetLevel, + * sefer: SetLevel, + * perek: SetLevel + * } + */ + private function seedLevels( + SetLevelRepository $repository, + Set $tanach, + ): array { + $levels = $repository->findBySet($tanach); + + foreach ($levels as $depth => $level) { + $expectedKind = self::LEVEL_KINDS[$depth] ?? null; + if ($level->getKind() !== $expectedKind) { + throw new RuntimeException( + 'Tanach levels do not match the expected hierarchy', + ); + } + } + + $missingKinds = array_slice(self::LEVEL_KINDS, count($levels)); + foreach ($missingKinds as $kind) { + $levels[] = $repository->create(new CreateSetLevelDto( + set: $tanach, + kind: $kind, + )); + } + + return [ + 'chelek' => $this->findLevel($levels, 'chelek'), + 'sefer' => $this->findLevel($levels, 'sefer'), + 'perek' => $this->findLevel($levels, 'perek'), + ]; + } + + /** + * @param list $levels + */ + private function findLevel(array $levels, string $kind): SetLevel + { + foreach ($levels as $level) { + if ($level->getKind() === $kind) { + return $level; + } + } + + throw new RuntimeException("Tanach {$kind} level not found"); + } + + /** + * @param array{ + * chelek: SetLevel, + * sefer: SetLevel, + * perek: SetLevel + * } $levels + */ + private function seedElements( + ElementRepository $repository, + Set $tanach, + array $levels, + ): void { + $chelakim = $repository->findTopLevelBySet($tanach); + + foreach (self::SEFARIM_BY_CHELEK as $chelekName => $sefarim) { + $chelek = $this->findOrCreateElement( + repository: $repository, + siblings: $chelakim, + name: $chelekName, + level: $levels['chelek'], + parentElement: null, + ); + $seededSefarim = $repository->findByParentElement($chelek); + + foreach ($sefarim as $seferName => $perekCount) { + $sefer = $this->findOrCreateElement( + repository: $repository, + siblings: $seededSefarim, + name: $seferName, + level: $levels['sefer'], + parentElement: $chelek, + ); + $perakim = $repository->findByParentElement($sefer); + + for ( + $perekNumber = 1; + $perekNumber <= $perekCount; + $perekNumber++ + ) { + $this->findOrCreateElement( + repository: $repository, + siblings: $perakim, + name: "Perek {$perekNumber}", + level: $levels['perek'], + parentElement: $sefer, + ); + } + } + } + } + + /** + * @param list $siblings + */ + private function findOrCreateElement( + ElementRepository $repository, + array &$siblings, + string $name, + SetLevel $level, + ?Element $parentElement, + ): Element { + foreach ($siblings as $sibling) { + if ( + $sibling->getName() === $name + && $sibling->getLevel()->getId() === $level->getId() + ) { + return $sibling; + } + } + + $element = $repository->create(new CreateElementDto( + name: $name, + level: $level, + parentElement: $parentElement, + )); + $siblings[] = $element; + + return $element; + } +}