diff --git a/app/main.py b/app/main.py index e05d0b9..59408a3 100644 --- a/app/main.py +++ b/app/main.py @@ -95,7 +95,7 @@ async def lifespan(app: FastAPI): registry.initialize(get_engine(), app) registry.discover_builtins() - # Activate plugins that are marked active in the database + # Auto-install and activate all discovered builtin plugins from sqlalchemy import select as sa_select from sqlalchemy.ext.asyncio import async_sessionmaker from app.models.plugin import Plugin as PluginModel @@ -105,25 +105,49 @@ async def lifespan(app: FastAPI): async_session = async_sessionmaker(get_engine(), expire_on_commit=False) async with async_session() as db: - result = await db.execute( - sa_select(PluginModel).where(PluginModel.active == True) # noqa: E712 - ) - active_plugins = result.scalars().all() - - for plugin_record in active_plugins: - plugin = registry.get_plugin(plugin_record.name) + for name in registry._plugins: + plugin = registry.get_plugin(name) if plugin is None: continue + + # Check if plugin already in DB + result = await db.execute( + sa_select(PluginModel).where(PluginModel.name == name) + ) + plugin_record = result.scalar_one_or_none() + + if plugin_record is None: + # Create DB record for this builtin plugin + plugin_record = PluginModel( + name=name, + version=plugin.manifest.version, + status="installed", + active=True, + ) + db.add(plugin_record) + await db.flush() + logger.info(f"Created plugin record: {name}") + + # Run migrations if not yet applied + if plugin.manifest.migrations: + try: + await registry.migration_runner.run_all_migrations( + db, name, plugin.manifest.migrations + ) + except Exception as exc: + logger.warning(f"Migration for {name}: {exc}") + + # Activate plugin and register routes try: await plugin.on_activate(db, container, event_bus) - # Register plugin routes into FastAPI app for route_def in plugin.manifest.routes: router_module = importlib.import_module(route_def.module) router = getattr(router_module, route_def.router_attr) app.include_router(router) - logger.info(f"Activated plugin: {plugin_record.name}") + plugin_record.active = True + logger.info(f"Activated plugin: {name} ({len(plugin.manifest.routes)} routes)") except Exception as exc: - logger.warning(f"Failed to activate plugin {plugin_record.name}: {exc}") + logger.warning(f"Failed to activate plugin {name}: {exc}") await db.commit()