🗃️ Add database schema, models & seeders (Story 1.2)
Migrations (translations, projects, skills, skill_project), Eloquent models with belongsToMany relations, scopes, and test seeders (74 translations FR/EN, 10 skills, 3 projects, 12 skill-project links). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
@@ -10,16 +9,13 @@ class DatabaseSeeder extends Seeder
|
||||
{
|
||||
use WithoutModelEvents;
|
||||
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// User::factory(10)->create();
|
||||
|
||||
User::factory()->create([
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
$this->call([
|
||||
TranslationSeeder::class,
|
||||
SkillSeeder::class,
|
||||
ProjectSeeder::class,
|
||||
SkillProjectSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
55
api/database/seeders/ProjectSeeder.php
Normal file
55
api/database/seeders/ProjectSeeder.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Project;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class ProjectSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$projects = [
|
||||
[
|
||||
'slug' => 'skycel-portfolio',
|
||||
'title_key' => 'project.skycel-portfolio.title',
|
||||
'description_key' => 'project.skycel-portfolio.description',
|
||||
'short_description_key' => 'project.skycel-portfolio.short_description',
|
||||
'image' => 'projects/skycel-portfolio.png',
|
||||
'url' => 'https://skycel.dev',
|
||||
'github_url' => 'https://git.araneite.dev/skycel/Portfolio-Game',
|
||||
'date_completed' => '2026-03-01',
|
||||
'is_featured' => true,
|
||||
'display_order' => 1,
|
||||
],
|
||||
[
|
||||
'slug' => 'ecommerce-app',
|
||||
'title_key' => 'project.ecommerce-app.title',
|
||||
'description_key' => 'project.ecommerce-app.description',
|
||||
'short_description_key' => 'project.ecommerce-app.short_description',
|
||||
'image' => 'projects/ecommerce-app.png',
|
||||
'url' => null,
|
||||
'github_url' => 'https://github.com/skycel/ecommerce-app',
|
||||
'date_completed' => '2025-09-15',
|
||||
'is_featured' => true,
|
||||
'display_order' => 2,
|
||||
],
|
||||
[
|
||||
'slug' => 'analytics-dashboard',
|
||||
'title_key' => 'project.analytics-dashboard.title',
|
||||
'description_key' => 'project.analytics-dashboard.description',
|
||||
'short_description_key' => 'project.analytics-dashboard.short_description',
|
||||
'image' => 'projects/analytics-dashboard.png',
|
||||
'url' => null,
|
||||
'github_url' => null,
|
||||
'date_completed' => '2025-06-01',
|
||||
'is_featured' => false,
|
||||
'display_order' => 3,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($projects as $project) {
|
||||
Project::create($project);
|
||||
}
|
||||
}
|
||||
}
|
||||
83
api/database/seeders/SkillProjectSeeder.php
Normal file
83
api/database/seeders/SkillProjectSeeder.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Project;
|
||||
use App\Models\Skill;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SkillProjectSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$skycel = Project::where('slug', 'skycel-portfolio')->first();
|
||||
$ecommerce = Project::where('slug', 'ecommerce-app')->first();
|
||||
$dashboard = Project::where('slug', 'analytics-dashboard')->first();
|
||||
|
||||
// Skycel Portfolio: Vue.js, Nuxt, Laravel, TailwindCSS, Git
|
||||
$skycel->skills()->attach(Skill::where('slug', 'vuejs')->first()->id, [
|
||||
'level_before' => 2,
|
||||
'level_after' => 4,
|
||||
'level_description_key' => 'skill_project.skycel-portfolio.vuejs.level_description',
|
||||
]);
|
||||
$skycel->skills()->attach(Skill::where('slug', 'nuxt')->first()->id, [
|
||||
'level_before' => 0,
|
||||
'level_after' => 3,
|
||||
'level_description_key' => 'skill_project.skycel-portfolio.nuxt.level_description',
|
||||
]);
|
||||
$skycel->skills()->attach(Skill::where('slug', 'laravel')->first()->id, [
|
||||
'level_before' => 2,
|
||||
'level_after' => 3,
|
||||
'level_description_key' => 'skill_project.skycel-portfolio.laravel.level_description',
|
||||
]);
|
||||
$skycel->skills()->attach(Skill::where('slug', 'tailwindcss')->first()->id, [
|
||||
'level_before' => 1,
|
||||
'level_after' => 3,
|
||||
'level_description_key' => 'skill_project.skycel-portfolio.tailwindcss.level_description',
|
||||
]);
|
||||
$skycel->skills()->attach(Skill::where('slug', 'git')->first()->id, [
|
||||
'level_before' => 3,
|
||||
'level_after' => 4,
|
||||
'level_description_key' => null,
|
||||
]);
|
||||
|
||||
// E-commerce App: Laravel, Vue.js, PHP, Docker
|
||||
$ecommerce->skills()->attach(Skill::where('slug', 'laravel')->first()->id, [
|
||||
'level_before' => 1,
|
||||
'level_after' => 2,
|
||||
'level_description_key' => 'skill_project.ecommerce-app.laravel.level_description',
|
||||
]);
|
||||
$ecommerce->skills()->attach(Skill::where('slug', 'vuejs')->first()->id, [
|
||||
'level_before' => 1,
|
||||
'level_after' => 2,
|
||||
'level_description_key' => 'skill_project.ecommerce-app.vuejs.level_description',
|
||||
]);
|
||||
$ecommerce->skills()->attach(Skill::where('slug', 'php')->first()->id, [
|
||||
'level_before' => 2,
|
||||
'level_after' => 3,
|
||||
'level_description_key' => null,
|
||||
]);
|
||||
$ecommerce->skills()->attach(Skill::where('slug', 'docker')->first()->id, [
|
||||
'level_before' => 0,
|
||||
'level_after' => 1,
|
||||
'level_description_key' => null,
|
||||
]);
|
||||
|
||||
// Analytics Dashboard: TypeScript, Node.js, Git
|
||||
$dashboard->skills()->attach(Skill::where('slug', 'typescript')->first()->id, [
|
||||
'level_before' => 1,
|
||||
'level_after' => 3,
|
||||
'level_description_key' => 'skill_project.analytics-dashboard.typescript.level_description',
|
||||
]);
|
||||
$dashboard->skills()->attach(Skill::where('slug', 'nodejs')->first()->id, [
|
||||
'level_before' => 1,
|
||||
'level_after' => 2,
|
||||
'level_description_key' => 'skill_project.analytics-dashboard.nodejs.level_description',
|
||||
]);
|
||||
$dashboard->skills()->attach(Skill::where('slug', 'git')->first()->id, [
|
||||
'level_before' => 2,
|
||||
'level_after' => 3,
|
||||
'level_description_key' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
36
api/database/seeders/SkillSeeder.php
Normal file
36
api/database/seeders/SkillSeeder.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Skill;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SkillSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$skills = [
|
||||
// Frontend
|
||||
['slug' => 'vuejs', 'name_key' => 'skill.vuejs.name', 'description_key' => 'skill.vuejs.description', 'icon' => 'vuejs', 'category' => 'Frontend', 'max_level' => 5, 'display_order' => 1],
|
||||
['slug' => 'nuxt', 'name_key' => 'skill.nuxt.name', 'description_key' => 'skill.nuxt.description', 'icon' => 'nuxt', 'category' => 'Frontend', 'max_level' => 5, 'display_order' => 2],
|
||||
['slug' => 'typescript', 'name_key' => 'skill.typescript.name', 'description_key' => 'skill.typescript.description', 'icon' => 'typescript', 'category' => 'Frontend', 'max_level' => 5, 'display_order' => 3],
|
||||
['slug' => 'tailwindcss', 'name_key' => 'skill.tailwindcss.name', 'description_key' => 'skill.tailwindcss.description', 'icon' => 'tailwindcss', 'category' => 'Frontend', 'max_level' => 5, 'display_order' => 4],
|
||||
|
||||
// Backend
|
||||
['slug' => 'laravel', 'name_key' => 'skill.laravel.name', 'description_key' => 'skill.laravel.description', 'icon' => 'laravel', 'category' => 'Backend', 'max_level' => 5, 'display_order' => 5],
|
||||
['slug' => 'php', 'name_key' => 'skill.php.name', 'description_key' => 'skill.php.description', 'icon' => 'php', 'category' => 'Backend', 'max_level' => 5, 'display_order' => 6],
|
||||
['slug' => 'nodejs', 'name_key' => 'skill.nodejs.name', 'description_key' => 'skill.nodejs.description', 'icon' => 'nodejs', 'category' => 'Backend', 'max_level' => 5, 'display_order' => 7],
|
||||
|
||||
// Tools
|
||||
['slug' => 'git', 'name_key' => 'skill.git.name', 'description_key' => 'skill.git.description', 'icon' => 'git', 'category' => 'Tools', 'max_level' => 5, 'display_order' => 8],
|
||||
['slug' => 'docker', 'name_key' => 'skill.docker.name', 'description_key' => 'skill.docker.description', 'icon' => 'docker', 'category' => 'Tools', 'max_level' => 5, 'display_order' => 9],
|
||||
|
||||
// Soft skills
|
||||
['slug' => 'communication', 'name_key' => 'skill.communication.name', 'description_key' => 'skill.communication.description', 'icon' => 'communication', 'category' => 'Soft skills', 'max_level' => 5, 'display_order' => 10],
|
||||
];
|
||||
|
||||
foreach ($skills as $skill) {
|
||||
Skill::create($skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
124
api/database/seeders/TranslationSeeder.php
Normal file
124
api/database/seeders/TranslationSeeder.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Translation;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class TranslationSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$translations = [
|
||||
// Skills - Vue.js
|
||||
['fr', 'skill.vuejs.name', 'Vue.js'],
|
||||
['en', 'skill.vuejs.name', 'Vue.js'],
|
||||
['fr', 'skill.vuejs.description', 'Framework JavaScript progressif pour construire des interfaces utilisateur'],
|
||||
['en', 'skill.vuejs.description', 'Progressive JavaScript framework for building user interfaces'],
|
||||
|
||||
// Skills - Nuxt
|
||||
['fr', 'skill.nuxt.name', 'Nuxt'],
|
||||
['en', 'skill.nuxt.name', 'Nuxt'],
|
||||
['fr', 'skill.nuxt.description', 'Framework fullstack basé sur Vue.js avec rendu côté serveur'],
|
||||
['en', 'skill.nuxt.description', 'Fullstack framework based on Vue.js with server-side rendering'],
|
||||
|
||||
// Skills - TypeScript
|
||||
['fr', 'skill.typescript.name', 'TypeScript'],
|
||||
['en', 'skill.typescript.name', 'TypeScript'],
|
||||
['fr', 'skill.typescript.description', 'Surensemble typé de JavaScript pour un code plus robuste'],
|
||||
['en', 'skill.typescript.description', 'Typed superset of JavaScript for more robust code'],
|
||||
|
||||
// Skills - TailwindCSS
|
||||
['fr', 'skill.tailwindcss.name', 'TailwindCSS'],
|
||||
['en', 'skill.tailwindcss.name', 'TailwindCSS'],
|
||||
['fr', 'skill.tailwindcss.description', 'Framework CSS utilitaire pour un design rapide et personnalisable'],
|
||||
['en', 'skill.tailwindcss.description', 'Utility-first CSS framework for rapid and customizable design'],
|
||||
|
||||
// Skills - Laravel
|
||||
['fr', 'skill.laravel.name', 'Laravel'],
|
||||
['en', 'skill.laravel.name', 'Laravel'],
|
||||
['fr', 'skill.laravel.description', 'Framework PHP élégant pour le développement web'],
|
||||
['en', 'skill.laravel.description', 'Elegant PHP framework for web development'],
|
||||
|
||||
// Skills - PHP
|
||||
['fr', 'skill.php.name', 'PHP'],
|
||||
['en', 'skill.php.name', 'PHP'],
|
||||
['fr', 'skill.php.description', 'Langage de programmation côté serveur largement utilisé'],
|
||||
['en', 'skill.php.description', 'Widely used server-side programming language'],
|
||||
|
||||
// Skills - Node.js
|
||||
['fr', 'skill.nodejs.name', 'Node.js'],
|
||||
['en', 'skill.nodejs.name', 'Node.js'],
|
||||
['fr', 'skill.nodejs.description', 'Environnement d\'exécution JavaScript côté serveur'],
|
||||
['en', 'skill.nodejs.description', 'Server-side JavaScript runtime environment'],
|
||||
|
||||
// Skills - Git
|
||||
['fr', 'skill.git.name', 'Git'],
|
||||
['en', 'skill.git.name', 'Git'],
|
||||
['fr', 'skill.git.description', 'Système de contrôle de version distribué'],
|
||||
['en', 'skill.git.description', 'Distributed version control system'],
|
||||
|
||||
// Skills - Docker
|
||||
['fr', 'skill.docker.name', 'Docker'],
|
||||
['en', 'skill.docker.name', 'Docker'],
|
||||
['fr', 'skill.docker.description', 'Plateforme de conteneurisation pour le déploiement d\'applications'],
|
||||
['en', 'skill.docker.description', 'Containerization platform for application deployment'],
|
||||
|
||||
// Skills - Communication
|
||||
['fr', 'skill.communication.name', 'Communication'],
|
||||
['en', 'skill.communication.name', 'Communication'],
|
||||
['fr', 'skill.communication.description', 'Capacité à transmettre des idées clairement et efficacement'],
|
||||
['en', 'skill.communication.description', 'Ability to convey ideas clearly and effectively'],
|
||||
|
||||
// Projects - Skycel Portfolio
|
||||
['fr', 'project.skycel-portfolio.title', 'Skycel Portfolio'],
|
||||
['en', 'project.skycel-portfolio.title', 'Skycel Portfolio'],
|
||||
['fr', 'project.skycel-portfolio.description', 'Portfolio gamifié avec système de progression et arbre de compétences interactif. Construit avec Nuxt 4 et Laravel 12.'],
|
||||
['en', 'project.skycel-portfolio.description', 'Gamified portfolio with progression system and interactive skill tree. Built with Nuxt 4 and Laravel 12.'],
|
||||
['fr', 'project.skycel-portfolio.short_description', 'Portfolio gamifié avec arbre de compétences'],
|
||||
['en', 'project.skycel-portfolio.short_description', 'Gamified portfolio with skill tree'],
|
||||
|
||||
// Projects - E-commerce
|
||||
['fr', 'project.ecommerce-app.title', 'E-Commerce App'],
|
||||
['en', 'project.ecommerce-app.title', 'E-Commerce App'],
|
||||
['fr', 'project.ecommerce-app.description', 'Application e-commerce complète avec panier, paiement Stripe et gestion des commandes. Interface responsive et performante.'],
|
||||
['en', 'project.ecommerce-app.description', 'Full e-commerce application with cart, Stripe payment and order management. Responsive and performant interface.'],
|
||||
['fr', 'project.ecommerce-app.short_description', 'Application e-commerce avec paiement Stripe'],
|
||||
['en', 'project.ecommerce-app.short_description', 'E-commerce app with Stripe payment'],
|
||||
|
||||
// Projects - Dashboard
|
||||
['fr', 'project.analytics-dashboard.title', 'Analytics Dashboard'],
|
||||
['en', 'project.analytics-dashboard.title', 'Analytics Dashboard'],
|
||||
['fr', 'project.analytics-dashboard.description', 'Tableau de bord analytique avec visualisations de données en temps réel, graphiques interactifs et export de rapports.'],
|
||||
['en', 'project.analytics-dashboard.description', 'Analytics dashboard with real-time data visualizations, interactive charts and report export.'],
|
||||
['fr', 'project.analytics-dashboard.short_description', 'Dashboard analytique avec données temps réel'],
|
||||
['en', 'project.analytics-dashboard.short_description', 'Analytics dashboard with real-time data'],
|
||||
|
||||
// Skill-Project level descriptions
|
||||
['fr', 'skill_project.skycel-portfolio.vuejs.level_description', 'Utilisation avancée de Vue 3 avec Composition API et réactivité'],
|
||||
['en', 'skill_project.skycel-portfolio.vuejs.level_description', 'Advanced use of Vue 3 with Composition API and reactivity'],
|
||||
['fr', 'skill_project.skycel-portfolio.nuxt.level_description', 'Premier projet avec Nuxt 4 et SSR'],
|
||||
['en', 'skill_project.skycel-portfolio.nuxt.level_description', 'First project with Nuxt 4 and SSR'],
|
||||
['fr', 'skill_project.skycel-portfolio.laravel.level_description', 'API REST complète avec middleware et Eloquent'],
|
||||
['en', 'skill_project.skycel-portfolio.laravel.level_description', 'Complete REST API with middleware and Eloquent'],
|
||||
['fr', 'skill_project.skycel-portfolio.tailwindcss.level_description', 'Design system complet avec tokens personnalisés'],
|
||||
['en', 'skill_project.skycel-portfolio.tailwindcss.level_description', 'Complete design system with custom tokens'],
|
||||
['fr', 'skill_project.ecommerce-app.laravel.level_description', 'Backend e-commerce avec intégration Stripe'],
|
||||
['en', 'skill_project.ecommerce-app.laravel.level_description', 'E-commerce backend with Stripe integration'],
|
||||
['fr', 'skill_project.ecommerce-app.vuejs.level_description', 'Interface dynamique avec gestion du panier'],
|
||||
['en', 'skill_project.ecommerce-app.vuejs.level_description', 'Dynamic interface with cart management'],
|
||||
['fr', 'skill_project.analytics-dashboard.typescript.level_description', 'Typage strict pour la fiabilité des données'],
|
||||
['en', 'skill_project.analytics-dashboard.typescript.level_description', 'Strict typing for data reliability'],
|
||||
['fr', 'skill_project.analytics-dashboard.nodejs.level_description', 'API backend avec agrégation de données'],
|
||||
['en', 'skill_project.analytics-dashboard.nodejs.level_description', 'Backend API with data aggregation'],
|
||||
];
|
||||
|
||||
foreach ($translations as [$lang, $key_name, $value]) {
|
||||
Translation::create([
|
||||
'lang' => $lang,
|
||||
'key_name' => $key_name,
|
||||
'value' => $value,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user