// Lecture de la configuration mail (singleton admin) export type MailConfigurationDto = { protocol: string | null imapHost: string | null imapPort: number | null imapEncryption: string | null smtpHost: string | null smtpPort: number | null smtpEncryption: string | null username: string | null sentFolderPath: string | null enabled: boolean hasPassword: boolean // password JAMAIS présent dans les réponses GET } // Input PATCH configuration (password optionnel, write-only) export type MailConfigurationUpdateDto = { protocol?: string | null imapHost?: string | null imapPort?: number | null imapEncryption?: string | null smtpHost?: string | null smtpPort?: number | null smtpEncryption?: string | null username?: string | null sentFolderPath?: string | null enabled?: boolean password?: string // write-only, jamais retourné } // Résultat du test de connexion export type MailTestConnectionResultDto = { ok: boolean foldersCount?: number error?: string } // Dossier mail (peut être imbriqué) export type MailFolderDto = { path: string displayName: string parentPath: string | null unreadCount: number totalCount: number children?: MailFolderDto[] } // Adresse mail (nom + email) export type MailAddressDto = { name: string | null email: string } // En-tête d'un message (liste) export type MailMessageHeaderDto = { id: number messageId: string // identifiant IMAP unique folderPath: string subject: string | null fromName: string | null fromEmail: string | null toRecipients: MailAddressDto[] ccRecipients: MailAddressDto[] sentAt: string | null // ISO 8601 receivedAt: string // ISO 8601 isRead: boolean isFlagged: boolean hasAttachments: boolean linkedTaskIds: number[] } // Pièce jointe (métadonnées uniquement, téléchargement via downloadId) export type MailAttachmentDto = { downloadId: string filename: string mimeType: string size: number // octets } // Détail complet d'un message (enrichi avec body + PJ) export type MailMessageDetailDto = { header: MailMessageHeaderDto bodyHtml: string | null // HTML brut — TOUJOURS passer par sanitizeMailHtml() avant affichage bodyText: string | null // Fallback texte plain attachments: MailAttachmentDto[] } // Page de messages paginée (cursor-based) export type MailMessagesPageDto = { items: MailMessageHeaderDto[] nextCursor: string | null // null = plus de page suivante total: number } // Input : marquer lu/non-lu export type MailMessageReadInput = { read: boolean } // Input : marquer étoilé/non-étoilé export type MailMessageFlagInput = { flagged: boolean } // Input : créer une tâche depuis un mail export type MailCreateTaskInput = { projectId: number taskGroupId?: number | null priority?: string | null } // Input : lier une tâche existante à un mail export type MailLinkTaskInput = { taskId: number } // Résultat de la sync manuelle export type MailSyncResultDto = { dispatched: boolean }