Synced files: - Quote wizard frontend (all components, hooks, types, config) - API updates (config, models, routers, schemas, services) - Client work (bg-builders, gurushow) - Scripts (BGB Lesley termination, CIPP, Datto, migration) - Temp files (Bardach contacts, VWP investigation, misc) - Credentials and session logs - Email service, PHP API, session logs Machine: ACG-M-L5090 Timestamp: 2026-03-10 19:11:00 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
131 lines
5.9 KiB
SQL
131 lines
5.9 KiB
SQL
-- ==========================================================================
|
|
-- MSP Quote Wizard - Database Schema
|
|
-- Target: MySQL 5.7+ / MariaDB 10.3+ on cPanel
|
|
-- Database: azcomputerguru_acg2025
|
|
-- Table prefix: acgq_
|
|
-- ==========================================================================
|
|
|
|
SET NAMES utf8mb4;
|
|
SET FOREIGN_KEY_CHECKS = 0;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- Quotes table - main quote records
|
|
-- --------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `acgq_quotes` (
|
|
`id` CHAR(36) NOT NULL,
|
|
`access_token` VARCHAR(64) NOT NULL,
|
|
`status` VARCHAR(20) NOT NULL DEFAULT 'draft',
|
|
`company_name` VARCHAR(255) DEFAULT NULL,
|
|
`contact_name` VARCHAR(255) DEFAULT NULL,
|
|
`contact_email` VARCHAR(255) DEFAULT NULL,
|
|
`contact_phone` VARCHAR(50) DEFAULT NULL,
|
|
`employee_count` INT DEFAULT NULL,
|
|
`industry` VARCHAR(100) DEFAULT NULL,
|
|
`current_it_situation` TEXT DEFAULT NULL,
|
|
`monthly_total` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
|
`setup_total` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
|
`expires_at` DATETIME DEFAULT NULL,
|
|
`submitted_at` DATETIME DEFAULT NULL,
|
|
`ip_address` VARCHAR(45) DEFAULT NULL,
|
|
`user_agent` TEXT DEFAULT NULL,
|
|
`source` VARCHAR(50) DEFAULT 'website',
|
|
`utm_source` VARCHAR(100) DEFAULT NULL,
|
|
`utm_medium` VARCHAR(100) DEFAULT NULL,
|
|
`utm_campaign` VARCHAR(100) DEFAULT NULL,
|
|
`syncro_lead_id` VARCHAR(100) DEFAULT NULL,
|
|
`syncro_synced_at` DATETIME DEFAULT NULL,
|
|
`is_existing_customer` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uq_quotes_access_token` (`access_token`),
|
|
INDEX `idx_quotes_access_token` (`access_token`),
|
|
INDEX `idx_quotes_status` (`status`),
|
|
INDEX `idx_quotes_contact_email` (`contact_email`),
|
|
INDEX `idx_quotes_created_at` (`created_at`),
|
|
CONSTRAINT `ck_quotes_status` CHECK (
|
|
`status` IN ('draft', 'submitted', 'viewed', 'followed_up', 'converted', 'expired', 'archived')
|
|
)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- Quote items table - line items within a quote
|
|
-- --------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `acgq_quote_items` (
|
|
`id` CHAR(36) NOT NULL,
|
|
`quote_id` CHAR(36) NOT NULL,
|
|
`category` VARCHAR(50) NOT NULL,
|
|
`product_code` VARCHAR(50) NOT NULL,
|
|
`product_name` VARCHAR(255) NOT NULL,
|
|
`description` TEXT DEFAULT NULL,
|
|
`quantity` INT NOT NULL DEFAULT 1,
|
|
`unit_price` DECIMAL(10,2) NOT NULL,
|
|
`setup_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
|
`billing_frequency` VARCHAR(20) NOT NULL DEFAULT 'monthly',
|
|
`tier` VARCHAR(50) DEFAULT NULL,
|
|
`is_recommended` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
INDEX `idx_quote_items_quote_id` (`quote_id`),
|
|
INDEX `idx_quote_items_category` (`category`),
|
|
CONSTRAINT `fk_quote_items_quote` FOREIGN KEY (`quote_id`)
|
|
REFERENCES `acgq_quotes` (`id`) ON DELETE CASCADE,
|
|
CONSTRAINT `ck_quote_items_category` CHECK (
|
|
`category` IN ('gps_monitoring', 'support_plan', 'voip', 'web_hosting', 'email', 'hardware', 'addon', 'backup', 'security', 'other')
|
|
),
|
|
CONSTRAINT `ck_quote_items_billing_frequency` CHECK (
|
|
`billing_frequency` IN ('monthly', 'yearly', 'one_time')
|
|
)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- Quote activity table - audit log of all actions on a quote
|
|
-- --------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `acgq_quote_activity` (
|
|
`id` CHAR(36) NOT NULL,
|
|
`quote_id` CHAR(36) NOT NULL,
|
|
`action` VARCHAR(50) NOT NULL,
|
|
`step_name` VARCHAR(50) DEFAULT NULL,
|
|
`details` TEXT DEFAULT NULL,
|
|
`ip_address` VARCHAR(45) DEFAULT NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
INDEX `idx_quote_activity_quote_id` (`quote_id`),
|
|
INDEX `idx_quote_activity_action` (`action`),
|
|
INDEX `idx_quote_activity_created_at` (`created_at`),
|
|
CONSTRAINT `fk_quote_activity_quote` FOREIGN KEY (`quote_id`)
|
|
REFERENCES `acgq_quotes` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- Quote notifications table - tracks emails and webhooks sent
|
|
-- --------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `acgq_quote_notifications` (
|
|
`id` CHAR(36) NOT NULL,
|
|
`quote_id` CHAR(36) NOT NULL,
|
|
`notification_type` VARCHAR(30) NOT NULL,
|
|
`recipient` VARCHAR(255) NOT NULL,
|
|
`subject` VARCHAR(255) DEFAULT NULL,
|
|
`body` TEXT DEFAULT NULL,
|
|
`status` VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
`attempts` INT NOT NULL DEFAULT 0,
|
|
`last_attempt_at` DATETIME DEFAULT NULL,
|
|
`sent_at` DATETIME DEFAULT NULL,
|
|
`error_message` TEXT DEFAULT NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
INDEX `idx_quote_notifications_quote_id` (`quote_id`),
|
|
INDEX `idx_quote_notifications_type` (`notification_type`),
|
|
INDEX `idx_quote_notifications_status` (`status`),
|
|
CONSTRAINT `fk_quote_notifications_quote` FOREIGN KEY (`quote_id`)
|
|
REFERENCES `acgq_quotes` (`id`) ON DELETE CASCADE,
|
|
CONSTRAINT `ck_quote_notifications_type` CHECK (
|
|
`notification_type` IN ('email', 'webhook')
|
|
),
|
|
CONSTRAINT `ck_quote_notifications_status` CHECK (
|
|
`status` IN ('pending', 'sent', 'failed')
|
|
)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
SET FOREIGN_KEY_CHECKS = 1;
|