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
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)
{

View File

@ -20,22 +20,53 @@ 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");
// 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()
{
try
{
using var scope = _serviceProvider.CreateScope();
var subscriptionRepository = scope.ServiceProvider.GetRequiredService<ISubscriptionRepository>();
@ -48,12 +79,18 @@ public class TrialExpirationService : BackgroundService
var trialSubscriptions = await subscriptionRepository.GetTrialSubscriptionsAsync();
var now = DateTime.UtcNow;
_logger.LogInformation($"Found {trialSubscriptions.Count} trial subscriptions to process");
foreach (var subscription in trialSubscriptions)
{
try
{
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;
@ -82,6 +119,12 @@ public class TrialExpirationService : BackgroundService
_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(
User user,