diff --git a/db/migrate-i18n.sql b/db/migrate-i18n.sql index d551532..b884599 100644 --- a/db/migrate-i18n.sql +++ b/db/migrate-i18n.sql @@ -19,8 +19,11 @@ CREATE INDEX IF NOT EXISTS entity_translations_lookup_idx CREATE INDEX IF NOT EXISTS entity_translations_locale_field_idx ON entity_translations (locale, field_name); -CREATE INDEX IF NOT EXISTS entity_translations_value_lower_idx - ON entity_translations (locale, lower(value)); +-- Search only matches name/title aliases; exclude long prose (bio_full) from btree index. +DROP INDEX IF EXISTS entity_translations_value_lower_idx; +CREATE INDEX IF NOT EXISTS entity_translations_search_alias_idx + ON entity_translations (locale, lower(value)) + WHERE field_name IN ('name', 'title') AND char_length(value) <= 512; CREATE OR REPLACE FUNCTION entity_translations_touch_updated_at() RETURNS TRIGGER AS $$ diff --git a/infra/deploy/devtoprod.config.example.json b/infra/deploy/devtoprod.config.example.json index 11f1beb..91d14b8 100644 --- a/infra/deploy/devtoprod.config.example.json +++ b/infra/deploy/devtoprod.config.example.json @@ -9,7 +9,7 @@ "thumbnails": true, "backupDev": true, "backupProd": true, - "migrateProdSchema": false, + "migrateProdSchema": true, "restoreProd": true, "syncImages": true, "dockerPublish": true, diff --git a/infra/scripts/deploy-dev-to-prod.ps1 b/infra/scripts/deploy-dev-to-prod.ps1 index 6bac93b..3928050 100644 --- a/infra/scripts/deploy-dev-to-prod.ps1 +++ b/infra/scripts/deploy-dev-to-prod.ps1 @@ -20,6 +20,7 @@ Set-Location $RepoRoot $BannerWidth = 64 $CompletedSteps = [System.Collections.Generic.List[string]]::new() $FailedStep = $null +$script:ProdSchemaMigrated = $false function Write-ReleaseBanner { param([bool]$Success, [string]$FailedAt = '') @@ -165,14 +166,12 @@ function Get-ProfileSteps { $base.thumbnails = $true $base.backupDev = $true $base.backupProd = $true + $base.migrateProdSchema = $true $base.restoreProd = $true $base.syncImages = $true $base.dockerPublish = $true $base.truenasRestartPause = $true $base.verify = $true - if ($SchemaChanged) { - $base.migrateProdSchema = $true - } } } @@ -517,21 +516,36 @@ if (Get-StepEnabled $steps 'backupProd') { if (-not $ok) { Write-ReleaseBanner -Success $false -FailedAt $FailedStep; exit 1 } } +function Invoke-MigrateProdSchema { + Assert-ProdDbTarget + $env:DB_NAME = 'gallery_prod' + try { + $code = Invoke-Npm 'dev:migrate' + if ($code -eq 0) { + $script:ProdSchemaMigrated = $true + } + return $code + } finally { + Remove-Item Env:\DB_NAME -ErrorAction SilentlyContinue + } +} + if (Get-StepEnabled $steps 'migrateProdSchema') { $ok = Invoke-Step 'migrateProdSchema' { - Assert-ProdDbTarget - $env:DB_NAME = 'gallery_prod' - try { - $code = Invoke-Npm 'dev:migrate' - return $code - } finally { - Remove-Item Env:\DB_NAME -ErrorAction SilentlyContinue - } + return (Invoke-MigrateProdSchema) } if (-not $ok) { Write-ReleaseBanner -Success $false -FailedAt $FailedStep; exit 1 } } if (Get-StepEnabled $steps 'restoreProd') { + if (-not $script:ProdSchemaMigrated) { + Write-Host 'Auto-running migrateProdSchema before restoreProd (prod schema must match dev backup).' -ForegroundColor Yellow + $ok = Invoke-Step 'migrateProdSchema' { + return (Invoke-MigrateProdSchema) + } + if (-not $ok) { Write-ReleaseBanner -Success $false -FailedAt $FailedStep; exit 1 } + } + $ok = Invoke-Step 'restoreProd' { Assert-ProdDbTarget if (-not $script:backupFile) {