fix: Plugin migration runner + unified_search + marketplace migrations
Check Cross-Plugin Imports / check (push) Has been cancelled

Fixes 3 issues found by API integration tests:
1. migration_runner.py: Add GLOBAL TABLE exemption for tables without tenant_id
   - New _extract_global_table_names() method parses -- GLOBAL TABLE: comments
   - marketplace_listings is intentionally global (no tenant_id)
2. unified_search/migrations/0002_embeddings.sql: Remove companies table (does not exist),
   add DO $$ BEGIN END $$ blocks to check table existence before ALTER
3. marketplace/migrations/0001_initial.sql: Add -- GLOBAL TABLE: marketplace_listings comment
This commit is contained in:
Agent Zero
2026-08-04 22:47:26 +02:00
parent fcc1c92b33
commit 16648f543a
3 changed files with 50 additions and 15 deletions
+17 -1
View File
@@ -95,8 +95,12 @@ class MigrationRunner:
created_tables = new_tables - existing_tables
# Validate: all newly created tables must have tenant_id column
# Exception: tables marked as global in the SQL with `-- GLOBAL TABLE` comment
global_tables = self._extract_global_table_names(sql_content)
tables_without_tenant = []
for table_name in created_tables:
if table_name in global_tables:
continue # Global tables are exempt from tenant_id requirement
if not await self._table_has_column_via_session(db, table_name, "tenant_id"):
tables_without_tenant.append(table_name)
@@ -105,7 +109,8 @@ class MigrationRunner:
await db.rollback()
raise MigrationValidationError(
f"Plugin '{plugin_name}' migration '{migration_filename}' created tables without tenant_id column: "
f"{', '.join(tables_without_tenant)}. All plugin tables must have tenant_id for multi-tenant isolation."
f"{', '.join(tables_without_tenant)}. All plugin tables must have tenant_id for multi-tenant isolation. "
f"If a table is intentionally global, add `-- GLOBAL TABLE: table_name` comment to the migration SQL."
)
# Record the migration in plugin_migrations table
@@ -469,3 +474,14 @@ class MigrationRunner:
# Match CREATE TABLE [IF NOT EXISTS] "table_name" or CREATE TABLE table_name
pattern = r'CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["\']?(\w+)["\']?'
return re.findall(pattern, sql, re.IGNORECASE)
def _extract_global_table_names(sql: str) -> set[str]:
"""Extract table names marked as global in SQL comments.
Looks for `-- GLOBAL TABLE: table_name` comments in the SQL.
These tables are exempt from the tenant_id column requirement.
"""
import re
pattern = r'--\s*GLOBAL\s+TABLE:\s*(\w+)'
return set(re.findall(pattern, sql, re.IGNORECASE))