From 1853b087f49979f7be210471457364427ee85693 Mon Sep 17 00:00:00 2001 From: F4ilji Date: Fri, 18 Sep 2026 01:39:28 +0500 Subject: [PATCH] chore: update seeders, add MockDataSeeder and AssignAllPermissions command - DatabaseSeeder: replace old seeders with MockDataSeeder - RolesSeeder: update role definitions - Add AssignAllPermissions artisan command - Register MockDataSeeder in AppServiceProvider - Register command in ConsoleKernel --- .gitignore | 3 +- .phpunit.result.cache | 2 +- app/Providers/AppServiceProvider.php | 18 ++ app/Ship/Commands/AssignAllPermissions.php | 40 ++++ app/Ship/Kernels/ConsoleKernel.php | 2 + database/seeders/DatabaseSeeder.php | 95 +------- database/seeders/MockDataSeeder.php | 251 +++++++++++++++++++++ database/seeders/RolesSeeder.php | 40 ++-- 8 files changed, 333 insertions(+), 118 deletions(-) create mode 100644 app/Ship/Commands/AssignAllPermissions.php create mode 100644 database/seeders/MockDataSeeder.php diff --git a/.gitignore b/.gitignore index 30c9301..18190c8 100755 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ public/vikon_core .qwen QWEN.md AGENTS.md -docs \ No newline at end of file +docs +.phpunit.result.cache \ No newline at end of file diff --git a/.phpunit.result.cache b/.phpunit.result.cache index 41fc388..b8ca064 100644 --- a/.phpunit.result.cache +++ b/.phpunit.result.cache @@ -1 +1 @@ -{"version":2,"defects":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":7},"times":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":0.018,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":0.027,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":0.002,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":0.003,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":0.011,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":0.003,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":0.001,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_requires_authentication":0.057,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":0.021,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":0.009,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_1":0.022,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_negative_1":0.001}} \ No newline at end of file +{"version":2,"defects":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":7,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":7,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_token_returns_value_from_db":8,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_api_url_returns_value_from_db":8,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_token_throws_when_not_configured":7,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_token_throws_when_payload_empty":8,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_inactive_credential_is_ignored":8,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_naprs_returns_data":1,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_programs_returns_data":1,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_programs_via_educational_program_service":1,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_program_by_uuid_returns_data":1,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_programs_via_educational_service":1,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_program_by_uuid":1,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_post_generation_with_files":8,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_post_generation_without_files":8,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_post_generation_with_multiple_file_blocks":8,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_link_format":8,"Tests\\Feature\\Auth\\AuthenticationTest::test_login_screen_can_be_rendered":7,"Tests\\Feature\\Auth\\AuthenticationTest::test_users_can_authenticate_using_the_login_screen":8,"Tests\\Feature\\Auth\\AuthenticationTest::test_users_can_not_authenticate_with_invalid_password":8,"Tests\\Feature\\Auth\\AuthenticationTest::test_users_can_logout":8,"Tests\\Feature\\Auth\\EmailVerificationTest::test_email_verification_screen_can_be_rendered":8,"Tests\\Feature\\Auth\\EmailVerificationTest::test_email_can_be_verified":8,"Tests\\Feature\\Auth\\EmailVerificationTest::test_email_is_not_verified_with_invalid_hash":8,"Tests\\Feature\\Auth\\PasswordConfirmationTest::test_confirm_password_screen_can_be_rendered":8,"Tests\\Feature\\Auth\\PasswordConfirmationTest::test_password_can_be_confirmed":8,"Tests\\Feature\\Auth\\PasswordConfirmationTest::test_password_is_not_confirmed_with_invalid_password":8,"Tests\\Feature\\Auth\\PasswordResetTest::test_reset_password_link_screen_can_be_rendered":7,"Tests\\Feature\\Auth\\PasswordResetTest::test_reset_password_link_can_be_requested":8,"Tests\\Feature\\Auth\\PasswordResetTest::test_reset_password_screen_can_be_rendered":8,"Tests\\Feature\\Auth\\PasswordResetTest::test_password_can_be_reset_with_valid_token":8,"Tests\\Feature\\Auth\\PasswordUpdateTest::test_password_can_be_updated":8,"Tests\\Feature\\Auth\\PasswordUpdateTest::test_correct_password_must_be_provided_to_update_password":8,"Tests\\Feature\\Auth\\RegistrationTest::test_registration_screen_can_be_rendered":7,"Tests\\Feature\\Auth\\RegistrationTest::test_new_users_can_register":5,"Tests\\Feature\\ProfileTest::test_profile_page_is_displayed":8,"Tests\\Feature\\ProfileTest::test_profile_information_can_be_updated":8,"Tests\\Feature\\ProfileTest::test_email_verification_status_is_unchanged_when_the_email_address_is_unchanged":8,"Tests\\Feature\\ProfileTest::test_user_can_delete_their_account":8,"Tests\\Feature\\ProfileTest::test_correct_password_must_be_provided_to_delete_account":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_requires_authentication":7,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_api_url_falls_back_when_not_in_payload":8},"times":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":0.003,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":0.027,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":0.002,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":0.011,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":0.011,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":0.002,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":0.001,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_requires_authentication":0.007,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":0.054,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":0.051,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_1":0.02,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_negative_1":0,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_token_returns_value_from_db":0.027,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_api_url_returns_value_from_db":0.003,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_api_url_falls_back_when_not_in_payload":0.003,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_token_throws_when_not_configured":0.003,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_token_throws_when_payload_empty":0.003,"Tests\\Feature\\Vicon\\ViconApiConfigTest::test_inactive_credential_is_ignored":0.002,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_naprs_returns_data":0.003,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_programs_returns_data":0.002,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_programs_via_educational_program_service":0.002,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_program_by_uuid_returns_data":0.001,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_api_rejects_invalid_token":0.002,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_programs_via_educational_service":0.002,"Tests\\Feature\\Vicon\\ViconApiIntegrationTest::test_get_program_by_uuid":0.003,"Tests\\Unit\\ExampleTest::test_that_true_is_true":0.005,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_post_generation_with_files":0.048,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_post_generation_without_files":0.003,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_post_generation_with_multiple_file_blocks":0.003,"App\\Containers\\Dashboard\\Tests\\Unit\\VkPostGenerationTest::test_vk_link_format":0.003,"Tests\\Feature\\Auth\\AuthenticationTest::test_login_screen_can_be_rendered":0.059,"Tests\\Feature\\Auth\\AuthenticationTest::test_users_can_authenticate_using_the_login_screen":0.001,"Tests\\Feature\\Auth\\AuthenticationTest::test_users_can_not_authenticate_with_invalid_password":0.001,"Tests\\Feature\\Auth\\AuthenticationTest::test_users_can_logout":0,"Tests\\Feature\\Auth\\EmailVerificationTest::test_email_verification_screen_can_be_rendered":0.002,"Tests\\Feature\\Auth\\EmailVerificationTest::test_email_can_be_verified":0.001,"Tests\\Feature\\Auth\\EmailVerificationTest::test_email_is_not_verified_with_invalid_hash":0.002,"Tests\\Feature\\Auth\\PasswordConfirmationTest::test_confirm_password_screen_can_be_rendered":0.001,"Tests\\Feature\\Auth\\PasswordConfirmationTest::test_password_can_be_confirmed":0.001,"Tests\\Feature\\Auth\\PasswordConfirmationTest::test_password_is_not_confirmed_with_invalid_password":0.001,"Tests\\Feature\\Auth\\PasswordResetTest::test_reset_password_link_screen_can_be_rendered":0.011,"Tests\\Feature\\Auth\\PasswordResetTest::test_reset_password_link_can_be_requested":0.003,"Tests\\Feature\\Auth\\PasswordResetTest::test_reset_password_screen_can_be_rendered":0.001,"Tests\\Feature\\Auth\\PasswordResetTest::test_password_can_be_reset_with_valid_token":0.001,"Tests\\Feature\\Auth\\PasswordUpdateTest::test_password_can_be_updated":0.001,"Tests\\Feature\\Auth\\PasswordUpdateTest::test_correct_password_must_be_provided_to_update_password":0.001,"Tests\\Feature\\Auth\\RegistrationTest::test_registration_screen_can_be_rendered":0.009,"Tests\\Feature\\Auth\\RegistrationTest::test_new_users_can_register":0.036,"Tests\\Feature\\ExampleTest::test_the_application_returns_a_successful_response":0.241,"Tests\\Feature\\ProfileTest::test_profile_page_is_displayed":0.001,"Tests\\Feature\\ProfileTest::test_profile_information_can_be_updated":0.001,"Tests\\Feature\\ProfileTest::test_email_verification_status_is_unchanged_when_the_email_address_is_unchanged":0.001,"Tests\\Feature\\ProfileTest::test_user_can_delete_their_account":0,"Tests\\Feature\\ProfileTest::test_correct_password_must_be_provided_to_delete_account":0}} \ No newline at end of file diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 8904673..136f2fd 100755 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -49,8 +49,10 @@ use Carbon\Carbon; use Filament\Facades\Filament; use Filament\Support\Facades\FilamentView; use Filament\Tables\View\TablesRenderHook; +use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Vite; +use Illuminate\Support\Facades\Str; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Sleep; use Intervention\Image\Facades\Image; @@ -70,6 +72,7 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { + self::configureFactoryResolution(); self::setObserversByModel(); self::setLocaleTime(); Model::preventLazyLoading(!app()->isProduction()); @@ -81,6 +84,21 @@ class AppServiceProvider extends ServiceProvider }); } + private static function configureFactoryResolution(): void + { + Factory::guessFactoryNamesUsing(function (string $modelName) { + $appNamespace = 'App\\'; + + if (str_starts_with($modelName, $appNamespace.'Models\\')) { + $modelName = substr($modelName, strlen($appNamespace.'Models\\')); + } else { + $modelName = substr($modelName, strlen($appNamespace)); + } + + return 'Database\\Factories\\'.$modelName.'Factory'; + }); + } + private static function setObserversByModel() : void { Page::observe(PageObserver::class); Post::observe(PostObserver::class); diff --git a/app/Ship/Commands/AssignAllPermissions.php b/app/Ship/Commands/AssignAllPermissions.php new file mode 100644 index 0000000..3d743dd --- /dev/null +++ b/app/Ship/Commands/AssignAllPermissions.php @@ -0,0 +1,40 @@ +argument('email') ?: 'admin@ntspi.ru'; + + $user = User::where('email', $email)->first(); + + if (!$user) { + $this->error("User [{$email}] not found."); + return static::FAILURE; + } + + $role = Role::firstOrCreate( + ['name' => 'super_admin', 'guard_name' => 'web'] + ); + + $allPerms = Permission::where('guard_name', 'web')->get(); + $role->syncPermissions($allPerms); + + $user->syncRoles(['super_admin']); + + $this->info("User [{$email}] assigned to [super_admin] with {$allPerms->count()} permissions."); + return static::SUCCESS; + } +} diff --git a/app/Ship/Kernels/ConsoleKernel.php b/app/Ship/Kernels/ConsoleKernel.php index e87f2a2..76b7cf0 100755 --- a/app/Ship/Kernels/ConsoleKernel.php +++ b/app/Ship/Kernels/ConsoleKernel.php @@ -5,6 +5,7 @@ namespace App\Ship\Kernels; use AlxDorosenco\PortoForLaravel\Loaders\CommandsLoader; use AlxDorosenco\PortoForLaravel\Loaders\RoutesLoader; use App\Containers\Dashboard\Commands\FetchEmailNewsCommand; +use App\Ship\Commands\AssignAllPermissions; use App\Ship\Commands\InitRoles; use App\Ship\Commands\SyncDashboardPermissions; use Illuminate\Console\Scheduling\Schedule; @@ -33,6 +34,7 @@ class ConsoleKernel extends LaravelConsoleKernel } protected $commands = [ + AssignAllPermissions::class, InitRoles::class, FetchEmailNewsCommand::class, SyncDashboardPermissions::class, diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 6c27ba2..49ec0a3 100755 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,107 +2,14 @@ namespace Database\Seeders; -use App\Containers\InstituteStructure\Models\Faculty; -use App\Containers\Article\Models\Post; -use App\Containers\Schedule\Models\EducationalGroup; -use App\Containers\Schedule\Models\Schedule; -use App\Containers\Widget\Data\Seeders\SlideSeeder; -use App\Ship\Seeders\ContactWidgetSeeder; -use App\Ship\Seeders\PageReferenceListSeeder; -use App\Ship\Seeders\SliderSeeder; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { - - public function run(): void { - $this->call([ - ContactWidgetSeeder::class, - PageReferenceListSeeder::class, - SliderSeeder::class, - SlideSeeder::class, + MockDataSeeder::class, ]); - - - -// $faker = Factory::create(); -// User::create([ -// 'name' => 'Failj', -// 'email' => 'Failj@bk.ru', -// 'slug' => 'failj', -// 'password' => "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi", -// ]); -// User::factory()->count(50)->has(UserDetail::factory())->create(); -// EventCategory::factory()->count(10)->create(); -// Category::factory()->count(80)->create(); -// Post::factory()->count(1000)->create(); -// Event::factory()->count(200)->create(); -// $faculties = Faculty::factory()->count(6)->create(); - -// Затем создаем 40 групп, распределяя их по созданным факультетам -// EducationalGroup::factory() -// ->count(40) -// ->sequence(fn () => [ -// 'faculty_id' => $faculties->random()->id -// ]) -// ->has(Schedule::factory()->count(90 / 40)) // Распределяем 90 расписаний по 40 группам -// ->create(); -// Department::factory()->count(12)->create(); -// -// for ($i = 0; $i < 20; $i++) { -// DB::table('workers_departments')->insert([ -// 'user_id' => User::inRandomOrder()->first()->id, -// 'department_id' => Department::inRandomOrder()->first()->id, -// 'position' => $faker->word, -// 'created_at' => now(), -// 'updated_at' => now(), -// ]); -// } -// -// for ($i = 0; $i < 20; $i++) { -// DB::table('workers_faculties')->insert([ -// 'user_id' => User::inRandomOrder()->first()->id, -// 'faculty_id' => Faculty::inRandomOrder()->first()->id, -// 'position' => $faker->word, -// 'created_at' => now(), -// 'updated_at' => now(), -// ]); -// } -// -// for ($i = 0; $i < 30; $i++) { -// DB::table('teachers_departments')->insert([ -// 'user_id' => User::inRandomOrder()->first()->id, -// 'department_id' => Department::inRandomOrder()->first()->id, -// 'teaching_position' => $faker->word, -// 'created_at' => now(), -// 'updated_at' => now(), -// ]); -// } -// $this->call([RolesSeeder::class]); -// $users = [ -// [ -// 'name' => 'Admin', -// 'email' => 'Admin@mail.ru', -// 'password' => 'R177p900', -// 'role' => 'admin', -// ], -// [ -// 'name' => 'John', -// 'email' => 'Test@mail.ru', -// 'password' => 'R177p900', -// 'role' => 'user', -// ] -// ]; -// foreach ($users as $user) { -// $created_user = User::create([ -// 'name' => $user['name'], -// 'email' => $user['email'], -// 'password' => Hash::make($user['password']), -// ]); -// $created_user->assignRole($user['role']); -// } } } diff --git a/database/seeders/MockDataSeeder.php b/database/seeders/MockDataSeeder.php new file mode 100644 index 0000000..2813f0a --- /dev/null +++ b/database/seeders/MockDataSeeder.php @@ -0,0 +1,251 @@ +command?->info('Creating mock data...'); + + // 1. Users & Roles + $this->createUsers(); + + // 2. Institute Structure + $faculties = Faculty::factory()->count(8)->create(); + $departments = Department::factory()->count(15)->create(); + $divisions = Division::factory()->count(5)->create(); + + // 3. Pivot: workers_faculties, workers_departments, teachers_departments + $this->attachWorkers($faculties, $departments); + + // 4. Article + $categories = Category::factory()->count(20)->create(); + Post::factory()->count(100)->create(); + Tag::factory()->count(30)->create(); + + // 5. Events + $eventCategories = EventCategory::factory()->count(8)->create(); + Event::factory()->count(50)->create(); + + // 6. Education + $directionStudies = DirectionStudy::factory()->count(10)->create(); + $programs = EducationalProgram::factory()->count(25)->create(); + $campaigns = AdmissionCampaign::factory()->count(5)->create(); + AdmissionPlan::factory()->count(30)->create(); + + // 7. Pivot: program_department + $this->attachProgramsToDepartments($programs, $departments); + + // 8. Additional Education + $directions = DirectionAdditionalEducation::factory()->count(5)->create(); + $addCategories = AdditionalEducationCategory::factory()->count(12)->create(); + AdditionalEducation::factory()->count(20)->create(); + + // 9. Science + $journals = AcademicJournal::factory()->count(4)->create(); + JournalIssue::factory()->count(15)->create(); + + // 10. Schedule + $groups = EducationalGroup::factory()->count(40)->create(); + Schedule::factory()->count(90)->create(); + + // 11. Widgets + Slider::create([ + 'title' => 'Главный слайдер', + 'slug' => 'quos-velit-quisquam', + 'is_active' => true, + ]); + Slider::factory()->count(4)->create(); + + $mainSlider = Slider::where('slug', 'quos-velit-quisquam')->first(); + Slide::factory()->count(5)->create([ + 'slider_id' => $mainSlider->id, + 'is_active' => true, + 'start_time' => now()->subWeek(), + 'end_time' => now()->addMonth(), + ]); + Slide::factory()->count(15)->create(); + + ContactWidget::create([ + 'title' => 'Главная страница контакты', + 'slug' => 'glavnaia-stranica-kontakty', + 'content' => [ + [ + 'title' => 'Контакты', + 'items' => [ + [ + 'header' => 'Главный корпус', + 'details' => [ + ['content' => '622031, Свердловская обл. Нижний Тагил ул. Красногвардейская, 57', 'url' => null], + ], + ], + [ + 'header' => 'Свяжитесь с нами', + 'details' => [ + ['content' => '(3435) 25-48-00', 'url' => null], + ['content' => 'office@ntspi.ru', 'url' => null], + ], + ], + ], + ], + ], + 'is_active' => true, + ]); + ContactWidget::factory()->count(2)->create(); + + PageReferenceList::create([ + 'title' => 'Главная страница ресурсы', + 'slug' => 'glavnaia-stranica-resurs', + 'content' => [ + ['title' => 'Приемная комиссия', 'url' => '/admission'], + ['title' => 'Образование', 'url' => '/education'], + ['title' => 'Наука', 'url' => '/science'], + ], + 'is_active' => true, + ]); + PageReferenceList::factory()->count(4)->create(); + $forms = CustomForm::factory()->count(8)->create(); + CustomFormResponse::factory()->count(40)->create(); + + // 12. App Structure + $mainSections = MainSection::factory()->count(5)->create(); + $subSections = SubSection::factory() + ->count(15) + ->sequence(fn () => ['main_section_id' => $mainSections->random()->id]) + ->create(); + Page::factory() + ->count(40) + ->sequence(fn () => ['sub_section_id' => $subSections->random()->id]) + ->create(); + + // 13. Integration Credentials + IntegrationCredential::factory()->count(3)->create(); + + $this->command?->info('Mock data created successfully!'); + } + + private function createUsers(): void + { + $admin = User::firstOrCreate( + ['email' => 'admin@ntspi.ru'], + [ + 'name' => 'Admin', + 'slug' => 'admin', + 'password' => Hash::make('password'), + ] + ); + + if (!$admin->hasRole('super_admin')) { + $admin->assignRole('super_admin'); + } + + User::firstOrCreate( + ['email' => 'editor@ntspi.ru'], + [ + 'name' => 'Editor', + 'slug' => 'editor', + 'password' => Hash::make('password'), + ] + ); + + User::factory()->count(50)->create(); + + UserDetail::factory()->count(30)->create(); + } + + private function attachWorkers($faculties, $departments): void + { + $users = User::all(); + + foreach ($faculties as $faculty) { + $workers = $users->random(fake()->numberBetween(2, 5)); + foreach ($workers as $worker) { + DB::table('workers_faculties')->insert([ + 'user_id' => $worker->id, + 'faculty_id' => $faculty->id, + 'position' => fake()->randomElement(['Преподаватель', 'Ст. преподаватель', 'Доцент', 'Профессор', 'Зав. кафедрой']), + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + } + + foreach ($departments as $department) { + $workers = $users->random(fake()->numberBetween(2, 4)); + foreach ($workers as $worker) { + DB::table('workers_departments')->insert([ + 'user_id' => $worker->id, + 'department_id' => $department->id, + 'position' => fake()->randomElement(['Преподаватель', 'Ст. преподаватель', 'Доцент', 'Лаборант']), + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + + $teachers = $users->random(fake()->numberBetween(3, 8)); + foreach ($teachers as $teacher) { + DB::table('teachers_departments')->insert([ + 'user_id' => $teacher->id, + 'department_id' => $department->id, + 'teaching_position' => fake()->randomElement(['Преподаватель', 'Ст. преподаватель', 'Доцент', 'Профессор']), + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + } + } + + private function attachProgramsToDepartments($programs, $departments): void + { + foreach ($programs as $program) { + $dept = $departments->random(fake()->numberBetween(1, 3)); + foreach ($dept as $d) { + DB::table('program_department')->insert([ + 'educational_program_id' => $program->id, + 'department_id' => $d->id, + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + } + } +} diff --git a/database/seeders/RolesSeeder.php b/database/seeders/RolesSeeder.php index 1ce4d63..1e717df 100755 --- a/database/seeders/RolesSeeder.php +++ b/database/seeders/RolesSeeder.php @@ -2,33 +2,29 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; +use BezhanSalleh\FilamentShield\FilamentShield; use Illuminate\Database\Seeder; -use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; +use Spatie\Permission\Models\Role; -class RolesSeeder extends Seeder +class RolesSeeder extends Seeder { - /** - * Run the database seeds. - */ public function run(): void { -// $role_admin = Role::create(['name' => 'admin']); -// $role_user = Role::create(['name' => 'user']); -// $permission_read = Permission::create(['name' => 'read posts']); -// $permission_create = Permission::create(['name' => 'create posts']); -// $permission_edit = Permission::create(['name' => 'edit posts']); -// $permission_delete = Permission::create(['name' => 'delete posts']); -// -// $permission_admin = [ -// $permission_create, -// $permission_read, -// $permission_edit, -// $permission_delete, -// ]; -// -// $role_admin->syncPermissions($permission_admin); -// $role_user->givePermissionTo($permission_read); + FilamentShield::createRole( + name: config('filament-shield.super_admin.name', 'super_admin') + ); + + FilamentShield::createRole( + name: config('filament-shield.dashboard_user.name', 'dashboard_user') + ); + + FilamentShield::createRole( + name: config('filament-shield.invited_user.name', 'invited_user') + ); + + $adminRole = Role::findByName('super_admin'); + $allPerms = Permission::where('guard_name', 'web')->get(); + $adminRole->syncPermissions($allPerms); } }