fix(tenant): Defer plugin seeding until after transaction commits

The post_save signal was trying to seed plugins before the tenant's
schema migrations had completed, causing a 500 error when accepting
tenant invitations. Using transaction.on_commit() ensures the schema
and tables exist before seeding.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-03 16:11:51 -05:00
parent 55cb97ca0d
commit 5244e16279

View File

@@ -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))