feat(#357): Paket 6 — Contact-Model ins ContactsPlugin (physischer Move + PEP-562-Lazy-Re-Export-Bruecke, ALEMBIC_OWNED_TABLES gegen Schema-Dual-Ownership, outbox-Vorbestands-Fix in models/__init__)
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
This commit is contained in:
@@ -64,6 +64,10 @@ EXEMPT_PATHS = {
|
||||
PROJECT_ROOT / "app" / "plugins" / "base.py",
|
||||
PROJECT_ROOT / "app" / "plugins" / "manifest.py",
|
||||
PROJECT_ROOT / "app" / "plugins" / "migration_runner.py",
|
||||
# Paket 6 (#357): deliberate re-export bridge — the ContactsPlugin owns the
|
||||
# Contact model; app/models/contact.py only mirrors it so alembic env.py,
|
||||
# Core services and tests keep their stable import path.
|
||||
PROJECT_ROOT / "app" / "models" / "contact.py",
|
||||
}
|
||||
|
||||
# Pattern for cross-plugin imports
|
||||
|
||||
@@ -15,10 +15,10 @@ Environment:
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
import pkgutil
|
||||
import sys
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
# Ensure /app is in sys.path for container execution
|
||||
@@ -33,6 +33,16 @@ from sqlalchemy.orm import DeclarativeBase
|
||||
logger = logging.getLogger("sync_plugin_schema")
|
||||
logging.basicConfig(level=logging.INFO, format="[sync] %(levelname)s: %(message)s")
|
||||
|
||||
# ── Alembic-owned tables (Paket 6, #357) ────────────────────────────────────
|
||||
# Tables whose ORM model classes moved into a plugin package but whose schema
|
||||
# is still owned by the Alembic migration chain (142 migrations reference
|
||||
# them). The plugin schema sync must NOT manage these tables — dual ownership
|
||||
# would cause schema drift between the two mechanisms.
|
||||
ALEMBIC_OWNED_TABLES: set[str] = {
|
||||
"contacts",
|
||||
"contactpersons",
|
||||
}
|
||||
|
||||
# ── Plugin model discovery ──────────────────────────────────────────────────
|
||||
|
||||
def _import_all_plugin_models() -> list[type[DeclarativeBase]]:
|
||||
@@ -48,7 +58,7 @@ def _import_all_plugin_models() -> list[type[DeclarativeBase]]:
|
||||
return models
|
||||
|
||||
# Import the builtins package to trigger model registrations
|
||||
for importer, modname, ispkg in pkgutil.iter_modules(builtins_pkg.__path__):
|
||||
for _importer, modname, ispkg in pkgutil.iter_modules(builtins_pkg.__path__):
|
||||
if not ispkg:
|
||||
continue
|
||||
module_path = f"app.plugins.builtins.{modname}.models"
|
||||
@@ -66,7 +76,12 @@ def _import_all_plugin_models() -> list[type[DeclarativeBase]]:
|
||||
# Filter to only plugin tables — we identify them by checking if the table
|
||||
# name appears in any plugin models module. We use metadata.tables which
|
||||
# contains all registered tables.
|
||||
for table_name, table in Base.metadata.tables.items():
|
||||
for table_name, _table in Base.metadata.tables.items():
|
||||
# Alembic-owned tables never go through the plugin sync, even when
|
||||
# their model class lives in a plugin package (Paket 6: contacts,
|
||||
# contactpersons — 142 Alembic migrations own their schema).
|
||||
if table_name in ALEMBIC_OWNED_TABLES:
|
||||
continue
|
||||
# We only process tables that are defined in plugin modules.
|
||||
# Core models are handled by alembic migrations.
|
||||
# We check the module of the model class.
|
||||
|
||||
Reference in New Issue
Block a user