- KnowledgeBaseController: ingest, list, firmOrgs, search, delete - VectorService (Qdrant + buildAuthzFilter), EmbedService (Voyage), RagService (pipeline) - AIService::askWithRag con fallback graceful - docker-compose: servizio qdrant + env Voyage (chiave da .env/vault, no hardcoded) - SQL 012 consulting_firms, 013 firm_assignments + kb_uploaded_documents - public/kb.html + kb.js (upload, lista, search preview) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
62 lines
2.9 KiB
SQL
62 lines
2.9 KiB
SQL
-- NIS2 Migration 012: Consulting Firms (Studio di Consulenza)
|
|
-- Database: nis2_agile_db
|
|
-- Data: 2026-04-11
|
|
-- Idempotente: rieseguibile in sicurezza.
|
|
|
|
USE nis2_agile_db;
|
|
|
|
-- 1. Anagrafica studi di consulenza cybersecurity / NIS2 (idempotente)
|
|
CREATE TABLE IF NOT EXISTS consulting_firms (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL COMMENT 'Ragione sociale studio',
|
|
vat_number VARCHAR(20) NULL,
|
|
fiscal_code VARCHAR(16) NULL,
|
|
forma_giuridica VARCHAR(50) NULL,
|
|
address VARCHAR(255) NULL,
|
|
city VARCHAR(100) NULL,
|
|
province VARCHAR(2) NULL,
|
|
cap VARCHAR(5) NULL,
|
|
phone VARCHAR(30) NULL,
|
|
pec VARCHAR(255) NULL,
|
|
website VARCHAR(255) NULL,
|
|
plan ENUM('starter','professional','enterprise') NOT NULL DEFAULT 'professional',
|
|
max_organizations INT NOT NULL DEFAULT 50,
|
|
max_users INT NOT NULL DEFAULT 5,
|
|
status ENUM('active','trial','suspended','inactive') NOT NULL DEFAULT 'active',
|
|
created_by INT NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
INDEX idx_vat (vat_number),
|
|
INDEX idx_status (status)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- 2. ALTER users.consulting_firm_id (idempotente)
|
|
SET @col := (SELECT COUNT(*) FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'users' AND COLUMN_NAME = 'consulting_firm_id');
|
|
SET @sql := IF(@col = 0,
|
|
'ALTER TABLE users ADD COLUMN consulting_firm_id INT NULL AFTER role',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
SET @idx := (SELECT COUNT(*) FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'users' AND INDEX_NAME = 'idx_user_firm');
|
|
SET @sql := IF(@idx = 0,
|
|
'ALTER TABLE users ADD INDEX idx_user_firm (consulting_firm_id)',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
-- 3. ALTER organizations.consulting_firm_id (idempotente)
|
|
SET @col := (SELECT COUNT(*) FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'organizations' AND COLUMN_NAME = 'consulting_firm_id');
|
|
SET @sql := IF(@col = 0,
|
|
'ALTER TABLE organizations ADD COLUMN consulting_firm_id INT NULL',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
SET @idx := (SELECT COUNT(*) FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'organizations' AND INDEX_NAME = 'idx_org_firm');
|
|
SET @sql := IF(@idx = 0,
|
|
'ALTER TABLE organizations ADD INDEX idx_org_firm (consulting_firm_id)',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|