feat: normalize subscription architecture, integrate pgvector, and implement Stripe webhook subscription management.

This commit is contained in:
2026-05-05 15:07:48 +02:00
parent e21c24b66d
commit 311eaa8b04
29 changed files with 1699 additions and 199 deletions
@@ -37,26 +37,29 @@ public class BillingService : IBillingService
return false;
}
string targetPlanName = SubscriptionPlan.FreeName;
int tokenLimit = 1000;
if (stripeProductId == _stripeSettings.ProProductId)
{
user.CurrentPlan = "Pro";
user.AITokenLimit = 50000;
targetPlanName = SubscriptionPlan.ProName;
tokenLimit = 50000;
}
else if (stripeProductId == _stripeSettings.BasicProductId)
{
user.CurrentPlan = "Basic";
user.AITokenLimit = 10000;
targetPlanName = SubscriptionPlan.BasicName;
tokenLimit = 10000;
}
else if (stripeProductId == _stripeSettings.FreeProductId || string.IsNullOrEmpty(stripeProductId))
else if (!string.IsNullOrEmpty(stripeProductId) && stripeProductId != _stripeSettings.FreeProductId)
{
user.CurrentPlan = "Free";
user.AITokenLimit = 1000;
_logger.LogWarning("Unrecognized Stripe Product ID: {ProductId} for user {Email}. Falling back to Free tier.", stripeProductId, customerEmail);
}
else
var plan = await _dbContext.SubscriptionPlans.FirstOrDefaultAsync(p => p.PlanName == targetPlanName);
if (plan != null)
{
_logger.LogWarning("Unrecognized Stripe Product ID: {ProductId} for user {Email}. Falling back to Free tier.", stripeProductId, customerEmail);
user.CurrentPlan = "Free";
user.AITokenLimit = 1000;
user.SubscriptionPlanId = plan.Id;
user.AITokenLimit = tokenLimit;
}
var result = await _userManager.UpdateAsync(user);
@@ -79,8 +82,12 @@ public class BillingService : IBillingService
return false;
}
user.CurrentPlan = "Free";
user.AITokenLimit = 1000; // Reset to free limit
var freePlan = await _dbContext.SubscriptionPlans.FirstOrDefaultAsync(p => p.PlanName == SubscriptionPlan.FreeName);
if (freePlan != null)
{
user.SubscriptionPlanId = freePlan.Id;
user.AITokenLimit = freePlan.AITokenLimit;
}
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)