/** Automation workflow graph — mirrors backend rules.Workflow */ export type RuleKind = 'rule' | 'function' export type TriggerType = | 'message_received' | 'label_added' | 'label_removed' | 'drive_file_created' | 'drive_file_updated' | 'drive_file_deleted' | 'drive_file_moved' | 'drive_share_updated' | 'contact_created' | 'contact_updated' | 'contact_deleted' | 'calendar_event_created' | 'calendar_event_updated' | 'calendar_event_deleted' | 'calendar_event_response' export interface AutomationTrigger { type: TriggerType folder_id?: string label?: string account_id?: string /** Chemin Drive (filtre optionnel sur les déclencheurs Drive) */ folder_path?: string /** Libellé contact (filtre optionnel sur les déclencheurs Contacts) */ contact_label?: string /** Agenda cible (filtre optionnel sur les déclencheurs Agenda) */ calendar_id?: string } export interface TriggerAndGroup { operator: 'and' items: AutomationTrigger[] } export interface TriggerOrGroup { operator: 'or' groups: TriggerAndGroup[] } export interface ExecVariable { name: string type: 'string' | 'number' | 'boolean' default?: string } export type WorkflowNodeType = | 'start' | 'condition' | 'label_check' | 'switch' | 'llm_check' | 'actions' | 'set_var' | 'call_function' | 'call_rule' | 'end' export type ConditionField = | 'from' | 'to' | 'subject' | 'body' | 'has_attachment' | 'label' | 'drive_file_name' | 'drive_file_path' | 'drive_mime_type' | 'drive_file_size' | 'drive_is_folder' | 'contact_name' | 'contact_email' | 'contact_phone' | 'contact_org' | 'contact_label' | 'calendar_event_title' | 'calendar_event_location' | 'calendar_event_organizer' | 'calendar_event_attendee' | 'calendar_event_all_day' | 'calendar_event_has_video' export type ConditionOperator = | 'contains' | 'equals' | 'starts_with' | 'ends_with' | 'not_contains' | 'regex' | 'not_regex' | 'has' | 'not_has' export interface ConditionNodeData { field: ConditionField operator: ConditionOperator value: string } /** @deprecated Legacy node — migrated to condition with field=label */ export interface LabelCheckNodeData { label: string operator: 'has' | 'not_has' } export interface SwitchCase { value: string label?: string } export interface SwitchNodeData { field: string cases: SwitchCase[] } export interface LLMCheckNodeData { prompt: string provider?: string model?: string } export type ActionType = | 'label' | 'remove_label' | 'move' | 'archive' | 'delete' | 'mark_read' | 'mark_important' | 'mark_spam' | 'star' | 'webhook' | 'notify' | 'reply' | 'send_mail' | 'forward' | 'drive_move' | 'drive_rename' | 'drive_delete' | 'drive_share' | 'drive_copy' | 'contact_add_label' | 'contact_remove_label' | 'contact_delete' | 'calendar_add_attendee' | 'calendar_update_title' | 'calendar_cancel_event' | 'calendar_notify_attendees' export interface ActionItem { type: ActionType value: string } export interface ActionsNodeData { actions: ActionItem[] } export interface SetVarNodeData { name: string value: string } export interface CallRuleNodeData { rule_id: string } export type WorkflowNodeData = | Record | ConditionNodeData | LabelCheckNodeData | SwitchNodeData | LLMCheckNodeData | ActionsNodeData | SetVarNodeData | CallRuleNodeData export interface WorkflowNodeDef { id: string type: WorkflowNodeType position: { x: number; y: number } data: WorkflowNodeData } export interface WorkflowEdgeDef { id: string source: string target: string sourceHandle?: string } export interface AutomationWorkflow { version: 1 kind: RuleKind triggers: TriggerOrGroup variables: ExecVariable[] nodes: WorkflowNodeDef[] edges: WorkflowEdgeDef[] } export interface RuleSimulationMessage { from: string to: string[] subject: string body_text: string has_attachments: boolean labels?: string[] } export interface RuleSimulationDriveFile { file_name: string file_path: string mime_type: string file_size: number is_folder: boolean } export interface RuleSimulationContact { name: string email: string phone: string org: string labels?: string[] } export interface RuleSimulationCalendarEvent { title: string location: string organizer: string attendee: string start: string end: string all_day: boolean has_video: boolean calendar_id: string } export interface RuleSimulationStep { node_id: string node_type: string handle?: string } export interface RuleSimulationResult { matched: boolean steps?: RuleSimulationStep[] actions?: Array<{ type: string value: string ok: boolean error?: string simulated_payload?: string }> } export interface RuleEditorState { name: string priority: number is_active: boolean rule_kind: RuleKind account_id?: string workflow: AutomationWorkflow }