feat: services database, reminders, taskprocessor init

This commit is contained in:
Julien Froidefond
2025-09-13 09:15:31 +02:00
parent ac689a0779
commit c5f0a71e22
6 changed files with 638 additions and 5 deletions

198
services/reminders.ts Normal file
View File

@@ -0,0 +1,198 @@
import { exec } from 'child_process';
import { promisify } from 'util';
import { MacOSReminder } from '@/lib/types';
const execAsync = promisify(exec);
/**
* Service pour récupérer les rappels macOS via AppleScript
* Approche sécurisée qui utilise l'API officielle d'Apple
*/
export class RemindersService {
/**
* Récupère tous les rappels depuis l'app Rappels macOS
*/
async getAllReminders(): Promise<MacOSReminder[]> {
try {
const script = `
tell application "Reminders"
set remindersList to {}
repeat with reminderList in lists
set listName to name of reminderList
repeat with reminder in reminders of reminderList
set reminderRecord to {id:(id of reminder as string), title:(name of reminder), notes:(body of reminder), completed:(completed of reminder), dueDate:missing value, completionDate:missing value, priority:(priority of reminder), list:listName}
-- Gérer la date d'échéance
try
set dueDate of reminderRecord to (due date of reminder as string)
end try
-- Gérer la date de completion
try
if completed of reminder then
set completionDate of reminderRecord to (completion date of reminder as string)
end if
end try
set end of remindersList to reminderRecord
end repeat
end repeat
return remindersList
end tell
`;
const { stdout } = await execAsync(`osascript -e '${script.replace(/'/g, "'\\''")}' 2>/dev/null || echo "[]"`);
return this.parseAppleScriptOutput(stdout);
} catch (error) {
console.error('Erreur lors de la récupération des rappels:', error);
return [];
}
}
/**
* Récupère les rappels d'une liste spécifique
*/
async getRemindersByList(listName: string): Promise<MacOSReminder[]> {
try {
const script = `
tell application "Reminders"
set remindersList to {}
set targetList to list "${listName}"
repeat with reminder in reminders of targetList
set reminderRecord to {id:(id of reminder as string), title:(name of reminder), notes:(body of reminder), completed:(completed of reminder), dueDate:missing value, completionDate:missing value, priority:(priority of reminder), list:"${listName}"}
-- Gérer la date d'échéance
try
set dueDate of reminderRecord to (due date of reminder as string)
end try
-- Gérer la date de completion
try
if completed of reminder then
set completionDate of reminderRecord to (completion date of reminder as string)
end if
end try
set end of remindersList to reminderRecord
end repeat
return remindersList
end tell
`;
const { stdout } = await execAsync(`osascript -e '${script.replace(/'/g, "'\\''")}' 2>/dev/null || echo "[]"`);
return this.parseAppleScriptOutput(stdout);
} catch (error) {
console.error(`Erreur lors de la récupération des rappels de la liste ${listName}:`, error);
return [];
}
}
/**
* Récupère la liste des listes de rappels
*/
async getReminderLists(): Promise<string[]> {
try {
const script = `
tell application "Reminders"
set listNames to {}
repeat with reminderList in lists
set end of listNames to name of reminderList
end repeat
return listNames
end tell
`;
const { stdout } = await execAsync(`osascript -e '${script.replace(/'/g, "'\\''")}' 2>/dev/null || echo ""`);
// Parse la sortie AppleScript pour extraire les noms de listes
const lists = stdout.trim().split(', ').filter(list => list.length > 0);
return lists;
} catch (error) {
console.error('Erreur lors de la récupération des listes:', error);
return [];
}
}
/**
* Test si l'app Rappels est accessible
*/
async testRemindersAccess(): Promise<boolean> {
try {
const script = `
tell application "Reminders"
return count of lists
end tell
`;
await execAsync(`osascript -e '${script.replace(/'/g, "'\\''")}' 2>/dev/null`);
return true;
} catch (error) {
console.error('Impossible d\'accéder à l\'app Rappels:', error);
return false;
}
}
/**
* Parse la sortie AppleScript en objets MacOSReminder
*/
private parseAppleScriptOutput(output: string): MacOSReminder[] {
try {
// AppleScript retourne un format spécial, on doit le parser manuellement
// Pour l'instant, on retourne un tableau vide et on implémentera le parsing plus tard
console.log('Sortie AppleScript brute:', output);
// TODO: Implémenter le parsing complet de la sortie AppleScript
// Pour l'instant, on retourne des données de test
return this.getMockReminders();
} catch (error) {
console.error('Erreur lors du parsing AppleScript:', error);
return [];
}
}
/**
* Données de test pour le développement
*/
private getMockReminders(): MacOSReminder[] {
return [
{
id: 'mock-1',
title: 'Finir le service reminders',
notes: 'Implémenter la récupération des rappels macOS',
completed: false,
dueDate: new Date('2025-01-16'),
priority: 5,
list: 'Travail',
tags: ['dev', 'backend']
},
{
id: 'mock-2',
title: 'Tester l\'intégration Jira',
notes: 'Configurer l\'API Jira pour récupérer les tâches',
completed: false,
dueDate: new Date('2025-01-18'),
priority: 9,
list: 'Projets',
tags: ['jira', 'api']
},
{
id: 'mock-3',
title: 'Créer le Kanban board',
completed: true,
completionDate: new Date('2025-01-10'),
priority: 5,
list: 'Travail',
tags: ['ui', 'frontend']
}
];
}
}
// Instance singleton
export const remindersService = new RemindersService();