104 lines
3.2 KiB
Python
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)")
|