Files
services_core/routes/api.php
T
2026-07-31 13:57:11 +07:00

468 lines
26 KiB
PHP

<?php
use App\Http\Controllers\Audit\AuditLogController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\Billing\BillingProfileController;
use App\Http\Controllers\Billing\InvoiceController;
use App\Http\Controllers\Customer\CustomerController;
use App\Http\Controllers\File\StoredFileController;
use App\Http\Controllers\Material\MaterialController;
use App\Http\Controllers\Menu\MenuController;
use App\Http\Controllers\Menu\MenuGroupController;
use App\Http\Controllers\Menu\MenuListController;
use App\Http\Controllers\Nas\NasResourceController;
use App\Http\Controllers\Notification\NotificationController;
use App\Http\Controllers\Notification\NotificationWebhookController;
use App\Http\Controllers\Payment\PaymentGatewayController;
use App\Http\Controllers\Profile\ProfileController;
use App\Http\Controllers\Tenant\TenantController;
use App\Http\Controllers\Ticket\TicketController;
use App\Http\Controllers\Ticket\TicketIncidentTypeController;
use App\Http\Controllers\Ticket\TicketTypeController;
use App\Http\Controllers\Ticket\TicketWorkflowController;
use App\Http\Controllers\Topology\TopologyController;
use App\Http\Controllers\User\UserController;
use App\Http\Controllers\Wilayah\WilayahController;
use App\Http\Controllers\Wallet\WalletController;
use Illuminate\Support\Facades\Route;
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);
Route::post('/register/verify', [AuthController::class, 'verifyRegistration']);
Route::post('/register/resend-code', [AuthController::class, 'resendVerificationCode']);
Route::get('/notification-webhooks/{notificationChannel}', [NotificationWebhookController::class, 'verify'])
->whereNumber('notificationChannel')->name('notification.webhooks.verify');
Route::post('/notification-webhooks/{notificationChannel}', [NotificationWebhookController::class, 'handle'])
->whereNumber('notificationChannel')->name('notification.webhooks.handle');
Route::post('/payment-webhooks/{accountUuid}', fn () => response()->json(['message' => 'Provider adapter belum dikonfigurasi.'], 501))
->name('payment.webhooks.handle');
Route::middleware(['auth:sanctum', 'tenant.context'])->group(function () {
Route::get('payment-gateway/providers', [PaymentGatewayController::class, 'providers'])
->middleware('menu.permission:payment-gateway-settings,view')->name('payment-gateway.providers');
Route::get('payment-gateway/settings', [PaymentGatewayController::class, 'settings'])
->middleware('menu.permission:payment-gateway-settings,view')->name('payment-gateway.settings.index');
Route::post('payment-gateway/accounts', [PaymentGatewayController::class, 'storeAccount'])
->middleware('menu.permission:payment-gateway-settings,create')->name('payment-gateway.accounts.store');
Route::put('payment-gateway/accounts/{account}', [PaymentGatewayController::class, 'updateAccount'])
->middleware('menu.permission:payment-gateway-settings,update')->whereNumber('account')->name('payment-gateway.accounts.update');
Route::put('payment-gateway/tenant-setting', [PaymentGatewayController::class, 'saveSetting'])
->middleware('menu.permission:payment-gateway-settings,update')->name('payment-gateway.tenant-setting.update');
Route::get('payment-gateway/transactions', [PaymentGatewayController::class, 'transactions'])
->middleware('menu.permission:payment-gateway-logs,view')->name('payment-gateway.transactions.index');
Route::get('wallets', [WalletController::class, 'index'])->name('wallets.index');
Route::get('wallets/{wallet}/ledger', [WalletController::class, 'ledger'])->whereNumber('wallet')->name('wallets.ledger');
Route::post('wallets/{wallet}/transfer', [WalletController::class, 'transfer'])->whereNumber('wallet')->name('wallets.transfer');
Route::post('wallets/{wallet}/withdraw', [WalletController::class, 'withdraw'])->whereNumber('wallet')->name('wallets.withdraw');
Route::get('notifications/events', [NotificationController::class, 'events'])->name('notifications.events');
Route::get('notifications/preferences', [NotificationController::class, 'preferences'])
->middleware('menu.permission:notifications-system,view')->name('notifications.preferences.index');
Route::put('notifications/preferences', [NotificationController::class, 'savePreferences'])
->middleware('menu.permission:notifications-system,update')->name('notifications.preferences.update');
Route::get('notifications/broadcasts', [NotificationController::class, 'broadcasts'])
->middleware('menu.permission:notifications-broadcasts,view')->name('notifications.broadcasts.index');
Route::post('notifications/broadcasts/preview', [NotificationController::class, 'previewBroadcast'])
->middleware('menu.permission:notifications-broadcasts,create')->name('notifications.broadcasts.preview');
Route::post('notifications/broadcasts', [NotificationController::class, 'storeBroadcast'])
->middleware('menu.permission:notifications-broadcasts,create')->name('notifications.broadcasts.store');
Route::get('notifications/broadcasts/{notificationBroadcast}', [NotificationController::class, 'showBroadcast'])
->middleware('menu.permission:notifications-broadcasts,view')->whereNumber('notificationBroadcast')->name('notifications.broadcasts.show');
Route::post('notifications/broadcasts/{notificationBroadcast}/approve', [NotificationController::class, 'approveBroadcast'])
->middleware('menu.permission:notifications-broadcasts,approve')->whereNumber('notificationBroadcast')->name('notifications.broadcasts.approve');
Route::get('me/notifications', [NotificationController::class, 'myNotifications'])->name('me.notifications.index');
Route::put('me/notifications/{uuid}/read', [NotificationController::class, 'markRead'])->name('me.notifications.read');
Route::get('customers/{customer}/notification-contacts', [NotificationController::class, 'contacts'])
->middleware('menu.permission:customers-active,view')->whereNumber('customer')->name('customers.notification-contacts.index');
Route::post('customers/{customer}/notification-contacts', [NotificationController::class, 'storeContact'])
->middleware('menu.permission:customers-active,update')->whereNumber('customer')->name('customers.notification-contacts.store');
Route::put('customers/{customer}/notification-contacts/{contact}', [NotificationController::class, 'updateContact'])
->middleware('menu.permission:customers-active,update')->whereNumber('customer')->whereNumber('contact')->name('customers.notification-contacts.update');
Route::delete('customers/{customer}/notification-contacts/{contact}', [NotificationController::class, 'destroyContact'])
->middleware('menu.permission:customers-active,update')->whereNumber('customer')->whereNumber('contact')->name('customers.notification-contacts.destroy');
foreach ([
'system' => ['channel' => 'system', 'menu' => 'notifications-system'],
'whatsapp-official' => ['channel' => 'whatsapp_official', 'menu' => 'notifications-wa-official'],
'whatsapp-unofficial' => ['channel' => 'whatsapp_unofficial', 'menu' => 'notifications-wa-unofficial'],
'email' => ['channel' => 'email', 'menu' => 'notifications-email'],
'telegram' => ['channel' => 'telegram', 'menu' => 'notifications-telegram'],
] as $path => $notification) {
Route::prefix("notifications/channels/{$path}")
->middleware("menu.resource:{$notification['menu']}")
->controller(NotificationController::class)
->group(function () use ($path, $notification) {
Route::get('/settings', 'channels')->defaults('notification_channel', $notification['channel'])->name("notifications.{$path}.settings.index");
Route::post('/settings', 'storeChannel')->defaults('notification_channel', $notification['channel'])->name("notifications.{$path}.settings.store");
Route::put('/settings/{notificationChannel}', 'updateChannel')->defaults('notification_channel', $notification['channel'])->whereNumber('notificationChannel')->name("notifications.{$path}.settings.update");
Route::post('/settings/{notificationChannel}/test', 'testChannel')->defaults('notification_channel', $notification['channel'])->whereNumber('notificationChannel')->name("notifications.{$path}.settings.test");
Route::get('/templates', 'templates')->defaults('notification_channel', $notification['channel'])->name("notifications.{$path}.templates.index");
Route::post('/templates', 'storeTemplate')->defaults('notification_channel', $notification['channel'])->name("notifications.{$path}.templates.store");
Route::put('/templates/{notificationTemplate}', 'updateTemplate')->defaults('notification_channel', $notification['channel'])->whereNumber('notificationTemplate')->name("notifications.{$path}.templates.update");
Route::get('/logs', 'deliveries')->defaults('notification_channel', $notification['channel'])->name("notifications.{$path}.logs.index");
});
}
Route::get('topology/options', [TopologyController::class, 'options'])
->name('topology.options');
Route::get('topology/map', [TopologyController::class, 'map'])
->middleware('menu.permission:topology-map,view')
->name('topology.map');
Route::post('topology/customer-connections', [TopologyController::class, 'connectCustomer'])
->middleware('menu.permission:topology-devices,update')
->name('topology.customer-connections.store');
Route::get('topology/customers/{customer}/path', [TopologyController::class, 'customerPath'])
->middleware('menu.permission:topology-network,view')
->whereNumber('customer')->name('topology.customers.path');
Route::get('topology/nodes/{node}/ports', [TopologyController::class, 'ports'])
->middleware('menu.permission:topology-devices,view')
->whereNumber('node')->name('topology.nodes.ports.index');
Route::post('topology/nodes/{node}/ports', [TopologyController::class, 'storePort'])
->defaults('topology_resource', 'port')
->middleware('menu.permission:topology-devices,create')
->whereNumber('node')->name('topology.nodes.ports.store');
Route::put('topology/ports/{port}', [TopologyController::class, 'updatePort'])
->defaults('topology_resource', 'port')
->middleware('menu.permission:topology-devices,update')
->whereNumber('port')->name('topology.ports.update');
Route::delete('topology/ports/{port}', [TopologyController::class, 'destroyPort'])
->middleware('menu.permission:topology-devices,delete')
->whereNumber('port')->name('topology.ports.destroy');
Route::get('topology/nodes/{node}/{direction}', [TopologyController::class, 'trace'])
->middleware('menu.permission:topology-network,view')
->whereNumber('node')->whereIn('direction', ['upstream', 'downstream'])
->name('topology.nodes.trace');
foreach ([
'device-types' => ['resource' => 'device-type', 'menu' => 'topology-device-types'],
'nodes' => ['resource' => 'node', 'menu' => 'topology-devices'],
'links' => ['resource' => 'link', 'menu' => 'topology-links'],
] as $path => $topology) {
Route::prefix("topology/{$path}")
->middleware("menu.resource:{$topology['menu']}")
->controller(TopologyController::class)
->group(function () use ($path, $topology) {
Route::get('/', 'index')->defaults('topology_resource', $topology['resource'])->name("topology.{$path}.index");
Route::post('/', 'store')->defaults('topology_resource', $topology['resource'])->name("topology.{$path}.store");
Route::get('/{id}', 'show')->defaults('topology_resource', $topology['resource'])->whereNumber('id')->name("topology.{$path}.show");
Route::put('/{id}', 'update')->defaults('topology_resource', $topology['resource'])->whereNumber('id')->name("topology.{$path}.update");
Route::patch('/{id}', 'update')->defaults('topology_resource', $topology['resource'])->whereNumber('id')->name("topology.{$path}.patch");
Route::delete('/{id}', 'destroy')->defaults('topology_resource', $topology['resource'])->whereNumber('id')->name("topology.{$path}.destroy");
});
}
Route::prefix('billing/profiles')
->middleware('menu.resource:billing-profiles')
->controller(BillingProfileController::class)
->group(function () {
Route::get('/', 'index')->name('billing.profiles.index');
Route::post('/', 'store')->name('billing.profiles.store');
Route::get('/{id}', 'show')->name('billing.profiles.show')->whereNumber('id');
Route::put('/{id}', 'update')->name('billing.profiles.update')->whereNumber('id');
Route::patch('/{id}', 'update')->name('billing.profiles.patch')->whereNumber('id');
Route::delete('/{id}', 'destroy')->name('billing.profiles.destroy')->whereNumber('id');
});
foreach ([
'running' => 'billing-running',
'overdue' => 'billing-overdue',
'paid' => 'billing-paid',
] as $scope => $menuSlug) {
Route::prefix("billing/invoices/{$scope}")
->middleware("menu.resource:{$menuSlug}")
->controller(InvoiceController::class)
->group(function () use ($scope) {
Route::get('/', 'index')->name("billing.invoices.{$scope}.index")->defaults('invoice_scope', $scope);
Route::get('/{id}', 'show')->name("billing.invoices.{$scope}.show")->whereNumber('id')->defaults('invoice_scope', $scope);
if ($scope !== 'paid') {
Route::post('/{id}/pay', 'pay')->name("billing.invoices.{$scope}.pay")->whereNumber('id');
}
});
}
Route::get('billing/invoice-options', [InvoiceController::class, 'options'])
->name('billing.invoices.options')
->middleware('menu.permission:billing-running,view');
Route::post('billing/invoices', [InvoiceController::class, 'store'])
->name('billing.invoices.store')
->middleware('menu.permission:billing-running,create');
Route::put('billing/invoices/{id}', [InvoiceController::class, 'update'])
->name('billing.invoices.update')->whereNumber('id')
->middleware('menu.permission:billing-running,update');
Route::patch('billing/invoices/{id}', [InvoiceController::class, 'update'])
->name('billing.invoices.patch')->whereNumber('id')
->middleware('menu.permission:billing-running,update');
Route::post('billing/invoices/{id}/cancel', [InvoiceController::class, 'cancel'])
->name('billing.invoices.cancel')->whereNumber('id')
->middleware('menu.permission:billing-running,delete');
Route::get('customers/options', [CustomerController::class, 'options'])
->name('customers.options')
->middleware('menu.permission:customers-orders,view');
foreach ([
'orders' => 'customers-orders',
'active' => 'customers-active',
'inactive' => 'customers-inactive',
'unmanaged' => 'customers-unmanaged',
'trash' => 'customers-trash',
] as $scope => $menuSlug) {
Route::get("customers/{$scope}", [CustomerController::class, 'index'])
->name("customers.{$scope}.index")
->defaults('customer_scope', $scope)
->middleware("menu.permission:{$menuSlug},view");
Route::get("customers/{$scope}/{id}", [CustomerController::class, 'show'])
->name("customers.{$scope}.show")
->whereNumber('id')
->defaults('customer_scope', $scope)
->middleware("menu.permission:{$menuSlug},view");
}
Route::post('customers', [CustomerController::class, 'store'])
->name('customers.store')
->middleware('menu.permission:customers-orders,create');
Route::put('customers/{id}', [CustomerController::class, 'update'])
->name('customers.update')
->whereNumber('id')
->middleware('menu.permission:customers-orders,update');
Route::patch('customers/{id}', [CustomerController::class, 'update'])
->name('customers.patch')
->whereNumber('id')
->middleware('menu.permission:customers-orders,update');
Route::post('customers/{id}/activate', [CustomerController::class, 'activate'])
->name('customers.activate')
->whereNumber('id')
->middleware('menu.permission:customers-orders,update');
Route::post('customers/{id}/deactivate', [CustomerController::class, 'deactivate'])
->name('customers.deactivate')
->whereNumber('id')
->middleware('menu.permission:customers-active,update');
Route::delete('customers/{id}', [CustomerController::class, 'destroy'])
->name('customers.destroy')
->whereNumber('id')
->middleware('menu.permission:customers-inactive,delete');
Route::post('customers/{id}/restore', [CustomerController::class, 'restore'])
->name('customers.restore')
->whereNumber('id')
->middleware('menu.permission:customers-trash,update');
Route::delete('customers/{id}/force', [CustomerController::class, 'forceDelete'])
->name('customers.force-delete')
->whereNumber('id')
->middleware('menu.permission:customers-trash,delete');
foreach ([
'mikrotiks' => ['resource' => 'mikrotik', 'menu' => 'nas-mikrotik'],
'package-profiles' => ['resource' => 'package-profile', 'menu' => 'nas-package-profiles'],
'olts' => ['resource' => 'olt', 'menu' => 'nas-olt'],
'webfig-devices' => ['resource' => 'webfig', 'menu' => 'nas-webfig'],
] as $path => $nas) {
Route::prefix("nas/{$path}")
->middleware("menu.resource:{$nas['menu']}")
->controller(NasResourceController::class)
->group(function () use ($nas, $path) {
Route::get('/', 'index')
->name("nas.{$path}.index")
->defaults('nas_resource', $nas['resource']);
Route::post('/', 'store')
->name("nas.{$path}.store")
->defaults('nas_resource', $nas['resource']);
Route::get('/{id}', 'show')
->name("nas.{$path}.show")
->whereNumber('id')
->defaults('nas_resource', $nas['resource']);
Route::put('/{id}', 'update')
->name("nas.{$path}.update")
->whereNumber('id')
->defaults('nas_resource', $nas['resource']);
Route::patch('/{id}', 'update')
->name("nas.{$path}.patch")
->whereNumber('id')
->defaults('nas_resource', $nas['resource']);
Route::delete('/{id}', 'destroy')
->name("nas.{$path}.destroy")
->whereNumber('id')
->defaults('nas_resource', $nas['resource']);
});
}
Route::apiResource('tickets', TicketController::class)
->middleware('menu.resource:ticketing-ticket');
Route::apiResource('ticket-types', TicketTypeController::class)
->middleware('menu.resource:ticketing-ticket-types');
Route::apiResource('ticket-incident-types', TicketIncidentTypeController::class)
->middleware('menu.resource:ticketing-ticket-incidents');
Route::prefix('tickets/{ticket}')
->controller(TicketWorkflowController::class)
->group(function () {
Route::get('/workflow', 'history')
->middleware('menu.permission:ticketing-ticket,view');
Route::post('/assign', 'assign')
->middleware('menu.permission:ticketing-ticket,update');
Route::post('/reassign', 'reassign')
->middleware('menu.permission:ticketing-ticket,update');
Route::post('/approve', 'approve')
->middleware('menu.permission:ticketing-approval,approve');
Route::post('/reject', 'reject')
->middleware('menu.permission:ticketing-approval,approve');
Route::post('/start', 'start')
->middleware('menu.permission:ticketing-ticket,update');
Route::post('/pending', 'pending')
->middleware('menu.permission:ticketing-ticket,update');
Route::post('/resume', 'resume')
->middleware('menu.permission:ticketing-ticket,update');
Route::post('/resolve', 'resolve')
->middleware('menu.permission:ticketing-ticket,update');
Route::post('/close', 'close')
->middleware('menu.permission:ticketing-ticket,update');
Route::post('/cancel', 'cancel')
->middleware('menu.permission:ticketing-ticket,delete');
Route::post('/escalate', 'escalate')
->middleware('menu.permission:ticketing-ticket,update');
});
Route::prefix('materials')
->middleware('menu.resource:ticketing-material')
->controller(MaterialController::class)
->group(function () {
Route::get('/', 'index');
Route::post('/assign', 'assign');
Route::post('/transfer', 'transfer');
Route::post('/return', 'return');
Route::get('/user/{user_id}', 'listByUser');
Route::get('/history/{barcode_id}', 'history');
});
Route::prefix('audit-logs')
->middleware('access.level:tenant_owner')
->controller(AuditLogController::class)
->group(function () {
Route::get('/', 'index');
Route::get('/{id}', 'show');
});
Route::prefix('me')
->group(function () {
Route::get('/menus', [MenuController::class, 'myMenus']);
Route::get('/profile', [ProfileController::class, 'show']);
Route::put('/profile', [ProfileController::class, 'update']);
});
Route::prefix('files')->controller(StoredFileController::class)->group(function () {
Route::get('/', 'index');
Route::post('/', 'store');
Route::get('/{storedFile}', 'show');
Route::get('/{storedFile}/temporary-url', 'temporaryUrl');
Route::delete('/{storedFile}', 'destroy');
});
Route::get('wilayah/alamat-lengkap', [WilayahController::class, 'alamatLengkap'])
->name('wilayah.alamat-lengkap');
Route::prefix('wilayah/options')->controller(WilayahController::class)->group(function () {
Route::get('/provinsi', 'provinsiOptions')->name('wilayah.options.provinsi');
Route::get('/kabupaten/{provinsi}', 'kabupatenOptions')->name('wilayah.options.kabupaten');
Route::get('/kecamatan/{kabupaten}', 'kecamatanOptions')->name('wilayah.options.kecamatan');
Route::get('/desa/{kecamatan}', 'desaOptions')->name('wilayah.options.desa');
});
foreach ([
'desa' => 'wilayah-desa',
'kecamatan' => 'wilayah-kecamatan',
'kabupaten' => 'wilayah-kabupaten',
'provinsi' => 'wilayah-provinsi',
] as $tingkat => $menuSlug) {
$readRoutes = [
Route::get("wilayah/{$tingkat}", [WilayahController::class, 'index'])
->name("wilayah.{$tingkat}.index"),
Route::get("wilayah/{$tingkat}/{wilayah}", [WilayahController::class, 'show'])
->name("wilayah.{$tingkat}.show")
->whereNumber('wilayah'),
];
$writeRoutes = [
Route::post("wilayah/{$tingkat}", [WilayahController::class, 'store'])
->name("wilayah.{$tingkat}.store"),
Route::put("wilayah/{$tingkat}/{wilayah}", [WilayahController::class, 'update'])
->name("wilayah.{$tingkat}.update")
->whereNumber('wilayah'),
Route::patch("wilayah/{$tingkat}/{wilayah}", [WilayahController::class, 'update'])
->name("wilayah.{$tingkat}.patch")
->whereNumber('wilayah'),
Route::delete("wilayah/{$tingkat}/{wilayah}", [WilayahController::class, 'destroy'])
->name("wilayah.{$tingkat}.destroy")
->whereNumber('wilayah'),
];
foreach ($readRoutes as $wilayahRoute) {
$wilayahRoute->defaults('tingkat', $tingkat);
}
foreach ($writeRoutes as $wilayahRoute) {
$wilayahRoute->defaults('tingkat', $tingkat)
->middleware("menu.resource:{$menuSlug}");
}
}
Route::apiResource('menus', MenuListController::class)
->parameters(['menus' => 'menu_list'])
->middleware('access.level:master_admin');
Route::apiResource('menu-groups', MenuGroupController::class)
->middleware([
'access.level:tenant_owner',
'menu.resource:users-group-menus',
]);
Route::apiResource('tenants', TenantController::class)
->only(['index', 'show'])
->middleware('access.level:tenant_owner');
Route::apiResource('tenants', TenantController::class)
->except(['index', 'show'])
->middleware('access.level:master_admin');
Route::apiResource('users', UserController::class)
->middleware([
'access.level:tenant_owner',
'menu.resource:users-user',
]);
Route::prefix('menu-groups/{menu_group}')
->middleware([
'access.level:tenant_owner',
'menu.permission:users-group-menus,update',
])
->controller(MenuGroupController::class)
->group(function () {
Route::get('/menus', 'menus');
Route::get('/available-menus', 'availableMenus');
Route::put('/menus', 'syncMenus');
});
Route::prefix('users/{user}')
->middleware([
'access.level:tenant_owner',
'menu.permission:users-group-menus,update',
])
->controller(MenuGroupController::class)
->group(function () {
Route::get('/menu-groups', 'userAssignments');
Route::put('/menu-groups', 'syncUserAssignments');
});
});