# sales_service ER map from migrated SQLite DB

Generated from a clean DB after `scripts/migrate_core_db.py`.

- `sales_leads`: 22 columns, 2 indexes, 1 unique constraints, 0 foreign keys
- `sales_deals`: 32 columns, 3 indexes, 1 unique constraints, 0 foreign keys
- `sales_communication_sessions`: 23 columns, 2 indexes, 1 unique constraints, 0 foreign keys
- `sales_messages`: 16 columns, 2 indexes, 1 unique constraints, 0 foreign keys
- `sales_calls`: 19 columns, 2 indexes, 1 unique constraints, 0 foreign keys
- `sales_transcripts`: 10 columns, 0 indexes, 1 unique constraints, 0 foreign keys
- `sales_notes`: 9 columns, 0 indexes, 1 unique constraints, 0 foreign keys
- `sales_offers`: 17 columns, 1 indexes, 1 unique constraints, 0 foreign keys
- `sales_deal_conditions`: missing
- `sales_conditions`: 19 columns, 0 indexes, 1 unique constraints, 0 foreign keys
- `sales_counterparties`: 18 columns, 0 indexes, 2 unique constraints, 0 foreign keys
- `sales_documents`: 15 columns, 1 indexes, 1 unique constraints, 0 foreign keys
- `sales_invoices`: 18 columns, 1 indexes, 2 unique constraints, 0 foreign keys
- `sales_payments`: 16 columns, 1 indexes, 1 unique constraints, 0 foreign keys
- `sales_stage_history`: 10 columns, 1 indexes, 1 unique constraints, 0 foreign keys
- `sales_escalations`: 11 columns, 1 indexes, 1 unique constraints, 0 foreign keys
- `sales_automation_tasks`: 12 columns, 1 indexes, 1 unique constraints, 0 foreign keys
- `sales_channel_switches`: 9 columns, 1 indexes, 1 unique constraints, 0 foreign keys
- `sales_external_links`: 20 columns, 6 indexes, 1 unique constraints, 0 foreign keys

