diff --git a/smoothschedule/core/signals.py b/smoothschedule/core/signals.py index 3950aa8..5123fcf 100644 --- a/smoothschedule/core/signals.py +++ b/smoothschedule/core/signals.py @@ -4,36 +4,26 @@ Core App Signals Handles automatic setup tasks when tenants are created. """ import logging +from django.db import transaction from django.db.models.signals import post_save from django.dispatch import receiver logger = logging.getLogger(__name__) -@receiver(post_save, sender='core.Tenant') -def seed_platform_plugins_on_tenant_create(sender, instance, created, **kwargs): +def _seed_plugins_for_tenant(tenant_schema_name): """ - Seed platform plugins when a new tenant is created. - - This ensures new tenants have access to all marketplace plugins immediately. + Internal function to seed platform plugins for a tenant. + Called after transaction commits to ensure schema tables exist. """ - if not created: - return - - # Skip public schema - if instance.schema_name == 'public': - return - - # Defer the import to avoid circular imports - from django.db import connection from django_tenants.utils import schema_context from schedule.models import PluginTemplate from django.utils import timezone - logger.info(f"Seeding platform plugins for new tenant: {instance.schema_name}") + logger.info(f"Seeding platform plugins for new tenant: {tenant_schema_name}") try: - with schema_context(instance.schema_name): + with schema_context(tenant_schema_name): # Import the plugin definitions from the seed command from schedule.management.commands.seed_platform_plugins import get_platform_plugins @@ -62,6 +52,28 @@ def seed_platform_plugins_on_tenant_create(sender, instance, created, **kwargs): ) created_count += 1 - logger.info(f"Created {created_count} platform plugins for tenant: {instance.schema_name}") + logger.info(f"Created {created_count} platform plugins for tenant: {tenant_schema_name}") except Exception as e: - logger.error(f"Failed to seed plugins for tenant {instance.schema_name}: {e}") + logger.error(f"Failed to seed plugins for tenant {tenant_schema_name}: {e}") + + +@receiver(post_save, sender='core.Tenant') +def seed_platform_plugins_on_tenant_create(sender, instance, created, **kwargs): + """ + Seed platform plugins when a new tenant is created. + + This ensures new tenants have access to all marketplace plugins immediately. + Uses transaction.on_commit() to defer seeding until after the schema is + fully created and migrations have run. + """ + if not created: + return + + # Skip public schema + if instance.schema_name == 'public': + return + + # Defer the seeding until after the transaction commits + # This ensures the schema and all tables exist before we try to use them + schema_name = instance.schema_name + transaction.on_commit(lambda: _seed_plugins_for_tenant(schema_name))