Checkpoint: Ajout du bouton "Vérifier maintenant" pour forcer une vérification immédiate des emails sans attendre le prochain cycle automatique.

This commit is contained in:
Manus
2026-02-11 05:52:56 -05:00
parent fcf9e8f7b7
commit 2715c9e0c7
7 changed files with 139 additions and 3 deletions

View File

@@ -0,0 +1,26 @@
{
"query": "SELECT * FROM importSettings;",
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.bd4328423008 --database fo4DRyBgjsuiigFAgNLuWm --execute SELECT * FROM importSettings;",
"rows": [
{
"id": "1",
"userId": "1",
"manualImportEnabled": "1",
"autoImportEnabled": "0",
"autoImportSourcePath": "NULL",
"autoImportFrequency": "60",
"emailImportEnabled": "1",
"emailImportAddress": "test-applicatif@itinova.org",
"emailImportPassword": "X.184037964588um",
"emailImportHost": "outlook.office365.com",
"emailImportPort": "993",
"emailImportFrequency": "2",
"createdAt": "2026-02-11 10:07:32",
"updatedAt": "2026-02-11 10:34:09"
}
],
"messages": [],
"stdout": "id\tuserId\tmanualImportEnabled\tautoImportEnabled\tautoImportSourcePath\tautoImportFrequency\temailImportEnabled\temailImportAddress\temailImportPassword\temailImportHost\temailImportPort\temailImportFrequency\tcreatedAt\tupdatedAt\n1\t1\t1\t0\tNULL\t60\t1\ttest-applicatif@itinova.org\tX.184037964588um\toutlook.office365.com\t993\t2\t2026-02-11 10:07:32\t2026-02-11 10:34:09\n",
"stderr": "",
"execution_time_ms": 225
}

View File

@@ -0,0 +1,18 @@
{
"query": "SELECT \n userId,\n emailImportEnabled,\n emailImportAddress,\n emailImportHost,\n emailImportPort,\n emailImportFrequency\nFROM importSettings;",
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.bd4328423008 --database fo4DRyBgjsuiigFAgNLuWm --execute SELECT \n userId,\n emailImportEnabled,\n emailImportAddress,\n emailImportHost,\n emailImportPort,\n emailImportFrequency\nFROM importSettings;",
"rows": [
{
"userId": "1",
"emailImportEnabled": "1",
"emailImportAddress": "test-applicatif@itinova.org",
"emailImportHost": "outlook.office365.com",
"emailImportPort": "993",
"emailImportFrequency": "2"
}
],
"messages": [],
"stdout": "userId\temailImportEnabled\temailImportAddress\temailImportHost\temailImportPort\temailImportFrequency\n1\t1\ttest-applicatif@itinova.org\toutlook.office365.com\t993\t2\n",
"stderr": "",
"execution_time_ms": 54
}

View File

@@ -0,0 +1,8 @@
{
"query": "SELECT \n userId,\n manualImportEnabled,\n folderImportEnabled,\n folderImportPath,\n folderImportFrequency,\n emailImportEnabled,\n emailImportAddress,\n emailImportHost,\n emailImportPort,\n emailImportFrequency\nFROM importSettings;",
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.bd4328423008 --database fo4DRyBgjsuiigFAgNLuWm --execute SELECT \n userId,\n manualImportEnabled,\n folderImportEnabled,\n folderImportPath,\n folderImportFrequency,\n emailImportEnabled,\n emailImportAddress,\n emailImportHost,\n emailImportPort,\n emailImportFrequency\nFROM importSettings;",
"returncode": 1,
"logs": [
"ERROR 1054 (42S22) at line 1: Unknown column 'folderimportenabled' in 'field list'"
]
}

View File

