Fix email case auto-create guard and CreateSagFromEmailRequest fields

This commit is contained in:
Christian 2026-04-02 09:40:23 +02:00
parent 0edb78f2ea
commit 9be8b57303
5 changed files with 19 additions and 6 deletions

View File

@ -130,6 +130,8 @@ EMAIL_RULES_AUTO_PROCESS=false
EMAIL_AI_ENABLED=false EMAIL_AI_ENABLED=false
EMAIL_AUTO_CLASSIFY=false EMAIL_AUTO_CLASSIFY=false
EMAIL_AI_CONFIDENCE_THRESHOLD=0.7 EMAIL_AI_CONFIDENCE_THRESHOLD=0.7
EMAIL_REQUIRE_MANUAL_APPROVAL=true
EMAIL_AUTO_CREATE_CASES_FROM_EMAIL=false
EMAIL_MAX_FETCH_PER_RUN=50 EMAIL_MAX_FETCH_PER_RUN=50
EMAIL_PROCESS_INTERVAL_MINUTES=5 EMAIL_PROCESS_INTERVAL_MINUTES=5
EMAIL_WORKFLOWS_ENABLED=true EMAIL_WORKFLOWS_ENABLED=true

View File

@ -123,6 +123,7 @@ class Settings(BaseSettings):
EMAIL_AUTO_CLASSIFY: bool = True # Enable classification by default (uses keywords if AI disabled) EMAIL_AUTO_CLASSIFY: bool = True # Enable classification by default (uses keywords if AI disabled)
EMAIL_AI_CONFIDENCE_THRESHOLD: float = 0.7 EMAIL_AI_CONFIDENCE_THRESHOLD: float = 0.7
EMAIL_REQUIRE_MANUAL_APPROVAL: bool = True # Phase 1: human approval before case creation/routing EMAIL_REQUIRE_MANUAL_APPROVAL: bool = True # Phase 1: human approval before case creation/routing
EMAIL_AUTO_CREATE_CASES_FROM_EMAIL: bool = False
EMAIL_MAX_FETCH_PER_RUN: int = 50 EMAIL_MAX_FETCH_PER_RUN: int = 50
EMAIL_PROCESS_INTERVAL_MINUTES: int = 5 EMAIL_PROCESS_INTERVAL_MINUTES: int = 5
EMAIL_WORKFLOWS_ENABLED: bool = True EMAIL_WORKFLOWS_ENABLED: bool = True

View File

@ -164,6 +164,8 @@ class CreateSagFromEmailRequest(BaseModel):
priority: Optional[str] = None priority: Optional[str] = None
ansvarlig_bruger_id: Optional[int] = None ansvarlig_bruger_id: Optional[int] = None
assigned_group_id: Optional[int] = None assigned_group_id: Optional[int] = None
created_by_user_id: int = 1
relation_type: str = "mail"
class EmailReadStateUpdate(BaseModel): class EmailReadStateUpdate(BaseModel):
@ -203,8 +205,6 @@ def _can_user_mark_case_email_read(user_id: Optional[int], linked_case_id: Optio
return True return True
return False return False
created_by_user_id: int = 1
relation_type: str = "mail"
class LinkEmailToSagRequest(BaseModel): class LinkEmailToSagRequest(BaseModel):

View File

@ -2425,7 +2425,7 @@
] %} ] %}
<li> <li>
<button class="dropdown-item d-flex align-items-center gap-2 {% if tkey == tval %}fw-semibold{% endif %}" <button class="dropdown-item d-flex align-items-center gap-2 {% if tkey == tval %}fw-semibold{% endif %}"
onclick="saveCaseType('{{ tval }}','{{ tlbl }}','{{ tico }}','{{ tclr }}')" onclick='saveCaseType({{ tval|tojson }}, {{ tlbl|tojson }}, {{ tico|tojson }}, {{ tclr|tojson }})'
style="font-size:.875rem;"> style="font-size:.875rem;">
<i class="bi {{ tico }}" style="color:{{ tclr }};"></i>{{ tlbl }} <i class="bi {{ tico }}" style="color:{{ tclr }};"></i>{{ tlbl }}
{% if tkey == tval %}<i class="bi bi-check ms-auto"></i>{% endif %} {% if tkey == tval %}<i class="bi bi-check ms-auto"></i>{% endif %}
@ -2852,7 +2852,7 @@
<button class="btn btn-outline-secondary" title="Tags" onclick="openRelTagPopover({{ node.case.id }})"> <button class="btn btn-outline-secondary" title="Tags" onclick="openRelTagPopover({{ node.case.id }})">
<i class="bi bi-tag"></i> <i class="bi bi-tag"></i>
</button> </button>
<button class="btn btn-outline-primary" title="Quick action" onclick="openRelQaMenu({{ node.case.id }}, '{{ node.case.titel | e }}', this)"> <button class="btn btn-outline-primary" title="Quick action" onclick='openRelQaMenu({{ node.case.id }}, {{ (node.case.titel or "")|tojson }}, this)'>
<i class="bi bi-plus-lg"></i> <i class="bi bi-plus-lg"></i>
</button> </button>
</div> </div>
@ -3297,7 +3297,7 @@
let relationSearchTimeout; let relationSearchTimeout;
let wikiSearchTimeout; let wikiSearchTimeout;
let selectedRelationCaseId = null; let selectedRelationCaseId = null;
const caseTypeKey = "{{ (case.template_key or case.type or 'ticket')|lower }}"; const caseTypeKey = {{ ((case.template_key or case.type or 'ticket')|lower)|tojson }};
function escapeCaseTopAlertHtml(value) { function escapeCaseTopAlertHtml(value) {
return String(value ?? '') return String(value ?? '')
@ -5348,7 +5348,7 @@
{% if call.ekstern_nummer %} {% if call.ekstern_nummer %}
<div class="d-flex gap-2 align-items-center flex-wrap"> <div class="d-flex gap-2 align-items-center flex-wrap">
<span>{{ call.ekstern_nummer }}</span> <span>{{ call.ekstern_nummer }}</span>
<button type="button" class="btn btn-sm btn-outline-success" onclick="ringOutFromCase('{{ call.ekstern_nummer }}')"> <button type="button" class="btn btn-sm btn-outline-success" onclick='ringOutFromCase({{ (call.ekstern_nummer or "")|tojson }})'>
Ring op Ring op
</button> </button>
</div> </div>

View File

@ -1106,6 +1106,16 @@ class EmailWorkflowService:
if sag_id: if sag_id:
return await self._finalize_sag_routing(email_id, email_data, sag_id, routing_source) return await self._finalize_sag_routing(email_id, email_data, sag_id, routing_source)
if not getattr(settings, 'EMAIL_AUTO_CREATE_CASES_FROM_EMAIL', False):
logger.info(
"⏭️ Email %s did not match existing SAG and auto-create is disabled",
email_id,
)
return {
'status': 'skipped',
'action': 'auto_create_disabled',
}
# 2) No SAG id -> create only if sender domain belongs to known customer # 2) No SAG id -> create only if sender domain belongs to known customer
sender_domain = self._extract_sender_domain(email_data) sender_domain = self._extract_sender_domain(email_data)
customer = self._find_customer_by_domain(sender_domain) if sender_domain else None customer = self._find_customer_by_domain(sender_domain) if sender_domain else None