update api register

This commit is contained in:
Wian Drs
2026-08-01 11:42:42 +07:00
parent b0d08211ec
commit 75342dc7b7
55 changed files with 2254 additions and 35 deletions
@@ -0,0 +1,65 @@
<?php
namespace App\Http\Controllers\Access;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Access\ReviewRoleApplicationRequest;
use App\Http\Requests\Access\StoreRoleApplicationRequest;
use App\Models\RoleApplication;
use App\Services\Access\RoleApplicationService;
use Illuminate\Http\Request;
class RoleApplicationController extends ApiController
{
public function __construct(protected RoleApplicationService $service) {}
public function mine(Request $request)
{
return $this->success($this->service->mine($request->user()), 'Daftar pengajuan berhasil diambil');
}
public function store(StoreRoleApplicationRequest $request)
{
return $this->created($this->service->submit($request->validated(), $request->user()), 'Pengajuan berhasil dikirim');
}
public function reviewList(Request $request, string $type)
{
$filters = $request->validate(['search' => ['nullable', 'string', 'max:100'], 'status' => ['nullable', 'in:pending,approved,rejected'], 'per_page' => ['nullable', 'integer', 'min:1', 'max:100']]);
return $this->success($this->service->reviewList($type, $filters, $request->user(), $this->tenantId($request)), 'Daftar pengajuan berhasil diambil');
}
public function tenantMenuGroupOptions(Request $request)
{
return $this->success(
$this->service->tenantMenuGroupOptions($request->user()),
'Pilihan Group Menu tenant berhasil diambil'
);
}
public function staffMenuGroupOptions(Request $request)
{
return $this->success(
$this->service->staffMenuGroupOptions($request->user(), $this->tenantId($request)),
'Pilihan Group Menu staff berhasil diambil'
);
}
public function review(ReviewRoleApplicationRequest $request, RoleApplication $application)
{
return $this->updated($this->service->review($application, $request->validated(), $request->user(), $this->tenantId($request)), 'Pengajuan berhasil ditinjau');
}
public function linkCustomer(Request $request)
{
$data = $request->validate(['customer_id' => ['required', 'integer', 'exists:customers,id'], 'user_id' => ['required', 'integer', 'exists:users,id'], 'relationship' => ['nullable', 'in:owner,family,staff'], 'is_primary' => ['nullable', 'boolean']]);
return $this->created($this->service->linkCustomer($data, $request->user(), (int) $this->tenantId($request)), 'User berhasil dihubungkan dengan customer');
}
private function tenantId(Request $request): ?int
{
return $request->attributes->get('tenant_id');
}
}
+27 -1
View File
@@ -13,14 +13,16 @@ class MenuController extends ApiController
{
$user = auth()->user();
$tenantId = request()->attributes->get('tenant_id');
$tenantRole = $user?->tenantRole($tenantId);
if (! $user) {
return $this->error('Unauthenticated', 401);
}
if ($user->isMasterAdmin()) {
if ($user->isMasterAdmin() || $user->is_platform_staff) {
$menus = MenuList::query()
->where('is_active', true)
->when($user->is_platform_staff && ! $user->isMasterAdmin(), fn ($q) => $q->whereIn('slug', ['role-applications', 'role-applications-tenants']))
->orderBy('sort_order')
->orderBy('id')
->get()
@@ -108,10 +110,22 @@ class MenuController extends ApiController
$tree = $this->buildMenuTree($menus);
if (! $user->isMasterAdmin() && ! $user->is_platform_staff && ! in_array($tenantRole, ['staff', 'tenant_owner'], true)) {
$restrictedSlugs = ['voucher-hotspot-agents', 'voucher-hotspot-login-page'];
$tree = $this->removeRestrictedMenus($tree, $restrictedSlugs);
}
if (! $user->isMasterAdmin() && ! $user->is_platform_staff) {
$tree = $this->removeRestrictedMenus($tree, ['role-applications-tenants']);
}
if (! $user->isTenantOwner($tenantId)) {
$tree = $this->removeRestrictedMenus($tree, ['role-applications-staff']);
}
return $this->success(
[
'is_master' => (bool) $user->is_master,
'access_level' => $user->access_level->value,
'tenant_role' => $tenantRole,
'tenant_id' => $tenantId,
'menus' => $tree,
],
@@ -143,4 +157,16 @@ class MenuController extends ApiController
})
->all();
}
private function removeRestrictedMenus(array $menus, array $restrictedSlugs): array
{
return collect($menus)
->reject(fn ($menu) => in_array($menu['slug'], $restrictedSlugs, true))
->map(function ($menu) use ($restrictedSlugs) {
$menu['children'] = $this->removeRestrictedMenus($menu['children'] ?? [], $restrictedSlugs);
return $menu;
})
->values()->all();
}
}
@@ -9,7 +9,9 @@ use App\Http\Requests\Notification\StoreCustomerContactRequest;
use App\Http\Requests\Notification\StoreNotificationBroadcastRequest;
use App\Http\Requests\Notification\StoreNotificationChannelRequest;
use App\Http\Requests\Notification\StoreNotificationTemplateRequest;
use App\Http\Requests\Notification\StoreSystemNotificationRequest;
use App\Http\Resources\Notification\NotificationDeliveryResource;
use App\Http\Resources\Notification\SystemNotificationCampaignResource;
use App\Models\Customer;
use App\Models\CustomerContact;
use App\Models\NotificationBroadcast;
@@ -17,11 +19,12 @@ use App\Models\NotificationChannel;
use App\Models\NotificationEvent;
use App\Models\NotificationTemplate;
use App\Services\Notification\NotificationService;
use App\Services\Notification\WhapiIdService;
use Illuminate\Http\Request;
class NotificationController extends ApiController
{
public function __construct(protected NotificationService $service) {}
public function __construct(protected NotificationService $service, protected WhapiIdService $whapi) {}
public function events()
{
@@ -33,9 +36,42 @@ class NotificationController extends ApiController
return $this->success($this->service->channels($this->channel($request), $request->user(), $this->tenantId($request)), 'Konfigurasi channel berhasil diambil');
}
public function systemCampaigns(IndexNotificationRequest $request)
{
return $this->successPaginated(
$this->service->systemCampaigns($request->validated(), $request->user(), $this->tenantId($request)),
SystemNotificationCampaignResource::class,
'Riwayat notifikasi System berhasil diambil'
);
}
public function storeSystemCampaign(StoreSystemNotificationRequest $request)
{
return $this->created(
$this->service->createSystemCampaign($request->validated(), $request->user(), $this->tenantId($request)),
'Notifikasi System masuk antrean'
);
}
public function systemAudienceOptions(Request $request)
{
$data = $request->validate([
'tenant_id' => ['nullable', 'integer', 'exists:tenants,id'],
'search' => ['nullable', 'string', 'max:100'],
]);
return $this->success(
$this->service->systemAudienceOptions(
$request->user(), $this->tenantId($request), $data['tenant_id'] ?? null, $data['search'] ?? null
),
'Pilihan penerima notifikasi berhasil diambil'
);
}
public function storeChannel(StoreNotificationChannelRequest $request)
{
abort_unless($request->validated('channel') === $this->channel($request), 422);
$this->authorizeChannelMutation($request);
return $this->created($this->service->saveChannel($request->validated(), $request->user(), $this->tenantId($request)), 'Konfigurasi channel berhasil dibuat');
}
@@ -44,6 +80,7 @@ class NotificationController extends ApiController
{
$this->authorizeTenant($request, $notificationChannel->tenant_id);
abort_unless($notificationChannel->channel === $this->channel($request), 404);
$this->authorizeChannelMutation($request);
return $this->updated($this->service->saveChannel($request->validated(), $request->user(), $this->tenantId($request), $notificationChannel), 'Konfigurasi channel berhasil diperbarui');
}
@@ -52,10 +89,56 @@ class NotificationController extends ApiController
{
$this->authorizeTenant($request, $notificationChannel->tenant_id);
abort_unless($notificationChannel->channel === $this->channel($request), 404);
$this->authorizeChannelMutation($request);
return $this->success($this->service->testChannel($notificationChannel), 'Pengujian channel selesai');
}
public function destroyChannel(Request $request, NotificationChannel $notificationChannel)
{
$this->authorizeTenant($request, $notificationChannel->tenant_id);
abort_unless($notificationChannel->channel === $this->channel($request), 404);
$this->authorizeChannelMutation($request);
$this->service->deleteChannel($notificationChannel);
return $this->deleted('Konfigurasi channel berhasil dinonaktifkan atau dihapus');
}
public function whapiState(Request $request, NotificationChannel $notificationChannel)
{
$this->authorizeWhapiAccess($request, $notificationChannel);
return $this->success($this->whapi->state($notificationChannel), 'Status perangkat WHAPI berhasil diambil');
}
public function whapiStart(Request $request, NotificationChannel $notificationChannel)
{
$this->authorizeWhapiAccess($request, $notificationChannel);
return $this->success($this->whapi->start($notificationChannel), 'Layanan WHAPI berhasil dijalankan');
}
public function whapiQr(Request $request, NotificationChannel $notificationChannel)
{
$this->authorizeWhapiAccess($request, $notificationChannel);
return $this->success($this->whapi->qr($notificationChannel), 'QR WHAPI berhasil diambil');
}
public function whapiTestMessage(Request $request, NotificationChannel $notificationChannel)
{
$this->authorizeWhapiAccess($request, $notificationChannel);
$data = $request->validate([
'phone' => ['required', 'string', 'max:25', 'regex:/^\+?[0-9][0-9\s\-()]{7,24}$/'],
'message' => ['required', 'string', 'max:4000'],
]);
return $this->success(
$this->whapi->send($notificationChannel, $data['phone'], $data['message']),
'Pesan uji WHAPI berhasil dikirim'
);
}
public function templates(Request $request)
{
return $this->success($this->service->templates($this->channel($request), $request->user(), $this->tenantId($request)), 'Daftar template berhasil diambil');
@@ -185,8 +268,24 @@ class NotificationController extends ApiController
return $request->attributes->get('tenant_id');
}
private function authorizeTenant(Request $request, int $tenantId): void
private function authorizeTenant(Request $request, ?int $tenantId): void
{
abort_unless($request->user()->isMasterAdmin() || $tenantId === $this->tenantId($request), 403);
abort_unless($request->user()->isMasterAdmin()
|| ($tenantId !== null && $tenantId === $this->tenantId($request)), 403);
}
private function authorizeChannelMutation(Request $request): void
{
if ($this->channel($request) === 'whatsapp_unofficial') {
abort_unless($request->user()->isMasterAdmin(), 403, 'WhatsApp Unofficial hanya dapat dikonfigurasi oleh Master Admin.');
}
}
private function authorizeWhapiAccess(Request $request, NotificationChannel $channel): void
{
abort_unless($channel->channel === 'whatsapp_unofficial' && $channel->provider === 'whapi_id', 404);
abort_unless($request->user()->isMasterAdmin()
|| ((int) $channel->tenant_id === (int) $this->tenantId($request)
&& $request->user()->isTenantOwner($this->tenantId($request))), 403);
}
}
@@ -0,0 +1,77 @@
<?php
namespace App\Http\Controllers\Voucher;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Voucher\IndexVoucherRequest;
use App\Http\Requests\Voucher\SaveVoucherLoginPageRequest;
use App\Http\Requests\Voucher\StoreVoucherAgentRequest;
use App\Http\Requests\Voucher\StoreVoucherSaleRequest;
use App\Http\Resources\Voucher\VoucherAgentResource;
use App\Http\Resources\Voucher\VoucherSaleResource;
use App\Models\VoucherAgent;
use App\Models\VoucherSale;
use App\Services\Voucher\VoucherService;
use Illuminate\Http\Request;
class VoucherController extends ApiController
{
public function __construct(protected VoucherService $service) {}
public function sales(IndexVoucherRequest $request)
{
return $this->successPaginated($this->service->sales($request->validated(), $request->user(), $this->tenantId($request)), VoucherSaleResource::class, 'Daftar penjualan voucher berhasil diambil');
}
public function storeSale(StoreVoucherSaleRequest $request)
{
return $this->created(new VoucherSaleResource($this->service->createSale($request->validated(), $request->user(), $this->tenantId($request))), 'Voucher berhasil dibuat');
}
public function showSale(Request $request, VoucherSale $sale)
{
return $this->success(new VoucherSaleResource($this->service->saleDetail($sale, $request->user(), $this->tenantId($request))), 'Detail voucher berhasil diambil');
}
public function agents(IndexVoucherRequest $request)
{
return $this->successPaginated($this->service->agents($request->validated(), $request->user(), $this->tenantId($request)), VoucherAgentResource::class, 'Daftar agen voucher berhasil diambil');
}
public function storeAgent(StoreVoucherAgentRequest $request)
{
return $this->created(new VoucherAgentResource($this->service->saveAgent($request->validated(), $request->user(), $this->tenantId($request))), 'Agen voucher berhasil dibuat');
}
public function updateAgent(StoreVoucherAgentRequest $request, VoucherAgent $agent)
{
return $this->updated(new VoucherAgentResource($this->service->saveAgent($request->validated(), $request->user(), $this->tenantId($request), $agent)), 'Agen voucher berhasil diperbarui');
}
public function destroyAgent(Request $request, VoucherAgent $agent)
{
$this->service->saveAgent([...$agent->toArray(), 'status' => 'inactive'], $request->user(), $this->tenantId($request), $agent);
return $this->deleted('Agen voucher berhasil dinonaktifkan');
}
public function options(Request $request)
{
return $this->success($this->service->options((string) $request->route('voucher_scope'), $request->user(), $this->tenantId($request)), 'Opsi voucher berhasil diambil');
}
public function loginPage(Request $request)
{
return $this->success($this->service->loginPage($request->user(), $this->tenantId($request)), 'Setting LoginPage berhasil diambil');
}
public function saveLoginPage(SaveVoucherLoginPageRequest $request)
{
return $this->updated($this->service->saveLoginPage($request->validated(), $request->user(), $this->tenantId($request)), 'Setting LoginPage berhasil disimpan');
}
private function tenantId(Request $request): ?int
{
return $request->attributes->get('tenant_id');
}
}