You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.3 KiB
TypeScript

import { query, execute } from '../database/db';
import { normalizeUserIdentifier } from '../utils/userUtils';
import { notifyTaskCreation, notifyTaskAssignment, notifyTaskCompletion } from './notificationService';
// Create a new task
export function createTask(sender: string, params: CreateTaskParams) {
let createdBy = sender;
let assignedTo = params.assignedTo || null;
// Only normalize if it's a user JID, not a group JID
if (!createdBy.endsWith('@g.us')) {
createdBy = normalizeUserIdentifier(createdBy);
}
if (assignedTo && !assignedTo.endsWith('@g.us')) {
assignedTo = normalizeUserIdentifier(assignedTo);
}
const cleanDescription = params.description?.trim() || '';
if (cleanDescription.length < 3) {
throw new Error('La descripción de la tarea debe tener al menos 3 caracteres');
}
if (params.dueDate && !isValidDate(params.dueDate)) {
throw new Error('Fecha inválida. Use el formato YYYY-MM-DD');
}
const result = execute(
'INSERT INTO tasks (description, created_by, assigned_to, due_date, completed) VALUES (?, ?, ?, ?, ?)',
[params.description.trim(), createdBy, assignedTo, params.dueDate || null, false]
);
const task = getTaskById(result.lastInsertRowid);
if (!task) {
throw new Error('Error al crear la tarea');
}
// Notify relevant users
notifyTaskCreation(task);
return task;
}
function isValidDate(dateString: string): boolean {
const date = new Date(dateString);
return !isNaN(date.getTime());
}
// Assign a task
export function assignTask(taskId: number, assignedTo: string) {
execute(
'UPDATE tasks SET assigned_to = ? WHERE id = ?',
[assignedTo, taskId]
);
}
// Mark a task as completed
export function completeTask(taskId: number, completedBy: string) {
const task = getTaskById(taskId);
if (!task) {
throw new Error('Tarea no encontrada');
}
// Only allow completion if task is assigned to the user or to no one
const currentUser = normalizeUserIdentifier(completedBy);
if (task.assignedTo && task.assignedTo !== currentUser) {
throw new Error('No puedes completar una tarea asignada a otro usuario');
}
const result = execute(
'UPDATE tasks SET completed = TRUE, completed_at = CURRENT_TIMESTAMP WHERE id = ?',
[taskId]
);
if (result.changes === 0) {
throw new Error('No se pudo completar la tarea');
}
// Return updated task with completion info
return getTaskById(taskId);
}
// Get all tasks (for debugging or future use)
export function getTasks() {
return query('SELECT * FROM tasks');
}
// Get pending tasks for a specific user
export function getPendingTasks(assignedTo: string) {
return query(
'SELECT * FROM tasks WHERE assigned_to = ? AND completed = FALSE',
[assignedTo]
);
}
// Get task by ID
export function getTaskById(taskId: number) {
if (!Number.isInteger(taskId) || taskId <= 0) {
throw new Error('ID de tarea inválido');
}
const tasks = query(
'SELECT * FROM tasks WHERE id = ?',
[taskId]
);
return tasks[0] || null;
}
// Validate task ID from string input
export function validateTaskId(taskIdStr: string): number {
const taskId = parseInt(taskIdStr);
if (isNaN(taskId) || taskId <= 0) {
throw new Error('ID de tarea inválido. Debe ser un número positivo');
}
return taskId;
}