# import-data.ps1 # Restores a database dump and .env config files from data_backup\\ # # Prerequisites on the new PC before running this script: # 1. Copy the project folder (or clone from git) # 2. Copy the data_backup\\ folder into the project root # 3. Start Postgres: cd infrastructure && docker compose up -d postgres redis # 4. Run this script: .\import-data.ps1 # 5. After import: cd backend && npm install && npm run start:dev # cd frontend && npm install && npm run dev $ErrorActionPreference = "Stop" $ProjectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path $BackupRoot = Join-Path $ProjectRoot "data_backup" Write-Host "" Write-Host "=== StudioFlow Data Import ===" -ForegroundColor Cyan Write-Host "" # --- Pick a backup ------------------------------------------------------------ if (-not (Test-Path $BackupRoot)) { Write-Error "No data_backup folder found. Copy it from the source PC first." } $Backups = Get-ChildItem $BackupRoot -Directory | Sort-Object Name -Descending if ($Backups.Count -eq 0) { Write-Error "data_backup folder is empty. Nothing to import." } Write-Host "Available backups:" for ($i = 0; $i -lt $Backups.Count; $i++) { $ManifestPath = Join-Path $Backups[$i].FullName "manifest.json" $Extra = "" if (Test-Path $ManifestPath) { $M = Get-Content $ManifestPath -Raw | ConvertFrom-Json $Extra = " (from $($M.machine), db: $($M.database.name))" } Write-Host " [$i] $($Backups[$i].Name)$Extra" } Write-Host "" $Choice = Read-Host "Enter number to restore (press Enter for 0 = most recent)" if ($Choice -eq "" -or $null -eq $Choice) { $Choice = 0 } $BackupDir = $Backups[[int]$Choice].FullName Write-Host "Restoring from: $BackupDir" Write-Host "" # --- Read manifest + credentials ---------------------------------------------- $ManifestFile = Join-Path $BackupDir "manifest.json" if (-not (Test-Path $ManifestFile)) { Write-Error "manifest.json missing from backup." } $Manifest = Get-Content $ManifestFile -Raw | ConvertFrom-Json $DbName = $Manifest.database.name $DbUser = $Manifest.database.user $DbHost = $Manifest.database.host $DbPort = $Manifest.database.port $BackupEnvFile = Join-Path $BackupDir "backend.env" if (-not (Test-Path $BackupEnvFile)) { Write-Error "backend.env missing from backup." } $DbUrl = (Get-Content $BackupEnvFile | Where-Object { $_ -match "^DATABASE_URL=" }) -replace "^DATABASE_URL=","" if ($DbUrl -match "postgresql://([^:]+):([^@]+)@") { $DbPassword = $Matches[2] } else { Write-Error "Could not parse DATABASE_URL from backup backend.env" } Write-Host "Database : $DbName on ${DbHost}:${DbPort} as $DbUser" $DumpFile = Join-Path $BackupDir "database.dump" if (-not (Test-Path $DumpFile)) { Write-Error "database.dump missing from backup." } # --- Detect running Postgres (Docker first, then local) ----------------------- $PgContainer = $null if (Get-Command docker -ErrorAction SilentlyContinue) { $Running = docker ps --format "{{.Names}}" 2>$null if ($Running) { $PgContainer = $Running | Where-Object { $_ -match "postgres" } | Select-Object -First 1 } if (-not $PgContainer) { $ByImage = docker ps --format "{{.Names}}|||{{.Image}}" 2>$null | Where-Object { $_ -match "postgres" } | ForEach-Object { ($_ -split "\|\|\|")[0] } | Select-Object -First 1 $PgContainer = $ByImage } } # --- Restore database --------------------------------------------------------- if ($PgContainer) { Write-Host "Using Docker container : $PgContainer" Write-Host "Copying dump into container..." docker cp $DumpFile "${PgContainer}:/tmp/studioflow_restore.dump" Write-Host "Terminating existing connections..." docker exec $PgContainer psql -U $DbUser -d postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$DbName';" | Out-Null Write-Host "Dropping and recreating database..." docker exec $PgContainer psql -U $DbUser -d postgres -c "DROP DATABASE IF EXISTS $DbName;" | Out-Null docker exec $PgContainer psql -U $DbUser -d postgres -c "CREATE DATABASE $DbName OWNER $DbUser;" | Out-Null Write-Host "Restoring data (this may take a moment)..." docker exec $PgContainer pg_restore -U $DbUser -d $DbName --no-owner --no-privileges /tmp/studioflow_restore.dump if ($LASTEXITCODE -ne 0) { Write-Error "pg_restore inside Docker failed." } docker exec $PgContainer rm /tmp/studioflow_restore.dump Write-Host "Database restored via Docker." -ForegroundColor Green } else { Write-Host "No running Docker postgres found -- using local pg_restore" $env:PGPASSWORD = $DbPassword Write-Host "Terminating existing connections..." psql -h $DbHost -p $DbPort -U $DbUser -d postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$DbName';" | Out-Null Write-Host "Dropping and recreating database..." psql -h $DbHost -p $DbPort -U $DbUser -d postgres -c "DROP DATABASE IF EXISTS $DbName;" | Out-Null psql -h $DbHost -p $DbPort -U $DbUser -d postgres -c "CREATE DATABASE $DbName OWNER $DbUser;" | Out-Null Write-Host "Restoring data (this may take a moment)..." pg_restore -h $DbHost -p $DbPort -U $DbUser -d $DbName --no-owner --no-privileges $DumpFile if ($LASTEXITCODE -ne 0) { Write-Error "pg_restore failed." } Remove-Item Env:\PGPASSWORD -ErrorAction SilentlyContinue Write-Host "Database restored via local pg_restore." -ForegroundColor Green } # --- Restore .env files ------------------------------------------------------- Write-Host "" Write-Host "Restoring config files..." $EnvFiles = @( @{ Src = "backend.env"; Dst = "backend\.env" } @{ Src = "frontend.env.local"; Dst = "frontend\.env.local" } @{ Src = "infrastructure.env"; Dst = "infrastructure\.env" } ) foreach ($f in $EnvFiles) { $Src = Join-Path $BackupDir $f.Src $Dst = Join-Path $ProjectRoot $f.Dst if (Test-Path $Src) { $DstDir = Split-Path $Dst -Parent if (-not (Test-Path $DstDir)) { New-Item -ItemType Directory -Path $DstDir -Force | Out-Null } Copy-Item $Src $Dst -Force Write-Host " Restored $($f.Dst)" -ForegroundColor Green } else { Write-Host " Skipped $($f.Dst) (not in backup)" -ForegroundColor Yellow } } # --- Done --------------------------------------------------------------------- Write-Host "" Write-Host "Import complete!" -ForegroundColor Cyan Write-Host "" Write-Host "Next steps:" Write-Host " cd backend && npm install && npm run start:dev" Write-Host " (second terminal) cd backend && npx ts-node src/worker.ts" Write-Host " cd frontend && npm install && npm run dev" Write-Host ""