-- Migración 001 (UP): integración CloudRestoreAS. -- Servidores de restauración (Alfa/Omega/Gamma) + asignación por base de datos -- (database_nodes.restore_target_id) + bitácora de jobs. Idempotente. -- Rollback en 001_restore_targets.down.sql. CREATE SCHEMA IF NOT EXISTS a24c; CREATE TABLE IF NOT EXISTS a24c.restore_targets ( id SERIAL PRIMARY KEY, name VARCHAR(120) NOT NULL UNIQUE, server_ip VARCHAR(255), sql_username VARCHAR(128), sql_password_encrypted TEXT, data_folder VARCHAR(500), ssh_host VARCHAR(255), ssh_port INTEGER DEFAULT 22, ssh_username VARCHAR(128), ssh_password_encrypted TEXT, remote_inbox_path VARCHAR(500), notes TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); INSERT INTO a24c.restore_targets (name) VALUES ('Alfa'), ('Omega'), ('Gamma') ON CONFLICT (name) DO NOTHING; -- Columna de asignación en database_nodes (tabla aprovisionada por el backend a24c). ALTER TABLE a24c.database_nodes ADD COLUMN IF NOT EXISTS restore_target_id INTEGER REFERENCES a24c.restore_targets (id) ON DELETE SET NULL; CREATE TABLE IF NOT EXISTS a24c.restore_job_logs ( id SERIAL PRIMARY KEY, filename VARCHAR(500) NOT NULL, restore_target_id INTEGER REFERENCES a24c.restore_targets (id) ON DELETE SET NULL, db_name VARCHAR(255), status VARCHAR(20) NOT NULL CHECK (status IN ('completed', 'failed', 'forwarded')), duration_ms INTEGER, error_message TEXT, restored_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_a24c_restore_job_logs_target ON a24c.restore_job_logs (restore_target_id); CREATE INDEX IF NOT EXISTS idx_a24c_restore_job_logs_restored_at ON a24c.restore_job_logs (restored_at); CREATE INDEX IF NOT EXISTS idx_a24c_restore_job_logs_status ON a24c.restore_job_logs (status);