-- ========================================== -- Switchboard Core — 003 Packages & Extensions -- ========================================== CREATE TABLE IF NOT EXISTS packages ( id TEXT PRIMARY KEY, title TEXT NOT NULL, type TEXT NOT NULL DEFAULT 'surface' CHECK (type IN ('surface', 'extension', 'full', 'workflow', 'library')), version TEXT NOT NULL DEFAULT '0.0.0', description TEXT NOT NULL DEFAULT '', author TEXT NOT NULL DEFAULT '', tier TEXT NOT NULL DEFAULT 'browser' CHECK (tier IN ('browser', 'starlark', 'sidecar')), is_system BOOLEAN NOT NULL DEFAULT false, scope TEXT NOT NULL DEFAULT 'global' CHECK (scope IN ('global', 'team', 'personal')), team_id UUID REFERENCES teams(id) ON DELETE CASCADE, installed_by UUID REFERENCES users(id) ON DELETE SET NULL, manifest JSONB NOT NULL DEFAULT '{}', enabled BOOLEAN NOT NULL DEFAULT true, status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'pending_review', 'suspended', 'dormant')), schema_version INTEGER NOT NULL DEFAULT 0, package_settings JSONB NOT NULL DEFAULT '{}', source TEXT NOT NULL DEFAULT 'core' CHECK (source IN ('core', 'builtin', 'extension', 'registry')), installed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_packages_type ON packages(type); CREATE INDEX IF NOT EXISTS idx_packages_enabled ON packages(enabled) WHERE enabled = true; CREATE INDEX IF NOT EXISTS idx_packages_team ON packages(team_id); CREATE INDEX IF NOT EXISTS idx_packages_source ON packages(source); CREATE INDEX IF NOT EXISTS idx_packages_status ON packages(status); -- ── Package User Settings ─────────────────── CREATE TABLE IF NOT EXISTS package_user_settings ( package_id TEXT NOT NULL REFERENCES packages(id) ON DELETE CASCADE, user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, settings JSONB NOT NULL DEFAULT '{}', is_enabled BOOLEAN NOT NULL DEFAULT true, PRIMARY KEY (package_id, user_id) ); -- ── Extension Permissions ─────────────────── CREATE TABLE IF NOT EXISTS extension_permissions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), package_id TEXT NOT NULL REFERENCES packages(id) ON DELETE CASCADE, permission TEXT NOT NULL, granted BOOLEAN NOT NULL DEFAULT false, granted_by UUID REFERENCES users(id) ON DELETE SET NULL, granted_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(package_id, permission) ); CREATE INDEX IF NOT EXISTS idx_ext_perm_package ON extension_permissions(package_id); CREATE INDEX IF NOT EXISTS idx_ext_perm_granted ON extension_permissions(granted) WHERE granted = true; -- ── Extension Data Tables Catalog ─────────── CREATE TABLE IF NOT EXISTS ext_data_tables ( package_id TEXT NOT NULL REFERENCES packages(id) ON DELETE CASCADE, table_name TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), PRIMARY KEY (package_id, table_name) ); CREATE INDEX IF NOT EXISTS idx_ext_data_tables_pkg ON ext_data_tables(package_id); -- ── Platform Read View ────────────────────── CREATE OR REPLACE VIEW ext_view_users AS SELECT id, display_name, email FROM users;