feat: activar WAL en SQLite y actualizar STATUS.md y .gitignore

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
pull/1/head
borja 2 months ago
parent bff4c99876
commit bdba776b5c

2
.gitignore vendored

@ -36,5 +36,7 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# DB
*.db
*.db-wal
*.db-shm
/data/*
!data/.gitkeep

@ -11,6 +11,7 @@ Estado general: listo para piloto con la junta directiva; 170 tests pasando. Rie
- Base de datos y migraciones
- Inicialización con PRAGMA FK y timestamps de alta precisión.
- Esquema: users, tasks, task_assignments, user_preferences, response_queue (con metadata).
- Modo journal WAL activado (busy_timeout y autocheckpoint configurados) para mejorar concurrencia y rendimiento.
- Migrador up-only con tabla schema_migrations; backup automático con VACUUM INTO; baseline si existe esquema previo.
- Cola de respuestas
- Persistente con workers en background, reintentos con backoff exponencial + jitter, recuperación de items processing tras reinicios, y limpieza/retención.
@ -77,7 +78,7 @@ Estado general: listo para piloto con la junta directiva; 170 tests pasando. Rie
- Falta: pruebas E2E reales contra Evolution API (recomendado antes del piloto).
## Notas de despliegue/operación
- Migraciones up-only al arranque; backup con VACUUM INTO previo.
- SQLite en modo WAL; backups consistentes con VACUUM INTO previo; tener en cuenta archivos -wal y -shm.
- Persistencia en data/; mapear a volumen y monitorizar tamaño; ejecutar VACUUM periódicamente si procede.
- Rotación de logs vía orquestador; considerar niveles/etiquetas para búsquedas.

@ -3,6 +3,18 @@ import { normalizeWhatsAppId } from './utils/whatsapp';
import { mkdirSync } from 'fs';
import { join } from 'path';
function applyDefaultPragmas(instance: Database): void {
try {
instance.exec(`PRAGMA busy_timeout = 5000;`);
// Intentar activar WAL (si no es soportado, SQLite devolverá 'memory' u otro modo)
instance.query(`PRAGMA journal_mode = WAL`).get();
instance.exec(`PRAGMA synchronous = NORMAL;`);
instance.exec(`PRAGMA wal_autocheckpoint = 1000;`);
} catch (e) {
console.warn('[db] No se pudieron aplicar PRAGMAs (WAL, busy_timeout...):', e);
}
}
// Function to get a database instance. Defaults to 'data/tasks.db'
export function getDb(filename: string = 'tasks.db'): Database {
// Try to create data directory if it doesn't exist (ignore if already exists)
@ -11,7 +23,9 @@ export function getDb(filename: string = 'tasks.db'): Database {
} catch (err) {
if (err.code !== 'EEXIST') throw err; // Only ignore "already exists" errors
}
return new Database(join('data', filename));
const instance = new Database(join('data', filename));
applyDefaultPragmas(instance);
return instance;
}
// Default export for the main application database
@ -19,6 +33,9 @@ export const db = getDb();
// Initialize function now accepts a database instance
export function initializeDatabase(instance: Database) {
// Aplicar PRAGMAs por defecto (WAL, busy_timeout, etc.)
applyDefaultPragmas(instance);
// Enable foreign key constraints
instance.exec(`PRAGMA foreign_keys = ON;`);

Loading…
Cancel
Save