chore: commit remaining workspace changes
This commit is contained in:
122
app/Console/Commands/AcademyCoursesSyncFoundationsCommand.php
Normal file
122
app/Console/Commands/AcademyCoursesSyncFoundationsCommand.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\AcademyCourse;
|
||||
use App\Models\AcademyCourseLesson;
|
||||
use App\Models\AcademyCourseSection;
|
||||
use App\Models\AcademyLesson;
|
||||
use App\Services\Academy\AcademyCacheService;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
final class AcademyCoursesSyncFoundationsCommand extends Command
|
||||
{
|
||||
protected $signature = 'academy:courses:sync-foundations';
|
||||
|
||||
protected $description = 'Create or update the default AI-Assisted Digital Art Foundations Academy course.';
|
||||
|
||||
public function __construct(private readonly AcademyCacheService $cache)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$course = AcademyCourse::query()->updateOrCreate(
|
||||
['slug' => 'ai-assisted-digital-art-foundations'],
|
||||
[
|
||||
'title' => 'AI-Assisted Digital Art Foundations',
|
||||
'subtitle' => 'A guided path through prompting, publishing, and better Skinbase-ready workflows.',
|
||||
'excerpt' => 'Learn the foundations of AI-assisted digital art, from better prompts and ethical rules to preparing, tagging, and publishing artwork on Skinbase.',
|
||||
'description' => 'A starter course for Skinbase creators who want a structured path from core AI-art concepts to cleaner publishing-ready results.',
|
||||
'access_level' => 'free',
|
||||
'difficulty' => 'beginner',
|
||||
'status' => 'published',
|
||||
'is_featured' => true,
|
||||
'order_num' => 1,
|
||||
'published_at' => now(),
|
||||
],
|
||||
);
|
||||
|
||||
$sectionOrder = [
|
||||
'Introduction',
|
||||
'Prompting Basics',
|
||||
'Publishing on Skinbase',
|
||||
'Workflow and Quality',
|
||||
];
|
||||
|
||||
$sections = collect($sectionOrder)->mapWithKeys(function (string $title, int $index) use ($course): array {
|
||||
$section = AcademyCourseSection::query()->updateOrCreate(
|
||||
['course_id' => $course->id, 'slug' => Str::slug($title)],
|
||||
[
|
||||
'title' => $title,
|
||||
'order_num' => $index,
|
||||
'is_visible' => true,
|
||||
],
|
||||
);
|
||||
|
||||
return [$title => $section];
|
||||
});
|
||||
|
||||
$lessonMap = [
|
||||
'Introduction' => [
|
||||
'what-is-ai-assisted-digital-art',
|
||||
'ai-ethics-and-skinbase-upload-rules',
|
||||
'ai-generated-vs-ai-assisted-artwork',
|
||||
],
|
||||
'Prompting Basics' => [
|
||||
'prompting-basics-for-skinbase-creators',
|
||||
'how-to-write-better-wallpaper-prompts',
|
||||
'understanding-style-mood-lighting-and-composition',
|
||||
],
|
||||
'Publishing on Skinbase' => [
|
||||
'how-to-prepare-ai-artwork-for-upload',
|
||||
'how-to-choose-better-tags-and-categories',
|
||||
],
|
||||
'Workflow and Quality' => [
|
||||
'how-to-avoid-common-ai-image-problems',
|
||||
'from-idea-to-artwork-a-simple-skinbase-workflow',
|
||||
],
|
||||
];
|
||||
|
||||
$orderNum = 0;
|
||||
foreach ($lessonMap as $sectionTitle => $slugs) {
|
||||
$section = $sections->get($sectionTitle);
|
||||
|
||||
foreach ($slugs as $slug) {
|
||||
$lesson = AcademyLesson::query()->where('slug', $slug)->first();
|
||||
|
||||
if (! $lesson instanceof AcademyLesson) {
|
||||
$this->warn(sprintf('Skipped missing lesson [%s].', $slug));
|
||||
continue;
|
||||
}
|
||||
|
||||
AcademyCourseLesson::query()->updateOrCreate(
|
||||
[
|
||||
'course_id' => $course->id,
|
||||
'lesson_id' => $lesson->id,
|
||||
],
|
||||
[
|
||||
'section_id' => $section?->id,
|
||||
'order_num' => $orderNum,
|
||||
'is_required' => true,
|
||||
],
|
||||
);
|
||||
|
||||
$orderNum++;
|
||||
}
|
||||
}
|
||||
|
||||
$course->forceFill([
|
||||
'lessons_count_cache' => AcademyCourseLesson::query()->where('course_id', $course->id)->count(),
|
||||
])->save();
|
||||
|
||||
$this->cache->clearAll();
|
||||
$this->info('AI-Assisted Digital Art Foundations course synced.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use App\Console\Commands\BackfillArtworkVectorIndexCommand;
|
||||
use App\Console\Commands\IndexArtworkVectorsCommand;
|
||||
use App\Console\Commands\SearchArtworkVectorsCommand;
|
||||
use App\Console\Commands\AggregateSimilarArtworkAnalyticsCommand;
|
||||
use App\Console\Commands\AcademyCoursesSyncFoundationsCommand;
|
||||
use App\Console\Commands\AggregateFeedAnalyticsCommand;
|
||||
use App\Console\Commands\AggregateTagInteractionAnalyticsCommand;
|
||||
use App\Console\Commands\SeedTagInteractionDemoCommand;
|
||||
@@ -71,6 +72,7 @@ class Kernel extends ConsoleKernel
|
||||
ZipUnsupportedArtworkOriginalsCommand::class,
|
||||
SendTestMail::class,
|
||||
DispatchCollectionMaintenanceCommand::class,
|
||||
AcademyCoursesSyncFoundationsCommand::class,
|
||||
BackfillArtworkEmbeddingsCommand::class,
|
||||
BackfillArtworkVectorIndexCommand::class,
|
||||
IndexArtworkVectorsCommand::class,
|
||||
|
||||
Reference in New Issue
Block a user