Files
bakery-ia/services/tenant/migrations/versions/20251028_remove_subscription_tier.py
2025-10-29 06:58:05 +01:00

104 lines
3.2 KiB
Python

"""remove subscription_tier from tenants
Revision ID: 20251028_remove_sub_tier
Revises: 20251025_supplier_approval
Create Date: 2025-10-28 12:00:00.000000
This migration removes the denormalized subscription_tier column from the tenants table.
The subscription tier is now sourced exclusively from the subscriptions table (single source of truth).
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '20251028_remove_sub_tier'
down_revision = '20251025_supplier_approval'
branch_labels = None
depends_on = None
def upgrade():
"""
Remove subscription_tier column from tenants table
"""
# Pre-flight check: Ensure all tenants have active subscriptions
# This is important to avoid breaking the application
connection = op.get_bind()
# Check for tenants without subscriptions
result = connection.execute(sa.text("""
SELECT COUNT(*) as count
FROM tenants t
LEFT JOIN subscriptions s ON t.id = s.tenant_id AND s.status = 'active'
WHERE s.id IS NULL
"""))
orphaned_count = result.fetchone()[0]
if orphaned_count > 0:
# Create default subscriptions for orphaned tenants
connection.execute(sa.text("""
INSERT INTO subscriptions (
id, tenant_id, plan, status, monthly_price, billing_cycle,
max_users, max_locations, max_products, features, created_at, updated_at
)
SELECT
gen_random_uuid(),
t.id,
'starter',
'active',
49.0,
'monthly',
5,
1,
50,
'{"inventory_management": true, "demand_prediction": true}'::jsonb,
NOW(),
NOW()
FROM tenants t
LEFT JOIN subscriptions s ON t.id = s.tenant_id AND s.status = 'active'
WHERE s.id IS NULL
"""))
print(f"Created default subscriptions for {orphaned_count} tenants without subscriptions")
# Drop the subscription_tier column
op.drop_column('tenants', 'subscription_tier')
print("Successfully removed subscription_tier column from tenants table")
def downgrade():
"""
Re-add subscription_tier column and populate from subscriptions table
Note: This is for rollback purposes only. Going forward, always use subscriptions table.
"""
# Add the column back
op.add_column('tenants',
sa.Column('subscription_tier', sa.String(length=50), nullable=True)
)
# Populate from subscriptions table
connection = op.get_bind()
connection.execute(sa.text("""
UPDATE tenants t
SET subscription_tier = s.plan
FROM subscriptions s
WHERE t.id = s.tenant_id
AND s.status = 'active'
"""))
# Set default for any tenants without active subscriptions
connection.execute(sa.text("""
UPDATE tenants
SET subscription_tier = 'starter'
WHERE subscription_tier IS NULL
"""))
# Make it non-nullable after population
op.alter_column('tenants', 'subscription_tier', nullable=False)
print("Restored subscription_tier column (downgrade)")