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
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;
|
|
}
|