group(function () { // Invoice Test — Send invoice email with PDF attachment Route::prefix('invoice-test') ->controller(InvoiceTestController::class) ->group(function () { Route::post('{invoiceNumber}/send-email', 'sendInvoiceEmail'); Route::get('{invoiceNumber}/preview-pdf', 'previewInvoicePdf'); }); }) /* Api for Admin */ ->group(function () { Route::prefix('administrator')->group(function () { Route::post('login', [AuthController::class, 'login']); Route::middleware('api.auth:admin')->group(function () { Route::post('logout', [AuthController::class, 'logout']); Route::post('refresh', [AuthController::class, 'refresh']); Route::get('me', [AuthController::class, 'me']); // Role Permissions Route::prefix('role-permissions')->group(function () { // Accessible bởi mọi admin — trả về permissions hiệu lực của user hiện tại Route::get('mine', [RolePermissionController::class, 'mine']); // Các endpoint sau chỉ dành cho Full Administrator (kiểm tra trong controller) Route::get('/', [RolePermissionController::class, 'index']); Route::get('all-permissions', [RolePermissionController::class, 'allPermissions']); Route::post('permissions', [RolePermissionController::class, 'createPermissionGroup']); Route::delete('permissions/group/{module}', [ RolePermissionController::class, 'deletePermissionGroup', ]); Route::patch('permissions/{id}', [RolePermissionController::class, 'renamePermission']); Route::put('{roleId}', [RolePermissionController::class, 'update']); }); // Employees (module: administrator) Route::prefix('employees')->group(function () { Route::get('roles', [EmployeeController::class, 'roles'])->middleware('perm:administrator.view'); Route::get('/', [EmployeeController::class, 'index'])->middleware('perm:administrator.view'); Route::post('/', [EmployeeController::class, 'store'])->middleware('perm:administrator.create'); Route::get('{id}', [EmployeeController::class, 'show'])->middleware('perm:administrator.view'); Route::put('{id}', [EmployeeController::class, 'update'])->middleware('perm:administrator.edit'); Route::delete('{id}', [EmployeeController::class, 'destroy'])->middleware( 'perm:administrator.destroy', ); }); // Customers (module: customer) Route::prefix('customers') ->controller(CustomerController::class) ->group(function () { Route::get('trash', 'trash')->middleware('perm:customer.view'); Route::get('vps/available', 'listAvailableVms')->middleware('perm:customer.view'); Route::get('/', 'index')->middleware('perm:customer.view'); Route::post('/', 'store')->middleware('perm:customer.create'); Route::get('{uuid}', 'show')->middleware('perm:customer.view'); Route::put('{uuid}', 'update')->middleware('perm:customer.edit'); Route::delete('{uuid}', 'destroy')->middleware('perm:customer.destroy'); Route::delete('{uuid}/destroy', 'destroy')->middleware('perm:customer.destroy'); Route::post('{uuid}/reset-password', 'resetPassword')->middleware('perm:customer.edit'); Route::post('{uuid}/send-password', 'sendPasswordEmail')->middleware('perm:customer.edit'); Route::post('{uuid}/send-email', 'sendEmail')->middleware('perm:customer.edit'); Route::post('{uuid}/login-as', 'loginAs')->middleware('perm:customer.edit'); Route::post('{uuid}/add-credit', 'addCredit')->middleware('perm:customer.edit'); Route::post('{uuid}/add-total', 'addTotal')->middleware('perm:customer.edit'); Route::get('{uuid}/services', 'getServices')->middleware('perm:customer.view'); Route::post('{uuid}/services', 'createService')->middleware('perm:customer.edit'); Route::post('{uuid}/services/bulk-delete', 'bulkDeleteServices')->middleware( 'perm:customer.edit', ); Route::put('{uuid}/services/{serviceId}', 'updateService')->middleware('perm:customer.edit'); Route::get('{uuid}/notes', 'getCustomerNotes')->middleware('perm:customer.view'); Route::post('{uuid}/notes', 'storeCustomerNote')->middleware('perm:customer.edit'); Route::delete('{uuid}/notes/{noteId}', 'destroyCustomerNote')->middleware('perm:customer.edit'); Route::get('{uuid}/services/{serviceId}/notes', 'getServiceNotes')->middleware('perm:customer.view'); Route::post('{uuid}/services/{serviceId}/notes', 'storeServiceNote')->middleware('perm:customer.edit'); Route::delete('{uuid}/services/{serviceId}/notes/{noteId}', 'destroyServiceNote')->middleware( 'perm:customer.edit', ); Route::get('{uuid}/orders', 'getOrders')->middleware('perm:customer.view'); Route::put('{uuid}/orders/{orderId}', 'updateOrder')->middleware('perm:customer.edit'); Route::get('{uuid}/invoices', 'getInvoices')->middleware('perm:customer.view'); Route::put('{uuid}/invoices/{invoiceId}', 'updateInvoice')->middleware( 'perm:customer.edit', ); Route::get('{uuid}/transactions', 'getTransactions')->middleware('perm:customer.view'); Route::put('{uuid}/transactions/{transactionId}', 'updateTransaction')->middleware( 'perm:customer.edit', ); Route::get('{uuid}/domains', 'getDomains')->middleware('perm:customer.view'); Route::get('{uuid}/dns-domains', 'getDnsDomains')->middleware('perm:customer.view'); Route::get('{uuid}/dns-domains/{domainId}/records', 'getDnsDomainRecords')->middleware( 'perm:customer.view', ); Route::patch('{uuid}/status', 'updateStatus')->middleware('perm:customer.edit'); Route::post('bulk-delete', 'bulkDelete')->middleware('perm:customer.destroy'); Route::post('bulk-restore', 'bulkRestore')->middleware('perm:customer.edit'); Route::post('bulk-force-delete', 'bulkForceDelete')->middleware('perm:customer.destroy'); Route::post('bulk-status', 'bulkStatus')->middleware('perm:customer.edit'); Route::post('{uuid}/restore', 'restore')->middleware('perm:customer.edit'); Route::delete('{uuid}/force', 'forceDelete')->middleware('perm:customer.destroy'); }); // Services (module: customer) Route::prefix('services')->controller(ServiceController::class)->group(function () { Route::get('/', 'index')->middleware('perm:customer.view'); Route::get('{id}', 'show')->middleware('perm:customer.view'); Route::patch('{id}/detach-customer', 'detachCustomer')->middleware('perm:customer.edit'); }); // Products (module: product-service) Route::prefix('products') ->controller(ProductController::class) ->group(function () { Route::get('export', 'export')->middleware('perm:product-service.manager'); Route::get('/', 'index')->middleware('perm:product-service.view'); Route::post('/', 'store')->middleware('perm:product-service.create'); Route::post('import', 'import')->middleware('perm:product-service.create'); Route::post('bulk-update-status', 'bulkUpdateStatus')->middleware('perm:product-service.edit'); Route::post('bulk-destroy', 'bulkDestroy')->middleware('perm:product-service.destroy'); Route::controller(ProductController::class)->group(function () { Route::get('os', 'getOsList')->middleware('perm:product-service.view'); Route::get('{id}', 'show')->middleware('perm:product-service.view'); Route::get('{id}/os', 'getOs')->middleware('perm:product-service.view'); Route::get('{id}/operating-systems', 'getOperatingSystems')->middleware( 'perm:product-service.view', ); Route::put('{id}', 'update')->middleware('perm:product-service.edit'); Route::delete('{id}', 'destroy')->middleware('perm:product-service.destroy'); Route::post('{id}/duplicate', 'duplicate')->middleware('perm:product-service.create'); }); }); Route::prefix('product-categories') ->controller(ProductCategoryController::class) ->as('product-categories.') ->group(function () { Route::get('/', 'index')->middleware('perm:product-service.view')->name('index'); Route::post('/', 'store')->middleware('perm:product-service.create')->name('store'); Route::get('trashed', 'trashed')->middleware('perm:product-service.view')->name('trashed'); Route::post('bulk-update-status', 'bulkUpdateStatus') ->middleware('perm:product-service.edit') ->name('bulk-update-status'); Route::post('bulk-destroy', 'bulkDestroy') ->middleware('perm:product-service.destroy') ->name('bulk-destroy'); Route::post('bulk-restore', 'bulkRestore') ->middleware('perm:product-service.edit') ->name('bulk-restore'); Route::post('bulk-force-delete', 'bulkForceDelete') ->middleware('perm:product-service.destroy') ->name('bulk-force-delete'); Route::get('{id}', 'show')->middleware('perm:product-service.view')->name('show'); Route::put('{id}', 'update')->middleware('perm:product-service.edit')->name('update'); Route::delete('{id}', 'destroy')->middleware('perm:product-service.destroy')->name('destroy'); Route::post('{id}/restore', 'restore') ->middleware('perm:product-service.edit') ->name('restore'); Route::delete('{id}/force', 'forceDelete') ->middleware('perm:product-service.destroy') ->name('force-delete'); }); // Addons (module: product-service) Route::prefix('addons') ->controller(AddonController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:product-service.view'); Route::post('/', 'store')->middleware('perm:product-service.create'); Route::post('bulk-update-status', 'bulkUpdateStatus')->middleware('perm:product-service.edit'); Route::post('bulk-destroy', 'bulkDestroy')->middleware('perm:product-service.destroy'); Route::get('{id}', 'show')->middleware('perm:product-service.view'); Route::put('{id}', 'update')->middleware('perm:product-service.edit'); Route::delete('{id}', 'destroy')->middleware('perm:product-service.destroy'); }); // Báo giá thiết kế website (module: order) Route::prefix('web-design-quotes') ->controller(WebDesignQuoteController::class) ->group(function () { Route::get('platform-options', 'platformOptions')->middleware('perm:order.view'); Route::get('/', 'index')->middleware('perm:order.view'); Route::post('/', 'store')->middleware('perm:order.create'); Route::get('{id}', 'show')->middleware('perm:order.view'); Route::put('{id}', 'update')->middleware('perm:order.edit'); Route::patch('{id}/status', 'updateStatus')->middleware('perm:order.edit'); Route::get('{id}/pdf', 'downloadPdf')->middleware('perm:order.view'); Route::delete('{id}', 'destroy')->middleware('perm:order.destroy'); }); Route::prefix('post-categories') ->controller(AdminPostCategoryController::class) ->as('post-categories.') ->group(function () { Route::get('/', 'index')->name('index'); Route::post('/', 'store')->name('store'); Route::get('trashed', 'trashed')->name('trashed'); Route::post('bulk-restore', 'bulkRestore')->name('bulk-restore'); Route::post('bulk-force-delete', 'bulkForceDelete')->name('bulk-force-delete'); Route::post('{id}/restore', 'restore')->name('restore'); Route::delete('{id}/force-delete', 'forceDelete')->name('force-delete'); Route::get('{id}', 'show')->name('show'); Route::put('{id}', 'update')->name('update'); Route::delete('{id}', 'destroy')->name('destroy'); }); Route::prefix('posts') ->controller(AdminPostController::class) ->as('posts.') ->group(function () { Route::get('/', 'index')->name('index'); Route::post('/', 'store')->name('store'); Route::post('sync-wordpress', 'syncWordpress')->name('sync-wordpress'); Route::post('bulk-delete', 'bulkDelete')->name('bulk-delete'); Route::post('bulk-update-status', 'bulkUpdateStatus')->name('bulk-update-status'); Route::get('trashed', 'trashed')->name('trashed'); Route::post('bulk-restore', 'bulkRestore')->name('bulk-restore'); Route::post('bulk-force-delete', 'bulkForceDelete')->name('bulk-force-delete'); Route::post('{id}/restore', 'restore')->name('restore'); Route::delete('{id}/force-delete', 'forceDelete')->name('force-delete'); Route::get('{id}', 'show')->name('show'); Route::put('{id}', 'update')->name('update'); Route::delete('{id}', 'destroy')->name('destroy'); }); // Orders (module: order) Route::prefix('orders') ->controller(OrderController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:order.view'); Route::post('/upload-proof', 'uploadProof')->middleware('perm:order.create'); Route::post('/', 'store')->middleware('perm:order.create'); Route::get('{id}', 'show')->middleware('perm:order.view'); Route::put('{id}', 'update')->middleware('perm:order.edit'); Route::delete('{id}', 'destroy')->middleware('perm:order.destroy'); Route::post('{id}/accept', 'accept')->middleware('perm:order.edit'); Route::post('{id}/cancel', 'cancel')->middleware('perm:order.edit'); }); // Invoices (module: invoice) Route::prefix('invoices') ->controller(InvoiceController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:invoice.view'); Route::get('/datatable', 'datatable')->middleware('perm:invoice.view'); Route::post('/', 'store')->middleware('perm:invoice.create'); Route::get('{id}', 'show')->middleware('perm:invoice.view'); Route::put('{id}', 'update')->middleware('perm:invoice.edit'); Route::delete('{id}', 'destroy')->middleware('perm:invoice.destroy'); Route::post('{id}/paid', 'markAsPaid')->middleware('perm:invoice.edit'); Route::post('{id}/cancel', 'cancel')->middleware('perm:invoice.edit'); // Attachments Route::get('{id}/attachments', 'listAttachments')->middleware('perm:invoice.view'); Route::post('{id}/attachments', 'uploadAttachment')->middleware('perm:invoice.edit'); Route::delete('{id}/attachments/{attachmentId}', 'deleteAttachment')->middleware( 'perm:invoice.edit', ); // Send mail notification Route::post('{id}/send-mail', 'sendMail')->middleware('perm:invoice.edit'); }); // Payments (module: payment) Route::prefix('payments') ->controller(PaymentController::class) ->group(function () { Route::get('for-select', 'forSelect'); Route::get('/', 'index')->middleware('perm:payment.view'); Route::post('/', 'store')->middleware('perm:payment.create'); Route::get('{id}', 'show')->middleware('perm:payment.view'); Route::put('{id}', 'update')->middleware('perm:payment.edit'); Route::delete('{id}', 'destroy')->middleware('perm:payment.destroy'); }); // OS Groups & OS Entries (module: module-vcenter) Route::prefix('os-groups') ->controller(OsGroupController::class) ->as('os-groups.') ->group(function () { Route::get('/', 'index')->middleware('perm:module-vcenter.manager')->name('index'); Route::post('/', 'store')->middleware('perm:module-vcenter.manager')->name('store'); Route::get('{id}', 'show')->middleware('perm:module-vcenter.manager')->name('show'); Route::put('{id}', 'update')->middleware('perm:module-vcenter.manager')->name('update'); Route::delete('{id}', 'destroy')->middleware('perm:module-vcenter.manager')->name('destroy'); }); Route::prefix('os') ->controller(OsController::class) ->as('os.') ->group(function () { Route::post('/', 'store')->middleware('perm:module-vcenter.manager')->name('store'); Route::put('{id}', 'update')->middleware('perm:module-vcenter.manager')->name('update'); Route::delete('{id}', 'destroy')->middleware('perm:module-vcenter.manager')->name('destroy'); }); // VPS (module: module-vcenter) Route::prefix('vps') ->controller(VPSController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:module-vcenter.view'); Route::get('{id}', 'show')->middleware('perm:module-vcenter.view'); Route::put('{id}', 'update')->middleware('perm:module-vcenter.edit'); Route::post('{id}/power-on', 'powerOn')->middleware('perm:module-vcenter.edit'); Route::post('{id}/power-off', 'powerOff')->middleware('perm:module-vcenter.edit'); Route::post('{id}/restart', 'restart')->middleware('perm:module-vcenter.edit'); Route::get('{id}/console-ticket', 'getConsoleTicket')->middleware('perm:module-vcenter.view'); }); // vCenter (module: module-vcenter) Route::prefix('vcenter') ->controller(VCenterController::class) ->group(function () { Route::get('tree', 'tree')->middleware('perm:module-vcenter.view'); Route::get('console-ticket', 'consoleTicket')->middleware('perm:module-vcenter.view'); Route::post('/', 'store')->middleware('perm:module-vcenter.create'); Route::post('sync', 'sync')->middleware('perm:module-vcenter.edit'); Route::post('node/{type}', 'storeNode')->middleware('perm:module-vcenter.create'); Route::put('node/{type}/{id}', 'updateNode')->middleware('perm:module-vcenter.edit'); Route::delete('node/{type}/{id}', 'destroyNode')->middleware('perm:module-vcenter.destroy'); }); // DNS Manager — Domains (module: domain.manager) Route::prefix('domains') ->controller(DnsDomainController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:domain.manager'); Route::post('/', 'store')->middleware('perm:domain.manager'); Route::post('sync-dns', 'syncDns')->middleware('perm:domain.manager'); Route::get('{id}', 'show')->middleware('perm:domain.manager'); Route::put('{id}', 'update')->middleware('perm:domain.manager'); Route::delete('{id}', 'destroy')->middleware('perm:domain.manager'); // DNS Records Route::get('{id}/dns', 'dnsIndex')->middleware('perm:domain.manager'); Route::post('{id}/dns', 'dnsStore')->middleware('perm:domain.manager'); Route::put('{id}/dns/{recordId}', 'dnsUpdate')->middleware('perm:domain.manager'); Route::delete('{id}/dns/{recordId}', 'dnsDestroy')->middleware('perm:domain.manager'); }); // DNS Manager — Servers (module: domain.manager) Route::prefix('dns-servers') ->controller(DnsServerController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:domain.manager'); Route::post('/', 'store')->middleware('perm:domain.manager'); Route::get('{id}', 'show')->middleware('perm:domain.manager'); Route::post('{id}/check-connection', 'checkConnection')->middleware('perm:domain.manager'); Route::put('{id}', 'update')->middleware('perm:domain.manager'); Route::delete('{id}', 'destroy')->middleware('perm:domain.manager'); }); Route::prefix('dns-records') ->controller(DnsRecordController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:domain.manager'); Route::get('{id}', 'show')->middleware('perm:domain.manager'); Route::put('{id}', 'update')->middleware('perm:domain.manager'); }); // InfraManagement (jumphost, vcenter config) Route::prefix('infra-management') ->controller(InfraManagementController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:module-vcenter.manager'); Route::post('/', 'store')->middleware('perm:module-vcenter.manager'); Route::get('{id}', 'show')->middleware('perm:module-vcenter.manager'); Route::put('{id}', 'update')->middleware('perm:module-vcenter.manager'); Route::delete('{id}', 'destroy')->middleware('perm:module-vcenter.manager'); }); // Domain Orders (module: order) Route::prefix('domain-orders') ->controller(AdminDomainOrderController::class) ->group(function () { Route::get('pending-count', 'pendingCount')->middleware('perm:order.view'); Route::get('/', 'index')->middleware('perm:order.view'); Route::get('{id}', 'show')->middleware('perm:order.view'); Route::post('{id}/confirm-registration', 'confirmRegistration')->middleware('perm:order.edit'); Route::patch('{id}/kyc', 'updateKyc')->middleware('perm:order.edit'); Route::patch('{id}/activate', 'activate')->middleware('perm:order.edit'); Route::post('{id}/reject-and-refund', 'rejectAndRefund')->middleware('perm:order.edit'); }); // Domain Pricing (module: settings) Route::prefix('domain-pricing') ->controller(AdminDomainPricingController::class) ->group(function () { Route::get('/', 'index'); Route::put('/', 'update'); Route::post('/reset', 'reset'); }); // Domain Tools — proxy tới iNET API (module: domain.manager) Route::prefix('domain-tools') ->controller(InetDomainController::class) ->group(function () { Route::get('whois/{domain}', 'whois')->middleware('perm:domain.manager'); Route::get('check-available', 'checkAvailable')->middleware('perm:domain.manager'); Route::post('bulk-check-available', 'bulkCheckAvailable')->middleware('perm:domain.manager'); Route::post('ai-suggest', 'aiSuggest')->middleware('perm:domain.manager'); Route::get('suffixes', 'suffixes')->middleware('perm:domain.manager'); }); // Settings (module: administrator) Route::prefix('settings') ->controller(AdminSettingController::class) ->group(function () { Route::get('/', 'index'); Route::put('/', 'update'); Route::post('test-telegram', 'testTelegram'); }); Route::prefix('media') ->controller(AdminMediaController::class) ->group(function () { Route::get('/', 'index'); Route::post('bulk-destroy', 'bulkDestroy'); Route::delete('{id}', 'destroy'); }); Route::post('media/upload', [AdminSettingController::class, 'uploadMedia']); // Provider (active vCenter chain + provider settings — module: module-vcenter) Route::prefix('provider')->group(function () { Route::get('active-chain', [ \App\Http\Controllers\Api\Admin\Provider\ActiveInfraController::class, 'chain', ])->middleware('perm:module-vcenter.view'); Route::post('{type}/{id}/activate', [ \App\Http\Controllers\Api\Admin\Provider\ActiveInfraController::class, 'activate', ]) ->whereIn('type', ['vcenter', 'datacenter', 'host', 'datastore', 'network']) ->middleware('perm:module-vcenter.edit'); Route::post('{type}/{id}/deactivate', [ \App\Http\Controllers\Api\Admin\Provider\ActiveInfraController::class, 'deactivate', ]) ->whereIn('type', ['vcenter', 'datacenter', 'host', 'datastore', 'network']) ->middleware('perm:module-vcenter.edit'); Route::get('settings', [ \App\Http\Controllers\Api\Admin\Provider\ProviderSettingController::class, 'index', ])->middleware('perm:module-vcenter.view'); Route::put('settings', [ \App\Http\Controllers\Api\Admin\Provider\ProviderSettingController::class, 'update', ])->middleware('perm:module-vcenter.edit'); }); // Dashboard Stats Route::prefix('dashboard') ->controller(\App\Http\Controllers\Api\Admin\Dashboard\DashboardController::class) ->group(function () { Route::get('stats', 'stats'); Route::get('monthly-stats', 'monthlyStats'); Route::get('daily-stats', 'dailyStats'); Route::get('recent-orders', 'recentOrders'); Route::get('recent-deposits', 'recentDeposits'); Route::get('top-services', 'topServices'); Route::get('expiring-services', 'expiringServices'); Route::get('activities', 'activities'); Route::get('latest-customers', 'latestCustomers'); }); // Staff Online Route::prefix('staff-online') ->controller(StaffOnlineController::class) ->group(function () { Route::get('/', 'index'); Route::post('ping', 'ping'); }); // Queue Monitor (Horizon) Route::prefix('queue') ->controller(QueueMonitorController::class) ->group(function () { Route::get('jobs/recent', 'recent'); Route::get('jobs/pending', 'pending'); Route::get('jobs/failed', 'failed'); Route::get('jobs/metrics', 'metrics'); }); // Banks — deposit bank accounts (module: settings) Route::prefix('banks') ->controller(BankController::class) ->group(function () { Route::get('/', 'index'); Route::post('/', 'store'); Route::put('{id}', 'update'); Route::delete('{id}', 'destroy'); Route::post('{id}/restore', 'restore'); }); // Email Templates (module: settings) Route::prefix('email-templates') ->controller(EmailTemplateController::class) ->group(function () { Route::get('/', 'index'); Route::post('/', 'store'); Route::get('email-settings', 'getEmailSettings'); Route::put('email-settings', 'updateEmailSettings'); Route::get('{id}', 'show'); Route::put('{id}', 'update'); Route::delete('{id}', 'destroy'); Route::get('{id}/preview-invoice', 'previewInvoiceJson'); }); // Notification Email Templates — block-based editor Route::prefix('notification-templates') ->controller(EmailNotificationTemplateController::class) ->group(function () { Route::get('/', 'index'); Route::post('/', 'store'); Route::get('field-definitions', 'fieldDefinitions'); Route::get('{id}', 'show'); Route::put('{id}', 'update'); Route::delete('{id}', 'destroy'); Route::get('{id}/preview', 'preview'); }); // Transactions — manual deposit review (module: transaction) Route::prefix('transactions') ->controller(AdminTransactionController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:customer.view'); Route::get('pending-count', 'pendingCount')->middleware('perm:customer.view'); Route::post('{uuid}/approve', 'approve')->middleware('perm:customer.edit'); Route::post('{uuid}/reject', 'reject')->middleware('perm:customer.edit'); }); // IP Pool (module: module-vcenter) Route::prefix('ip-pool') ->controller(IpPoolController::class) ->group(function () { Route::get('networks', 'networks')->middleware('perm:module-vcenter.view'); Route::get('used-services', 'usedServices')->middleware('perm:module-vcenter.view'); Route::get('/', 'index')->middleware('perm:module-vcenter.view'); Route::post('/', 'store')->middleware('perm:module-vcenter.manager'); Route::post('sync', 'sync')->middleware('perm:module-vcenter.manager'); Route::delete('bulk', 'bulkDelete')->middleware('perm:module-vcenter.manager'); Route::get('{id}', 'show')->middleware('perm:module-vcenter.view'); Route::put('{id}', 'update')->middleware('perm:module-vcenter.manager'); Route::delete('{id}', 'destroy')->middleware('perm:module-vcenter.manager'); }); // vCenter Manager Power Operations (module: module-vcenter) Route::prefix('vcenter-manager') ->controller(VCenterManagerController::class) ->group(function () { Route::post('vm/power-on', 'powerOn')->middleware('perm:module-vcenter.edit'); Route::post('vm/power-off', 'powerOff')->middleware('perm:module-vcenter.edit'); Route::post('vm/restart', 'restart')->middleware('perm:module-vcenter.edit'); Route::post('vm/snapshot', 'snapshot')->middleware('perm:module-vcenter.edit'); Route::post('vm/suspend', 'suspend')->middleware('perm:module-vcenter.edit'); Route::post('vm/update-config', 'updateConfig')->middleware('perm:module-vcenter.edit'); Route::post('vm/delete', 'deleteVM')->middleware('perm:module-vcenter.edit'); Route::get('vm/stats', 'stats')->middleware('perm:module-vcenter.view'); Route::get('vms/powered-off', 'getPoweredOffVms')->middleware('perm:module-vcenter.view'); }); // Tickets (support tickets) Route::prefix('tickets') ->controller(AdminTicketController::class) ->group(function () { Route::get('/', 'index'); Route::get('{ticket_num}', 'show'); Route::patch('{ticket_num}/status', 'updateStatus'); Route::post('{ticket_num}/reply', 'reply'); }); Route::prefix('notifications') ->controller(NotificationController::class) ->group(function () { Route::get('/', fn() => app(NotificationController::class)->index(request(), 'admin')); Route::get( '{id}', fn($id) => app(NotificationController::class)->show(request(), 'admin', (int) $id), )->whereNumber('id'); Route::patch( '{id}/read', fn($id) => app(NotificationController::class)->markRead(request(), 'admin', (int) $id), ); Route::patch( 'read-all', fn() => app(NotificationController::class)->markAllRead(request(), 'admin'), ); }); // Activity Logs Route::prefix('activity-logs') ->controller(ActivityLogController::class) ->group(function () { Route::get('/', 'index'); Route::get('modules', 'modules'); Route::get('stats', 'stats'); Route::get('{id}', 'show'); }); // Email Logs Route::prefix('email-logs') ->controller(EmailLogController::class) ->group(function () { Route::get('/', 'index'); Route::get('{id}', 'show')->whereNumber('id'); }); // VM Rebuild Logs — who rebuilt, which OS, post-rebuild password Route::prefix('rebuild-logs') ->controller(AdminReinstallLogController::class) ->group(function () { Route::get('/', 'index')->middleware('perm:vps.view'); Route::get('stats', 'stats')->middleware('perm:vps.view'); Route::get('{id}', 'show')->middleware('perm:vps.view')->whereNumber('id'); }); }); }); Route::prefix('system') ->middleware(['api.auth']) ->group(function () { Route::post('get-all-image', function (Media $media) { $files = $media->getAllMedia(); return response()->json(['data' => $files]); })->name('api.GetAllImage'); Route::get('get-ticket-console', function (Request $request, ServiceVCenter $serviceVCenter) { $product_id = $request->get('product'); if (!$product_id) { return response()->json(['error' => true, 'message' => 'Please choose product']); } $product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($product_id); if (!$product) { return response()->json(['error' => true, 'message' => "Can't find product"]); } $vcenter = null; if ( $product->ipAddress && $product->ipAddress->host && $product->ipAddress->host->datacenter && $product->ipAddress->host->datacenter->vCenter ) { $vcenter = $product->ipAddress->host->datacenter->vCenter; } if (!$vcenter) { return response()->json(['error' => true, 'message' => "Can't find vCenter information"]); } // Đăng nhập vCenter trước khi lấy ticket if (!$serviceVCenter->loginServer($vcenter)) { return response()->json([ 'error' => true, 'message' => 'Không thể đăng nhập vào vCenter', ]); } $ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id); // Nếu login hết hạn, thử login lại 1 lần nữa if ($ConsoleTicket === 'Login_Again') { if ($serviceVCenter->loginServer($vcenter)) { $ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id); } else { return response()->json([ 'error' => true, 'message' => 'Không thể đăng nhập lại vào vCenter', ]); } } // Nếu vẫn lỗi, trả về lỗi rõ ràng if (is_string($ConsoleTicket)) { return response()->json([ 'error' => true, 'message' => "Failed to get console ticket: $ConsoleTicket", ]); } if ($ConsoleTicket['error']) { return response()->json([ 'error' => true, 'message' => $ConsoleTicket['data'], ]); } return response() ->json([ 'error' => false, 'data' => $ConsoleTicket['data'], 'vmware-api-session-id' => $serviceVCenter->token, ]) ->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false); })->name('api.GetConsoleTicket'); }); Route::get('pdf-invoice', function () { // return Pdf::loadView('pdf.invoice-pdf')->setPaper('a4', 'portrait')->stream('hoa-don-mau.pdf'); }); }); Route::any('{any}', function () { return response()->json( [ 'error' => true, 'message' => 'API Route not found', ], 404, ); })->where('any', '.*');