From 9a14b8fbbd6c0d1af1a171122b090eae2b04c4ac Mon Sep 17 00:00:00 2001 From: ncoronel Date: Mon, 21 Sep 2026 09:24:19 -0300 Subject: [PATCH] feat(menus): add storefront category permissions --- ...1_010000_add_storefront_category_menus.php | 81 +++++++++++++++++++ database/seeders/MenuSeeder.php | 16 ++++ tests/Feature/Seeders/MenuSeederTest.php | 15 ++++ 3 files changed, 112 insertions(+) create mode 100644 database/migrations/2026_09_21_010000_add_storefront_category_menus.php diff --git a/database/migrations/2026_09_21_010000_add_storefront_category_menus.php b/database/migrations/2026_09_21_010000_add_storefront_category_menus.php new file mode 100644 index 0000000..5cfcf37 --- /dev/null +++ b/database/migrations/2026_09_21_010000_add_storefront_category_menus.php @@ -0,0 +1,81 @@ + [ + 'label' => 'Categoría de eventos', + 'route' => '/eventos/categoria/:id', + ], + 'product.category' => [ + 'label' => 'Categoría de productos', + 'route' => '/categoria/:id', + ], + ]; + + public function up(): void + { + $now = now(); + + DB::transaction(function () use ($now): void { + foreach (self::MENUS as $code => $menu) { + DB::table('menues')->updateOrInsert( + ['code' => $code], + [ + 'label' => $menu['label'], + 'parent_menu_code' => null, + 'content_type' => 'dynamic', + 'static_content_schema' => null, + 'route' => $menu['route'], + 'created_at' => $now, + 'updated_at' => $now, + ], + ); + } + + DB::table('roles') + ->whereIn('codigo', ['admin', 'adminapp', 'user']) + ->pluck('codigo') + ->each(function (string $roleCode): void { + foreach (array_keys(self::MENUS) as $menuCode) { + DB::table('roles_menues')->updateOrInsert([ + 'rol_codigo' => $roleCode, + 'menu_codigo' => $menuCode, + ]); + } + }); + + DB::table('tenants') + ->pluck('codigo') + ->each(function (string $tenantCode) use ($now): void { + $menuCode = $tenantCode === 'onticket' ? 'event.category' : 'product.category'; + + DB::table('tenants_menues')->updateOrInsert( + [ + 'tenant_code' => $tenantCode, + 'menu_code' => $menuCode, + ], + [ + 'static_content' => null, + 'created_at' => $now, + 'updated_at' => $now, + ], + ); + }); + }); + } + + public function down(): void + { + DB::transaction(function (): void { + $menuCodes = array_keys(self::MENUS); + + DB::table('tenants_menues')->whereIn('menu_code', $menuCodes)->delete(); + DB::table('roles_menues')->whereIn('menu_codigo', $menuCodes)->delete(); + DB::table('menues')->whereIn('code', $menuCodes)->delete(); + }); + } +}; diff --git a/database/seeders/MenuSeeder.php b/database/seeders/MenuSeeder.php index 64db9e5..02d980e 100644 --- a/database/seeders/MenuSeeder.php +++ b/database/seeders/MenuSeeder.php @@ -18,11 +18,21 @@ class MenuSeeder extends Seeder $menus = [ ['code' => 'index', 'label' => 'Inicio', 'route' => '/'], ['code' => 'event.index', 'label' => 'Eventos', 'route' => '/'], + [ + 'code' => 'event.category', + 'label' => 'Categoría de eventos', + 'route' => '/eventos/categoria/:id', + ], [ 'code' => 'event.detail', 'label' => 'Detalle de evento', 'route' => '/evento/:id', ], + [ + 'code' => 'product.category', + 'label' => 'Categoría de productos', + 'route' => '/categoria/:id', + ], [ 'code' => 'product.detail', 'label' => 'Detalle de producto', @@ -299,8 +309,12 @@ class MenuSeeder extends Seeder ]; $onTicketMenuCodes = [ 'event.index', + 'event.category', 'event.detail', ]; + $catalogMenuCodes = [ + 'product.category', + ]; $frequentlyAskedQuestions = [ [ 'pregunta' => '¿Hay algún límite de compra?', @@ -370,6 +384,8 @@ class MenuSeeder extends Seeder if ($tenant->codigo !== 'onticket') { $menuCodes = array_diff($menuCodes, $onTicketMenuCodes); + } else { + $menuCodes = array_diff($menuCodes, $catalogMenuCodes); } // Usar sync para asociar los menues al tenant diff --git a/tests/Feature/Seeders/MenuSeederTest.php b/tests/Feature/Seeders/MenuSeederTest.php index 7f0c994..9214e1b 100644 --- a/tests/Feature/Seeders/MenuSeederTest.php +++ b/tests/Feature/Seeders/MenuSeederTest.php @@ -193,6 +193,7 @@ class MenuSeederTest extends TestCase foreach ([ 'event.index' => '/', + 'event.category' => '/eventos/categoria/:id', 'event.detail' => '/evento/:id', ] as $code => $route) { $menu = Menu::query()->where('code', $code)->firstOrFail(); @@ -209,6 +210,20 @@ class MenuSeederTest extends TestCase ->exists() ); } + + $productCategory = Menu::query()->where('code', 'product.category')->firstOrFail(); + + $this->assertSame('/categoria/:id', $productCategory->route); + $this->assertFalse($onTicket->menues()->where('menues.code', 'product.category')->exists()); + $this->assertTrue($otherTenant->menues()->where('menues.code', 'product.category')->exists()); + $this->assertTrue( + Role::query() + ->where('codigo', RoleCode::User->value) + ->firstOrFail() + ->menus() + ->where('menues.code', 'product.category') + ->exists() + ); } public function test_it_seeds_the_account_menu_hierarchy(): void