---
title: "Архитектура Email AI-CRM"
description: "IMAP poll, EmailProcessor, JSONB коллекции, SMTP, cron и webhook"
locale: "ru"
---
# Архитектура Email AI-CRM

> **EN canonical:** полная диаграмма, индексы JSONB и режимы cron/IDLE — [Email AI-CRM architecture (EN)](/docs/architecture/email-ai-crm.md)

## Система

```mermaid
flowchart TB
    subgraph Ingest["Сбор"]
        Cron["POST /api/cron/email-processor poll"]
        Webhook["POST /api/webhooks/email/inbound"]
        Idle["EMAIL_PROCESSOR_AUTOSTART опционально"]
    end

    subgraph Core["services/email"]
        EP[EmailProcessor]
        IMAP[ImapListener.pollBatch]
        Parser[EmailParser]
        Sec[SecurityPipeline]
        AI[Intent + Sentiment + Generator]
        CRM[ContactService + TaskService]
        Drafts[EmailDraftService]
    end

    subgraph Persist["features/email-crm JSONB"]
        T[email_threads]
        C[email_contacts]
        M[email_messages]
        D[email_drafts]
        TK[email_tasks]
        U[email_api_usage]
    end

    subgraph Out["Исходящие"]
        SMTP[EmailSenderService]
        Notify[EmailNotificationService]
    end

    subgraph Admin["Админ"]
        API["/api/admin/email/*"]
        UI["admin/crm/*"]
    end

    Cron --> IMAP
    Webhook --> EP
    Idle --> EP
    IMAP --> EP
    EP --> Parser --> Sec --> AI
    AI --> CRM
    AI --> Drafts
    EP --> T
    EP --> C
    EP --> M
    EP --> D
    EP --> TK
    AI --> U
    Drafts --> SMTP
    EP --> Notify
    API --> Persist
    UI --> API
```

## Модули

| Путь | Роль |
|------|------|
| `features/email-crm/pipeline/email-processor.ts` | Оркестратор: dedup, poll, ingest |
| `features/email-crm/pipeline/imap/` | `pollBatch()` для cron |
| `features/email-crm/pipeline/smtp/email-sender.ts` | Исходящие ответы |
| `features/email-crm/repositories/` | JSONB Contact / Task / Draft |
| `features/email-crm/services/` | Thread, message, analytics, send |

## JSONB модель

Строка платформы: `id`, `data`, `created_at`, `updated_at`.

| Коллекция | Id документа |
|-----------|--------------|
| `email_threads` | RFC thread root / Message-ID |
| `email_contacts` | `contact_<sha256(email)>` |
| `email_messages` | RFC Message-ID |
| `email_drafts` | `draft_` |
| `email_tasks` | `task_` |
| `email_api_usage` | `req__` |

Миграции: `009_email_crm_jsonb.sql`, `010_email_crm_tasks_jsonb.sql`.

`EMAIL_CRM_PERSISTENCE=memory` — только dev/tests; иначе Postgres через фабрики сервисов.

## Идемпотентность

| Механизм | Поведение |
|----------|-----------|
| DB dedup | `EmailMessageService.exists(messageId)` |
| Poll mutex | Параллельный `pollInboundBatch` → `{ skipped: true }` |
| pollBatch | Ждёт все `handleEmail` перед disconnect |
| Webhook | `uid: 0` — без IMAP mark-seen |

## Cron vs IDLE

| Режим | Когда |
|-------|-------|
| **poll** (рекомендуется) | k8s CronJob, serverless |
| **start** | Dedicated Node + `instrumentation.ts` |
| HTTP start | Debug: `EMAIL_PROCESSOR_ALLOW_HTTP_START=true` |

## Безопасность

- Cron/webhook: `Bearer $CRON_SECRET` или HMAC `X-Email-Webhook-Signature`.
- Admin API: сессия + `isPlatformAdmin`.
- Inbound: 4 слоя anti-injection до LLM.

## Связанное

- [Email AI-CRM (функция)](/docs/features/email-ai-crm.md)
- [Email AI-CRM API](/docs/api/email-ai-crm.md)
- [Backend modes](/docs/architecture/backend-modes-and-databases.md)
