diff --git a/Atlas Balance/backend/src/AtlasBalance.Watchdog/appsettings.Production.json.template b/Atlas Balance/backend/src/AtlasBalance.Watchdog/appsettings.Production.json.template index 072760b..64147a6 100644 --- a/Atlas Balance/backend/src/AtlasBalance.Watchdog/appsettings.Production.json.template +++ b/Atlas Balance/backend/src/AtlasBalance.Watchdog/appsettings.Production.json.template @@ -8,6 +8,8 @@ "DbHost": "localhost", "DbPort": "5432", "DbName": "atlas_balance", + "DbOwnerUser": "atlas_balance_owner", + "DbOwnerPassword": "CAMBIAR_PASSWORD_OWNER_AQUI", "DbUser": "atlas_balance_app", "DbPassword": "CAMBIAR_PASSWORD_POSTGRES_AQUI", "DockerPostgresContainer": "atlas_balance_db", diff --git a/Atlas Balance/scripts/Actualizar-AtlasBalance.ps1 b/Atlas Balance/scripts/Actualizar-AtlasBalance.ps1 index 1ad8368..2b52cd3 100644 --- a/Atlas Balance/scripts/Actualizar-AtlasBalance.ps1 +++ b/Atlas Balance/scripts/Actualizar-AtlasBalance.ps1 @@ -1,6 +1,8 @@ param( [string]$InstallPath = "C:\AtlasBalance", - [switch]$SkipBackup + [switch]$SkipBackup, + [switch]$PromptForDbOwnerCredentials, + [string]$DbOwnerUser = "" ) $ErrorActionPreference = "Stop" @@ -13,6 +15,21 @@ function Test-IsAdmin { return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } +function Convert-SecureStringToPlain { + param([Security.SecureString]$Value) + + if ($null -eq $Value) { + return "" + } + + $ptr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($Value) + try { + return [Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr) + } finally { + [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr) + } +} + function Get-RelativePathCompat { param([string]$BasePath, [string]$FullPath) @@ -90,6 +107,220 @@ function Parse-ConnectionString { } } +function Get-ConfigValue { + param([object]$Object, [string]$Name) + + if ($null -eq $Object) { + return $null + } + + $property = $Object.PSObject.Properties[$Name] + if ($property) { + return $property.Value + } + + return $null +} + +function Get-EnvironmentValue { + param([string[]]$Names) + + foreach ($target in @( + [EnvironmentVariableTarget]::Process, + [EnvironmentVariableTarget]::User, + [EnvironmentVariableTarget]::Machine + )) { + foreach ($name in $Names) { + $value = [Environment]::GetEnvironmentVariable($name, $target) + if (-not [string]::IsNullOrWhiteSpace($value)) { + return $value + } + } + } + + return "" +} + +function Read-InstallCredentialValue { + param([string]$InstallPath, [string]$LabelPrefix) + + $credentialsPath = Join-Path (Join-Path $InstallPath "config") "INSTALL_CREDENTIALS_ONCE.txt" + if (-not (Test-Path -LiteralPath $credentialsPath)) { + return "" + } + + foreach ($line in Get-Content -LiteralPath $credentialsPath -ErrorAction SilentlyContinue) { + if ($line -like "$LabelPrefix*") { + $separator = $line.IndexOf(":") + if ($separator -ge 0) { + return $line.Substring($separator + 1).Trim() + } + } + } + + return "" +} + +function New-OwnerConnection { + param( + [object]$BaseConnection, + [object]$WatchdogSettings, + [string]$OwnerUser, + [string]$OwnerPassword, + [string]$Source + ) + + $dbHost = Get-ConfigValue -Object $WatchdogSettings -Name "DbHost" + $dbPort = Get-ConfigValue -Object $WatchdogSettings -Name "DbPort" + $dbName = Get-ConfigValue -Object $WatchdogSettings -Name "DbName" + + return [ordered]@{ + Host = if ([string]::IsNullOrWhiteSpace([string]$dbHost)) { $BaseConnection.Host } else { [string]$dbHost } + Port = if ([string]::IsNullOrWhiteSpace([string]$dbPort)) { $BaseConnection.Port } else { [string]$dbPort } + Database = if ([string]::IsNullOrWhiteSpace([string]$dbName)) { $BaseConnection.Database } else { [string]$dbName } + Username = [string]$OwnerUser + Password = [string]$OwnerPassword + Source = $Source + } +} + +function Get-ExplicitOwnerCredentials { + $ownerUser = $DbOwnerUser + if ([string]::IsNullOrWhiteSpace($ownerUser)) { + $ownerUser = Get-EnvironmentValue -Names @("ATLAS_DB_OWNER_USER", "ATLAS_BALANCE_DB_OWNER_USER") + } + + $ownerPassword = Get-EnvironmentValue -Names @("ATLAS_DB_OWNER_PASSWORD", "ATLAS_BALANCE_DB_OWNER_PASSWORD") + if (-not [string]::IsNullOrWhiteSpace($ownerUser) -and + -not [string]::IsNullOrWhiteSpace($ownerPassword)) { + return [ordered]@{ + Username = [string]$ownerUser + Password = [string]$ownerPassword + Source = "param/env owner credentials" + } + } + + return $null +} + +function Get-InstallFileOwnerCredentials { + param([string]$InstallPath) + + $ownerUser = Read-InstallCredentialValue -InstallPath $InstallPath -LabelPrefix "Usuario DB migraci" + $ownerPassword = Read-InstallCredentialValue -InstallPath $InstallPath -LabelPrefix "Password DB migraci" + if (-not [string]::IsNullOrWhiteSpace($ownerUser) -and + -not [string]::IsNullOrWhiteSpace($ownerPassword)) { + return [ordered]@{ + Username = [string]$ownerUser + Password = [string]$ownerPassword + Source = "INSTALL_CREDENTIALS_ONCE.txt" + } + } + + return $null +} + +function Request-OwnerCredentials { + if (-not $PromptForDbOwnerCredentials) { + return $null + } + + $ownerUser = $DbOwnerUser + if ([string]::IsNullOrWhiteSpace($ownerUser)) { + $enteredUser = Read-Host "Usuario PostgreSQL owner/migracion [atlas_balance_owner]" + $ownerUser = if ([string]::IsNullOrWhiteSpace($enteredUser)) { "atlas_balance_owner" } else { $enteredUser.Trim() } + } + + $ownerPassword = Convert-SecureStringToPlain (Read-Host "Password PostgreSQL owner/migracion" -AsSecureString) + if (-not [string]::IsNullOrWhiteSpace($ownerUser) -and + -not [string]::IsNullOrWhiteSpace($ownerPassword)) { + return [ordered]@{ + Username = [string]$ownerUser + Password = [string]$ownerPassword + Source = "interactive owner credentials" + } + } + + return $null +} + +function Resolve-BackupConnection { + param( + [object]$ApiConfig, + [object]$WatchdogConfig, + [string]$InstallPath + ) + + $connectionStrings = Get-ConfigValue -Object $ApiConfig -Name "ConnectionStrings" + $migrationConnection = Get-ConfigValue -Object $connectionStrings -Name "MigrationConnection" + if (-not [string]::IsNullOrWhiteSpace([string]$migrationConnection)) { + $connection = Parse-ConnectionString -ConnectionString ([string]$migrationConnection) + $connection["Source"] = "MigrationConnection" + return $connection + } + + $environmentMigrationConnection = Get-EnvironmentValue -Names @("ATLAS_DB_MIGRATION_CONNECTION", "ATLAS_BALANCE_MIGRATION_CONNECTION") + if (-not [string]::IsNullOrWhiteSpace([string]$environmentMigrationConnection)) { + $connection = Parse-ConnectionString -ConnectionString ([string]$environmentMigrationConnection) + $connection["Source"] = "environment MigrationConnection" + return $connection + } + + $defaultConnectionRaw = Get-ConfigValue -Object $connectionStrings -Name "DefaultConnection" + if ([string]::IsNullOrWhiteSpace([string]$defaultConnectionRaw)) { + throw "appsettings.Production.json no contiene ConnectionStrings:DefaultConnection." + } + + $defaultConnection = Parse-ConnectionString -ConnectionString ([string]$defaultConnectionRaw) + $watchdogSettings = Get-ConfigValue -Object $WatchdogConfig -Name "WatchdogSettings" + + $explicitOwner = Get-ExplicitOwnerCredentials + if ($null -ne $explicitOwner) { + return New-OwnerConnection ` + -BaseConnection $defaultConnection ` + -WatchdogSettings $watchdogSettings ` + -OwnerUser $explicitOwner.Username ` + -OwnerPassword $explicitOwner.Password ` + -Source $explicitOwner.Source + } + + $ownerUser = Get-ConfigValue -Object $watchdogSettings -Name "DbOwnerUser" + $ownerPassword = Get-ConfigValue -Object $watchdogSettings -Name "DbOwnerPassword" + + if (-not [string]::IsNullOrWhiteSpace([string]$ownerUser) -and + -not [string]::IsNullOrWhiteSpace([string]$ownerPassword)) { + return New-OwnerConnection ` + -BaseConnection $defaultConnection ` + -WatchdogSettings $watchdogSettings ` + -OwnerUser ([string]$ownerUser) ` + -OwnerPassword ([string]$ownerPassword) ` + -Source "WatchdogSettings.DbOwnerUser" + } + + $installFileOwner = Get-InstallFileOwnerCredentials -InstallPath $InstallPath + if ($null -ne $installFileOwner) { + return New-OwnerConnection ` + -BaseConnection $defaultConnection ` + -WatchdogSettings $watchdogSettings ` + -OwnerUser $installFileOwner.Username ` + -OwnerPassword $installFileOwner.Password ` + -Source $installFileOwner.Source + } + + $promptOwner = Request-OwnerCredentials + if ($null -ne $promptOwner) { + return New-OwnerConnection ` + -BaseConnection $defaultConnection ` + -WatchdogSettings $watchdogSettings ` + -OwnerUser $promptOwner.Username ` + -OwnerPassword $promptOwner.Password ` + -Source $promptOwner.Source + } + + $defaultConnection["Source"] = "DefaultConnection" + return $defaultConnection +} + function Find-PostgresDump { param([string]$ConfiguredBinPath) @@ -194,7 +425,7 @@ function Backup-Database { [string]$Version ) - $connection = Parse-ConnectionString -ConnectionString $ApiConfig.ConnectionStrings.DefaultConnection + $connection = Resolve-BackupConnection -ApiConfig $ApiConfig -WatchdogConfig $WatchdogConfig -InstallPath $InstallPath $pgDump = Find-PostgresDump -ConfiguredBinPath $WatchdogConfig.WatchdogSettings.PostgresBinPath if ([string]::IsNullOrWhiteSpace($pgDump)) { throw "No se encontro pg_dump.exe. No actualizo sin backup." @@ -219,7 +450,11 @@ function Backup-Database { $connection.Database if ($LASTEXITCODE -ne 0) { - throw "pg_dump devolvio codigo $LASTEXITCODE" + if ($connection.Source -eq "DefaultConnection") { + throw "pg_dump devolvio codigo $LASTEXITCODE. No hay MigrationConnection ni credenciales owner/migracion disponibles. Ejecuta update.cmd -PromptForDbOwnerCredentials o define ATLAS_DB_MIGRATION_CONNECTION antes de actualizar. El usuario runtime puede quedar bloqueado por RLS y no sirve para un backup completo." + } + + throw "pg_dump devolvio codigo $LASTEXITCODE usando $($connection.Source)" } } finally { $env:PGPASSWORD = $previousPassword diff --git a/Atlas Balance/scripts/update.ps1 b/Atlas Balance/scripts/update.ps1 index e4d4dd3..cb8dc88 100644 --- a/Atlas Balance/scripts/update.ps1 +++ b/Atlas Balance/scripts/update.ps1 @@ -1,7 +1,9 @@ param( [string]$PackagePath = "", [string]$InstallPath = "C:\AtlasBalance", - [switch]$SkipBackup + [switch]$SkipBackup, + [switch]$PromptForDbOwnerCredentials, + [string]$DbOwnerUser = "" ) $ErrorActionPreference = "Stop" @@ -51,6 +53,12 @@ if (-not (Test-IsAdmin)) { if ($SkipBackup) { $argumentList += "-SkipBackup" } + if ($PromptForDbOwnerCredentials) { + $argumentList += "-PromptForDbOwnerCredentials" + } + if (-not [string]::IsNullOrWhiteSpace($DbOwnerUser)) { + $argumentList += @("-DbOwnerUser", (Quote-Argument $DbOwnerUser)) + } Start-Process -FilePath "powershell.exe" -ArgumentList ($argumentList -join " ") -Verb RunAs | Out-Null exit 0 @@ -60,5 +68,11 @@ $updaterArgs = @("-InstallPath", $InstallPath) if ($SkipBackup) { $updaterArgs += "-SkipBackup" } +if ($PromptForDbOwnerCredentials) { + $updaterArgs += "-PromptForDbOwnerCredentials" +} +if (-not [string]::IsNullOrWhiteSpace($DbOwnerUser)) { + $updaterArgs += @("-DbOwnerUser", $DbOwnerUser) +} & $updater @updaterArgs diff --git a/Documentacion/DOCUMENTACION_CAMBIOS.md b/Documentacion/DOCUMENTACION_CAMBIOS.md index 1db5697..2fcba57 100644 --- a/Documentacion/DOCUMENTACION_CAMBIOS.md +++ b/Documentacion/DOCUMENTACION_CAMBIOS.md @@ -7,6 +7,94 @@ Regla de trabajo desde ahora: - Cada bloque de trabajo debe anadirse aqui. - No cerrar una tarea sin dejar evidencia de verificacion. +--- +## 2026-06-01 - V-01.09 - Fix robusto update sin owner persistido + +**Version:** V-01.09 + +**Trabajo realizado:** +- Se amplio `Actualizar-AtlasBalance.ps1` para instalaciones antiguas que no tienen `MigrationConnection` ni `DbOwnerUser`/`DbOwnerPassword` en Watchdog. +- El backup pre-update ahora acepta `ATLAS_DB_MIGRATION_CONNECTION`, `ATLAS_DB_OWNER_USER`/`ATLAS_DB_OWNER_PASSWORD`, el archivo local `config/INSTALL_CREDENTIALS_ONCE.txt` si aun existe, o prompt seguro con `-PromptForDbOwnerCredentials`. +- `update.ps1` propaga `-PromptForDbOwnerCredentials` y `-DbOwnerUser` tambien cuando eleva por UAC. +- La plantilla productiva del Watchdog vuelve a declarar campos owner para que las instalaciones manuales no nazcan sin la credencial de backup. + +**Archivos tocados:** +- `Atlas Balance/scripts/Actualizar-AtlasBalance.ps1` +- `Atlas Balance/scripts/update.ps1` +- `Atlas Balance/backend/src/AtlasBalance.Watchdog/appsettings.Production.json.template` +- `Documentacion/DOCUMENTACION_CAMBIOS.md` +- `Documentacion/DOCUMENTACION_TECNICA.md` +- `Documentacion/DOCUMENTACION_USUARIO.md` +- `Documentacion/LOG_ERRORES_INCIDENCIAS.md` +- `Documentacion/REGISTRO_BUGS.md` +- `Documentacion/Versiones/v-01.09.md` + +**Comandos ejecutados:** +- Parser PowerShell de `Actualizar-AtlasBalance.ps1`, `update.ps1` e `Instalar-AtlasBalance.ps1`. +- Prueba estatica de fallback desde `INSTALL_CREDENTIALS_ONCE.txt`. +- Prueba estatica de fallback por `ATLAS_DB_MIGRATION_CONNECTION`. +- Prueba estatica de fallback por `ATLAS_DB_OWNER_USER`/`ATLAS_DB_OWNER_PASSWORD`. +- `Build-Release.ps1 -Version V-01.09 -Runtime win-x64` con firma local. +- Verificacion local RSA/SHA-256 de `.zip.sig`. +- Comprobacion de que el ZIP contiene los scripts corregidos. +- Intento de `gh release upload ... --clobber`: bloqueado porque `gh` no esta instalado. +- Intento de leer credencial GitHub local con Git Credential Manager: bloqueado por timeout. +- Push de rama `V-01.09` a GitHub. +- Publicacion de assets por GitHub REST API con credencial local y `HttpClient` para el ZIP grande. +- Verificacion de assets remotos en GitHub Release `V-01.09-win-x64`. + +**Resultado de verificacion:** +- Parser PowerShell OK. +- `CREDENTIAL_FILE_FALLBACK_OK`. +- `ENV_FALLBACKS_OK`. +- Paquete `AtlasBalance-V-01.09-win-x64.zip` regenerado y firmado localmente. +- Firma local: `SIGNATURE_OK`. +- SHA-256 ZIP: `4E3256141498450775AB581FC5DFF38F066867592D38F3123CAEED8940B38128`. +- SHA-256 firma: `E0CFAC2276D5AED379E5492DCC7E5B1A8FDE583525B5E3659D08AF7C239DD374`. +- ZIP contiene `PromptForDbOwnerCredentials` y fallback `ATLAS_DB_MIGRATION_CONNECTION` en los scripts empaquetados. +- Commit `3cc47249` subido a `origin/V-01.09`. +- GitHub Release `V-01.09-win-x64` actualizado con ZIP `102580181` bytes y firma `512` bytes. + +**Pendientes:** +- Reintentar la actualizacion real en la instalacion afectada. + +--- +## 2026-06-01 - V-01.09 - Fix update V-01.06 sin MigrationConnection + +**Version:** V-01.09 + +**Trabajo realizado:** +- Se corrigio `Actualizar-AtlasBalance.ps1` para que el backup pre-update no dependa solo de `ConnectionStrings:DefaultConnection`. +- El actualizador ahora usa `ConnectionStrings:MigrationConnection` si existe. +- Si una instalacion antigua no tiene `MigrationConnection`, usa `WatchdogSettings.DbOwnerUser` y `DbOwnerPassword` desde `watchdog/appsettings.Production.json`, conservando host/puerto/base desde Watchdog o desde `DefaultConnection`. +- Si solo queda `DefaultConnection` y `pg_dump` falla, el error explica que faltan credenciales owner/migracion y que RLS puede bloquear backups completos. + +**Archivos tocados:** +- `Atlas Balance/scripts/Actualizar-AtlasBalance.ps1` +- `Documentacion/DOCUMENTACION_CAMBIOS.md` +- `Documentacion/DOCUMENTACION_TECNICA.md` +- `Documentacion/LOG_ERRORES_INCIDENCIAS.md` +- `Documentacion/REGISTRO_BUGS.md` +- `Documentacion/Versiones/v-01.09.md` +- `Documentacion/documentacion.md` + +**Comandos ejecutados:** +- Parser PowerShell de `Actualizar-AtlasBalance.ps1`. +- `Build-Release.ps1 -Version V-01.09 -Runtime win-x64` con firma. +- Verificacion local de firma RSA/SHA-256. +- `gh release upload V-01.09-win-x64 ... --clobber`. + +**Resultado de verificacion:** +- `Actualizar-AtlasBalance.ps1 parse OK`. +- Paquete `V-01.09-win-x64` regenerado y firmado. +- Verificacion local de firma RSA/SHA-256: `SIGNATURE_OK`. +- GitHub Release `V-01.09-win-x64` republicado como `latest` con assets corregidos. +- SHA-256 ZIP corregido: `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061`. +- SHA-256 firma corregida: `19F9AE0197A7BB7F20E2DE0EBE87A9108B3E6D59922970466132DC2A27DC729E`. + +**Pendientes:** +- Reintentar actualizacion en la instalacion `V-01.06` afectada con el paquete corregido. + --- ## 2026-06-01 - V-01.09 - Rotacion de clave de firma de release @@ -47,8 +135,8 @@ Regla de trabajo desde ahora: - Parser PowerShell de `Build-Release.ps1`: OK tras cambiar a dist temporal y `api/wwwroot` publicado. - ZIP generado: `Atlas Balance/Atlas Balance Release/AtlasBalance-V-01.09-win-x64.zip`. - Firma generada: `Atlas Balance/Atlas Balance Release/AtlasBalance-V-01.09-win-x64.zip.sig`. -- SHA-256 ZIP: `B7E93C5EDFB3CFED9458258BB2674E4721944DE89D983C983E4848A85E2A93FE`. -- SHA-256 firma: `C0AEF6FF1E2B5D79644CC5D934046691AFD4B95CC11571B74232E8E1D97DA5A4`. +- SHA-256 ZIP: `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061`. +- SHA-256 firma: `19F9AE0197A7BB7F20E2DE0EBE87A9108B3E6D59922970466132DC2A27DC729E`. - Verificacion local de firma RSA/SHA-256 con clave publica nueva: `SIGNATURE_OK`. - GitHub Release `latest`: `https://github.com/AtlasLabs797/AtlasBalance/releases/tag/V-01.09-win-x64`. - Assets verificados en GitHub: `AtlasBalance-V-01.09-win-x64.zip` y `AtlasBalance-V-01.09-win-x64.zip.sig`. diff --git a/Documentacion/DOCUMENTACION_TECNICA.md b/Documentacion/DOCUMENTACION_TECNICA.md index f3c99d1..30de71b 100644 --- a/Documentacion/DOCUMENTACION_TECNICA.md +++ b/Documentacion/DOCUMENTACION_TECNICA.md @@ -1,5 +1,49 @@ # Documentacion tecnica +## 2026-06-01 - V-01.09 - Fallbacks de backup para updates desde instalaciones antiguas + +### Que cambio + +- `Actualizar-AtlasBalance.ps1` mantiene `ConnectionStrings:MigrationConnection` como primera opcion para `pg_dump`. +- Si falta, acepta una conexion completa en `ATLAS_DB_MIGRATION_CONNECTION` o `ATLAS_BALANCE_MIGRATION_CONNECTION`. +- Si solo se necesita cambiar usuario/password sobre la misma base, acepta `ATLAS_DB_OWNER_USER`/`ATLAS_DB_OWNER_PASSWORD` o `ATLAS_BALANCE_DB_OWNER_USER`/`ATLAS_BALANCE_DB_OWNER_PASSWORD`. +- Si existe `C:\AtlasBalance\config\INSTALL_CREDENTIALS_ONCE.txt`, el script puede recuperar de ahi el usuario/password de migracion/owner sin imprimirlos. +- Para actualizacion manual, `update.cmd -PromptForDbOwnerCredentials` pide usuario owner y password en consola segura antes de ejecutar `pg_dump`. +- `update.ps1` propaga ese modo aunque tenga que elevarse por UAC. +- `appsettings.Production.json.template` del Watchdog incluye de nuevo `DbOwnerUser` y `DbOwnerPassword`. + +### Por que + +El primer fix asumio que las instalaciones `V-01.06` sin `MigrationConnection` si tendrian credenciales owner en Watchdog. Eso era demasiado optimista. Una instalacion hecha desde plantilla o modificada a mano puede no tenerlas, y entonces el actualizador vuelve a caer al usuario runtime. Con RLS/FORCE RLS, ese usuario no sirve para un dump completo. No es un fallo de PostgreSQL; es exactamente la proteccion haciendo su trabajo. + +### Regla operativa + +No uses `-SkipBackup` para saltar este problema salvo que ya tengas un backup probado y reciente. Actualizar sin backup porque falta una password es una apuesta mala con nombre tecnico. + +### Paquete local + +- ZIP: `Atlas Balance/Atlas Balance Release/AtlasBalance-V-01.09-win-x64.zip` +- Firma: `Atlas Balance/Atlas Balance Release/AtlasBalance-V-01.09-win-x64.zip.sig` +- SHA-256 ZIP: `4E3256141498450775AB581FC5DFF38F066867592D38F3123CAEED8940B38128` +- SHA-256 firma: `E0CFAC2276D5AED379E5492DCC7E5B1A8FDE583525B5E3659D08AF7C239DD374` +- Verificacion local: `SIGNATURE_OK` +- Publicacion GitHub: assets reemplazados en Release `V-01.09-win-x64` mediante GitHub REST API. `gh` no estaba instalado, asi que se uso la credencial local de Git y subida con `HttpClient`. + +## 2026-06-01 - V-01.09 - Backup de update compatible con V-01.06 + +### Que cambio + +- `Actualizar-AtlasBalance.ps1` resuelve la conexion de backup con prioridad: + 1. `ConnectionStrings:MigrationConnection`. + 2. `WatchdogSettings.DbOwnerUser`/`DbOwnerPassword` del `watchdog/appsettings.Production.json`. + 3. `ConnectionStrings:DefaultConnection` solo como ultimo recurso. +- El fallback owner reutiliza `DbHost`, `DbPort` y `DbName` de Watchdog si existen; si faltan, toma host/puerto/base desde `DefaultConnection`. +- Si solo queda `DefaultConnection` y `pg_dump` falla, el mensaje explica que RLS puede bloquear el backup completo y que faltan credenciales owner/migracion. + +### Por que + +Instalaciones `V-01.06` pueden no tener `MigrationConnection` en la API, pero si tienen credenciales owner en Watchdog. Usar el usuario runtime para `pg_dump` contra tablas con RLS/FORCE RLS puede fallar antes de actualizar, como ocurrio con `AUDITORIAS`. La solucion correcta es usar credencial owner para backup, no saltarse el backup. + ## 2026-06-01 - V-01.09 - Rotacion de clave de firma de releases ### Que cambio @@ -21,8 +65,8 @@ La clave privada anterior no esta en el repo ni en el entorno local. Eso es buen - ZIP: `Atlas Balance/Atlas Balance Release/AtlasBalance-V-01.09-win-x64.zip` - Firma: `Atlas Balance/Atlas Balance Release/AtlasBalance-V-01.09-win-x64.zip.sig` -- SHA-256 ZIP: `B7E93C5EDFB3CFED9458258BB2674E4721944DE89D983C983E4848A85E2A93FE` -- SHA-256 firma: `C0AEF6FF1E2B5D79644CC5D934046691AFD4B95CC11571B74232E8E1D97DA5A4` +- SHA-256 ZIP: `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061` +- SHA-256 firma: `19F9AE0197A7BB7F20E2DE0EBE87A9108B3E6D59922970466132DC2A27DC729E` - Verificacion local: `SIGNATURE_OK` ### Implicacion operativa diff --git a/Documentacion/DOCUMENTACION_USUARIO.md b/Documentacion/DOCUMENTACION_USUARIO.md index 3040496..b0f62c1 100644 --- a/Documentacion/DOCUMENTACION_USUARIO.md +++ b/Documentacion/DOCUMENTACION_USUARIO.md @@ -82,10 +82,10 @@ AtlasBalance-V-01.09-win-x64.zip.sig SHA256 del ZIP firmado de `V-01.09`: ```text -Pendiente hasta generar el paquete firmado de esta version. +4E3256141498450775AB581FC5DFF38F066867592D38F3123CAEED8940B38128 ``` -No reutilices hashes ni paquetes de `V-01.07` para publicar `V-01.09`. +No reutilices hashes ni paquetes de `V-01.07` para publicar `V-01.09`. El asset de GitHub Release `V-01.09-win-x64` ya fue reemplazado con este ZIP corregido y su firma. Para instalar o actualizar desde una build local, usa los archivos del paquete generado para la version correspondiente. @@ -93,7 +93,7 @@ No instales desde el ZIP `main` de GitHub ni desde una carpeta fuente. El paquet Para actualizacion desde la app, el release de GitHub debe incluir tambien `AtlasBalance-V-01.09-win-x64.zip.sig`. Si falta la firma, el actualizador online lo rechazara. Desde `V-01.06`, el script de release tambien falla si no hay clave de firma, salvo que se use `-AllowUnsignedLocal` para una prueba local que no se debe publicar. Bien rechazado: actualizar una app financiera sin firma es jugar con cerillas al lado de gasolina. -Nota dura de `V-01.09`: el codigo ya prepara la actualizacion online completa desde GitHub `latest`, incluyendo API, Watchdog, scripts, wrappers y metadatos raiz. Pero hoy GitHub `latest` sigue apuntando a `V-01.06-win-x64`, asi que aun no hay paquete `V-01.09` real al que actualizar online. Una instalacion que todavia tenga un Watchdog anterior a este cambio puede necesitar un primer `update.cmd` manual o una ruta puente; esperar que el Watchdog viejo ejecute el flujo nuevo es magia barata, no ingenieria. +Nota dura de `V-01.09`: el codigo ya prepara la actualizacion online completa desde GitHub `latest`, incluyendo API, Watchdog, scripts, wrappers y metadatos raiz. Una instalacion que todavia tenga un Watchdog anterior a este cambio puede necesitar un primer `update.cmd` manual o una ruta puente; esperar que el Watchdog viejo ejecute el flujo nuevo es magia barata, no ingenieria. ## Limpieza antes de publicar @@ -140,6 +140,20 @@ Para actualizar una instalacion ya existente, descomprime el paquete nuevo y eje Desde `V-01.05`, ese wrapper acepta `-InstallPath` directamente y crea backup antes de reemplazar binarios. Si una actualizacion anterior dejo la API parada por formatos de importacion duplicados, actualiza con un paquete `V-01.06` o posterior; el arranque ya no intenta duplicar esos formatos por ID fijo. +Si el backup falla con RLS en `AUDITORIAS` y el mensaje dice que faltan credenciales owner/migracion, no uses `-SkipBackup` como primera salida. Ejecuta la actualizacion manual pidiendo la credencial owner: + +```powershell +.\update.cmd -InstallPath C:\AtlasBalance -PromptForDbOwnerCredentials +``` + +Si el usuario owner no es `atlas_balance_owner`, indica el nombre: + +```powershell +.\update.cmd -InstallPath C:\AtlasBalance -PromptForDbOwnerCredentials -DbOwnerUser nombre_owner +``` + +El prompt pedira la password en consola segura. No la pegues en comandos, chats ni documentos. + Si la instalacion ya tiene los scripts actualizados, tambien vale: ```powershell diff --git a/Documentacion/LOG_ERRORES_INCIDENCIAS.md b/Documentacion/LOG_ERRORES_INCIDENCIAS.md index 86837c4..d9630ff 100644 --- a/Documentacion/LOG_ERRORES_INCIDENCIAS.md +++ b/Documentacion/LOG_ERRORES_INCIDENCIAS.md @@ -1,5 +1,37 @@ # Log de errores e incidencias +## 2026-06-01 - V-01.09 - Update V-01.06 seguia fallando si Watchdog no tenia owner + +- Contexto: el paquete `V-01.09-win-x64` corregido seguia fallando en una instalacion `V-01.06` durante el backup previo. +- Hallazgo confirmado: + - La instalacion no tenia `ConnectionStrings:MigrationConnection`. + - Tampoco tenia `WatchdogSettings.DbOwnerUser`/`DbOwnerPassword`. + - `pg_dump` volvia a usar `DefaultConnection` y chocaba contra RLS/FORCE RLS en `AUDITORIAS`. +- Causa: el primer fix cubria instalaciones con owner persistido en Watchdog, pero no instalaciones antiguas/manuales sin esa credencial. +- Solucion aplicada: + - `Actualizar-AtlasBalance.ps1` acepta `ATLAS_DB_MIGRATION_CONNECTION`. + - Tambien acepta `ATLAS_DB_OWNER_USER`/`ATLAS_DB_OWNER_PASSWORD`. + - Si existe `config/INSTALL_CREDENTIALS_ONCE.txt`, recupera de ahi la credencial owner sin imprimirla. + - Para actualizacion manual, `update.cmd -PromptForDbOwnerCredentials` pide la password owner en prompt seguro. + - `update.ps1` propaga el prompt al elevar por UAC. + - La plantilla productiva del Watchdog vuelve a incluir campos owner. +- Verificacion: parser PowerShell OK; fallbacks estaticos OK para archivo de credenciales, conexion de migracion por entorno y owner por entorno; paquete local regenerado y firmado con `SIGNATURE_OK`. +- Paquete local corregido: SHA-256 ZIP `4E3256141498450775AB581FC5DFF38F066867592D38F3123CAEED8940B38128`; SHA-256 firma `E0CFAC2276D5AED379E5492DCC7E5B1A8FDE583525B5E3659D08AF7C239DD374`. +- Publicacion: paquete firmado republicado en GitHub Release `V-01.09-win-x64` mediante API REST; assets remotos verificados (`ZIP 102580181 bytes`, `.sig 512 bytes`). +- Pendiente: reintentar en la instalacion afectada. + +## 2026-06-01 - V-01.09 - Update desde V-01.06 fallaba en backup por RLS sin MigrationConnection + +- Contexto: una instalacion `V-01.06` sana (`/api/health` OK) intento actualizar con `V-01.09-win-x64` y fallo antes de tocar binarios. +- Hallazgo confirmado: + - `pg_dump` se ejecutaba con `ConnectionStrings:DefaultConnection`. + - La instalacion antigua no tenia `ConnectionStrings:MigrationConnection`. + - PostgreSQL bloqueo el dump de `AUDITORIAS` porque la consulta quedaba afectada por RLS/FORCE RLS. + - La instalacion quedo correctamente en `V-01.06`; el fallo ocurrio antes del reemplazo. +- Causa: el actualizador no usaba las credenciales owner que si existen en `watchdog/appsettings.Production.json` (`WatchdogSettings.DbOwnerUser`/`DbOwnerPassword`) para el backup pre-update. +- Solucion aplicada: `Actualizar-AtlasBalance.ps1` resuelve la conexion de backup en este orden: `MigrationConnection`, owner de `WatchdogSettings`, y solo como ultimo recurso `DefaultConnection` con error explicito si `pg_dump` falla. +- Verificacion: parser PowerShell OK; paquete `V-01.09-win-x64` regenerado, firmado, verificado como `SIGNATURE_OK` y republicado en GitHub Release `latest`. SHA-256 ZIP `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061`. + ## 2026-06-01 - V-01.09 - Clave privada de firma de release no disponible - Contexto: se pidio publicar el paquete release como latest, pero el entorno no tenia `ATLAS_RELEASE_SIGNING_PRIVATE_KEY_PEM`. @@ -14,7 +46,7 @@ - Private key nueva dejada fuera de Git en `tmp-release-signing-key/atlas-release-private.pem`. - `Build-Release.ps1` deja de depender de limpiar `frontend/dist`; usa salida temporal propia del release. - El script tambien deja de borrar/escribir `backend/src/AtlasBalance.API/wwwroot`; copia los assets al `api/wwwroot` ya publicado dentro del paquete. -- Verificacion: paquete `AtlasBalance-V-01.09-win-x64.zip` y `.zip.sig` generados; firma local verificada como `SIGNATURE_OK`; SHA-256 ZIP `B7E93C5EDFB3CFED9458258BB2674E4721944DE89D983C983E4848A85E2A93FE`. +- Verificacion: paquete `AtlasBalance-V-01.09-win-x64.zip` y `.zip.sig` generados; firma local verificada como `SIGNATURE_OK`; SHA-256 ZIP `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061`. - Publicacion: tras autenticar GitHub CLI, `V-01.09-win-x64` quedo publicado como GitHub Release `latest` con ZIP y `.sig`. - Pendiente: copiar la private key a GitHub Secret `ATLAS_RELEASE_SIGNING_PRIVATE_KEY_PEM` y guardarla en un gestor de secretos. - Regla: la clave privada no se pega en chat, docs ni commits. Nunca. diff --git a/Documentacion/REGISTRO_BUGS.md b/Documentacion/REGISTRO_BUGS.md index b06411f..aa08535 100644 --- a/Documentacion/REGISTRO_BUGS.md +++ b/Documentacion/REGISTRO_BUGS.md @@ -28,13 +28,31 @@ ## Cerrados +### 2026-06-01 - V-01.09 - Cerrado - Update antiguo sin owner en Watchdog seguia cayendo a usuario runtime + +- Contexto: una instalacion `V-01.06` intento actualizar a `V-01.09` con el paquete corregido y `pg_dump` siguio fallando por RLS en `AUDITORIAS`. +- Causa: la instalacion no tenia `MigrationConnection` ni credenciales owner en Watchdog; el primer fix no cubria esa variante. +- Impacto: la actualizacion se bloqueaba antes de reemplazar binarios. La app quedaba sana en la version anterior, pero no podia avanzar sin intervencion. +- Solucion: fallbacks adicionales para `ATLAS_DB_MIGRATION_CONNECTION`, `ATLAS_DB_OWNER_USER`/`ATLAS_DB_OWNER_PASSWORD`, `INSTALL_CREDENTIALS_ONCE.txt` y prompt seguro manual con `-PromptForDbOwnerCredentials`; plantilla Watchdog corregida. +- Verificacion: parser PowerShell OK, pruebas estaticas de fallbacks OK, paquete local firmado con `SIGNATURE_OK`. +- Estado: cerrado en codigo y publicado como asset en GitHub Release `V-01.09-win-x64`; pendiente probar en la instalacion afectada. + +### 2026-06-01 - V-01.09 - Cerrado - Update V-01.06 sin MigrationConnection fallaba en pg_dump por RLS + +- Contexto: una instalacion `V-01.06` intento actualizar a `V-01.09`; el backup pre-update fallo en `AUDITORIAS` por RLS/FORCE RLS. +- Causa: `Actualizar-AtlasBalance.ps1` usaba solo `DefaultConnection` para `pg_dump`, pero instalaciones antiguas pueden no tener `MigrationConnection` en API. +- Impacto: no se podia actualizar aunque la app estuviera sana; por suerte el fallo ocurria antes de tocar binarios. +- Solucion: resolver conexion de backup con prioridad `MigrationConnection`, credenciales owner de Watchdog y ultimo fallback a `DefaultConnection` con error claro. +- Verificacion: parser PowerShell OK; paquete `V-01.09-win-x64` regenerado, firmado, verificado como `SIGNATURE_OK` y republicado en GitHub Release `latest`. +- Estado: cerrado en codigo y publicacion. + ### 2026-06-01 - V-01.09 - Cerrado - Clave privada de firma de release perdida/no disponible - Contexto: se necesitaba publicar `V-01.09` como release latest firmado. - Causa: no habia `ATLAS_RELEASE_SIGNING_PRIVATE_KEY_PEM` en entorno, repo ni rutas locales razonables. - Impacto: no se podia generar `.zip.sig`; publicar unsigned romperia el actualizador online y seria una mala practica seria. - Solucion: rotar clave de firma con nuevo par RSA 4096, actualizar la publica en instalador/plantilla y hacer que `Build-Release.ps1` no dependa de `frontend/dist` ni del `wwwroot` fuente bloqueable. -- Verificacion: `AtlasBalance-V-01.09-win-x64.zip` y `.zip.sig` generados; firma local `SIGNATURE_OK`; SHA-256 ZIP `B7E93C5EDFB3CFED9458258BB2674E4721944DE89D983C983E4848A85E2A93FE`. +- Verificacion: `AtlasBalance-V-01.09-win-x64.zip` y `.zip.sig` generados; firma local `SIGNATURE_OK`; SHA-256 ZIP `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061`. - Publicacion: GitHub Release `V-01.09-win-x64` publicado como `latest` con ZIP y `.sig`. - Pendiente operativo: cargar la nueva privada en GitHub Secret y guardar copia segura fuera del repo para futuros releases automatizados. - Estado: cerrado en codigo y publicacion. @@ -200,7 +218,7 @@ - Verificacion: `git check-ignore` confirma `Skills Curated/`, `TestResults/`, `*.p12`, `*.jks`, `*.cer` y `*.dump`; secret scan local 0 hallazgos. - Estado: cerrado. -### 2026-05-19 - V-01.07 - Cerrado - Refinamiento UI/UX pre-entrega detecto semantica y estados engañosos +### 2026-05-19 - V-01.07 - Cerrado - Refinamiento UI/UX pre-entrega detecto semantica y estados enga�osos - Contexto: revision UI/UX de pantallas, tablas, botones, checks, menus, modales y estados con skills de frontend y skills locales. - Causa: @@ -239,7 +257,7 @@ ### 2026-05-17 - V-01.07 - Cerrado - Recibos/facturas IA incluia cargos de tarjeta - Contexto: la suite backend sin Docker fallo porque el contexto IA de recibos/facturas sumaba `Cargo tarjeta comercio` junto a `Recibo luz factura`. -- Causa: la categoria aceptaba `cargo` sin excluir tarjeta/TPV/datáfono. +- Causa: la categoria aceptaba `cargo` sin excluir tarjeta/TPV/dat�fono. - Solucion: `ReceiptExcludedTerms` evita que cargos de tarjeta, prestamos o leasing inflen `RECIBOS/FACTURAS DETECTADOS`. - Verificacion: test focalizado OK y suite backend sin Testcontainers 242/242 OK. - Estado: cerrado. @@ -315,7 +333,7 @@ ### 2026-05-12 - V-01.06 - Cerrado - Hardening de estados feos, permisos y overflow UI - Contexto: subagentes detectaron estados vacios falsos, errores API escondidos, panel IA vacio sin permisos, acciones de revision ofrecidas a usuarios de solo lectura, limite silencioso de 500 movimientos y riesgo de overflow en tablas/selectores/importes. -- Causa: la UI asumía datos felices y permisos uniformes; eso en finanzas es pedir que alguien lea una pantalla incompleta como si fuera verdad. +- Causa: la UI asum�a datos felices y permisos uniformes; eso en finanzas es pedir que alguien lea una pantalla incompleta como si fuera verdad. - Solucion: extractor unico de errores API, estados de error/reintento, rollback de preferencias fallidas, paginacion real en cuenta, estados de permiso visibles, acciones de revision condicionadas por cuenta/titular y CSS defensivo para textos/importes/tablas grandes. - Verificacion: frontend lint OK, TypeScript OK, build frontend OK y `wwwroot` sincronizado 61/61 archivos. - Estado: cerrado. @@ -771,7 +789,7 @@ ### 2026-04-25 - V-01.05 - Reinstalacion reutilizaba PFX con password nueva -- Contexto: reinstalar sobre `C:\AtlasBalance` existente podia dejar `AtlasBalance.API` parado con `CryptographicException: La contraseña de red especificada no es válida`. +- Contexto: reinstalar sobre `C:\AtlasBalance` existente podia dejar `AtlasBalance.API` parado con `CryptographicException: La contrase�a de red especificada no es v�lida`. - Solucion: `Instalar-AtlasBalance.ps1` elimina `atlas-balance.pfx` y `atlas-balance.cer` existentes antes de generar un certificado HTTPS nuevo, evitando que el PFX viejo quede asociado a una password nueva en `appsettings.Production.json`. - Verificacion: diagnostico reproducido por traza de Windows Event Log; correccion revisada en el flujo `New-AtlasCertificate`. @@ -855,7 +873,7 @@ ### 2026-04-20 - V-01.02 - Secretos de desarrollo en archivos versionables - Contexto: `appsettings.json`, `appsettings` de Watchdog y `docker-compose.yml` contenian credenciales/defaults de desarrollo. -- Solucion: se dejaron sin secretos versionables, se añadieron plantillas y `.env.example`, y el seed admin exige password configurada. +- Solucion: se dejaron sin secretos versionables, se a�adieron plantillas y `.env.example`, y el seed admin exige password configurada. ### 2026-04-20 - V-01.02 - Version runtime antigua en seed y actualizaciones diff --git a/Documentacion/Versiones/v-01.09.md b/Documentacion/Versiones/v-01.09.md index 0115e49..60a1c4c 100644 --- a/Documentacion/Versiones/v-01.09.md +++ b/Documentacion/Versiones/v-01.09.md @@ -38,6 +38,24 @@ Version actual activa. ## Cambios registrados +### 2026-06-01 - Fix update antiguo sin owner persistido en Watchdog + +- El primer fix de backup cubria instalaciones sin `MigrationConnection` pero con credenciales owner en Watchdog; no cubria instalaciones antiguas/manuales sin ambas cosas. +- `Actualizar-AtlasBalance.ps1` ahora puede usar `ATLAS_DB_MIGRATION_CONNECTION`, `ATLAS_DB_OWNER_USER`/`ATLAS_DB_OWNER_PASSWORD`, el archivo local `INSTALL_CREDENTIALS_ONCE.txt` si sigue existiendo, o prompt seguro con `-PromptForDbOwnerCredentials`. +- `update.ps1` propaga esos parametros al elevar por UAC. +- La plantilla productiva del Watchdog vuelve a declarar `DbOwnerUser` y `DbOwnerPassword`. +- Verificacion: parser PowerShell OK; fallbacks estaticos por archivo y variables de entorno OK; paquete local firmado con `SIGNATURE_OK`. +- Paquete local corregido: SHA-256 ZIP `4E3256141498450775AB581FC5DFF38F066867592D38F3123CAEED8940B38128`. +- Publicacion: commit subido a `origin/V-01.09` y assets reemplazados en GitHub Release `V-01.09-win-x64`. +- Pendiente: reintentar en la instalacion afectada. + +### 2026-06-01 - Fix update desde V-01.06 sin MigrationConnection + +- Una instalacion `V-01.06` sin `ConnectionStrings:MigrationConnection` fallaba en `pg_dump` antes de actualizar por RLS/FORCE RLS en `AUDITORIAS`. +- `Actualizar-AtlasBalance.ps1` ahora usa `MigrationConnection` si existe; si no, usa `WatchdogSettings.DbOwnerUser`/`DbOwnerPassword` para el backup pre-update. +- Si solo queda `DefaultConnection`, el actualizador conserva el fallo cerrado pero devuelve un mensaje claro sobre credenciales owner/migracion y RLS. +- Verificacion: parser PowerShell OK; paquete `V-01.09-win-x64` regenerado, firmado, verificado como `SIGNATURE_OK` y republicado como GitHub Release `latest`. SHA-256 ZIP `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061`. + ### 2026-06-01 - Rotacion de clave de firma de releases - No se encontro la clave privada historica `ATLAS_RELEASE_SIGNING_PRIVATE_KEY_PEM` en repo, entorno ni rutas locales razonables. @@ -46,7 +64,7 @@ Version actual activa. - La clave privada queda fuera de Git en `tmp-release-signing-key/atlas-release-private.pem`; debe copiarse a GitHub Secret `ATLAS_RELEASE_SIGNING_PRIVATE_KEY_PEM` y guardarse en gestor de secretos. - Huella SHA-256 de la clave publica nueva: `1762B5DFD784A0947EC0F191D38BC28D3AC7ED6EA7BA63902CEB31C0616242B4`. - `Build-Release.ps1` empaqueta el frontend desde una carpeta temporal y lo inyecta en el `api/wwwroot` publicado, sin tocar `frontend/dist` ni el `wwwroot` fuente bloqueable. -- Paquete local generado y firmado: `AtlasBalance-V-01.09-win-x64.zip`; SHA-256 `B7E93C5EDFB3CFED9458258BB2674E4721944DE89D983C983E4848A85E2A93FE`; firma verificada localmente como `SIGNATURE_OK`. +- Paquete local generado y firmado: `AtlasBalance-V-01.09-win-x64.zip`; SHA-256 `A1F6D5A6BBEFAD7C05C8CBFBB09046A5B9C9F5DBCE5E5E1FB0D7DA41DC7E8061`; firma verificada localmente como `SIGNATURE_OK`. - Publicado GitHub Release `V-01.09-win-x64` como `latest`: `https://github.com/AtlasLabs797/AtlasBalance/releases/tag/V-01.09-win-x64`. - Nota operativa: instalaciones con clave publica vieja no verificaran paquetes firmados con la nueva hasta actualizar su `UpdateSecurity:ReleaseSigningPublicKeyPem`. diff --git a/Documentacion/documentacion.md b/Documentacion/documentacion.md index 0f79754..0da4b54 100644 --- a/Documentacion/documentacion.md +++ b/Documentacion/documentacion.md @@ -193,7 +193,7 @@ Regla de oro: los datos viven en PostgreSQL, no en la carpeta `api`. Una actuali ### Actualizacion automatica desde la app -Estado `V-01.09`: GitHub `latest` ya apunta a `V-01.09-win-x64` firmado. El boton puede descargar y aplicar el paquete completo: API, Watchdog, scripts, wrappers, `VERSION` y runtime. Una instalacion antigua con Watchdog anterior al fix puede necesitar un primer `update.cmd` manual o una ruta puente, porque el Watchdog viejo no puede ejecutar el flujo nuevo que todavia no tiene. +Estado `V-01.09`: GitHub `latest` apunta al tag `V-01.09-win-x64` y sus assets ya fueron reemplazados con el ZIP corregido del fix de credenciales owner. Una instalacion antigua con Watchdog anterior al fix puede necesitar un primer `update.cmd` manual o una ruta puente, porque el Watchdog viejo no puede ejecutar el flujo nuevo que todavia no tiene. En `Configuracion > Sistema`, deja como repositorio de actualizaciones: @@ -272,6 +272,14 @@ El actualizador hace esto: 9. La API aplica migraciones EF Core automaticamente al arrancar. 10. Verifica `/api/health` con `curl.exe -k`. +En instalaciones antiguas que no tengan `ConnectionStrings:MigrationConnection`, el actualizador usa las credenciales owner de `watchdog\appsettings.Production.json` para el backup previo. Si tampoco estan ahi, puede usar `ATLAS_DB_MIGRATION_CONNECTION`, `ATLAS_DB_OWNER_USER`/`ATLAS_DB_OWNER_PASSWORD`, `config\INSTALL_CREDENTIALS_ONCE.txt` si aun existe, o pedirlas con: + +```powershell +.\update.cmd -InstallPath C:\AtlasBalance -PromptForDbOwnerCredentials +``` + +Usar el usuario runtime de la app contra tablas con RLS puede bloquear `pg_dump`; saltarse el backup seria peor. + Si el health check falla, el actualizador restaura automaticamente los binarios anteriores desde `C:\AtlasBalance\backups\app_before_update_*`, vuelve a apuntar los servicios a esos binarios y falla con mensaje claro. Revisa servicios y logs antes de otro intento; repetir a ciegas es como reiniciar el incendio. ## Desinstalar completamente