Add subcription feature 2

This commit is contained in:
Urtzi Alfaro
2026-01-14 13:15:48 +01:00
parent 6ddf608d37
commit a4c3b7da3f
32 changed files with 4240 additions and 965 deletions

View File

@@ -228,8 +228,8 @@ CREATE TABLE tenants (
-- Subscription
subscription_tier VARCHAR(50) DEFAULT 'free', -- free, pro, enterprise
stripe_customer_id VARCHAR(255), -- Stripe customer ID
stripe_subscription_id VARCHAR(255), -- Stripe subscription ID
customer_id VARCHAR(255), -- Stripe customer ID
subscription_id VARCHAR(255), -- Stripe subscription ID
-- 🆕 Enterprise hierarchy fields (NEW)
parent_tenant_id UUID REFERENCES tenants(id) ON DELETE RESTRICT,
@@ -271,8 +271,8 @@ CREATE INDEX idx_tenants_hierarchy_path ON tenants(hierarchy_path);
CREATE TABLE tenant_subscriptions (
id UUID PRIMARY KEY,
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
stripe_subscription_id VARCHAR(255) UNIQUE,
stripe_customer_id VARCHAR(255),
subscription_id VARCHAR(255) UNIQUE,
customer_id VARCHAR(255),
-- Plan details
plan_tier VARCHAR(50) NOT NULL, -- free, pro, enterprise
@@ -486,7 +486,7 @@ CREATE TABLE tenant_audit_log (
```sql
CREATE INDEX idx_tenants_status ON tenants(status);
CREATE INDEX idx_tenants_subscription_tier ON tenants(subscription_tier);
CREATE INDEX idx_subscriptions_stripe ON tenant_subscriptions(stripe_subscription_id);
CREATE INDEX idx_subscriptions_stripe ON tenant_subscriptions(subscription_id);
CREATE INDEX idx_subscriptions_status ON tenant_subscriptions(tenant_id, status);
CREATE INDEX idx_members_tenant ON tenant_members(tenant_id);
CREATE INDEX idx_members_user ON tenant_members(user_id);
@@ -555,7 +555,7 @@ async def create_tenant_with_subscription(
}] if tenant.tax_id else None
)
tenant.stripe_customer_id = stripe_customer.id
tenant.customer_id = stripe_customer.id
# Attach payment method if provided
if payment_method_id:
@@ -587,13 +587,13 @@ async def create_tenant_with_subscription(
stripe_subscription = stripe.Subscription.create(**subscription_params)
tenant.stripe_subscription_id = stripe_subscription.id
tenant.subscription_id = stripe_subscription.id
# Create subscription record
subscription = TenantSubscription(
tenant_id=tenant.id,
stripe_subscription_id=stripe_subscription.id,
stripe_customer_id=stripe_customer.id,
subscription_id=stripe_subscription.id,
customer_id=stripe_customer.id,
plan_tier=plan_tier,
plan_interval='month',
plan_amount=get_plan_amount(plan_tier),
@@ -705,11 +705,11 @@ async def update_subscription(
new_price_id = get_stripe_price_id(new_plan_tier, subscription.plan_interval)
# Update Stripe subscription
stripe_subscription = stripe.Subscription.retrieve(subscription.stripe_subscription_id)
stripe_subscription = stripe.Subscription.retrieve(subscription.subscription_id)
# Update subscription items (Stripe handles proration automatically)
stripe_subscription = stripe.Subscription.modify(
subscription.stripe_subscription_id,
subscription.subscription_id,
items=[{
'id': stripe_subscription['items']['data'][0].id,
'price': new_price_id
@@ -828,7 +828,7 @@ async def handle_subscription_updated(stripe_subscription: dict):
tenant_id = UUID(stripe_subscription['metadata'].get('tenant_id'))
subscription = await db.query(TenantSubscription).filter(
TenantSubscription.stripe_subscription_id == stripe_subscription['id']
TenantSubscription.subscription_id == stripe_subscription['id']
).first()
if subscription:
@@ -846,7 +846,7 @@ async def handle_payment_failed(stripe_invoice: dict):
customer_id = stripe_invoice['customer']
tenant = await db.query(Tenant).filter(
Tenant.stripe_customer_id == customer_id
Tenant.customer_id == customer_id
).first()
if tenant:
@@ -923,9 +923,9 @@ async def upgrade_tenant_to_enterprise(
import stripe
stripe.api_key = os.getenv('STRIPE_SECRET_KEY')
stripe_subscription = stripe.Subscription.retrieve(subscription.stripe_subscription_id)
stripe_subscription = stripe.Subscription.retrieve(subscription.subscription_id)
stripe.Subscription.modify(
subscription.stripe_subscription_id,
subscription.subscription_id,
items=[{
'id': stripe_subscription['items']['data'][0].id,
'price': new_price_id
@@ -1052,8 +1052,8 @@ async def add_child_outlet_to_parent(
# 3. Create linked subscription (child shares parent subscription)
child_subscription = TenantSubscription(
tenant_id=child_tenant.id,
stripe_subscription_id=None, # Linked to parent, no separate billing
stripe_customer_id=parent.stripe_customer_id, # Same customer
subscription_id=None, # Linked to parent, no separate billing
customer_id=parent.customer_id, # Same customer
plan_tier='enterprise',
plan_interval='month',
plan_amount=Decimal('0.00'), # No additional charge