diff --git a/app/Console/Commands/Cloud/RestoreDatabase.php b/app/Console/Commands/Cloud/RestoreDatabase.php
new file mode 100644
index 000000000..6c60d1c6c
--- /dev/null
+++ b/app/Console/Commands/Cloud/RestoreDatabase.php
@@ -0,0 +1,219 @@
+debug = $this->option('debug');
+
+ if (! $this->isDevelopment()) {
+ $this->error('This command can only be run in development mode.');
+
+ return 1;
+ }
+
+ $filePath = $this->argument('file');
+
+ if (! file_exists($filePath)) {
+ $this->error("File not found: {$filePath}");
+
+ return 1;
+ }
+
+ if (! is_readable($filePath)) {
+ $this->error("File is not readable: {$filePath}");
+
+ return 1;
+ }
+
+ try {
+ $this->info('Starting database restoration...');
+
+ $database = config('database.connections.pgsql.database');
+ $host = config('database.connections.pgsql.host');
+ $port = config('database.connections.pgsql.port');
+ $username = config('database.connections.pgsql.username');
+ $password = config('database.connections.pgsql.password');
+
+ if (! $database || ! $username) {
+ $this->error('Database configuration is incomplete.');
+
+ return 1;
+ }
+
+ $this->info("Restoring to database: {$database}");
+
+ // Drop all tables
+ if (! $this->dropAllTables($database, $host, $port, $username, $password)) {
+ return 1;
+ }
+
+ // Restore the database dump
+ if (! $this->restoreDatabaseDump($filePath, $database, $host, $port, $username, $password)) {
+ return 1;
+ }
+
+ $this->info('Database restoration completed successfully!');
+
+ return 0;
+ } catch (\Exception $e) {
+ $this->error("An error occurred: {$e->getMessage()}");
+
+ return 1;
+ }
+ }
+
+ private function dropAllTables(string $database, string $host, string $port, string $username, string $password): bool
+ {
+ $this->info('Dropping all tables...');
+
+ // SQL to drop all tables
+ $dropTablesSQL = <<<'SQL'
+ DO $$ DECLARE
+ r RECORD;
+ BEGIN
+ FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = 'public') LOOP
+ EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
+ END LOOP;
+ END $$;
+ SQL;
+
+ // Build the psql command to drop all tables
+ $command = sprintf(
+ 'PGPASSWORD=%s psql -h %s -p %s -U %s -d %s -c %s',
+ escapeshellarg($password),
+ escapeshellarg($host),
+ escapeshellarg($port),
+ escapeshellarg($username),
+ escapeshellarg($database),
+ escapeshellarg($dropTablesSQL)
+ );
+
+ if ($this->debug) {
+ $this->line('Executing drop command:');
+ $this->line($command);
+ }
+
+ $output = shell_exec($command.' 2>&1');
+
+ if ($this->debug) {
+ $this->line("Output: {$output}");
+ }
+
+ $this->info('All tables dropped successfully.');
+
+ return true;
+ }
+
+ private function restoreDatabaseDump(string $filePath, string $database, string $host, string $port, string $username, string $password): bool
+ {
+ $this->info('Restoring database from dump file...');
+
+ // Handle gzipped files by decompressing first
+ $actualFile = $filePath;
+ if (str_ends_with($filePath, '.gz')) {
+ $actualFile = rtrim($filePath, '.gz');
+ $this->info('Decompressing gzipped dump file...');
+
+ $decompressCommand = sprintf(
+ 'gunzip -c %s > %s',
+ escapeshellarg($filePath),
+ escapeshellarg($actualFile)
+ );
+
+ if ($this->debug) {
+ $this->line('Executing decompress command:');
+ $this->line($decompressCommand);
+ }
+
+ $decompressOutput = shell_exec($decompressCommand.' 2>&1');
+ if ($this->debug && $decompressOutput) {
+ $this->line("Decompress output: {$decompressOutput}");
+ }
+ }
+
+ // Use pg_restore for custom format dumps
+ $command = sprintf(
+ 'PGPASSWORD=%s pg_restore -h %s -p %s -U %s -d %s -v %s',
+ escapeshellarg($password),
+ escapeshellarg($host),
+ escapeshellarg($port),
+ escapeshellarg($username),
+ escapeshellarg($database),
+ escapeshellarg($actualFile)
+ );
+
+ if ($this->debug) {
+ $this->line('Executing restore command:');
+ $this->line($command);
+ }
+
+ // Execute the restore command
+ $process = proc_open(
+ $command,
+ [
+ 1 => ['pipe', 'w'],
+ 2 => ['pipe', 'w'],
+ ],
+ $pipes
+ );
+
+ if (! is_resource($process)) {
+ $this->error('Failed to start restoration process.');
+
+ return false;
+ }
+
+ $output = stream_get_contents($pipes[1]);
+ $error = stream_get_contents($pipes[2]);
+ $exitCode = proc_close($process);
+
+ // Clean up decompressed file if we created one
+ if ($actualFile !== $filePath && file_exists($actualFile)) {
+ unlink($actualFile);
+ }
+
+ if ($this->debug) {
+ if ($output) {
+ $this->line('Output:');
+ $this->line($output);
+ }
+ if ($error) {
+ $this->line('Error output:');
+ $this->line($error);
+ }
+ $this->line("Exit code: {$exitCode}");
+ }
+
+ if ($exitCode !== 0) {
+ $this->error("Restoration failed with exit code: {$exitCode}");
+ if ($error) {
+ $this->error('Error details:');
+ $this->error($error);
+ }
+
+ return false;
+ }
+
+ if ($output && ! $this->debug) {
+ $this->line($output);
+ }
+
+ return true;
+ }
+
+ private function isDevelopment(): bool
+ {
+ return app()->environment(['local', 'development', 'dev']);
+ }
+}