$label, 'path' => $path, 'exists' => is_dir($path), 'writable' => is_writable($path), ]; } /** * Health check endpoint - checks filesystem paths and database schema */ public function index() { try { // Use storage_path('app') as the base (equivalent to WRITEPATH in CodeIgniter) $uploadsBase = storage_path('app') . DIRECTORY_SEPARATOR . 'uploads'; $paths = [ 'uploads' => $uploadsBase, 'uploads/reimbursements' => $uploadsBase . DIRECTORY_SEPARATOR . 'reimbursements', 'uploads/receipts' => $uploadsBase . DIRECTORY_SEPARATOR . 'receipts', 'uploads/checks' => $uploadsBase . DIRECTORY_SEPARATOR . 'checks', ]; $pathsStatus = []; foreach ($paths as $label => $p) { $pathsStatus[] = $this->checkPath($label, $p); } // Use Laravel's schema builder to check tables and columns $schema = DB::getSchemaBuilder(); $dbChecks = [ 'user_preferences_exists' => $schema->hasTable('user_preferences'), 'settings_exists' => $schema->hasTable('settings'), 'migrations_exists' => $schema->hasTable('migrations'), ]; $dbChecks['user_preferences_has_timezone'] = $dbChecks['user_preferences_exists'] ? $schema->hasColumn('user_preferences', 'timezone') : false; $dbChecks['settings_has_timezone'] = $dbChecks['settings_exists'] ? $schema->hasColumn('settings', 'timezone') : false; // Check if all paths are OK $okPaths = array_reduce($pathsStatus, function ($carry, $row) { return $carry && $row['exists'] && $row['writable']; }, true); // Check if database schema is OK $okDb = true; if ($dbChecks['user_preferences_exists'] && !$dbChecks['user_preferences_has_timezone']) { $okDb = false; } if ($dbChecks['settings_exists'] && !$dbChecks['settings_has_timezone']) { $okDb = false; } $ok = $okPaths && $okDb; $payload = [ 'ok' => $ok, 'paths' => $pathsStatus, 'database' => $dbChecks, 'write_path' => storage_path('app'), 'timestamp' => date('c'), ]; $status = $ok ? Response::HTTP_OK : Response::HTTP_SERVICE_UNAVAILABLE; // Return JSON response with appropriate status code return response()->json($payload, $status); } catch (\Throwable $e) { log_message('error', 'Health check error: ' . $e->getMessage()); return $this->error('Health check failed', Response::HTTP_INTERNAL_SERVER_ERROR); } } }