Files
SkinbaseNova/database/seeders/AcademyDemoSeeder.php

422 lines
21 KiB
PHP

<?php
declare(strict_types=1);
namespace Database\Seeders;
use App\Models\AcademyBadge;
use App\Models\AcademyCategory;
use App\Models\AcademyChallenge;
use App\Models\AcademyLesson;
use App\Models\AcademyPromptPack;
use App\Models\AcademyPromptPackItem;
use App\Models\AcademyPromptTemplate;
use App\Services\Academy\AcademyCacheService;
use Illuminate\Database\Seeder;
class AcademyDemoSeeder extends Seeder
{
public function run(): void
{
$this->call(AcademyCategorySeeder::class);
$categories = AcademyCategory::query()->get()->keyBy('slug');
$lessons = [
[
'slug' => 'what-is-ai-assisted-digital-art',
'category_slug' => 'prompting-basics',
'title' => 'What Is AI-Assisted Digital Art?',
'excerpt' => 'A grounded overview of how Skinbase creators can use AI as a creative assistant instead of a shortcut.',
'content' => 'AI-assisted digital art combines prompt-driven ideation, composition decisions, and manual finishing into a single workflow that still depends on taste and intent.',
'difficulty' => 'beginner',
'access_level' => 'free',
'lesson_type' => 'article',
'featured' => true,
],
[
'slug' => 'prompting-basics-for-skinbase-creators',
'category_slug' => 'prompting-basics',
'title' => 'Prompting Basics for Skinbase Creators',
'excerpt' => 'Learn how to describe subject, mood, lighting, composition, and finish for Skinbase-native prompt workflows.',
'content' => 'Start with a clear subject. Add mood and lighting. Then anchor the composition for the output you actually want to upload.',
'difficulty' => 'beginner',
'access_level' => 'free',
'lesson_type' => 'article',
'featured' => true,
],
[
'slug' => 'ai-ethics-and-skinbase-upload-rules',
'category_slug' => 'ai-ethics',
'title' => 'AI Ethics and Skinbase Upload Rules',
'excerpt' => 'Use AI responsibly, label your workflow clearly, and avoid imitation-based prompt packs.',
'content' => 'Respect artists, disclose your workflow, and avoid packaging prompts around living-artist imitation or deceptive attribution.',
'difficulty' => 'beginner',
'access_level' => 'free',
'lesson_type' => 'ethics',
'featured' => false,
],
[
'slug' => 'how-to-prepare-ai-artwork-for-upload',
'category_slug' => 'wallpapers',
'title' => 'How to Prepare AI Artwork for Upload',
'excerpt' => 'A cleanup checklist for exporting Academy-ready artwork to Skinbase.',
'content' => 'Check crop, upscale carefully, fix edge artifacts, and export a final image that fits the target category and composition.',
'difficulty' => 'beginner',
'access_level' => 'free',
'lesson_type' => 'workflow',
'featured' => false,
],
[
'slug' => 'advanced-wallpaper-prompt-engineering',
'category_slug' => 'wallpapers',
'title' => 'Advanced Wallpaper Prompt Engineering',
'excerpt' => 'Build prompts that control focal depth, desktop negative space, and repeatable atmosphere.',
'content' => 'Use layered subject directives, desktop-safe composition notes, and finishing instructions to keep wallpapers clean and reusable.',
'difficulty' => 'advanced',
'access_level' => 'creator',
'lesson_type' => 'workflow',
'featured' => true,
],
[
'slug' => 'creating-consistent-robot-mascots',
'category_slug' => 'sci-fi',
'title' => 'Creating Consistent Robot Mascots',
'excerpt' => 'Keep mascot silhouettes, palettes, and expression readable across multiple prompt iterations.',
'content' => 'Define anchor traits first, then preserve them with repeated descriptors and a fixed framing recipe across generations.',
'difficulty' => 'advanced',
'access_level' => 'creator',
'lesson_type' => 'workflow',
'featured' => false,
],
[
'slug' => 'building-a-skinbase-world-from-scratch',
'category_slug' => 'skinbase-worlds',
'title' => 'Building a Skinbase World From Scratch',
'excerpt' => 'Plan a world cover, atmosphere kit, and visual language that feels coherent beyond one image.',
'content' => 'Start from a world premise, define color anchors, then generate covers, teaser crops, and supporting scenes that share the same visual DNA.',
'difficulty' => 'pro',
'access_level' => 'pro',
'lesson_type' => 'workflow',
'featured' => true,
],
[
'slug' => 'creating-editorial-news-cover-images',
'category_slug' => 'news-covers',
'title' => 'Creating Editorial News Cover Images',
'excerpt' => 'Design news cover art that reads fast, supports headlines, and avoids clutter.',
'content' => 'Compose with headline space in mind, simplify the focal idea, and leave enough structure for editorial overlays to stay readable.',
'difficulty' => 'pro',
'access_level' => 'pro',
'lesson_type' => 'workflow',
'featured' => false,
],
];
foreach ($lessons as $index => $lesson) {
AcademyLesson::query()->updateOrCreate(
['slug' => $lesson['slug']],
[
'category_id' => $categories->get($lesson['category_slug'])?->id,
'title' => $lesson['title'],
'excerpt' => $lesson['excerpt'],
'content' => $lesson['content'],
'difficulty' => $lesson['difficulty'],
'access_level' => $lesson['access_level'],
'lesson_type' => $lesson['lesson_type'],
'featured' => $lesson['featured'],
'active' => true,
'published_at' => now()->subDays(8 - $index),
],
);
}
$prompts = [
[
'slug' => 'fantasy-floating-island-wallpaper',
'category_slug' => 'fantasy',
'title' => 'Fantasy Floating Island Wallpaper',
'excerpt' => 'A cinematic floating-island prompt for wide wallpaper compositions.',
'prompt' => 'A cinematic fantasy floating island above glowing clouds, ancient ruins, waterfalls falling into the sky, sunrise, dramatic lighting, ultra detailed digital painting.',
'negative_prompt' => 'blurry, low quality, watermark, text, noisy image',
'difficulty' => 'beginner',
'access_level' => 'creator',
'aspect_ratio' => '16:9',
'tags' => ['fantasy', 'wallpaper', 'floating island'],
'featured' => true,
'prompt_of_week' => true,
],
[
'slug' => 'sci-fi-robot-mascot-scene',
'category_slug' => 'sci-fi',
'title' => 'Sci-Fi Robot Mascot Scene',
'excerpt' => 'A prompt recipe for a polished Skinbase-style mascot reveal scene.',
'prompt' => 'Friendly futuristic robot mascot in a sleek digital gallery, cinematic rim light, crisp silhouette, polished sci-fi materials, editorial composition.',
'negative_prompt' => 'duplicate limbs, muddy details, unreadable face, text, watermark',
'difficulty' => 'intermediate',
'access_level' => 'creator',
'aspect_ratio' => '16:9',
'tags' => ['sci-fi', 'robot', 'mascot'],
'featured' => true,
'prompt_of_week' => false,
],
[
'slug' => 'amiga-pixel-art-island',
'category_slug' => 'pixel-art',
'title' => 'Amiga Pixel Art Island',
'excerpt' => 'A nostalgic pixel-art prompt tuned for an Amiga-inspired island scene.',
'prompt' => 'Retro Amiga-inspired pixel art island, chunky palette, bright shoreline, palm trees, crisp dithering, overhead scene composition.',
'negative_prompt' => 'smooth gradients, modern UI, blurry pixels, text, watermark',
'difficulty' => 'beginner',
'access_level' => 'free',
'aspect_ratio' => '4:3',
'tags' => ['pixel art', 'amiga', 'island'],
'featured' => false,
'prompt_of_week' => false,
],
[
'slug' => 'hello-again-world-cover',
'category_slug' => 'fantasy',
'title' => 'Hello Again World Cover',
'excerpt' => 'A hopeful world-cover prompt for relaunch and rebirth themes.',
'prompt' => 'Hopeful rebirth world cover, luminous horizon, layered clouds, visual depth, centered emblem space, cinematic optimism.',
'negative_prompt' => 'dark horror tone, cluttered foreground, low detail, text, watermark',
'difficulty' => 'intermediate',
'access_level' => 'free',
'aspect_ratio' => '16:9',
'tags' => ['world cover', 'hopeful', 'rebirth'],
'featured' => false,
'prompt_of_week' => false,
],
[
'slug' => 'spring-vibes-meadow',
'category_slug' => 'fantasy',
'title' => 'Spring Vibes Meadow',
'excerpt' => 'A bright meadow prompt with clean wallpaper composition and airy color direction.',
'prompt' => 'Spring meadow wallpaper, soft golden light, airy depth, blooming flowers, gentle wind, clean composition for desktop background.',
'negative_prompt' => 'muddy colors, clutter, overexposed sky, text, watermark',
'difficulty' => 'beginner',
'access_level' => 'free',
'aspect_ratio' => '16:9',
'tags' => ['spring', 'meadow', 'wallpaper'],
'featured' => false,
'prompt_of_week' => false,
],
[
'slug' => 'ai-news-cover-image',
'category_slug' => 'sci-fi',
'title' => 'AI News Cover Image',
'excerpt' => 'A structured prompt for editorial cover art with clear subject hierarchy.',
'prompt' => 'Editorial AI news cover, strong focal subject, clean negative space for title overlay, sleek modern composition, dramatic but readable lighting.',
'negative_prompt' => 'busy background, unreadable subject, headline text, watermark, logo',
'difficulty' => 'advanced',
'access_level' => 'pro',
'aspect_ratio' => '3:2',
'tags' => ['news cover', 'editorial', 'ai art'],
'featured' => true,
'prompt_of_week' => false,
],
];
$promptIdsBySlug = [];
foreach ($prompts as $index => $prompt) {
$record = AcademyPromptTemplate::query()->updateOrCreate(
['slug' => $prompt['slug']],
[
'category_id' => $categories->get($prompt['category_slug'])?->id,
'title' => $prompt['title'],
'excerpt' => $prompt['excerpt'],
'prompt' => $prompt['prompt'],
'negative_prompt' => $prompt['negative_prompt'],
'difficulty' => $prompt['difficulty'],
'access_level' => $prompt['access_level'],
'aspect_ratio' => $prompt['aspect_ratio'],
'tags' => $prompt['tags'],
'featured' => $prompt['featured'],
'prompt_of_week' => $prompt['prompt_of_week'],
'active' => true,
'published_at' => now()->subDays(6 - $index),
],
);
$promptIdsBySlug[$prompt['slug']] = $record->id;
}
$packs = [
[
'slug' => 'wallpaper-starter-pack',
'title' => 'Wallpaper Starter Pack',
'excerpt' => 'A first bundle of Academy prompt templates for wallpaper-focused creators.',
'description' => 'Starter bundle for creators who want reusable composition and atmosphere prompts for desktop-ready work.',
'access_level' => 'creator',
'featured' => true,
'prompt_slugs' => ['fantasy-floating-island-wallpaper', 'spring-vibes-meadow'],
],
[
'slug' => 'hello-again-world-builder-pack',
'title' => 'Hello Again World Builder Pack',
'excerpt' => 'A focused set of prompts for world covers, teaser art, and relaunch atmosphere.',
'description' => 'Built for Skinbase Worlds concepts, relaunch visuals, and hopeful teaser compositions.',
'access_level' => 'creator',
'featured' => false,
'prompt_slugs' => ['hello-again-world-cover', 'fantasy-floating-island-wallpaper'],
],
[
'slug' => 'fantasy-realms-prompt-pack',
'title' => 'Fantasy Realms Prompt Pack',
'excerpt' => 'Premium fantasy prompts for scenic covers and high-detail digital worlds.',
'description' => 'A denser fantasy pack for creators building larger scene families and cover variants.',
'access_level' => 'pro',
'featured' => true,
'prompt_slugs' => ['fantasy-floating-island-wallpaper', 'hello-again-world-cover'],
],
];
foreach ($packs as $packData) {
$pack = AcademyPromptPack::query()->updateOrCreate(
['slug' => $packData['slug']],
[
'title' => $packData['title'],
'excerpt' => $packData['excerpt'],
'description' => $packData['description'],
'access_level' => $packData['access_level'],
'featured' => $packData['featured'],
'active' => true,
'published_at' => now()->subDay(),
],
);
foreach ($packData['prompt_slugs'] as $order => $promptSlug) {
if (! isset($promptIdsBySlug[$promptSlug])) {
continue;
}
AcademyPromptPackItem::query()->updateOrCreate(
['pack_id' => $pack->id, 'prompt_template_id' => $promptIdsBySlug[$promptSlug]],
['order_num' => $order],
);
}
}
$challenges = [
[
'slug' => 'hello-again-create-a-rebirth-wallpaper',
'title' => 'Hello Again: Create a Rebirth Wallpaper',
'excerpt' => 'Create a launch-era wallpaper using bright skies, hopeful atmosphere, and a strong desktop composition.',
'description' => 'An Academy launch brief focused on optimistic wallpaper composition and Skinbase-style color direction.',
'brief' => 'Create a wallpaper that communicates return, energy, and visual clarity.',
'rules' => 'Use original prompts and clearly mark AI-assisted workflow details.',
'access_level' => 'free',
'required_tags' => ['academy', 'rebirth'],
'allowed_categories' => ['wallpapers', 'prompting-basics'],
'featured' => true,
],
[
'slug' => 'fantasy-realms-build-a-magical-world',
'title' => 'Fantasy Realms: Build a Magical World',
'excerpt' => 'Design a fantasy cover or world scene with readable atmosphere and strong visual storytelling.',
'description' => 'A challenge built around fantasy world-building, magical landscapes, and cover-ready imagery.',
'brief' => 'Develop a magical world scene with a clear horizon, mood, and focal subject.',
'rules' => 'Original prompts only. Keep the composition upload-ready and explain your workflow briefly.',
'access_level' => 'creator',
'required_tags' => ['academy', 'fantasy-realms'],
'allowed_categories' => ['fantasy', 'skinbase-worlds'],
'featured' => true,
],
[
'slug' => 'amiga-memories-pixel-art-challenge',
'title' => 'Amiga Memories: Pixel Art Challenge',
'excerpt' => 'Use retro palettes and strong pixel readability to build a nostalgic island or world scene.',
'description' => 'A retro prompt challenge with strict readability, palette discipline, and nostalgic energy.',
'brief' => 'Create an Amiga-inspired pixel scene that feels coherent at thumbnail and full size.',
'rules' => 'Stay readable, avoid smooth gradients, and describe any manual cleanup in your notes.',
'access_level' => 'free',
'required_tags' => ['academy', 'pixel-art'],
'allowed_categories' => ['pixel-art'],
'featured' => false,
],
];
foreach ($challenges as $index => $challenge) {
AcademyChallenge::query()->updateOrCreate(
['slug' => $challenge['slug']],
[
'title' => $challenge['title'],
'excerpt' => $challenge['excerpt'],
'description' => $challenge['description'],
'brief' => $challenge['brief'],
'rules' => $challenge['rules'],
'access_level' => $challenge['access_level'],
'status' => 'active',
'starts_at' => now()->subDays(2 + $index),
'ends_at' => now()->addDays(10 + $index),
'required_tags' => $challenge['required_tags'],
'allowed_categories' => $challenge['allowed_categories'],
'featured' => $challenge['featured'],
'active' => true,
],
);
}
$badges = [
[
'slug' => 'ai-academy-explorer',
'name' => 'AI Academy Explorer',
'description' => 'Awarded for participating in Skinbase AI Academy as a free learner.',
'badge_type' => 'plan',
'rules' => ['access_level' => 'free'],
],
[
'slug' => 'ai-academy-creator',
'name' => 'AI Academy Creator',
'description' => 'Awarded to Creator-tier Academy members.',
'badge_type' => 'plan',
'rules' => ['access_level' => 'creator'],
],
[
'slug' => 'ai-academy-pro',
'name' => 'AI Academy Pro',
'description' => 'Awarded to Pro-tier Academy members.',
'badge_type' => 'plan',
'rules' => ['access_level' => 'pro'],
],
[
'slug' => 'prompt-beginner',
'name' => 'Prompt Beginner',
'description' => 'Awarded after saving your first Academy prompt.',
'badge_type' => 'achievement',
'rules' => ['save_prompts' => 1],
],
[
'slug' => 'world-builder',
'name' => 'World Builder',
'description' => 'Awarded after completing World-focused Academy content.',
'badge_type' => 'achievement',
'rules' => ['complete_world_lessons' => 1],
],
[
'slug' => 'challenge-participant',
'name' => 'Challenge Participant',
'description' => 'Awarded after submitting to an Academy challenge.',
'badge_type' => 'challenge',
'rules' => ['submit_challenges' => 1],
],
];
foreach ($badges as $badge) {
AcademyBadge::query()->updateOrCreate(
['slug' => $badge['slug']],
[
'name' => $badge['name'],
'description' => $badge['description'],
'badge_type' => $badge['badge_type'],
'rules' => $badge['rules'],
'active' => true,
],
);
}
app(AcademyCacheService::class)->clearAll();
}
}