fix: inyectar db en AllowedGroups y extraer mappers en src/tasks

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
main
brobert 1 month ago
parent e3ec82037b
commit a72184f82c

@ -55,6 +55,7 @@ export function enqueueCompletionReactionIfEligible(db: Database, taskId: number
const mode = String(process.env.GROUP_GATING_MODE || 'off').toLowerCase();
if (mode === 'enforce') {
let allowed = true;
try { (AllowedGroups as any).dbInstance = db; } catch {}
try { allowed = AllowedGroups.isAllowed(chatId); } catch { allowed = true; }
if (!allowed) return;
}

@ -0,0 +1,67 @@
/**
* Mapeadores puros para normalizar filas SQLite a DTOs usados por TaskService.
* Mantienen las mismas formas que consumen comandos, recordatorios y API web.
*/
export function mapTaskListItem(
row: { id: number; description: string; due_date: string | null; group_id: string | null; display_code: number | null },
assignees: string[]
): {
id: number;
description: string;
due_date: string | null;
group_id: string | null;
display_code: number | null;
assignees: string[];
} {
return {
id: Number(row.id),
description: String(row.description || ''),
due_date: row.due_date ? String(row.due_date) : null,
group_id: row.group_id ? String(row.group_id) : null,
display_code: row.display_code != null ? Number(row.display_code) : null,
assignees: Array.isArray(assignees) ? assignees.map(a => String(a)) : []
};
}
export function mapTaskWithGroupNameRow(
row: { id: number; description: string; due_date: string | null; group_id: string | null; display_code: number | null; group_name: string | null }
): {
id: number;
description: string;
due_date: string | null;
group_id: string | null;
group_name: string | null;
display_code: number | null;
} {
return {
id: Number(row.id),
description: String(row.description || ''),
due_date: row.due_date ? String(row.due_date) : null,
group_id: row.group_id ? String(row.group_id) : null,
group_name: row.group_name ? String(row.group_name) : null,
display_code: row.display_code != null ? Number(row.display_code) : null
};
}
export function mapTaskDetailsRow(
row: { id?: number; description?: string; due_date?: string | null; group_id?: string | null; display_code?: number | null; completed?: number; completed_at?: string | null }
): {
id: number;
description: string;
due_date: string | null;
group_id: string | null;
display_code: number | null;
completed: number;
completed_at: string | null;
} {
return {
id: Number(row.id),
description: String(row.description || ''),
due_date: row.due_date ? String(row.due_date) : null,
group_id: row.group_id ? String(row.group_id) : null,
display_code: row.display_code != null ? Number(row.display_code) : null,
completed: Number(row.completed || 0),
completed_at: row.completed_at ? String(row.completed_at) : null
};
}

@ -4,6 +4,7 @@ import { AllowedGroups } from '../services/allowed-groups';
import { isGroupId } from '../utils/whatsapp';
import { pickNextDisplayCode } from './display-code';
import { enqueueCompletionReactionIfEligible } from './complete-reaction';
import { mapTaskListItem, mapTaskWithGroupNameRow, mapTaskDetailsRow } from './mappers';
type CreateTaskInput = {
description: string;
@ -125,14 +126,7 @@ export class TaskService {
return rows.map((r) => {
const assigneesRows = getAssignees.all(r.id) as Array<{ user_id: string }>;
const assignees = assigneesRows.map((a) => String(a.user_id));
return {
id: Number(r.id),
description: String(r.description || ''),
due_date: r.due_date ? String(r.due_date) : null,
group_id: r.group_id ? String(r.group_id) : null,
display_code: r.display_code != null ? Number(r.display_code) : null,
assignees,
};
return mapTaskListItem(r, assignees);
});
}
@ -169,14 +163,7 @@ export class TaskService {
return rows.map((r) => {
const assigneesRows = getAssignees.all(r.id) as Array<{ user_id: string }>;
const assignees = assigneesRows.map((a) => String(a.user_id));
return {
id: Number(r.id),
description: String(r.description || ''),
due_date: r.due_date ? String(r.due_date) : null,
group_id: r.group_id ? String(r.group_id) : null,
display_code: r.display_code != null ? Number(r.display_code) : null,
assignees,
};
return mapTaskListItem(r, assignees);
});
}
@ -290,14 +277,7 @@ export class TaskService {
`)
.all(groupId, limit) as Array<{ id: number; description: string; due_date: string | null; group_id: string | null; display_code: number | null }>;
return rows.map((r) => ({
id: Number(r.id),
description: String(r.description || ''),
due_date: r.due_date ? String(r.due_date) : null,
group_id: r.group_id ? String(r.group_id) : null,
display_code: r.display_code != null ? Number(r.display_code) : null,
assignees: [],
}));
return rows.map((r) => mapTaskListItem(r, []));
}
// Contar pendientes sin dueño del grupo (sin límite)
@ -507,15 +487,7 @@ export class TaskService {
WHERE id = ?
`).get(taskId) as { id?: number; description?: string; due_date?: string | null; group_id?: string | null; completed?: number; completed_at?: string | null; display_code?: number | null } | undefined;
if (!row) return null;
return {
id: Number(row.id),
description: String(row.description || ''),
due_date: row.due_date ? String(row.due_date) : null,
group_id: row.group_id ? String(row.group_id) : null,
display_code: row.display_code != null ? Number(row.display_code) : null,
completed: Number(row.completed || 0),
completed_at: row.completed_at ? String(row.completed_at) : null,
};
return mapTaskDetailsRow(row);
}
// Buscar tarea activa por display_code global
@ -591,14 +563,7 @@ export class TaskService {
`)
.all(limit) as Array<{ id: number; description: string; due_date: string | null; group_id: string | null; display_code: number | null; group_name: string | null }>;
return rows.map(r => ({
id: Number(r.id),
description: String(r.description || ''),
due_date: r.due_date ? String(r.due_date) : null,
group_id: r.group_id ? String(r.group_id) : null,
group_name: r.group_name ? String(r.group_name) : null,
display_code: r.display_code != null ? Number(r.display_code) : null,
}));
return rows.map(r => mapTaskWithGroupNameRow(r));
}
static countAllActive(): number {

Loading…
Cancel
Save