botserver/migrations/20250729000001_add_dashboards_tables/up.sql
Rodrigo Rodriguez (Pragmatismo) a886478548 Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
  - Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
    dashboard_widget_data_sources, conversational_queries
  - Full CRUD operations with spawn_blocking pattern

- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
  - Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
    legal_acceptances, data_deletion_requests, data_export_requests
  - GDPR-compliant consent tracking and document management

- Add PostgreSQL persistence for compliance module (was returning empty results)
  - Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
    compliance_risk_assessments, compliance_risks, compliance_training_records,
    compliance_access_reviews
  - Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks

- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00

100 lines
4.1 KiB
SQL

CREATE TABLE dashboards (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL,
bot_id UUID NOT NULL,
owner_id UUID NOT NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
layout JSONB NOT NULL DEFAULT '{"columns": 12, "row_height": 80, "gap": 16}',
refresh_interval INTEGER,
is_public BOOLEAN NOT NULL DEFAULT FALSE,
is_template BOOLEAN NOT NULL DEFAULT FALSE,
tags TEXT[] NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE dashboard_widgets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
dashboard_id UUID NOT NULL REFERENCES dashboards(id) ON DELETE CASCADE,
widget_type VARCHAR(50) NOT NULL,
title VARCHAR(255) NOT NULL,
position_x INTEGER NOT NULL DEFAULT 0,
position_y INTEGER NOT NULL DEFAULT 0,
width INTEGER NOT NULL DEFAULT 4,
height INTEGER NOT NULL DEFAULT 3,
config JSONB NOT NULL DEFAULT '{}',
data_query JSONB,
style JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE dashboard_data_sources (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL,
bot_id UUID NOT NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
source_type VARCHAR(50) NOT NULL,
connection JSONB NOT NULL DEFAULT '{}',
schema_definition JSONB NOT NULL DEFAULT '{}',
refresh_schedule VARCHAR(100),
last_sync TIMESTAMPTZ,
status VARCHAR(50) NOT NULL DEFAULT 'active',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE dashboard_filters (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
dashboard_id UUID NOT NULL REFERENCES dashboards(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
field VARCHAR(255) NOT NULL,
filter_type VARCHAR(50) NOT NULL,
default_value JSONB,
options JSONB NOT NULL DEFAULT '[]',
linked_widgets JSONB NOT NULL DEFAULT '[]',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE dashboard_widget_data_sources (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
widget_id UUID NOT NULL REFERENCES dashboard_widgets(id) ON DELETE CASCADE,
data_source_id UUID NOT NULL REFERENCES dashboard_data_sources(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(widget_id, data_source_id)
);
CREATE TABLE conversational_queries (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL,
bot_id UUID NOT NULL,
dashboard_id UUID REFERENCES dashboards(id) ON DELETE SET NULL,
user_id UUID NOT NULL,
natural_language TEXT NOT NULL,
generated_query TEXT,
result_widget_config JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_dashboards_org_bot ON dashboards(org_id, bot_id);
CREATE INDEX idx_dashboards_owner ON dashboards(owner_id);
CREATE INDEX idx_dashboards_is_public ON dashboards(is_public) WHERE is_public = TRUE;
CREATE INDEX idx_dashboards_is_template ON dashboards(is_template) WHERE is_template = TRUE;
CREATE INDEX idx_dashboards_tags ON dashboards USING GIN(tags);
CREATE INDEX idx_dashboards_created ON dashboards(created_at DESC);
CREATE INDEX idx_dashboard_widgets_dashboard ON dashboard_widgets(dashboard_id);
CREATE INDEX idx_dashboard_widgets_type ON dashboard_widgets(widget_type);
CREATE INDEX idx_dashboard_data_sources_org_bot ON dashboard_data_sources(org_id, bot_id);
CREATE INDEX idx_dashboard_data_sources_type ON dashboard_data_sources(source_type);
CREATE INDEX idx_dashboard_data_sources_status ON dashboard_data_sources(status);
CREATE INDEX idx_dashboard_filters_dashboard ON dashboard_filters(dashboard_id);
CREATE INDEX idx_conversational_queries_org_bot ON conversational_queries(org_id, bot_id);
CREATE INDEX idx_conversational_queries_dashboard ON conversational_queries(dashboard_id) WHERE dashboard_id IS NOT NULL;
CREATE INDEX idx_conversational_queries_user ON conversational_queries(user_id);
CREATE INDEX idx_conversational_queries_created ON conversational_queries(created_at DESC);