diff --git a/Taskfile.yml b/Taskfile.yml index 46b1848..25ac35b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -16,10 +16,10 @@ tasks: db:seed: desc: Seed the Blog module database - cmd: php artisan modules:seed --module=blog + cmd: '{{.APP}} php artisan modules:seed --module=blog' # ── Code Generation ──────────────────────────────────────────── types:generate: desc: Generate TypeScript types from PHP DTOs and enums - cmd: php artisan module:generate-types blog + cmd: '{{.APP}} php artisan module:generate-types blog' diff --git a/database/seeders/BlogDatabaseSeeder.php b/database/seeders/BlogDatabaseSeeder.php index 0365798..ac4789f 100644 --- a/database/seeders/BlogDatabaseSeeder.php +++ b/database/seeders/BlogDatabaseSeeder.php @@ -14,11 +14,12 @@ public function run(): void { $author = User::first(); - $gettingStarted = Category::create(['name' => 'Getting Started']); - $featuresModules = Category::create(['name' => 'Features & Modules']); - $devExperience = Category::create(['name' => 'Developer Experience']); + $gettingStarted = Category::firstOrCreate(['name' => 'Getting Started']); + $featuresModules = Category::firstOrCreate(['name' => 'Features & Modules']); + $devExperience = Category::firstOrCreate(['name' => 'Developer Experience']); $content = fn (string $file): string => file_get_contents(__DIR__.'/content/'.$file); + $image = fn (string $file): string => __DIR__.'/../../resources/assets/images/'.$file; $this->createPost([ 'title' => 'What Is Saucebase? The Modular Laravel Starter Kit', @@ -28,7 +29,7 @@ public function run(): void 'published_at' => now()->subMonths(5), 'category_id' => $gettingStarted->id, 'author_id' => $author?->id, - ], public_path('modules/blog/images/what-is-saucebase.jpg')); + ], $image('what-is-saucebase.jpg')); $this->createPost([ 'title' => 'Stop Rebuilding the Same Boilerplate Every Project', @@ -48,7 +49,7 @@ public function run(): void 'published_at' => now()->subMonths(3), 'category_id' => $devExperience->id, 'author_id' => $author?->id, - ], public_path('modules/blog/images/tech-stack.jpg')); + ], $image('tech-stack.jpg')); $this->createPost([ 'title' => 'Your First Module: Scaffold and Ship in Under 10 Minutes', @@ -58,7 +59,7 @@ public function run(): void 'published_at' => now()->subMonths(2), 'category_id' => $featuresModules->id, 'author_id' => $author?->id, - ], public_path('modules/blog/images/add-your-saucebase.jpg')); + ], $image('add-your-saucebase.jpg')); $this->createPost([ 'title' => 'Auth, Billing, and Privacy: The Three Modules Every SaaS Needs', @@ -68,7 +69,7 @@ public function run(): void 'published_at' => now()->subMonth(), 'category_id' => $featuresModules->id, 'author_id' => $author?->id, - ], public_path('modules/blog/images/cookies-or-privacy.jpg')); + ], $image('cookies-or-privacy.jpg')); $this->createPost([ 'title' => 'Copy-and-Own: The Philosophy Behind Saucebase Modules', @@ -78,7 +79,7 @@ public function run(): void 'published_at' => now()->subWeeks(2), 'category_id' => $devExperience->id, 'author_id' => $author?->id, - ], public_path('modules/blog/images/your-recipes.jpg')); + ], $image('your-recipes.jpg')); $this->createPost([ 'title' => 'Vue or React? What about both!', @@ -88,15 +89,15 @@ public function run(): void 'published_at' => now()->subDays(3), 'category_id' => $devExperience->id, 'author_id' => $author?->id, - ], public_path('modules/blog/images/vue-and-react.jpg')); + ], $image('vue-and-react.jpg')); } private function createPost(array $data, string $coverImage = ''): Post { - $post = Post::create($data); + $post = Post::firstOrCreate(['title' => $data['title']], $data); if ($coverImage && file_exists($coverImage)) { - $post->addMedia($coverImage)->preservingOriginal()->toMediaCollection('cover'); + $post->addMedia($coverImage)->preservingOriginal()->toMediaCollection('cover', 'public'); } return $post;