fix: bug para excluir trial
All checks were successful
BCards Deployment Pipeline / Run Tests (push) Successful in 2s
BCards Deployment Pipeline / PR Validation (push) Has been skipped
BCards Deployment Pipeline / Build and Push Image (push) Successful in 8m1s
BCards Deployment Pipeline / Deploy to Production (ARM - OCI) (push) Successful in 3m48s
BCards Deployment Pipeline / Deploy to Staging (x86 - Local) (push) Has been skipped
BCards Deployment Pipeline / Cleanup Old Resources (push) Has been skipped
BCards Deployment Pipeline / Deployment Summary (push) Successful in 0s
All checks were successful
BCards Deployment Pipeline / Run Tests (push) Successful in 2s
BCards Deployment Pipeline / PR Validation (push) Has been skipped
BCards Deployment Pipeline / Build and Push Image (push) Successful in 8m1s
BCards Deployment Pipeline / Deploy to Production (ARM - OCI) (push) Successful in 3m48s
BCards Deployment Pipeline / Deploy to Staging (x86 - Local) (push) Has been skipped
BCards Deployment Pipeline / Cleanup Old Resources (push) Has been skipped
BCards Deployment Pipeline / Deployment Summary (push) Successful in 0s
This commit is contained in:
parent
55ad73b505
commit
aea64c0b8e
@ -30,40 +30,44 @@ public class SitemapController : Controller
|
||||
// 🔥 NOVA FUNCIONALIDADE: Usar LivePages em vez de UserPages
|
||||
var livePages = await _livePageService.GetAllActiveAsync();
|
||||
|
||||
// Define namespace corretamente para evitar conflitos
|
||||
XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
|
||||
|
||||
// Construir URLs das páginas dinâmicas separadamente para evitar problemas
|
||||
var dynamicUrls = livePages.Select(page =>
|
||||
new XElement(ns + "url",
|
||||
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/page/{page.Category?.Replace(" ", "-")?.ToLower()}/{page.Slug}"),
|
||||
new XElement(ns + "lastmod", page.LastSyncAt.ToString("yyyy-MM-dd")),
|
||||
new XElement(ns + "changefreq", "weekly"),
|
||||
new XElement(ns + "priority", "0.8")
|
||||
)
|
||||
).ToList();
|
||||
|
||||
var sitemap = new XDocument(
|
||||
new XDeclaration("1.0", "utf-8", "yes"),
|
||||
new XElement("urlset",
|
||||
new XAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9"),
|
||||
|
||||
new XElement(ns + "urlset",
|
||||
// Add static pages
|
||||
new XElement("url",
|
||||
new XElement("loc", $"{Request.Scheme}://{Request.Host}/"),
|
||||
new XElement("lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
|
||||
new XElement("changefreq", "daily"),
|
||||
new XElement("priority", "1.0")
|
||||
new XElement(ns + "url",
|
||||
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/"),
|
||||
new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
|
||||
new XElement(ns + "changefreq", "daily"),
|
||||
new XElement(ns + "priority", "1.0")
|
||||
),
|
||||
new XElement("url",
|
||||
new XElement("loc", $"{Request.Scheme}://{Request.Host}/Home/Pricing"),
|
||||
new XElement("lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
|
||||
new XElement("changefreq", "weekly"),
|
||||
new XElement("priority", "0.9")
|
||||
new XElement(ns + "url",
|
||||
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/Home/Pricing"),
|
||||
new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
|
||||
new XElement(ns + "changefreq", "weekly"),
|
||||
new XElement(ns + "priority", "0.9")
|
||||
),
|
||||
|
||||
// Add live pages (SEO-optimized URLs only)
|
||||
livePages.Select(page =>
|
||||
new XElement("url",
|
||||
new XElement("loc", $"{Request.Scheme}://{Request.Host}/page/{page.Category}/{page.Slug}"),
|
||||
new XElement("lastmod", page.LastSyncAt.ToString("yyyy-MM-dd")),
|
||||
new XElement("changefreq", "weekly"),
|
||||
new XElement("priority", "0.8")
|
||||
)
|
||||
)
|
||||
dynamicUrls
|
||||
)
|
||||
);
|
||||
|
||||
_logger.LogInformation($"Generated sitemap with {livePages.Count} live pages");
|
||||
|
||||
return Content(sitemap.ToString(), "application/xml", Encoding.UTF8);
|
||||
return Content(sitemap.ToString(SaveOptions.DisableFormatting), "application/xml", Encoding.UTF8);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -20,67 +20,110 @@ public class TrialExpirationService : BackgroundService
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
_logger.LogInformation("TrialExpirationService started");
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ProcessTrialExpirationsAsync();
|
||||
|
||||
// Verificar cancelamento antes de fazer delay
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
await Task.Delay(_checkInterval, stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Cancelamento normal - não é erro
|
||||
_logger.LogInformation("TrialExpirationService is being cancelled");
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error processing trial expirations");
|
||||
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); // Wait 5 minutes on error
|
||||
|
||||
// Verificar cancelamento antes de fazer delay de erro
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); // Wait 5 minutes on error
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Cancelamento durante delay de erro - também é normal
|
||||
_logger.LogInformation("TrialExpirationService cancelled during error delay");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("TrialExpirationService stopped");
|
||||
}
|
||||
|
||||
private async Task ProcessTrialExpirationsAsync()
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var subscriptionRepository = scope.ServiceProvider.GetRequiredService<ISubscriptionRepository>();
|
||||
var userPageRepository = scope.ServiceProvider.GetRequiredService<IUserPageRepository>();
|
||||
var userRepository = scope.ServiceProvider.GetRequiredService<IUserRepository>();
|
||||
|
||||
_logger.LogInformation("Checking for expired trials...");
|
||||
|
||||
// Get all active trial subscriptions
|
||||
var trialSubscriptions = await subscriptionRepository.GetTrialSubscriptionsAsync();
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
foreach (var subscription in trialSubscriptions)
|
||||
try
|
||||
{
|
||||
try
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var subscriptionRepository = scope.ServiceProvider.GetRequiredService<ISubscriptionRepository>();
|
||||
var userPageRepository = scope.ServiceProvider.GetRequiredService<IUserPageRepository>();
|
||||
var userRepository = scope.ServiceProvider.GetRequiredService<IUserRepository>();
|
||||
|
||||
_logger.LogInformation("Checking for expired trials...");
|
||||
|
||||
// Get all active trial subscriptions
|
||||
var trialSubscriptions = await subscriptionRepository.GetTrialSubscriptionsAsync();
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
_logger.LogInformation($"Found {trialSubscriptions.Count} trial subscriptions to process");
|
||||
|
||||
foreach (var subscription in trialSubscriptions)
|
||||
{
|
||||
var user = await userRepository.GetByIdAsync(subscription.UserId);
|
||||
if (user == null) continue;
|
||||
|
||||
var daysUntilExpiration = (subscription.CurrentPeriodEnd - now).TotalDays;
|
||||
|
||||
if (daysUntilExpiration <= 0)
|
||||
try
|
||||
{
|
||||
// Trial expired - deactivate page
|
||||
_logger.LogInformation($"Trial expired for user {user.Email}");
|
||||
await HandleTrialExpiredAsync(user, subscription, userPageRepository);
|
||||
var user = await userRepository.GetByIdAsync(subscription.UserId);
|
||||
if (user == null)
|
||||
{
|
||||
_logger.LogWarning($"User not found for subscription {subscription.Id}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var daysUntilExpiration = (subscription.CurrentPeriodEnd - now).TotalDays;
|
||||
|
||||
if (daysUntilExpiration <= 0)
|
||||
{
|
||||
// Trial expired - deactivate page
|
||||
_logger.LogInformation($"Trial expired for user {user.Email}");
|
||||
await HandleTrialExpiredAsync(user, subscription, userPageRepository);
|
||||
}
|
||||
else if (daysUntilExpiration <= 2 && !user.NotifiedOfExpiration)
|
||||
{
|
||||
// Trial expiring soon - send notification
|
||||
_logger.LogInformation($"Trial expiring in {daysUntilExpiration:F1} days for user {user.Email}");
|
||||
await SendExpirationWarningAsync(user, subscription, daysUntilExpiration);
|
||||
|
||||
// Mark as notified
|
||||
user.NotifiedOfExpiration = true;
|
||||
await userRepository.UpdateAsync(user);
|
||||
}
|
||||
}
|
||||
else if (daysUntilExpiration <= 2 && !user.NotifiedOfExpiration)
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Trial expiring soon - send notification
|
||||
_logger.LogInformation($"Trial expiring in {daysUntilExpiration:F1} days for user {user.Email}");
|
||||
await SendExpirationWarningAsync(user, subscription, daysUntilExpiration);
|
||||
|
||||
// Mark as notified
|
||||
user.NotifiedOfExpiration = true;
|
||||
await userRepository.UpdateAsync(user);
|
||||
_logger.LogError(ex, $"Error processing trial for subscription {subscription.Id}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"Error processing trial for subscription {subscription.Id}");
|
||||
}
|
||||
|
||||
_logger.LogInformation("Finished checking trial expirations");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Critical error in ProcessTrialExpirationsAsync");
|
||||
throw; // Re-throw para ser tratado pelo ExecuteAsync
|
||||
}
|
||||
|
||||
_logger.LogInformation("Finished checking trial expirations");
|
||||
}
|
||||
|
||||
private async Task HandleTrialExpiredAsync(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user