CREATE TABLE IF NOT EXISTS app_settings ( id INTEGER PRIMARY KEY CHECK (id = 1), qc_base_url TEXT NOT NULL DEFAULT '', qc_bearer_token_encrypted TEXT NOT NULL DEFAULT '', language_output_mode TEXT NOT NULL DEFAULT 'EN', job_poll_interval_seconds INTEGER NOT NULL DEFAULT 5, job_poll_timeout_seconds INTEGER NOT NULL DEFAULT 300, updated_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS qc_templates ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL DEFAULT '', locale TEXT NOT NULL DEFAULT '', thumbnail_url TEXT NOT NULL DEFAULT '', template_preview_url TEXT NOT NULL DEFAULT '', type TEXT NOT NULL DEFAULT '', palette_ready INTEGER NOT NULL DEFAULT 0, raw_template_json BLOB, is_ai_template INTEGER NOT NULL DEFAULT 0, is_onboarded INTEGER NOT NULL DEFAULT 0, manifest_status TEXT NOT NULL DEFAULT 'missing', last_discovered_at TEXT, updated_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS qc_template_manifests ( id TEXT PRIMARY KEY, template_id INTEGER NOT NULL, manifest_version INTEGER NOT NULL, source TEXT NOT NULL, language_used_discovery TEXT NOT NULL, discovery_payload_json BLOB, discovery_response_json BLOB, flattened_manifest_json BLOB, is_active INTEGER NOT NULL DEFAULT 1, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, FOREIGN KEY (template_id) REFERENCES qc_templates(id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_manifests_template_active ON qc_template_manifests(template_id, is_active); CREATE TABLE IF NOT EXISTS qc_template_fields ( id TEXT PRIMARY KEY, template_id INTEGER NOT NULL, manifest_id TEXT NOT NULL, section TEXT NOT NULL, key_name TEXT NOT NULL, path TEXT NOT NULL, field_kind TEXT NOT NULL, sample_value TEXT NOT NULL DEFAULT '', is_enabled INTEGER NOT NULL DEFAULT 1, is_required_by_us INTEGER NOT NULL DEFAULT 0, display_label TEXT NOT NULL DEFAULT '', display_order INTEGER NOT NULL DEFAULT 0, notes TEXT NOT NULL DEFAULT '', FOREIGN KEY (template_id) REFERENCES qc_templates(id) ON DELETE CASCADE, FOREIGN KEY (manifest_id) REFERENCES qc_template_manifests(id) ON DELETE CASCADE, UNIQUE(template_id, manifest_id, path) ); CREATE INDEX IF NOT EXISTS idx_fields_manifest ON qc_template_fields(manifest_id); CREATE TABLE IF NOT EXISTS site_builds ( id TEXT PRIMARY KEY, template_id INTEGER NOT NULL, manifest_id TEXT NOT NULL, request_name TEXT NOT NULL, global_data_json BLOB, ai_data_json BLOB, final_sites_payload_json BLOB, qc_job_id INTEGER, qc_site_id INTEGER, qc_status TEXT NOT NULL, qc_preview_url TEXT NOT NULL DEFAULT '', qc_editor_url TEXT NOT NULL DEFAULT '', qc_result_json BLOB, qc_error_json BLOB, started_at TEXT, finished_at TEXT, FOREIGN KEY (template_id) REFERENCES qc_templates(id) ON DELETE RESTRICT, FOREIGN KEY (manifest_id) REFERENCES qc_template_manifests(id) ON DELETE RESTRICT ); CREATE INDEX IF NOT EXISTS idx_builds_status ON site_builds(qc_status); CREATE TABLE IF NOT EXISTS build_drafts ( id TEXT PRIMARY KEY, template_id INTEGER NOT NULL, manifest_id TEXT NOT NULL DEFAULT '', source TEXT NOT NULL DEFAULT 'ui', request_name TEXT NOT NULL DEFAULT '', global_data_json BLOB, field_values_json BLOB, status TEXT NOT NULL DEFAULT 'draft', notes TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, FOREIGN KEY (template_id) REFERENCES qc_templates(id) ON DELETE RESTRICT ); CREATE INDEX IF NOT EXISTS idx_drafts_updated_at ON build_drafts(updated_at DESC);