Release v4928.1.4.2 stable

This commit is contained in:
2026-06-09 22:55:58 +01:00
commit 6445044ac6
280 changed files with 41775 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
-- ClientFlow v4 migration 001: core operational indexes and migration ledger.
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE IF NOT EXISTS schema_migrations (
version TEXT PRIMARY KEY,
name TEXT NOT NULL,
applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_outbox_target_status_created
ON integration_outbox(target_system, status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_outbox_status_created
ON integration_outbox(status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_raw_events_source_created
ON raw_events(source_system, created_at DESC);

View File

@@ -0,0 +1,25 @@
-- ClientFlow v4 migration 002: customer/document/shipment indexes.
CREATE INDEX IF NOT EXISTS idx_customers_tax_id
ON customers(tax_id)
WHERE tax_id IS NOT NULL AND tax_id <> '';
CREATE INDEX IF NOT EXISTS idx_customers_jasmin_party_key
ON customers(jasmin_customer_party_key)
WHERE jasmin_customer_party_key IS NOT NULL AND jasmin_customer_party_key <> '';
CREATE INDEX IF NOT EXISTS idx_commercial_documents_opportunity_kind
ON commercial_documents(opportunity_id, document_kind, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_commercial_documents_customer_kind
ON commercial_documents(customer_id, document_kind, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_commercial_documents_external
ON commercial_documents(system, external_id)
WHERE external_id IS NOT NULL AND external_id <> '';
CREATE INDEX IF NOT EXISTS idx_shipments_opportunity_status
ON shipments(opportunity_id, status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_shipments_external_reference
ON shipments(system, external_reference)
WHERE external_reference IS NOT NULL AND external_reference <> '';

View File

@@ -0,0 +1,12 @@
-- ClientFlow v4 migration 003: separated external product codes.
ALTER TABLE products ADD COLUMN IF NOT EXISTS jasmin_sales_item TEXT;
ALTER TABLE opportunity_items ADD COLUMN IF NOT EXISTS jasmin_sales_item TEXT;
ALTER TABLE order_items ADD COLUMN IF NOT EXISTS jasmin_sales_item TEXT;
CREATE INDEX IF NOT EXISTS idx_products_jasmin_sales_item
ON products(jasmin_sales_item)
WHERE jasmin_sales_item IS NOT NULL AND jasmin_sales_item <> '';
CREATE INDEX IF NOT EXISTS idx_opportunity_items_jasmin_sales_item
ON opportunity_items(jasmin_sales_item)
WHERE jasmin_sales_item IS NOT NULL AND jasmin_sales_item <> '';

View File

@@ -0,0 +1,12 @@
-- ClientFlow v4 migration 004: stronger outbox idempotency and state visibility.
ALTER TABLE integration_outbox ADD COLUMN IF NOT EXISTS locked_at TIMESTAMPTZ;
ALTER TABLE integration_outbox ADD COLUMN IF NOT EXISTS lock_owner TEXT;
ALTER TABLE integration_outbox ADD COLUMN IF NOT EXISTS ignored_at TIMESTAMPTZ;
CREATE UNIQUE INDEX IF NOT EXISTS ux_integration_outbox_idempotency_key
ON integration_outbox(idempotency_key)
WHERE idempotency_key IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_integration_outbox_pending_dispatch
ON integration_outbox(target_system, created_at)
WHERE status = 'pending';

View File

@@ -0,0 +1,19 @@
-- ClientFlow v4.2 migration 005: operation dashboard helper indexes.
CREATE INDEX IF NOT EXISTS idx_opportunities_status_updated
ON opportunities(status, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_tasks_status_created
ON tasks(status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_commercial_documents_kind_created
ON commercial_documents(document_kind, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_commercial_documents_status_created
ON commercial_documents(status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_shipments_status_created
ON shipments(status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_products_active_jasmin_missing
ON products(active, jasmin_sales_item)
WHERE active = TRUE;

View File

@@ -0,0 +1,73 @@
-- 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);