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

This commit is contained in:
Ricardo Carneiro 2025-09-12 08:44:05 -03:00
parent 55ad73b505
commit aea64c0b8e
2 changed files with 106 additions and 59 deletions

View File

@ -30,40 +30,44 @@ public class SitemapController : Controller
// 🔥 NOVA FUNCIONALIDADE: Usar LivePages em vez de UserPages // 🔥 NOVA FUNCIONALIDADE: Usar LivePages em vez de UserPages
var livePages = await _livePageService.GetAllActiveAsync(); 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( var sitemap = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"), new XDeclaration("1.0", "utf-8", "yes"),
new XElement("urlset", new XElement(ns + "urlset",
new XAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9"),
// Add static pages // Add static pages
new XElement("url", new XElement(ns + "url",
new XElement("loc", $"{Request.Scheme}://{Request.Host}/"), new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/"),
new XElement("lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")), new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
new XElement("changefreq", "daily"), new XElement(ns + "changefreq", "daily"),
new XElement("priority", "1.0") new XElement(ns + "priority", "1.0")
), ),
new XElement("url", new XElement(ns + "url",
new XElement("loc", $"{Request.Scheme}://{Request.Host}/Home/Pricing"), new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/Home/Pricing"),
new XElement("lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")), new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
new XElement("changefreq", "weekly"), new XElement(ns + "changefreq", "weekly"),
new XElement("priority", "0.9") new XElement(ns + "priority", "0.9")
), ),
// Add live pages (SEO-optimized URLs only) // Add live pages (SEO-optimized URLs only)
livePages.Select(page => dynamicUrls
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")
)
)
) )
); );
_logger.LogInformation($"Generated sitemap with {livePages.Count} live pages"); _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) catch (Exception ex)
{ {

View File

@ -20,22 +20,53 @@ public class TrialExpirationService : BackgroundService
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{ {
_logger.LogInformation("TrialExpirationService started");
while (!stoppingToken.IsCancellationRequested) while (!stoppingToken.IsCancellationRequested)
{ {
try try
{ {
await ProcessTrialExpirationsAsync(); await ProcessTrialExpirationsAsync();
// Verificar cancelamento antes de fazer delay
if (stoppingToken.IsCancellationRequested)
break;
await Task.Delay(_checkInterval, stoppingToken); await Task.Delay(_checkInterval, stoppingToken);
} }
catch (OperationCanceledException)
{
// Cancelamento normal - não é erro
_logger.LogInformation("TrialExpirationService is being cancelled");
break;
}
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error processing trial expirations"); _logger.LogError(ex, "Error processing trial expirations");
// 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 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() private async Task ProcessTrialExpirationsAsync()
{
try
{ {
using var scope = _serviceProvider.CreateScope(); using var scope = _serviceProvider.CreateScope();
var subscriptionRepository = scope.ServiceProvider.GetRequiredService<ISubscriptionRepository>(); var subscriptionRepository = scope.ServiceProvider.GetRequiredService<ISubscriptionRepository>();
@ -48,12 +79,18 @@ public class TrialExpirationService : BackgroundService
var trialSubscriptions = await subscriptionRepository.GetTrialSubscriptionsAsync(); var trialSubscriptions = await subscriptionRepository.GetTrialSubscriptionsAsync();
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
_logger.LogInformation($"Found {trialSubscriptions.Count} trial subscriptions to process");
foreach (var subscription in trialSubscriptions) foreach (var subscription in trialSubscriptions)
{ {
try try
{ {
var user = await userRepository.GetByIdAsync(subscription.UserId); var user = await userRepository.GetByIdAsync(subscription.UserId);
if (user == null) continue; if (user == null)
{
_logger.LogWarning($"User not found for subscription {subscription.Id}");
continue;
}
var daysUntilExpiration = (subscription.CurrentPeriodEnd - now).TotalDays; var daysUntilExpiration = (subscription.CurrentPeriodEnd - now).TotalDays;
@ -82,6 +119,12 @@ public class TrialExpirationService : BackgroundService
_logger.LogInformation("Finished checking trial expirations"); _logger.LogInformation("Finished checking trial expirations");
} }
catch (Exception ex)
{
_logger.LogError(ex, "Critical error in ProcessTrialExpirationsAsync");
throw; // Re-throw para ser tratado pelo ExecuteAsync
}
}
private async Task HandleTrialExpiredAsync( private async Task HandleTrialExpiredAsync(
User user, User user,