- ASP.NET Core 9 Razor Pages + Minimal API hybrid - 14 validators (CPF, CEP, CNPJ, email, phone, name, yes-no, birthdate, handoff, cancel-intent, company-name, plate-br, postal-code, validate_reply) - OAuth login (Google, Microsoft, GitHub) + cookie auth - MongoDB usage tracking + CEP cache collection - Stripe checkout with inline PriceData (no Price IDs) - MCP server for Claude Code / Cursor integration - Playground (10 calls/IP/day, no auth) - Docs: Quickstart, API Reference, N8N, MCP, Créditos, Erros, Fluxos - Credit system: 3 cr standard validators, 5 cr validate_reply - SmartSuggestion: contextual re-ask via IA when obtained=false - Per-IP rate limiting + daily cap + shared-IP abuse detection - Lightbox for comic images - Validadores page split: Brasileiros / Universais + Em breve Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
41 lines
1.2 KiB
C#
41 lines
1.2 KiB
C#
using MongoDB.Driver;
|
|
using Nalu.Web.Data.Models;
|
|
|
|
namespace Nalu.Web.Data.Repositories;
|
|
|
|
public class WebhookEventRepository(MongoDbContext db)
|
|
{
|
|
/// <summary>
|
|
/// Attempts to record a Stripe event for idempotency.
|
|
/// Returns true if inserted (first time seen), false if already processed.
|
|
/// </summary>
|
|
public async Task<bool> TryInsertAsync(string stripeEventId, string eventType, CancellationToken ct = default)
|
|
{
|
|
if (!db.IsConnected) return true; // fallback: allow processing if DB unavailable
|
|
|
|
try
|
|
{
|
|
await db.WebhookEvents.InsertOneAsync(new WebhookEvent
|
|
{
|
|
StripeEventId = stripeEventId,
|
|
EventType = eventType
|
|
}, cancellationToken: ct);
|
|
|
|
return true;
|
|
}
|
|
catch (MongoWriteException ex) when (ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> ExistsAsync(string stripeEventId, CancellationToken ct = default)
|
|
{
|
|
if (!db.IsConnected) return false;
|
|
|
|
return await db.WebhookEvents
|
|
.Find(w => w.StripeEventId == stripeEventId)
|
|
.AnyAsync(ct);
|
|
}
|
|
}
|