fix(backup): corregir descarga y añadir restauración de BD

- Backend usa DATABASE_URL (resolvePgConnInfo) en vez de DB_* que no
  existían en el contenedor API, arreglando el fallo de pg_dump
- Dockerfile backend: alpine 3.23 para pg_dump 18.4 (compatible con
  PostgreSQL 18 del servidor)
- BackupDatabase ya no usa docker exec (no disponible en la imagen)
- Nuevo endpoint POST /api/admin/restore para restaurar .sql o .zip vía psql
- UI de Configuración: sección Restaurar Base de Datos
- Regenerado go.sum para el build
This commit is contained in:
jlimolina 2026-08-10 15:25:41 +02:00
parent ecd7a3cdf8
commit a285021e6c
22 changed files with 7624 additions and 450 deletions

View file

@ -0,0 +1,11 @@
BEGIN;
-- Columnas para el clustering de noticias (cluster_worker.py)
ALTER TABLE eventos
ADD COLUMN IF NOT EXISTS centroid JSONB,
ADD COLUMN IF NOT EXISTS total_traducciones INTEGER DEFAULT 1,
ADD COLUMN IF NOT EXISTS fecha_inicio TIMESTAMP,
ADD COLUMN IF NOT EXISTS fecha_fin TIMESTAMP,
ADD COLUMN IF NOT EXISTS n_noticias INTEGER DEFAULT 1;
COMMIT;

View file

@ -0,0 +1,18 @@
BEGIN;
INSERT INTO topics (nombre, descripcion, weight, keywords) VALUES
('Política', 'Noticias políticas y de gobierno', 3, 'política,político,gobierno,presidente,ministro,parlamento,elecciones,partido,senado,diputado'),
('Economía', 'Economía y finanzas', 3, 'economía,económico,finanzas,mercado,inflación,banco,bancos,empresa,empresas,negocio,bolsa,inversión,presupuesto,impuestos'),
('Seguridad', 'Seguridad y defensa', 3, 'seguridad,ataque,ataques,explosión,terrorismo,terrorista,ejército,militar,patrulla,armas,policía'),
('Afganistán', 'Asuntos de Afganistán', 4, 'afganistán,afgano,afgana,kabul,candahar,kandahar,herat,mazar,talibán,talibanes,emirato'),
('Conflicto', 'Conflictos y guerra', 3, 'conflicto,guerra,enfrentamiento,enfrentamientos,crisis,víctimas,frontera,invasIón,ocupación'),
('Internacional', 'Relaciones internacionales', 2, 'internacional,diplomacia,diplomático,acuerdo,acuerdos,naciones unidas,embajador,tratado,extranjero'),
('Deportes', 'Deportes y competiciones', 2, 'deportes,deporte,fútbol,futbol,partido,equipo,liga,campeonato,tenis,baloncesto,cricket,selección'),
('Salud', 'Salud y medicina', 2, 'salud,hospital,médico,médicos,enfermedad,vacuna,tratamiento,pandemia,clínica,medicina'),
('Tecnología', 'Tecnología y digital', 2, 'tecnología,internet,digital,telefonía,telecomunicaciones,software,aplicación,aplicaciones,internet,tecnológico'),
('Educación', 'Educación y enseñanza', 2, 'educación,escuela,escuelas,universidad,universidades,estudiantes,profesor,enseñanza,academia,alumnos'),
('Cultura', 'Cultura y arte', 1, 'cultura,arte,literatura,cine,música,música,patrimonio,historia,museo,libro,libros'),
('Medio Ambiente', 'Clima y medio ambiente', 2, 'medio ambiente,clima,cambio climático,contaminación,sequía,inundación,agua,ecología,desastre natural')
ON CONFLICT (nombre) DO NOTHING;
COMMIT;

View file

@ -0,0 +1,7 @@
BEGIN;
-- El worker topics escribe en score (topics/main.go usa news_topics.score)
ALTER TABLE news_topics
ADD COLUMN IF NOT EXISTS score INTEGER DEFAULT 0;
COMMIT;

View file

@ -0,0 +1,10 @@
BEGIN;
-- El worker related (cmd/related/main.go) trabaja con traducciones
ALTER TABLE related_noticias
ADD COLUMN IF NOT EXISTS related_traduccion_id INTEGER REFERENCES traducciones(id) ON DELETE CASCADE;
CREATE UNIQUE INDEX IF NOT EXISTS idx_related_tr_pair
ON related_noticias(traduccion_id, related_traduccion_id);
COMMIT;

View file

@ -0,0 +1,2 @@
ALTER TABLE traducciones ADD COLUMN IF NOT EXISTS vectorization_date TIMESTAMP;
ALTER TABLE traducciones ADD COLUMN IF NOT EXISTS qdrant_point_id TEXT;