## `sales_leads`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `lead_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `source_type` | `TEXT` | no | `` | no |
| `source_channel` | `TEXT` | no | `` | no |
| `source_campaign_id` | `TEXT` | yes | `` | no |
| `full_name` | `TEXT` | no | `` | no |
| `company_name` | `TEXT` | yes | `` | no |
| `phone` | `TEXT` | yes | `` | no |
| `email` | `TEXT` | yes | `` | no |
| `messenger_handles_json` | `TEXT` | no | `'{}'` | no |
| `lead_temperature` | `TEXT` | no | `` | no |
| `lead_score` | `REAL` | no | `50` | no |
| `customer_type` | `TEXT` | yes | `` | no |
| `segment_type` | `TEXT` | yes | `` | no |
| `initial_need_summary` | `TEXT` | yes | `` | no |
| `preferred_channel` | `TEXT` | no | `` | no |
| `assigned_agent_type` | `TEXT` | no | `` | no |
| `status` | `TEXT` | no | `` | no |
| `crm_customer_id` | `TEXT` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_leads_phone_email`: `phone`, `email`
- `idx_sales_leads_tenant_status_score`: `tenant_id`, `status`, `lead_score`

Unique constraints:
- `None`: `lead_id`

## `sales_deals`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `deal_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `lead_id` | `TEXT` | yes | `` | no |
| `customer_id` | `TEXT` | yes | `` | no |
| `pipeline_id` | `TEXT` | no | `'sales_default'` | no |
| `stage_id` | `TEXT` | no | `` | no |
| `scenario_type` | `TEXT` | no | `` | no |
| `priority` | `INTEGER` | no | `3` | no |
| `title` | `TEXT` | no | `` | no |
| `need_summary` | `TEXT` | yes | `` | no |
| `product_context_json` | `TEXT` | no | `'{}'` | no |
| `estimated_amount` | `REAL` | yes | `` | no |
| `final_amount` | `REAL` | yes | `` | no |
| `currency` | `TEXT` | no | `'KZT'` | no |
| `payment_model` | `TEXT` | yes | `` | no |
| `document_required` | `INTEGER` | no | `1` | no |
| `payment_required` | `INTEGER` | no | `1` | no |
| `assigned_human_user_id` | `TEXT` | yes | `` | no |
| `assigned_ai_orchestrator_id` | `TEXT` | yes | `` | no |
| `preferred_channel` | `TEXT` | no | `` | no |
| `current_channel` | `TEXT` | no | `` | no |
| `status` | `TEXT` | no | `'active'` | no |
| `won_reason` | `TEXT` | yes | `` | no |
| `lost_reason` | `TEXT` | yes | `` | no |
| `close_reason` | `TEXT` | yes | `` | no |
| `next_action_type` | `TEXT` | yes | `` | no |
| `next_action_at` | `TEXT` | yes | `` | no |
| `last_contact_at` | `TEXT` | yes | `` | no |
| `closed_at` | `TEXT` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_deals_customer_channel`: `customer_id`, `current_channel`
- `idx_sales_deals_next_action`: `next_action_at`, `status`
- `idx_sales_deals_tenant_stage_status`: `tenant_id`, `stage_id`, `status`

Unique constraints:
- `None`: `deal_id`

## `sales_communication_sessions`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `communication_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `lead_id` | `TEXT` | yes | `` | no |
| `customer_id` | `TEXT` | yes | `` | no |
| `channel_type` | `TEXT` | no | `` | no |
| `direction` | `TEXT` | no | `` | no |
| `agent_type` | `TEXT` | no | `` | no |
| `started_at` | `TEXT` | no | `` | no |
| `ended_at` | `TEXT` | yes | `` | no |
| `duration_sec` | `INTEGER` | yes | `` | no |
| `subject` | `TEXT` | yes | `` | no |
| `status` | `TEXT` | no | `'active'` | no |
| `summary` | `TEXT` | yes | `` | no |
| `transcript_id` | `TEXT` | yes | `` | no |
| `next_action_type` | `TEXT` | yes | `` | no |
| `next_action_at` | `TEXT` | yes | `` | no |
| `sentiment` | `TEXT` | yes | `` | no |
| `result_code` | `TEXT` | yes | `` | no |
| `metadata_json` | `TEXT` | no | `'{}'` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_comm_channel_status`: `channel_type`, `status`
- `idx_sales_comm_deal_started`: `deal_id`, `started_at`

Unique constraints:
- `None`: `communication_id`

## `sales_messages`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `message_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `communication_id` | `TEXT` | no | `` | no |
| `sender_type` | `TEXT` | no | `` | no |
| `sender_id` | `TEXT` | yes | `` | no |
| `channel_provider` | `TEXT` | no | `` | no |
| `external_message_id` | `TEXT` | yes | `` | no |
| `body` | `TEXT` | no | `` | no |
| `attachments_json` | `TEXT` | no | `'[]'` | no |
| `delivery_status` | `TEXT` | yes | `` | no |
| `read_status` | `TEXT` | yes | `` | no |
| `message_metadata_json` | `TEXT` | no | `'{}'` | no |
| `sent_at` | `TEXT` | no | `` | no |
| `created_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_messages_deal_sent`: `deal_id`, `sent_at`
- `idx_sales_messages_ext_id`: `channel_provider`, `external_message_id`

Unique constraints:
- `None`: `message_id`

## `sales_calls`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `call_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `communication_id` | `TEXT` | no | `` | no |
| `phone_number` | `TEXT` | no | `` | no |
| `direction` | `TEXT` | no | `` | no |
| `provider` | `TEXT` | no | `` | no |
| `external_call_id` | `TEXT` | yes | `` | no |
| `recording_url` | `TEXT` | yes | `` | no |
| `transcript_status` | `TEXT` | no | `'pending'` | no |
| `transcript_id` | `TEXT` | yes | `` | no |
| `call_status` | `TEXT` | no | `'started'` | no |
| `summary` | `TEXT` | yes | `` | no |
| `started_at` | `TEXT` | no | `` | no |
| `ended_at` | `TEXT` | yes | `` | no |
| `duration_sec` | `INTEGER` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_calls_deal_started`: `deal_id`, `started_at`
- `idx_sales_calls_ext_provider`: `provider`, `external_call_id`

Unique constraints:
- `None`: `call_id`

## `sales_transcripts`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `transcript_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `call_id` | `TEXT` | no | `` | no |
| `language` | `TEXT` | no | `'ru'` | no |
| `transcript_text` | `TEXT` | no | `` | no |
| `diarization_json` | `TEXT` | no | `'{}'` | no |
| `extracted_entities_json` | `TEXT` | no | `'{}'` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Unique constraints:
- `None`: `transcript_id`

