74 lines
3.1 KiB
SQL
74 lines
3.1 KiB
SQL
-- ClientFlow v4.5 Operational Core
|
|
-- Communications, contextual tasks and unified timeline.
|
|
-- Safe to run more than once.
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
CREATE TABLE IF NOT EXISTS communications (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
source_system TEXT NOT NULL DEFAULT 'email',
|
|
source_message_id TEXT,
|
|
thread_id TEXT,
|
|
conversation_id TEXT,
|
|
contact_id TEXT,
|
|
direction TEXT NOT NULL DEFAULT 'inbound',
|
|
sender_name TEXT,
|
|
sender_email TEXT,
|
|
recipient TEXT,
|
|
subject TEXT,
|
|
body TEXT,
|
|
classification TEXT,
|
|
confidence NUMERIC(4,3),
|
|
status TEXT NOT NULL DEFAULT 'new',
|
|
customer_id UUID,
|
|
opportunity_id UUID,
|
|
task_id UUID,
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS ux_communications_source_message
|
|
ON communications(source_system, source_message_id)
|
|
WHERE source_message_id IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_communications_created ON communications(created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_communications_status ON communications(status);
|
|
CREATE INDEX IF NOT EXISTS idx_communications_classification ON communications(classification);
|
|
CREATE INDEX IF NOT EXISTS idx_communications_sender_email ON communications(sender_email);
|
|
CREATE INDEX IF NOT EXISTS idx_communications_customer ON communications(customer_id);
|
|
CREATE INDEX IF NOT EXISTS idx_communications_opportunity ON communications(opportunity_id);
|
|
|
|
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS communication_id UUID;
|
|
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS document_id UUID;
|
|
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS shipment_id UUID;
|
|
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS outbox_id UUID;
|
|
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS priority TEXT NOT NULL DEFAULT 'normal';
|
|
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS assigned_to TEXT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_communication ON tasks(communication_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_document ON tasks(document_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_shipment ON tasks(shipment_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_outbox ON tasks(outbox_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);
|
|
CREATE INDEX IF NOT EXISTS idx_tasks_due_status ON tasks(status, due_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS timeline_events (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
opportunity_id UUID,
|
|
customer_id UUID,
|
|
event_type TEXT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
source TEXT NOT NULL DEFAULT 'clientflow',
|
|
related_type TEXT,
|
|
related_id TEXT,
|
|
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_by TEXT NOT NULL DEFAULT 'system',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_timeline_opportunity ON timeline_events(opportunity_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_timeline_customer ON timeline_events(customer_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_timeline_related ON timeline_events(related_type, related_id);
|