@@ -16,6 +16,8 @@ export default function ImportSettings() {
const updateMutation = trpc.importSettings.update.useMutation();
const startEmailServiceMutation = trpc.emailImportService.start.useMutation();
const stopEmailServiceMutation = trpc.emailImportService.stop.useMutation();
const checkNowEmailMutation = trpc.emailImportService.checkNow.useMutation();
const utils = trpc.useUtils();
const startFolderServiceMutation = trpc.folderImportService.start.useMutation();
const stopFolderServiceMutation = trpc.folderImportService.stop.useMutation();
@@ -413,6 +415,42 @@ export default function ImportSettings() {
Service actif
</span>
)}
{emailServiceStatus?.isRunning && (
<Button
variant="outline"
onClick={async () => {
try {
toast.info("V\u00e9rification en cours...", {
description: "Connexion au serveur IMAP et recherche de nouveaux emails.",
});
const result = await checkNowEmailMutation.mutateAsync();
if (result.success) {
await utils.importLogs.getByUser.invalidate();
toast.success("V\u00e9rification termin\u00e9e", {
description: result.message,
});
} else {
toast.error("Erreur", {
description: result.message,
});
}
} catch (error: any) {
toast.error("Erreur", {
description: error.message || "Impossible de v\u00e9rifier les emails.",
});
}
}}
disabled={checkNowEmailMutation.isPending}
>
{checkNowEmailMutation.isPending ? (
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
) : (
<Mail className="mr-2 h-4 w-4" />
)}
V\u00e9rifier maintenant
</Button>
)}
</div>
</>
)}

View File

@@ -442,6 +442,40 @@ export function isEmailImportServiceRunning(userId: number): boolean {
return activeIntervals.has(userId);
}
/**
* Manually trigger an immediate email check for a user
*/
export async function triggerEmailCheck(userId: number): Promise<{ success: boolean; message: string }> {
try {
// Get user's import settings
const settings = await getImportSettingsByUser(userId);
if (!settings || settings.emailImportEnabled !== 1) {
return { success: false, message: "Import par email non activ\u00e9" };
}
if (!settings.emailImportAddress || !settings.emailImportPassword || !settings.emailImportHost) {
return { success: false, message: "Configuration IMAP incompl\u00e8te" };
}
const config: EmailImportConfig = {
userId,
emailAddress: settings.emailImportAddress,
password: settings.emailImportPassword,
host: settings.emailImportHost,
port: settings.emailImportPort || 993,
};
console.log(`[EmailImport] Manual check triggered for user ${userId}`);
await checkEmailsForPDFs(config);
return { success: true, message: "V\u00e9rification termin\u00e9e avec succ\u00e8s" };
} catch (error: any) {
console.error(`[EmailImport] Error during manual check for user ${userId}:`, error);
return { success: false, message: `Erreur: ${error.message}` };
}
}
/**
* Stop all email import services
*/

View File

@@ -34,7 +34,7 @@ import { loginLocal, hashPassword, getAzureAuthUrl, isAzureAdConfigured, generat
import { extractInvoicesWithMistral, generateMetadataJSON } from "./invoiceExtractor";
import { localStoragePut, generateStorageKey } from "./localStorage";
import { testSftpConnection, exportInvoiceToSftp, getUserSftpConfig } from "./sftpExport";
import { startEmailImportService, stopEmailImportService, isEmailImportServiceRunning } from "./emailImportService";
import { startEmailImportService, stopEmailImportService, isEmailImportServiceRunning, triggerEmailCheck } from "./emailImportService";
import { startFolderImportService, stopFolderImportService, isFolderImportServiceRunning } from "./folderImportService";
import { TRPCError } from "@trpc/server";
@@ -614,8 +614,12 @@ export const appRouter = router({
}),
status: protectedProcedure.query(async ({ ctx }) => {
const isRunning = isEmailImportServiceRunning(ctx.user.id);
return { isRunning };
return { isRunning: isEmailImportServiceRunning(ctx.user.id) };
}),
checkNow: protectedProcedure.mutation(async ({ ctx }) => {
const result = await triggerEmailCheck(ctx.user.id);
return result;
}),
}),

View File

@@ -183,3 +183,11 @@
- [x] Ajouter bouton "Effacer les logs" dans la page History
- [x] Ajouter confirmation avant suppression (AlertDialog)
- [x] Tester la fonctionnalité
## Bug : Import automatique par email ne fonctionne pas
- [x] Vérifier la configuration IMAP dans la base de données
- [x] Vérifier si le service d'import email est démarré
- [x] Ajouter un bouton "Vérifier maintenant" pour forcer une vérification immédiate
- [x] Ajouter fonction triggerEmailCheck dans emailImportService
- [x] Ajouter route tRPC emailImportService.checkNow
- [ ] Tester avec un email réel et diagnostiquer les erreurs IMAP