## `sales_notes`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `note_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `author_type` | `TEXT` | no | `` | no |
| `author_id` | `TEXT` | yes | `` | no |
| `note_type` | `TEXT` | no | `` | no |
| `content` | `TEXT` | no | `` | no |
| `created_at` | `TEXT` | no | `` | no |

Unique constraints:
- `None`: `note_id`

## `sales_offers`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `offer_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `offer_type` | `TEXT` | no | `` | no |
| `title` | `TEXT` | no | `` | no |
| `description` | `TEXT` | yes | `` | no |
| `line_items_json` | `TEXT` | no | `'[]'` | no |
| `pricing_json` | `TEXT` | no | `'{}'` | no |
| `total_amount` | `REAL` | no | `0` | no |
| `currency` | `TEXT` | no | `'KZT'` | no |
| `validity_until` | `TEXT` | yes | `` | no |
| `status` | `TEXT` | no | `'draft'` | no |
| `rendered_document_url` | `TEXT` | yes | `` | no |
| `created_by_type` | `TEXT` | no | `'text_ai'` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_offers_deal_status`: `deal_id`, `status`

Unique constraints:
- `None`: `offer_id`

## `sales_deal_conditions`

Not present in migrated DB.

## `sales_conditions`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `condition_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `product_name` | `TEXT` | yes | `` | no |
| `service_name` | `TEXT` | yes | `` | no |
| `quantity` | `REAL` | yes | `` | no |
| `unit` | `TEXT` | yes | `` | no |
| `delivery_mode` | `TEXT` | yes | `` | no |
| `execution_date` | `TEXT` | yes | `` | no |
| `start_date` | `TEXT` | yes | `` | no |
| `end_date` | `TEXT` | yes | `` | no |
| `payment_terms` | `TEXT` | yes | `` | no |
| `custom_terms_json` | `TEXT` | no | `'{}'` | no |
| `agreed_price` | `REAL` | yes | `` | no |
| `currency` | `TEXT` | no | `'KZT'` | no |
| `confirmed_at` | `TEXT` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Unique constraints:
- `None`: `condition_id`

## `sales_counterparties`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `counterparty_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `customer_id` | `TEXT` | yes | `` | no |
| `company_name` | `TEXT` | yes | `` | no |
| `full_name` | `TEXT` | yes | `` | no |
| `bin_iin` | `TEXT` | yes | `` | no |
| `address` | `TEXT` | yes | `` | no |
| `bank_details_json` | `TEXT` | no | `'{}'` | no |
| `signer_name` | `TEXT` | yes | `` | no |
| `signer_role` | `TEXT` | yes | `` | no |
| `signer_basis` | `TEXT` | yes | `` | no |
| `email_for_docs` | `TEXT` | yes | `` | no |
| `phone_for_docs` | `TEXT` | yes | `` | no |
| `completeness_status` | `TEXT` | no | `'draft'` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Unique constraints:
- `None`: `counterparty_id`
- `None`: `deal_id`

## `sales_documents`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `document_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `customer_id` | `TEXT` | yes | `` | no |
| `document_type` | `TEXT` | no | `` | no |
| `template_id` | `TEXT` | yes | `` | no |
| `version` | `INTEGER` | no | `1` | no |
| `status` | `TEXT` | no | `'draft'` | no |
| `file_url` | `TEXT` | yes | `` | no |
| `rendered_payload_json` | `TEXT` | no | `'{}'` | no |
| `external_sign_provider_id` | `TEXT` | yes | `` | no |
| `signed_at` | `TEXT` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_documents_deal_status`: `deal_id`, `status`

Unique constraints:
- `None`: `document_id`

## `sales_invoices`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `invoice_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `customer_id` | `TEXT` | yes | `` | no |
| `invoice_number` | `TEXT` | no | `` | no |
| `basis_document_id` | `TEXT` | yes | `` | no |
| `amount` | `REAL` | no | `0` | no |
| `currency` | `TEXT` | no | `'KZT'` | no |
| `due_date` | `TEXT` | yes | `` | no |
| `status` | `TEXT` | no | `'draft'` | no |
| `payment_link` | `TEXT` | yes | `` | no |
| `line_items_json` | `TEXT` | no | `'[]'` | no |
| `metadata_json` | `TEXT` | no | `'{}'` | no |
| `issued_at` | `TEXT` | yes | `` | no |
| `paid_at` | `TEXT` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_invoices_deal_status_due`: `deal_id`, `status`, `due_date`

Unique constraints:
- `None`: `invoice_id`
- `None`: `invoice_number`

## `sales_payments`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `payment_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `invoice_id` | `TEXT` | yes | `` | no |
| `payment_provider` | `TEXT` | yes | `` | no |
| `external_payment_id` | `TEXT` | yes | `` | no |
| `amount` | `REAL` | no | `0` | no |
| `currency` | `TEXT` | no | `'KZT'` | no |
| `status` | `TEXT` | no | `'pending'` | no |
| `paid_at` | `TEXT` | yes | `` | no |
| `payment_method` | `TEXT` | yes | `` | no |
| `failure_reason` | `TEXT` | yes | `` | no |
| `metadata_json` | `TEXT` | no | `'{}'` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_payments_deal_status`: `deal_id`, `status`

Unique constraints:
- `None`: `payment_id`

## `sales_stage_history`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `history_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `from_stage_id` | `TEXT` | yes | `` | no |
| `to_stage_id` | `TEXT` | no | `` | no |
| `changed_by_type` | `TEXT` | no | `` | no |
| `changed_by_id` | `TEXT` | yes | `` | no |
| `reason` | `TEXT` | yes | `` | no |
| `changed_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_stage_history_deal_changed`: `deal_id`, `changed_at`

