147 lines
7.7 KiB
MySQL
147 lines
7.7 KiB
MySQL
|
|
CREATE TABLE IF NOT EXISTS app_config (
|
||
|
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||
|
|
timezone TEXT DEFAULT 'America/New_York',
|
||
|
|
business_start INTEGER DEFAULT 9,
|
||
|
|
business_end INTEGER DEFAULT 17,
|
||
|
|
default_extension_days INTEGER DEFAULT 30,
|
||
|
|
backup_enabled BOOLEAN DEFAULT 1,
|
||
|
|
backup_interval_hours INTEGER DEFAULT 24,
|
||
|
|
backup_retention_days INTEGER DEFAULT 30
|
||
|
|
);
|
||
|
|
|
||
|
|
INSERT OR IGNORE INTO app_config (id) VALUES (1);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS domains (name TEXT PRIMARY KEY);
|
||
|
|
INSERT OR IGNORE INTO domains (name) VALUES ('Vulnerability'), ('Privacy'), ('Compliance'), ('Incident');
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS departments (name TEXT PRIMARY KEY);
|
||
|
|
INSERT OR IGNORE INTO departments (name) VALUES ('Security'), ('IT'), ('Privacy'), ('Legal'), ('Compliance');
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS sla_policies (
|
||
|
|
domain TEXT NOT NULL,
|
||
|
|
severity TEXT NOT NULL,
|
||
|
|
days_to_triage INTEGER NOT NULL DEFAULT 3,
|
||
|
|
days_to_remediate INTEGER NOT NULL,
|
||
|
|
max_extensions INTEGER NOT NULL DEFAULT 3,
|
||
|
|
PRIMARY KEY (domain, severity),
|
||
|
|
FOREIGN KEY(domain) REFERENCES domains(name) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
INSERT OR IGNORE INTO sla_policies (domain, severity, days_to_triage, days_to_remediate, max_extensions) VALUES
|
||
|
|
('Vulnerability', 'Critical', 3, 14, 1), ('Vulnerability', 'High', 3, 30, 2),
|
||
|
|
('Privacy', 'Critical', 3, 3, 0), ('Privacy', 'High', 3, 7, 1),
|
||
|
|
('Incident', 'Critical', 3, 1, 0);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS users (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
email TEXT UNIQUE NOT NULL,
|
||
|
|
password_hash TEXT NOT NULL,
|
||
|
|
full_name TEXT NOT NULL,
|
||
|
|
global_role TEXT NOT NULL CHECK(global_role IN ('Sheriff', 'RangeHand', 'Wrangler', 'CircuitRider', 'Magistrate')),
|
||
|
|
department TEXT NOT NULL DEFAULT 'Security',
|
||
|
|
is_active BOOLEAN DEFAULT 1,
|
||
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
FOREIGN KEY(department) REFERENCES departments(name) ON DELETE SET DEFAULT
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
||
|
|
session_token TEXT PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL,
|
||
|
|
expires_at DATETIME NOT NULL,
|
||
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS tickets (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
domain TEXT NOT NULL DEFAULT 'Vulnerability',
|
||
|
|
source TEXT NOT NULL DEFAULT 'Manual',
|
||
|
|
asset_identifier TEXT NOT NULL DEFAULT 'Default',
|
||
|
|
cve_id TEXT,
|
||
|
|
audit_id TEXT UNIQUE,
|
||
|
|
compliance_tags TEXT,
|
||
|
|
title TEXT NOT NULL,
|
||
|
|
description TEXT,
|
||
|
|
recommended_remediation TEXT,
|
||
|
|
severity TEXT NOT NULL,
|
||
|
|
status TEXT DEFAULT 'Waiting to be Triaged'
|
||
|
|
CHECK(status IN (
|
||
|
|
'Waiting to be Triaged',
|
||
|
|
'Returned to Security',
|
||
|
|
'Triaged',
|
||
|
|
'Assigned Out',
|
||
|
|
'Patched',
|
||
|
|
'False Positive'
|
||
|
|
)),
|
||
|
|
dedupe_hash TEXT UNIQUE NOT NULL,
|
||
|
|
patch_evidence TEXT,
|
||
|
|
accessible_to_internet BOOLEAN DEFAULT 0,
|
||
|
|
assignee TEXT DEFAULT 'Unassigned',
|
||
|
|
latest_comment TEXT DEFAULT '',
|
||
|
|
|
||
|
|
assigned_at DATETIME,
|
||
|
|
owner_viewed_at DATETIME,
|
||
|
|
triage_due_date DATETIME,
|
||
|
|
remediation_due_date DATETIME,
|
||
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
patched_at DATETIME,
|
||
|
|
FOREIGN KEY(domain) REFERENCES domains(name) ON DELETE SET DEFAULT
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_severity ON tickets(severity);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_domain ON tickets(domain);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_source_asset ON tickets(source, asset_identifier);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS ticket_assignments (
|
||
|
|
ticket_id INTEGER NOT NULL,
|
||
|
|
assignee TEXT NOT NULL,
|
||
|
|
role TEXT NOT NULL CHECK(role IN ('RangeHand', 'Wrangler', 'Magistrate')),
|
||
|
|
PRIMARY KEY (ticket_id, assignee, role),
|
||
|
|
FOREIGN KEY(ticket_id) REFERENCES tickets(id) ON DELETE CASCADE
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS data_adapters (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
name TEXT NOT NULL UNIQUE,
|
||
|
|
source_name TEXT NOT NULL,
|
||
|
|
findings_path TEXT NOT NULL DEFAULT '.',
|
||
|
|
mapping_title TEXT NOT NULL,
|
||
|
|
mapping_asset TEXT NOT NULL,
|
||
|
|
mapping_severity TEXT NOT NULL,
|
||
|
|
mapping_description TEXT,
|
||
|
|
mapping_remediation TEXT,
|
||
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS sync_logs (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
source TEXT NOT NULL,
|
||
|
|
status TEXT NOT NULL,
|
||
|
|
records_processed INTEGER NOT NULL,
|
||
|
|
error_message TEXT,
|
||
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS draft_tickets (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
report_id TEXT NOT NULL,
|
||
|
|
title TEXT DEFAULT '',
|
||
|
|
description TEXT,
|
||
|
|
severity TEXT DEFAULT 'Medium',
|
||
|
|
asset_identifier TEXT DEFAULT '',
|
||
|
|
recommended_remediation TEXT DEFAULT '',
|
||
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_draft_tickets_report_id ON draft_tickets(report_id);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_assignments_assignee ON ticket_assignments(assignee);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_status_asset ON tickets(status, asset_identifier);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_updated_at ON tickets(updated_at);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_analytics ON tickets(status, severity, source);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_due_dates ON tickets(status, remediation_due_date, triage_due_date);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_tickets_source_status ON tickets(source, status);
|