feat: mostrar resumen '… y N más' en recordatorios cuando hay tope

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
pull/1/head
borja 1 month ago
parent db9f71abaa
commit 78efc857bc

@ -111,6 +111,7 @@ export class RemindersService {
try {
const allItems = TaskService.listUserPending(pref.user_id, 10);
const items = enforce ? allItems.filter(t => !t.group_id || AllowedGroups.isAllowed(t.group_id)) : allItems;
const total = TaskService.countUserPending(pref.user_id);
if (!items || items.length === 0) {
// No enviar si no hay tareas; no marcamos last_reminded_on para permitir enviar si aparecen más tarde hoy
continue;
@ -159,7 +160,10 @@ export class RemindersService {
sections.push(...rendered);
}
// No contamos "total" global para evitar inconsistencias de grupos bloqueados; dejamos el resumen por ítems visibles.
// Si hay más tareas de las listadas (tope), añadir resumen
if (total > items.length) {
sections.push(italic(`… y ${total - items.length} más`));
}
// (Etapa 3) Sección opcional de "sin responsable" filtrada por membresía activa + snapshot fresca.
const includeUnassigned = String(process.env.REMINDERS_INCLUDE_UNASSIGNED_FROM_MEMBERSHIP || '').toLowerCase() === 'true';

@ -5,21 +5,54 @@ import { TaskService } from '../../../src/tasks/service';
import { AllowedGroups } from '../../../src/services/allowed-groups';
function seedGroup(db: Database, groupId: string) {
// Intento genérico de seed para la tabla groups con columnas comunes
// Sembrado robusto: cubrir columnas NOT NULL sin valor por defecto
const cols = db.query(`PRAGMA table_info(groups)`).all() as any[];
const colNames = cols.map(c => String(c.name));
const values: Record<string, any> = {};
for (const c of colNames) {
if (c === 'id') values[c] = groupId;
else if (c === 'name' || c === 'title' || c === 'subject') values[c] = 'Test Group';
else if (c === 'is_active' || c === 'active') values[c] = 1;
else if (c.endsWith('_at')) values[c] = new Date().toISOString().replace('T', ' ').replace('Z', '');
else if (c === 'created_by') values[c] = 'tester';
// Para otras columnas dejaremos NULL si lo permite
const nowIso = new Date().toISOString().replace('T', ' ').replace('Z', '');
for (const c of cols) {
const name = String(c.name);
const type = String(c.type || '').toUpperCase();
const notnull = Number(c.notnull || 0) === 1;
const hasDefault = c.dflt_value != null;
if (name === 'id') {
values[name] = groupId;
continue;
}
// Preconfigurar algunos alias comunes
if (name === 'name' || name === 'title' || name === 'subject') {
values[name] = 'Test Group';
continue;
}
if (name === 'created_by') {
values[name] = 'tester';
continue;
}
if (name.endsWith('_at')) {
values[name] = nowIso;
continue;
}
if (name === 'is_active' || name === 'active') {
values[name] = 1;
continue;
}
// Para columnas NOT NULL sin valor por defecto, asignar valores genéricos
if (notnull && !hasDefault) {
if (type.includes('INT')) values[name] = 1;
else if (type.includes('REAL')) values[name] = 0;
else values[name] = 'N/A';
}
}
// Asegurar que id esté siempre
if (!('id' in values)) values['id'] = groupId;
const colsList = Object.keys(values);
const placeholders = colsList.map(() => '?').join(', ');
const sql = `INSERT OR IGNORE INTO groups (${colsList.join(', ')}) VALUES (${placeholders})`;
const sql = `INSERT OR REPLACE INTO groups (${colsList.join(', ')}) VALUES (${placeholders})`;
db.prepare(sql).run(...colsList.map(k => values[k]));
}

Loading…
Cancel
Save