Files
bot_palmas/setup/migrate.php
T
2026-06-12 12:18:21 -05:00

223 lines
9.4 KiB
PHP

<?php
declare(strict_types=1);
require_once dirname(__DIR__) . '/config/env.php';
require_once dirname(__DIR__) . '/config/db.php';
$db = db();
// ─── Tablas ───────────────────────────────────────────────────────────────────
$db->exec("
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
$db->exec("
CREATE TABLE IF NOT EXISTS webhook_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
event_field VARCHAR(50) NOT NULL DEFAULT 'messages',
from_number VARCHAR(30),
contact_name VARCHAR(150),
message_type VARCHAR(30),
message_preview TEXT,
raw_payload LONGTEXT,
received_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_received_at (received_at),
INDEX idx_from_number (from_number),
INDEX idx_event_field (event_field)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
$db->exec("
CREATE TABLE IF NOT EXISTS conversations (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
message_id VARCHAR(100) NOT NULL UNIQUE,
phone_number VARCHAR(30) NOT NULL,
contact_name VARCHAR(150),
direction ENUM('inbound','outbound') DEFAULT 'inbound',
message_type VARCHAR(30),
content TEXT,
media_id VARCHAR(150),
timestamp INT UNSIGNED,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_conv_phone (phone_number),
INDEX idx_conv_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
$db->exec("
CREATE TABLE IF NOT EXISTS notifications (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(50) NOT NULL DEFAULT 'new_message',
reference_id BIGINT,
phone_number VARCHAR(30),
message TEXT,
is_read TINYINT(1) DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_notif_read (is_read),
INDEX idx_notif_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
$db->exec("
CREATE TABLE IF NOT EXISTS media_queue (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
message_id VARCHAR(100) NOT NULL,
media_id VARCHAR(150) NOT NULL,
media_type VARCHAR(30),
attempts TINYINT DEFAULT 0,
processed TINYINT(1) DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_mq_processed (processed),
INDEX idx_mq_message_id (message_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
// ─── Tabla de empresas (multi-tenant) ─────────────────────────────────────────
$db->exec("
CREATE TABLE IF NOT EXISTS companies (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(150) NOT NULL,
display_name VARCHAR(150),
phone_number_id VARCHAR(50) NOT NULL UNIQUE,
display_phone VARCHAR(30),
api_base_url VARCHAR(500) NOT NULL,
api_key VARCHAR(255),
bot_type ENUM('ai','normal','hybrid') DEFAULT 'normal',
requires_approval TINYINT(1) DEFAULT 0,
is_active TINYINT(1) DEFAULT 1,
config_json TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_phone_number_id (phone_number_id),
INDEX idx_is_active (is_active)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
// ─── Cola de mensajes salientes ──────────────────────────────────────────────
$db->exec("
CREATE TABLE IF NOT EXISTS outbound_queue (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
to_number VARCHAR(30) NOT NULL,
message_type VARCHAR(30) NOT NULL DEFAULT 'text',
payload TEXT NOT NULL,
status ENUM('queued','sent','delivered','failed') DEFAULT 'queued',
attempts TINYINT DEFAULT 0,
max_attempts TINYINT DEFAULT 5,
last_error TEXT,
wam_id VARCHAR(100),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_company_status (company_id, status),
INDEX idx_status (status),
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
// ─── Contexto de conversación del bot ─────────────────────────────────────────
$db->exec("
CREATE TABLE IF NOT EXISTS bot_context (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
phone_number VARCHAR(30) NOT NULL,
bot_type ENUM('normal','ai') DEFAULT 'normal',
current_node VARCHAR(100),
ai_history LONGTEXT,
metadata TEXT,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY idx_bot_context (company_id, phone_number),
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
// ─── Cola de aprobación — mensajes que requieren revisión humana ──────────────
$db->exec("
CREATE TABLE IF NOT EXISTS pending_approval (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
phone_number VARCHAR(30) NOT NULL,
contact_name VARCHAR(150),
incoming_msg TEXT NOT NULL,
bot_response TEXT,
bot_type VARCHAR(30),
context_json TEXT,
status ENUM('pending','approved','rejected') DEFAULT 'pending',
reviewed_by VARCHAR(100),
review_note TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
reviewed_at DATETIME,
INDEX idx_company_status (company_id, status),
INDEX idx_status (status),
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
// ─── Agregar company_id a tablas existentes ────────────────────────────────────
try {
$db->exec("ALTER TABLE conversations ADD COLUMN company_id INT DEFAULT NULL AFTER id, ADD INDEX idx_conv_company (company_id)");
} catch (\PDOException $e) {
// Columna ya existe
}
try {
$db->exec("ALTER TABLE webhook_logs ADD COLUMN company_id INT DEFAULT NULL AFTER id, ADD INDEX idx_wh_company (company_id)");
} catch (\PDOException $e) {}
try {
$db->exec("ALTER TABLE notifications ADD COLUMN company_id INT DEFAULT NULL AFTER id, ADD INDEX idx_notif_company (company_id)");
} catch (\PDOException $e) {}
// ─── Tabla de configuración general ────────────────────────────────────────────
$db->exec("
CREATE TABLE IF NOT EXISTS settings (
`key` VARCHAR(100) NOT NULL PRIMARY KEY,
`value` TEXT DEFAULT NULL,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
// Seed defaults si están vacíos
$seedSettings = [
'whatsapp_access_token' => '',
'whatsapp_app_secret' => '',
'whatsapp_verify_token' => '',
'whatsapp_business_account_id' => '',
'whatsapp_default_phone_number_id' => '',
'ai_provider' => 'mock',
'openai_api_key' => '',
'openai_model' => 'gpt-4o-mini',
'ai_max_tokens' => '500',
'ai_default_prompt' => 'Eres un asistente virtual de Palmas360. Responde de forma amable y profesional.',
];
$insertStmt = $db->prepare("INSERT IGNORE INTO settings (`key`, `value`) VALUES (?, ?)");
foreach ($seedSettings as $k => $v) {
$insertStmt->execute([$k, $v]);
}
// ─── Usuario admin por defecto ────────────────────────────────────────────────
$email = 'admin@palmas360.com';
$password = 'Palmas360@Admin26';
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
$stmt = $db->prepare("INSERT IGNORE INTO users (name, email, password) VALUES (?, ?, ?)");
$stmt->execute(['Lizandro', $email, $hash]);
echo "\n✅ Tablas creadas correctamente.\n";
echo "👤 Usuario: {$email}\n";
echo "🔑 Contraseña: {$password}\n";
echo "⚠️ Cambia la contraseña después del primer login.\n\n";