Unique constraints:
- `None`: `history_id`

## `sales_escalations`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `escalation_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `escalation_type` | `TEXT` | no | `` | no |
| `reason` | `TEXT` | no | `` | no |
| `severity` | `TEXT` | no | `` | no |
| `status` | `TEXT` | no | `'open'` | no |
| `assigned_to_user_id` | `TEXT` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `resolved_at` | `TEXT` | yes | `` | no |

Indexes:
- `idx_sales_escalations_deal_status`: `deal_id`, `status`

Unique constraints:
- `None`: `escalation_id`

## `sales_automation_tasks`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `task_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `task_type` | `TEXT` | no | `` | no |
| `payload_json` | `TEXT` | no | `'{}'` | no |
| `run_at` | `TEXT` | no | `` | no |
| `status` | `TEXT` | no | `'pending'` | no |
| `retry_count` | `INTEGER` | no | `0` | no |
| `last_error` | `TEXT` | yes | `` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_tasks_run_status`: `run_at`, `status`

Unique constraints:
- `None`: `task_id`

## `sales_channel_switches`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `switch_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `communication_id` | `TEXT` | yes | `` | no |
| `from_channel` | `TEXT` | no | `` | no |
| `to_channel` | `TEXT` | no | `` | no |
| `reason_for_channel_switch` | `TEXT` | no | `` | no |
| `switched_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_channel_switches_deal_switched`: `deal_id`, `switched_at`

Unique constraints:
- `None`: `switch_id`

## `sales_external_links`

| Column | Type | Null | Default | PK |
|---|---|---:|---|---:|
| `id` | `INTEGER` | yes | `` | yes |
| `link_id` | `TEXT` | no | `` | no |
| `tenant_id` | `TEXT` | no | `` | no |
| `deal_id` | `TEXT` | no | `` | no |
| `communication_id` | `TEXT` | yes | `` | no |
| `sales_call_id` | `TEXT` | yes | `` | no |
| `channel_provider` | `TEXT` | no | `` | no |
| `external_thread_id` | `TEXT` | yes | `` | no |
| `external_chat_id` | `TEXT` | yes | `` | no |
| `external_call_id` | `TEXT` | yes | `` | no |
| `voice_session_id` | `TEXT` | yes | `` | no |
| `ai_session_id` | `TEXT` | yes | `` | no |
| `interaction_id` | `TEXT` | yes | `` | no |
| `customer_id` | `TEXT` | yes | `` | no |
| `phone_number` | `TEXT` | yes | `` | no |
| `external_status` | `TEXT` | yes | `` | no |
| `link_metadata_json` | `TEXT` | no | `'{}'` | no |
| `created_at` | `TEXT` | no | `` | no |
| `updated_at` | `TEXT` | no | `` | no |
| `last_sync_at` | `TEXT` | no | `` | no |

Indexes:
- `idx_sales_external_links_customer_phone`: `customer_id`, `phone_number`
- `idx_sales_external_links_deal_sync`: `deal_id`, `last_sync_at`
- `idx_sales_external_links_external_call`: `external_call_id`
- `idx_sales_external_links_interaction`: `interaction_id`
- `idx_sales_external_links_thread`: `external_thread_id`
- `idx_sales_external_links_voice_session`: `voice_session_id`

Unique constraints:
- `None`: `link_id`
