# Email Rules vs Workflows - Analyse ## 🔍 Oversigt BMC Hub har **2 systemer** til automatisk email-behandling: 1. **Email Rules** (legacy) - `email_rules` tabel 2. **Email Workflows** (nyere) - `email_workflows` tabel ## ⚙️ Hvordan Fungerer De? ### Email Processing Flow ``` 📧 Ny Email Modtaget ↓ 1️⃣ Save email til database (email_messages) ↓ 2️⃣ Classify med AI/simple classifier ↓ (classification + confidence_score gemmes) ↓ 3️⃣ Execute WORKFLOWS først 🆕 ├─ Finder workflows med matching classification ├─ Tjekker confidence_threshold ├─ Checker sender/subject patterns (regex) ├─ Executer workflow steps i rækkefølge └─ Stopper hvis stop_on_match=true ↓ 4️⃣ Match RULES bagefter (legacy) 🕰️ ├─ Finder rules med matching conditions ├─ Tjekker sender, domain, classification, subject ├─ Executer rule action (kun 1 action per rule) └─ Stopper efter første match ``` ## 🆚 Forskelle | Feature | Email Rules (Legacy) | Email Workflows (Ny) | |---------|---------------------|---------------------| | **Fleksibilitet** | Enkelt action per rule | Multiple steps per workflow | | **Priority** | Ja (priority field) | Ja (priority field) | | **Stop on match** | Implicit (første match vinder) | Explicit (stop_on_match flag) | | **Pattern matching** | Basic (exact match, contains) | Advanced (regex patterns) | | **Confidence check** | Nej | Ja (confidence_threshold) | | **Execution tracking** | Nej | Ja (email_workflow_executions) | | **Statistics** | Ja (match_count) | Ja (execution_count, success/failure) | | **Actions** | 5 types | 10+ types | | **Database table** | email_rules | email_workflows | | **Enabled by** | EMAIL_RULES_ENABLED | EMAIL_WORKFLOWS_ENABLED | | **Auto-execute** | EMAIL_RULES_AUTO_PROCESS | Altid (hvis enabled) | ## ⚠️ PROBLEM: Duplikering og Konflikter ### 1. Begge Kan Køre Samtidigt **Scenarie:** ``` Email: Faktura fra leverandør@example.com Classification: invoice, confidence: 0.95 WORKFLOW matches: - "Invoice Processing Workflow" → Steps: link_to_vendor, extract_invoice_data, mark_as_processed → Executes first! ✅ RULE matches: - "Link Supplier Emails" → Action: link_supplier → Executes after! ⚠️ RESULTAT: link_to_vendor køres 2 gange! ``` ### 2. Ingen Koordination Workflows ved ikke om rules har kørt (eller omvendt). **Problem:** - Email kan markeres som "processed" af workflow - Rule prøver stadig at køre action bagefter - Resultatet logges 2 steder (workflow_executions + rule match_count) ### 3. Overlappende Actions **Samme funktionalitet i begge systemer:** | Action Type | Rule Name | Workflow Action | |-------------|-----------|----------------| | Link vendor | `link_supplier` | `link_to_vendor` | | Link customer | `link_customer` | `link_to_customer` | | Mark spam | `mark_spam` | *(mangler)* | | Link case | `link_case` | `create_ticket` | | Invoice extraction | *(mangler)* | `extract_invoice_data` | ### 4. Auto-Process Flag Virker Ikke for Workflows **I koden:** ```python # Rules respekterer auto-process flag if self.auto_process: await self._execute_rule_action(email_data, rule) else: logger.info(f"⏭️ Auto-process disabled - rule action not executed") # Workflows kører ALTID hvis enabled=true workflow_result = await email_workflow_service.execute_workflows(email_data) ``` **Problem:** Man kan ikke disable workflow auto-execution uden at disable hele workflow systemet. ## ✅ Hvad Virker Godt ### 1. Workflows Er Mere Kraftfulde - Multi-step execution - Better tracking (execution history) - Regex pattern matching - Confidence threshold check - Success/failure statistics ### 2. Rules Er Simplere - God til simple hvis-så logik - Lettere at forstå for non-technical brugere - Fungerer fint for basic email routing ### 3. Begge Har Priority Ordering - Workflows executes i priority order - Rules matches i priority order - Første match kan stoppe kæden (hvis configured) ## 🐛 Konkrete Bugs Fundet ### Bug #1: Workflow Executes ALTID **Kode:** `email_processor_service.py` line 77-79 ```python # Step 4: Execute workflows based on classification workflow_result = await email_workflow_service.execute_workflows(email_data) ``` **Problem:** Ingen check af `EMAIL_RULES_AUTO_PROCESS` eller lignende flag. **Fix:** ```python if settings.EMAIL_WORKFLOWS_ENABLED: workflow_result = await email_workflow_service.execute_workflows(email_data) ``` ### Bug #2: Rules Kører Efter Workflows **Kode:** `email_processor_service.py` line 84-88 ```python # Step 5: Match against rules (legacy support) if self.rules_enabled: matched = await self._match_rules(email_data) ``` **Problem:** Hvis workflow allerede har processed emailen, skal rule ikke køre. **Fix:** ```python # Step 5: Match against rules (legacy support) - skip if already processed by workflow if self.rules_enabled and not email_data.get('_workflow_processed'): matched = await self._match_rules(email_data) ``` ### Bug #3: Manglende Deduplication **Problem:** Samme action kan executes af både workflow og rule. **Fix:** Add check i rule execution: ```python # Check if email already processed by workflow already_processed = execute_query( "SELECT id FROM email_workflow_executions WHERE email_id = %s AND status = 'completed'", (email_id,), fetchone=True ) if already_processed: logger.info(f"⏭️ Email already processed by workflow, skipping rule") return False ``` ### Bug #4: `extract_invoice_data` Workflow Action Kan Fejle Stille **Kode:** `email_workflow_service.py` line 380+ ```python if not file_path.exists(): # No error raised! Just continues... ``` **Problem:** Hvis PDF fil ikke findes, fejler workflow ikke - den fortsætter bare. **Fix:** Raise exception: ```python if not file_path.exists(): raise FileNotFoundError(f"Attachment file not found: {attachment_path}") ``` ## 💡 Anbefalinger ### Anbefaling #1: Vælg ÉT System **Option A: Deprecate Rules (anbefalet)** - Workflows er mere kraftfulde - Better tracking og debugging - Fremtidssikret arkitektur **Migration plan:** 1. Opret workflows der matcher alle aktive rules 2. Disable rules (set enabled=false) 3. Test workflows grundigt 4. Fjern rule execution fra processor **Option B: Keep Both, Men Koordinér** - Add `_workflow_processed` flag til email_data - Skip rules hvis workflow har kørt - Document clearly når man skal bruge rules vs workflows ### Anbefaling #2: Tilføj Workflow Auto-Process Flag **Tilføj til `email_workflows` tabel:** ```sql ALTER TABLE email_workflows ADD COLUMN auto_execute BOOLEAN DEFAULT true; ``` **Check flag før execution:** ```python if workflow.get('auto_execute', True): result = await self._execute_workflow(workflow, email_data) ``` ### Anbefaling #3: Unified Action Registry **Opret fælles action handlers:** ```python # shared/email_actions.py class EmailActions: @staticmethod async def link_to_vendor(email_id, vendor_id): # Single implementation used by both rules and workflows ... ``` ### Anbefaling #4: Better Conflict Detection **Add admin UI warning:** ```python # Check for overlapping rules and workflows def check_conflicts(): conflicts = [] for rule in active_rules: for workflow in active_workflows: if might_conflict(rule, workflow): conflicts.append({ 'rule': rule['name'], 'workflow': workflow['name'], 'reason': 'Both match same classification' }) return conflicts ``` ### Anbefaling #5: Execution Log Consolidation **Single view af alle actions:** ```sql CREATE VIEW email_action_log AS SELECT 'workflow' as source, e.email_id, w.name as action_name, e.status, e.started_at FROM email_workflow_executions e JOIN email_workflows w ON w.id = e.workflow_id UNION ALL SELECT 'rule' as source, em.id as email_id, er.name as action_name, CASE WHEN em.auto_processed THEN 'completed' ELSE 'skipped' END as status, em.updated_at as started_at FROM email_messages em JOIN email_rules er ON er.id = em.rule_id WHERE em.rule_id IS NOT NULL ORDER BY started_at DESC; ``` ## 🎯 Action Plan ### Umiddelbart (Kritisk): 1. ✅ Add `EMAIL_WORKFLOWS_ENABLED` check før workflow execution 2. ✅ Add workflow-processed check før rule matching 3. ✅ Fix `extract_invoice_data` silent failure 4. ✅ Add duplicate action detection ### Kort Sigt: 5. Add `auto_execute` column til workflows tabel 6. Create unified action handlers 7. Add conflict detection admin tool 8. Document clearly hvornår man skal bruge hvad ### Lang Sigt: 9. Decide: Deprecate rules eller keep both? 10. Migrate existing rules til workflows (hvis deprecating) 11. Create unified execution log view 12. Add UI for viewing all email actions i ét dashboard ## 📊 Hvad Skal Du Gøre Nu? **Spørgsmål til dig:** 1. **Vil du beholde begge systemer eller kun workflows?** - Hvis kun workflows: Vi kan migrate rules → workflows nu - Hvis begge: Vi skal fixe koordineringen 2. **Skal workflows kunne disables uden at slukke helt for systemet?** - Ja → Vi tilføjer auto_execute flag - Nej → Workflows kører altid når enabled=true 3. **Er der aktive rules i produktion lige nu?** - Ja → Vi skal være forsigtige med ændringer - Nej → Vi kan bare disable rule system **Quick Fix (5 min):** Jeg kan tilføje de 4 kritiske fixes nu hvis du vil fortsætte med begge systemer. **Long Fix (1 time):** Jeg kan deprecate rules og migrate til workflows hvis du vil simplificere. Hvad foretrækker du? 🤔