feat: crear tabla response_queue, actualizar tests DB y README

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

@ -60,7 +60,7 @@ graph TD
## Arquitectura de la cola persistente (MVP)
- Estados: queued | processing | sent | failed.
- Campos mínimos por mensaje: id (PK), recipient, type (text), payload_text, status, attempts (0), last_error (nullable), created_at, updated_at.
- Campos mínimos por mensaje: id (PK), recipient, type (text), message, status, attempts (0), last_error (nullable), created_at, updated_at.
- Índices recomendados: (status, created_at) para seleccionar pendientes rápidamente.
- Sin orden estricto por chat; el envío puede intercalarse entre destinatarios.
- Concurrencia: N workers globales operando en bucle, cada uno toma mensajes en estado queued y los marca processing.

@ -72,6 +72,26 @@ export function initializeDatabase(instance: Database) {
FOREIGN KEY (assigned_by) REFERENCES users(id) ON DELETE CASCADE
);
`);
// Create response_queue table (persistent outbox for replies)
instance.exec(`
CREATE TABLE IF NOT EXISTS response_queue (
id INTEGER PRIMARY KEY AUTOINCREMENT,
recipient TEXT NOT NULL,
message TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'queued' CHECK (status IN ('queued','processing','sent','failed')),
attempts INTEGER NOT NULL DEFAULT 0,
last_error TEXT NULL,
created_at TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now')),
updated_at TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now'))
);
`);
// Index to fetch pending items efficiently
instance.exec(`
CREATE INDEX IF NOT EXISTS idx_response_queue_status_created_at
ON response_queue (status, created_at);
`);
}
/**

@ -38,7 +38,7 @@ describe('Database', () => {
.map((t: any) => t.name);
// Order matters if foreign keys are involved during creation, though SQLite is flexible
const expectedTables = ['users', 'groups', 'tasks', 'task_assignments'];
const expectedTables = ['users', 'groups', 'tasks', 'task_assignments', 'response_queue'];
const userTables = tables.filter(t => !t.startsWith('sqlite_'));
// Check if all expected tables exist, order might vary slightly depending on execution
expect(userTables).toHaveLength(expectedTables.length);
@ -82,6 +82,14 @@ describe('Database', () => {
const group = testDb.query("SELECT active FROM groups WHERE id = 'test-group'").get();
expect(group.active).toBe(1); // SQLite uses 1 for TRUE
});
test('response_queue table should have required columns', () => {
const columns = testDb
.query("PRAGMA table_info(response_queue)")
.all()
.map((c: any) => c.name);
expect(columns).toEqual(['id', 'recipient', 'message', 'status', 'attempts', 'last_error', 'created_at', 'updated_at']);
});
});
describe('Foreign Keys', () => {

Loading…
Cancel
Save