PRAGMA foreign_keys = ON; CREATE TABLE groups ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE services ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE domains ( id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER REFERENCES groups(id) ON DELETE SET NULL, zone_name TEXT NOT NULL UNIQUE, cf_zone_id TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'active', last_synced_at TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE INDEX idx_domains_cf_zone_id ON domains(cf_zone_id); CREATE INDEX idx_domains_group_id ON domains(group_id); CREATE TABLE subdomains ( id INTEGER PRIMARY KEY AUTOINCREMENT, domain_id INTEGER NOT NULL REFERENCES domains(id) ON DELETE CASCADE, name TEXT NOT NULL, fqdn TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE(domain_id, name) ); CREATE INDEX idx_subdomains_domain_id ON subdomains(domain_id); CREATE TABLE dns_records ( id INTEGER PRIMARY KEY AUTOINCREMENT, domain_id INTEGER NOT NULL REFERENCES domains(id) ON DELETE CASCADE, cf_record_id TEXT, record_type TEXT NOT NULL, name TEXT NOT NULL, content TEXT NOT NULL, ttl INTEGER NOT NULL DEFAULT 1, proxied INTEGER NOT NULL DEFAULT 0, priority INTEGER, sync_status TEXT NOT NULL DEFAULT 'pending_push', origin TEXT NOT NULL DEFAULT 'local', last_error TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE INDEX idx_dns_records_domain_type_name ON dns_records(domain_id, record_type, name); CREATE INDEX idx_dns_records_sync_status ON dns_records(sync_status); CREATE TABLE domain_services ( domain_id INTEGER NOT NULL REFERENCES domains(id) ON DELETE CASCADE, service_id INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE, PRIMARY KEY (domain_id, service_id) ); CREATE TABLE subdomain_services ( subdomain_id INTEGER NOT NULL REFERENCES subdomains(id) ON DELETE CASCADE, service_id INTEGER NOT NULL REFERENCES services(id) ON DELETE CASCADE, PRIMARY KEY (subdomain_id, service_id) ); CREATE TABLE certificates ( id INTEGER PRIMARY KEY AUTOINCREMENT, domain_id INTEGER NOT NULL REFERENCES domains(id) ON DELETE CASCADE, subdomain_id INTEGER REFERENCES subdomains(id) ON DELETE SET NULL, hostname TEXT NOT NULL UNIQUE, expires_at TEXT, last_checked_at TEXT, last_error TEXT, status TEXT NOT NULL DEFAULT 'unknown', created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE INDEX idx_certificates_status_expires ON certificates(status, expires_at); CREATE TABLE sync_jobs ( id TEXT PRIMARY KEY, status TEXT NOT NULL DEFAULT 'pending', domain_id INTEGER REFERENCES domains(id) ON DELETE SET NULL, message TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), finished_at TEXT ); INSERT INTO groups (name, slug) VALUES ('Local', 'local'), ('VPN', 'vpn'), ('External', 'external'); INSERT INTO services (name, slug) VALUES ('DNS', 'dns'), ('BGP', 'bgp'), ('CDN', 'cdn'), ('Mail', 'mail');