'success', 'message' => $message, 'data' => $data]); exit; } function sendError(string $message = 'Bad Request', int $code = 400): void { http_response_code($code); echo json_encode(['status' => 'error', 'message' => $message, 'data' => null]); exit; } function getInput(): array { return json_decode(file_get_contents('php://input'), true) ?? []; } function requireApiRole(string $role): void { requireApiAnyRole([$role]); } function requireApiAnyRole(array $roles): void { if (session_status() === PHP_SESSION_NONE) { startAppSession(); } if (!isset($_SESSION['user_id'], $_SESSION['role'])) { sendError('Unauthorized', 401); } if (!in_array($_SESSION['role'], $roles, true)) { sendError('Forbidden', 403); } } /** * Mutasi data (POST/PUT/DELETE) hanya untuk Operator. * GET tetap terbuka sesuai kebutuhan endpoint. */ function requireOperatorForMutation(): void { if ($_SERVER['REQUEST_METHOD'] !== 'GET') { requireApiAnyRole(['operator']); } } /** * Alias kompatibilitas lama. */ function requireAdminForMutation(): void { requireOperatorForMutation(); }