Initial commit: YouTube Studio Flow (backend, frontend, infrastructure, docs)
This commit is contained in:
+113
@@ -0,0 +1,113 @@
|
||||
# export-data.ps1
|
||||
# Exports the PostgreSQL database and all .env config files into data_backup\<timestamp>\
|
||||
# Run from the project root: .\export-data.ps1
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ProjectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
|
||||
# --- Create backup directory --------------------------------------------------
|
||||
$Timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
|
||||
$BackupDir = Join-Path $ProjectRoot "data_backup\$Timestamp"
|
||||
New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== StudioFlow Data Export ===" -ForegroundColor Cyan
|
||||
Write-Host "Backup dir : $BackupDir"
|
||||
Write-Host ""
|
||||
|
||||
# --- Parse DATABASE_URL from backend/.env -------------------------------------
|
||||
$EnvFile = Join-Path $ProjectRoot "backend\.env"
|
||||
if (-not (Test-Path $EnvFile)) {
|
||||
Write-Error "backend\.env not found. Run this script from the project root."
|
||||
}
|
||||
|
||||
$DbUrl = (Get-Content $EnvFile | Where-Object { $_ -match "^DATABASE_URL=" }) -replace "^DATABASE_URL=",""
|
||||
if (-not $DbUrl) { Write-Error "DATABASE_URL not found in backend\.env" }
|
||||
|
||||
if ($DbUrl -match "postgresql://([^:]+):([^@]+)@([^:/]+):?(\d*)/([^?]+)") {
|
||||
$DbUser = $Matches[1]
|
||||
$DbPassword = $Matches[2]
|
||||
$DbHost = $Matches[3]
|
||||
$DbPort = if ($Matches[4] -ne "") { $Matches[4] } else { "5432" }
|
||||
$DbName = $Matches[5]
|
||||
} else {
|
||||
Write-Error "Could not parse DATABASE_URL: $DbUrl"
|
||||
}
|
||||
|
||||
Write-Host "Database : $DbName on ${DbHost}:${DbPort} as $DbUser"
|
||||
|
||||
# --- 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) {
|
||||
# Also check by image name
|
||||
$ByImage = docker ps --format "{{.Names}}|||{{.Image}}" 2>$null |
|
||||
Where-Object { $_ -match "postgres" } |
|
||||
ForEach-Object { ($_ -split "\|\|\|")[0] } |
|
||||
Select-Object -First 1
|
||||
$PgContainer = $ByImage
|
||||
}
|
||||
}
|
||||
|
||||
# --- Dump database ------------------------------------------------------------
|
||||
$DumpFile = Join-Path $BackupDir "database.dump"
|
||||
|
||||
if ($PgContainer) {
|
||||
Write-Host "Using Docker container : $PgContainer"
|
||||
docker exec $PgContainer pg_dump -U $DbUser -d $DbName -F c -f /tmp/studioflow_export.dump
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "pg_dump inside Docker failed." }
|
||||
docker cp "${PgContainer}:/tmp/studioflow_export.dump" $DumpFile
|
||||
docker exec $PgContainer rm /tmp/studioflow_export.dump
|
||||
Write-Host "Database dumped via Docker." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "No running Docker postgres found -- using local pg_dump"
|
||||
$env:PGPASSWORD = $DbPassword
|
||||
pg_dump -h $DbHost -p $DbPort -U $DbUser -d $DbName -F c -f $DumpFile
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "pg_dump failed. Is PostgreSQL running and pg_dump in PATH?" }
|
||||
Remove-Item Env:\PGPASSWORD -ErrorAction SilentlyContinue
|
||||
Write-Host "Database dumped via local pg_dump." -ForegroundColor Green
|
||||
}
|
||||
|
||||
$DumpSizeMB = [math]::Round((Get-Item $DumpFile).Length / 1MB, 2)
|
||||
Write-Host "Dump size : $DumpSizeMB MB"
|
||||
|
||||
# --- Copy .env files ----------------------------------------------------------
|
||||
Write-Host ""
|
||||
Write-Host "Copying 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 $ProjectRoot $f.Src
|
||||
if (Test-Path $Src) {
|
||||
Copy-Item $Src (Join-Path $BackupDir $f.Dst)
|
||||
Write-Host " Copied $($f.Src)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " Skipped $($f.Src) (not found)" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
# --- Write manifest -----------------------------------------------------------
|
||||
$Manifest = [ordered]@{
|
||||
timestamp = $Timestamp
|
||||
created_by = $env:USERNAME
|
||||
machine = $env:COMPUTERNAME
|
||||
database = [ordered]@{ host = $DbHost; port = $DbPort; user = $DbUser; name = $DbName }
|
||||
}
|
||||
$Manifest | ConvertTo-Json | Set-Content (Join-Path $BackupDir "manifest.json") -Encoding UTF8
|
||||
|
||||
# --- Done ---------------------------------------------------------------------
|
||||
Write-Host ""
|
||||
Write-Host "Export complete!" -ForegroundColor Cyan
|
||||
Write-Host "Folder : $BackupDir"
|
||||
Write-Host ""
|
||||
Write-Host "Copy the data_backup\$Timestamp folder to the other PC and run .\import-data.ps1"
|
||||
Write-Host ""
|
||||
Reference in New Issue
Block a user